Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

homunculus

Package Overview
Dependencies
Maintainers
2
Versions
164
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

homunculus - npm Package Compare versions

Comparing version 0.2.7 to 0.2.8

tests/csslexer.js

4

package.json
{
"name": "homunculus",
"version": "0.2.7",
"version": "0.2.8",
"description": "A lexer&parser by Javascript",

@@ -18,2 +18,3 @@ "maintainers": [

"src/lexer/Lexer",
"src/lexer/CssLexer",
"src/lexer/Token",

@@ -23,2 +24,3 @@ "src/lexer/match",

"src/lexer/rule/EcmascriptRule",
"src/lexer/rule/CssRule",
"src/parser/js",

@@ -25,0 +27,0 @@ "src/parser/es6",

@@ -5,195 +5,249 @@ var Lexer = require('./Lexer');

var CssLexer = Lexer.extend(function(rule) {
Lexer.call(this, rule);
this.isValue = false;
this.parenthese = false;
this.inBlock = false;
this.isUrl = false;
}).methods({
//@override
scan: function(temp) {
var length = this.code.length,
count = 0;
outer:
while(this.index < length) {
if(this.cacheLine > 0 && count >= this.cacheLine) {
break;
Lexer.call(this, rule);
this.media = false;
this.import = false;
this.isValue = false;
this.parenthese = false;
this.bracket = false;
this.isNumber = false;
this.isUrl = false;
this.isKw = false;
this.isSelector = false;
this.depth = 0;
}).methods({
//@override
scan: function(temp) {
var length = this.code.length;
var count = 0;
outer:
while(this.index < length) {
if(this.cacheLine > 0 && count >= this.cacheLine) {
break;
}
this.readch();
//(之后的字符串可省略"号
if(this.parenthese && this.isUrl) {
if(!{
"'": true,
'"': true,
' ': true,
'\n': true,
'\r': true,
'\t': true,
')': true
}.hasOwnProperty(this.peek)) {
this.dealPt(temp);
this.isUrl = false;
continue outer;
}
this.readch();
for(var i = 0, matches = this.rule.matches(), len = matches.length; i < len; i++) {
var match = matches[i];
if(match.match(this.peek, this.code, this.index)) {
var token = new Token(match.tokenType(), match.content(), match.val()),
matchLen = match.content().length;
//(之后的字符串可省略"号
if(this.parenthese) {
if([Token.BLANK, Token.TAB, Token.LINE, Token.ENTER].indexOf(token.type()) != -1) {
//
}
for(var i = 0, matches = this.rule.matches(), len = matches.length; i < len; i++) {
var match = matches[i];
if(match.match(this.peek, this.code, this.index)) {
var token = new Token(match.tokenType(), match.content(), match.val(), this.index - 1);
var matchLen = match.content().length;
var s = token.content();
switch(token.type()) {
//@import和@media之后进入值状态
case Token.HEAD:
switch(s) {
case '@import':
this.import = true;
break;
case '@media':
this.media = true;
break;
}
else if(token.type() == Token.STRING) {
//
this.isSelector = false;
this.isKw = false;
this.isValue = true;
this.isNumber = false;
break;
//单位要跟在数字之后,否则便不是单位
case Token.UNITS:
if(!this.isNumber) {
continue;
}
else if(token.content() == ')') {
this.parenthese = false;
}
else {
this.dealPt(temp);
continue outer;
}
}
this.isSelector = false;
this.isKw = false;
break;
//将id区分出属性名和属性值
if(token.type() == Token.ID) {
//-webkit-
if(token.content().indexOf('-webkit-') == 0) {
if(this.rule.keyWords().hasOwnProperty(token.content().slice(8))) {
token.type(Token.KEYWORD);
}
case Token.ID:
this.isKw = false;
this.isSelector = false;
if(this.bracket) {
token.type(Token.ATTR);
}
//-moz-
else if(token.content().indexOf('-moz-') == 0) {
if(this.rule.keyWords().hasOwnProperty(token.content().slice(5))) {
token.type(Token.KEYWORD);
else if(this.isValue) {
token.type(Token.PROPERTY);
if(this.rule.colors().hasOwnProperty(s)) {
token.type(Token.NUMBER);
}
}
//-ms-
else if(token.content().indexOf('-ms-') == 0) {
if(this.rule.keyWords().hasOwnProperty(token.content().slice(4))) {
token.type(Token.KEYWORD);
else {
this.isUrl = s == 'url' || s == 'format';
}
}
//-o-
else if(token.content().indexOf('-o-') == 0) {
if(this.rule.keyWords().hasOwnProperty(token.content().slice(3))) {
token.type(Token.KEYWORD);
}
}
//ie hack也算关键字
else if(/^[*\-_]/.test(token.content().charAt(0))) {
if(this.rule.keyWords().hasOwnProperty(token.content().slice(1))) {
token.type(Token.KEYWORD);
}
}
else {
//分属性和值
if(this.rule.keyWords().hasOwnProperty(token.content())) {
if(this.isValue) {
token.type(Token.PROPERTY);
if(this.rule.keyWords().hasOwnProperty(s)) {
if(this.depth || this.media || this.import) {
token.type(Token.KEYWORD);
this.isKw = true;
}
else {
token.type(Token.KEYWORD);
token.type(Token.IGNORE);
}
}
else {
var s = token.content();
if(this.rule.colors().hasOwnProperty(s)) {
token.type(Token.NUMBER);
}
else if(this.rule.values().hasOwnProperty(s)) {
token.type(Token.PROPERTY);
}
token.type(Token.SELECTOR);
this.isSelector = true;
}
}
}
//@import和@media之后进入值状态
if(token.type() == Token.HEAD && ['@import', '@media'].indexOf(token.content()) != -1) {
this.isValue = true;
}
else if(token.type() == Token.SIGN) {
if(token.content() == ':') {
this.isValue = true;
this.isNumber = false;
break;
case Token.PSEUDO:
if(!this.isSelector) {
continue;
}
else if(token.content() == '(' && this.isUrl) {
this.parenthese = true;
break;
case Token.SELECTOR:
this.isSelector = true;
this.isKw = false;
this.isNumber = false;
break;
case Token.HACK:
if(!this.depth || !this.isValue) {
token.type(Token.IGNORE);
}
else if([';', '{', '}', '(', '='].indexOf(token.content()) > -1) {
if(token.content() == '{') {
this.inBlock = true;
}
else if(token.content() == '}') {
this.inBlock = false;
}
if(token.content() == '(') {
this.isValue = this.inBlock;
}
else {
this.isUrl = false;
break;
case Token.IMPORTANT:
if(!this.depth || !this.isValue) {
token.type(Token.IGNORE);
}
this.isUrl = false;
break;
case Token.SIGN:
this.isNumber = false;
switch(s) {
case ':':
if(this.isKw) {
this.isValue = true;
}
this.isUrl = false;
this.isKw = false;
this.isSelector = false;
break;
case '(':
if(this.media || this.import) {
this.isValue = false;
}
this.parenthese = true;
break;
case ')':
if(this.media || this.import) {
this.isValue = true;
}
this.isUrl = false;
this.parenthese = false;
case '[':
if(this.isSelector) {
this.bracket = true;
}
this.isUrl = false;
break;
case ']':
this.bracket = false;
this.isUrl = false;
break;
case ';':
this.isValue = false;
}
this.import = false;
this.isUrl = false;
break;
case '{':
this.depth++;
this.isValue = false;
this.media = false;
this.import = false;
this.isUrl = false;
break;
case '}':
this.isValue = false;
this.media = false;
this.import = false;
this.isUrl = false;
this.depth--;
break;
case '-':
case '*':
case '_':
if(this.depth && !this.isValue) {
token.type(Token.HACK);
}
this.isUrl = false;
break;
default:
this.isUrl = false;
break;
}
}
//非值状态的属性被当作id
if(token.type() == Token.PROPERTY && !this.isValue) {
token.type(Token.ID);
}
//非值状态的数字被当作id
if(token.type() == Token.NUMBER && !this.isValue && token.content().charAt(0) == '#') {
token.type(Token.ID);
}
this.isUrl = token.content() == 'url' || token.content() == 'format';
temp.push(token);
this.tokenList.push(token);
this.index += matchLen - 1;
var n = character.count(token.val(), character.LINE);
count += n;
this.totalLine += n;
if(n) {
var i = match.content().indexOf(character.LINE),
j = match.content().lastIndexOf(character.LINE);
this.colMax = Math.max(this.colMax, this.colNum + i);
this.colNum = match.content().length - j;
}
else {
this.colNum += matchLen;
}
this.colMax = Math.max(this.colMax, this.colNum);
continue outer;
break;
case Token.NUMBER:
if(!this.isValue && token.content().charAt(0) == '#') {
token.type(Token.SELECTOR);
}
else {
this.isNumber = true;
}
break;
}
}
if(this.parenthese) {
this.dealPt(temp);
//回调可自定义处理匹配的token
if(match.callback) {
match.callback(token);
}
temp.push(token);
this.tokenList.push(token);
this.index += matchLen - 1;
var n = character.count(token.val(), character.LINE);
count += n;
this.totalLine += n;
if(n) {
var i = match.content().indexOf(character.LINE);
var j = match.content().lastIndexOf(character.LINE);
this.colMax = Math.max(this.colMax, this.colNum + i);
this.colNum = match.content().length - j;
}
else {
this.colNum += matchLen;
}
this.colMax = Math.max(this.colMax, this.colNum);
continue outer;
}
//如果有未匹配的,css默认忽略,查找下一个;
var j = this.code.indexOf(';', this.index);
}
//如果有未匹配的,css默认忽略,查找下一个;
var j = this.code.indexOf(';', this.index);
if(j == -1) {
j = this.code.indexOf('}', this.index);
if(j == -1) {
j = this.code.length;
}
var s = this.code.slice(this.index - 1, ++j);
var token = new Token(Token.IGNORE, s);
temp.push(token);
this.tokenList.push(token);
this.index = j;
}
return this;
},
dealPt: function(temp) {
var k = this.code.indexOf(')', this.index);
//()未结束直接跳出
if(k == -1) {
var token = new Token(Token.IGNORE, this.code.slice(this.index - 1, this.code.length));
temp.push(token);
this.tokenList.push(token);
this.index = this.code.length;
var n = character.count(token.val(), character.LINE);
if(n > 0) {
var i = token.content().indexOf(character.LINE),
j = token.content().lastIndexOf(character.LINE);
this.colMax = Math.max(this.colMax, this.colNum + i);
this.colNum = token.content().length - j;
}
else {
this.colNum += token.content().length;
}
this.colMax = Math.max(this.colMax, this.colNum);
return;
}
var s = this.code.slice(this.index - 1, k),
reg = /[\s\r\n]+\)$/.exec(s);
//)之前的空白要判断
if(reg) {
s = s.slice(0, s.length - reg[0].length);
}
var token = new Token(Token.STRING, s);
var s = this.code.slice(this.index - 1, ++j);
var token = new Token(Token.IGNORE, s);
temp.push(token);
this.tokenList.push(token);
this.index += s.length - 1;
this.parenthese = false;
this.index = j;
}
return this;
},
dealPt: function(temp) {
var k = this.code.indexOf(')', this.index);
//()未结束直接跳出
if(k == -1) {
var token = new Token(Token.IGNORE, this.code.slice(this.index - 1, this.code.length));
temp.push(token);
this.tokenList.push(token);
this.index = this.code.length;
var n = character.count(token.val(), character.LINE);

@@ -210,4 +264,36 @@ if(n > 0) {

this.colMax = Math.max(this.colMax, this.colNum);
return;
}
});
var s = this.code.slice(this.index - 1, k);
var reg = /[\s\r\n]/.exec(s.trim());
var token;
//)之前的空白要判断
if(reg) {
token = new Token(Token.IGNORE, s);
}
else {
token = new Token(Token.STRING, s);
}
temp.push(token);
this.tokenList.push(token);
this.index += s.length - 1;
this.parenthese = false;
this.url = false;
var n = character.count(token.val(), character.LINE);
if(n > 0) {
var i = token.content().indexOf(character.LINE);
var j = token.content().lastIndexOf(character.LINE);
this.colMax = Math.max(this.colMax, this.colNum + i);
this.colNum = token.content().length - j;
}
else {
this.colNum += token.content().length;
}
this.colMax = Math.max(this.colMax, this.colNum);
},
find: function() {
//
}
});
module.exports = CssLexer;

@@ -46,3 +46,6 @@ var Class = require('../util/Class');

//perl风格正则
if(perlReg && this.isReg == Lexer.IS_REG && this.peek == character.SLASH && !{ '/': true, '*': true }[this.code.charAt(this.index)]) {
if(perlReg
&& this.isReg == Lexer.IS_REG
&& this.peek == character.SLASH
&& !{ '/': true, '*': true }[this.code.charAt(this.index)]) {
this.dealReg(temp, length);

@@ -58,8 +61,11 @@ this.isReg = Lexer.NOT_REG;

var error = match.error();
if(error) {
this.error(error, this.code.slice(this.index - matchLen, this.index));
}
var matchLen = match.content().length;
if(token.type() == Token.ID && this.rule.keyWords().hasOwnProperty(token.content())) {
if(token.type() == Token.ID
&& this.rule.keyWords().hasOwnProperty(token.content())) {
token.type(Token.KEYWORD);
}
temp.push(token);
this.tokenList.push(token);
//回调可自定义处理匹配的token

@@ -69,2 +75,5 @@ if(match.callback) {

}
temp.push(token);
this.tokenList.push(token);
this.index += matchLen - 1;

@@ -84,5 +93,3 @@ var n = character.count(token.val(), character.LINE);

this.colMax = Math.max(this.colMax, this.colNum);
if(error) {
this.error(error, this.code.slice(this.index - matchLen, this.index));
}
//支持perl正则需判断关键字、圆括号对除号语义的影响

@@ -126,3 +133,4 @@ if(perlReg && match.perlReg() != Lexer.IGNORE) {

if(this.peek == character.LINE) {
this.error('SyntaxError: unterminated regular expression literal ' + this.peek, this.code.slice(lastIndex, this.index));
this.error('SyntaxError: unterminated regular expression literal '
+ this.peek, this.code.slice(lastIndex, this.index));
break;

@@ -137,3 +145,4 @@ }

if(this.peek == character.LINE) {
this.error('SyntaxError: unterminated regular expression literal ' + this.peek, this.code.slice(lastIndex, this.index));
this.error('SyntaxError: unterminated regular expression literal '
+ this.peek, this.code.slice(lastIndex, this.index));
break outer;

@@ -164,3 +173,4 @@ }

if(hash.hasOwnProperty(this.peek) || !flag.hasOwnProperty(this.peek)) {
this.error('SyntaxError: invalid regular expression flag ' + this.peek, this.code.slice(lastIndex, this.index));
this.error('SyntaxError: invalid regular expression flag '
+ this.peek, this.code.slice(lastIndex, this.index));
break outer;

@@ -177,3 +187,4 @@ }

if(!res) {
this.error('SyntaxError: unterminated regular expression literal', this.code.slice(lastIndex, this.index - 1));
this.error('SyntaxError: unterminated regular expression literal',
this.code.slice(lastIndex, this.index - 1));
}

@@ -209,6 +220,4 @@ var token = new Token(Token.REG, this.code.slice(lastIndex, --this.index), lastIndex);

}
else if(Lexer.mode() === Lexer.LOOSE && !character.isUndefined(console)) {
if(console.warn) {
console.warn(s + ', line ' + this.line() + ' col ' + this.colNum + '\n' + str);
}
else if(Lexer.mode() === Lexer.LOOSE && typeof console !== void 0) {
console.warn(s + ', line ' + this.line() + ' col ' + this.colNum + '\n' + str);
}

@@ -215,0 +224,0 @@ return this;

var Match = require('./Match');
var character = require('../../util/character');
var CompleteEqual = Match.extend(function(type, result, setPReg) {
var CompleteEqual = Match.extend(function(type, result, setPReg, ignoreCase) {
Match.call(this, type, setPReg);
this.result = result;
this.ignoreCase = ignoreCase;
}).methods({
match: function(c, code, index) {
return code.substr(--index, this.result.length) == this.result;
var s = code.substr(--index, this.result.length);
return this.ignoreCase
? s.toLowerCase() == this.result.toLowerCase()
: s == this.result;
}
});
module.exports = CompleteEqual;

@@ -5,2 +5,3 @@ var Rule = require('./Rule');

var CompleteEqual = require('../match/CompleteEqual');
var CharacterSet = require('../match/CharacterSet');
var RegMatch = require('../match/RegMatch');

@@ -10,99 +11,84 @@ var Token = require('../Token');

var CssRule = Rule.extend(function() {
var self = this;
Rule.call(self, CssRule.KEYWORDS);
var self = this;
Rule.call(self, CssRule.KEYWORDS);
self.vl = {};
CssRule.VALUES.forEach(function(o) {
self.vl[o] = true;
});
self.vl = {};
CssRule.VALUES.forEach(function(o) {
self.vl[o] = true;
});
self.cl = {};
CssRule.COLORS.forEach(function(o) {
self.cl[o] = true;
});
self.addMatch(new CompleteEqual(Token.BLANK, character.BLANK));
self.addMatch(new CompleteEqual(Token.TAB, character.TAB));
self.addMatch(new CompleteEqual(Token.ENTER, character.ENTER));
self.addMatch(new CompleteEqual(Token.LINE, character.LINE));
self.cl = {};
CssRule.COLORS.forEach(function(o) {
self.cl[o] = true;
});
self.addMatch(new LineSearch(Token.COMMENT, '//', '\n'));
self.addMatch(new LineSearch(Token.COMMENT, '/*', '*/', true));
self.addMatch(new LineParse(Token.STRING, '"', '"', false));
self.addMatch(new LineParse(Token.STRING, "'", "'", false));
self.addMatch(new RegMatch(Token.NUMBER, /^-\d+\.?\d*[a-z%]*/i));
self.addMatch(new CompleteEqual(Token.BLANK, character.BLANK));
self.addMatch(new CompleteEqual(Token.TAB, character.TAB));
self.addMatch(new CompleteEqual(Token.LINE, character.ENTER + character.LINE));
self.addMatch(new CompleteEqual(Token.LINE, character.ENTER));
self.addMatch(new CompleteEqual(Token.LINE, character.LINE));
self.addMatch(new CompleteEqual(Token.HACK, '\\9\\0'));
self.addMatch(new CompleteEqual(Token.HACK, '\\0'));
self.addMatch(new CompleteEqual(Token.HACK, '\\9'));
self.addMatch(new LineSearch(Token.COMMENT, '//', [character.ENTER + character.LINE, character.ENTER, character.LINE]));
self.addMatch(new LineSearch(Token.COMMENT, '/*', '*/', true));
self.addMatch(new LineParse(Token.STRING, '"', '"', false));
self.addMatch(new LineParse(Token.STRING, "'", "'", false));
self.addMatch(new RegMatch(Token.ID, /^[a-z_\-*][\w\-_]+/i));
self.addMatch(new RegMatch(Token.ID, /^(\\[a-z\d]{4})+/i));
self.addMatch(new CompleteEqual(Token.IMPORTANT, '!important'));
self.addMatch(new RegMatch(Token.NUMBER, /^-?\d+\.?\d*/i));
self.addMatch(new RegMatch(Token.NUMBER, /^\.\d+/i));
['%', 'em', 'px', 'rem', 'ex', 'ch', 'vw', 'vh', 'vm', 'cm', 'mm', 'in', 'pt', 'pc', 's', 'ms', 'Hz', 'kHz', 'fr', 'gr'].forEach(function(o) {
self.addMatch(new CompleteEqual(Token.UNITS, o, null, true));
});
self.addMatch(new RegMatch(Token.NUMBER, /^\.\d+[a-z%]*/i));
self.addMatch(new CompleteEqual(Token.HACK, '\\9\\0'));
self.addMatch(new CompleteEqual(Token.HACK, '\\0'));
self.addMatch(new CompleteEqual(Token.HACK, '\\9'));
self.addMatch(new CompleteEqual(Token.HACK, '-moz-'), null, true);
self.addMatch(new CompleteEqual(Token.HACK, '-webkit-'), null, true);
self.addMatch(new CompleteEqual(Token.HACK, '-ms-'), null, true);
self.addMatch(new CompleteEqual(Token.HACK, '-o-'), null, true);
self.addMatch(new CompleteEqual(Token.ID, '::first-letter'));
self.addMatch(new CompleteEqual(Token.ID, ':first-letter'));
self.addMatch(new CompleteEqual(Token.ID, '::first-line'));
self.addMatch(new CompleteEqual(Token.ID, '::first-line'));
self.addMatch(new CompleteEqual(Token.ID, '::before'));
self.addMatch(new CompleteEqual(Token.ID, ':before'));
self.addMatch(new CompleteEqual(Token.ID, '::after'));
self.addMatch(new CompleteEqual(Token.ID, ':after'));
self.addMatch(new CompleteEqual(Token.ID, '::selection'));
self.addMatch(new CompleteEqual(Token.ID, ':link'));
self.addMatch(new CompleteEqual(Token.ID, ':visited'));
self.addMatch(new CompleteEqual(Token.ID, ':hover'));
self.addMatch(new CompleteEqual(Token.ID, ':active'));
self.addMatch(new CompleteEqual(Token.ID, ':focus'));
self.addMatch(new RegMatch(Token.ID, /^:lang\([\w-]+\)/));
self.addMatch(new CompleteEqual(Token.ID, /^:not\([\w-]+\)/));
self.addMatch(new CompleteEqual(Token.ID, ':root'));
self.addMatch(new CompleteEqual(Token.ID, ':first-child'));
self.addMatch(new CompleteEqual(Token.ID, ':last-child'));
self.addMatch(new CompleteEqual(Token.ID, ':only-child'));
self.addMatch(new CompleteEqual(Token.ID, /^:nth-child\(\d+\)/));
self.addMatch(new CompleteEqual(Token.ID, /^:nth-last-child\(\d+\)/));
self.addMatch(new CompleteEqual(Token.ID, ':first-of-type'));
self.addMatch(new CompleteEqual(Token.ID, ':last-of-type'));
self.addMatch(new CompleteEqual(Token.ID, ':only-of-type'));
self.addMatch(new CompleteEqual(Token.ID, /^:nth-of-type\(\d+\)/));
self.addMatch(new CompleteEqual(Token.ID, /^:nth-last-of-type\(\d+\)/));
self.addMatch(new CompleteEqual(Token.ID, ':empty'));
self.addMatch(new CompleteEqual(Token.ID, ':checked'));
self.addMatch(new CompleteEqual(Token.ID, ':enabled'));
self.addMatch(new CompleteEqual(Token.ID, ':disabled'));
self.addMatch(new CompleteEqual(Token.ID, '@page:first'));
self.addMatch(new CompleteEqual(Token.ID, '@page:left'));
self.addMatch(new CompleteEqual(Token.ID, '@page:right'));
self.addMatch(new RegMatch(Token.ID, /^::?(?:-(?:moz|webkit|ms|o)-)?(?:placeholder|clear)/));
self.addMatch(new CompleteEqual(Token.ID, '&'));
self.addMatch(new RegMatch(Token.NUMBER, /^#[\da-f]{3,6}/i));
self.addMatch(new RegMatch(Token.SELECTOR, /^\.[a-z_][\w_]*/i));
self.addMatch(new RegMatch(Token.SELECTOR, /^#\w[\w\-]*/i));
self.addMatch(new RegMatch(Token.ID, /^[a-z]\w*(?:-\w+)*/i));
self.addMatch(new RegMatch(Token.STRING, /^(\\[a-z\d]{4})+/i));
self.addMatch(new CompleteEqual(Token.IMPORTANT, '!important', null, true));
self.addMatch(new RegMatch(Token.PSEUDO, /^::?(?:-(?:moz|webkit|ms|o)-)?[a-z]+(?:-[a-z]+)*(?:\(:?[\w\-]+\))?/i));
['$=', '|=', '*=', '~=', '^='].forEach(function(o) {
self.addMatch(new CompleteEqual(Token.SIGN, o));
});
self.addMatch(new CharacterSet(Token.SIGN, '&{},:();-{}>+/[]=~*_'));
['{', '}', ',', ';', '::', ':', '-', '(', ')', '>', '+', '/', '[', ']', '$=', '|=', '*=', '~=', '^=', '=', '~', '*'].forEach(function(o) {
self.addMatch(new CompleteEqual(Token.SIGN, o));
});
self.addMatch(new RegMatch(Token.HEAD, /^@[\w-]+/));
self.addMatch(new RegMatch(Token.VARS, /^@\{[\w-]+\}/));
self.addMatch(new RegMatch(Token.VARS, /^\$[\w-]+/));
self.addMatch(new RegMatch(Token.VARS, /^\$\{[\w-]+\}/));
var head = new RegMatch(Token.HEAD, /^@[\w-]+/);
head.callback = function(token) {
var s = token.content().toLowerCase();
if(!{
'@page': true,
'@import': true,
'@charset': true,
'@media': true,
'@font-face': true,
'@keyframes': true,
'@namespace': true
}.hasOwnProperty(s)) {
token.type(Token.VARS);
}
};
self.addMatch(head);
self.addMatch(new RegMatch(Token.NUMBER, /^#[\da-f]{6}/i));
self.addMatch(new RegMatch(Token.NUMBER, /^#[\da-f]{3}/i));
self.addMatch(new RegMatch(Token.NUMBER, /^\d+\.?\d*[a-z%]*/i));
self.addMatch(new RegMatch(Token.ID, /^[.#]?[a-z_][\w\-_.#]*/i));
}).methods({
values: function() {
return this.vl;
},
colors: function() {
return this.cl;
}
}).statics({
KEYWORDS: 'appearance ascent aspect-ratio azimuth backface-visibility background-attachment background-clip background-color background-image background-origin background-position background-repeat background-size background baseline bbox border-collapse border-color border-image border-radius border-spacing border-style border-top border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width border-bottom-width border-left-width border-width border-top-left-radius border-bottom-left-radius border-top-right-radius border-bottom-right-radius border bottom box-shadow box-sizing cap-height caption-side centerline clear clip color color-index content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent device-aspect-ratio device-height device-width direction display elevation empty-cells filter float font-size-adjust font-smoothing font-family font-size font-stretch font-style font-variant font-weight font grid height interpolation-mode left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top margin-right margin-bottom margin-left margin marker-offset marks mathline max-aspect-ratio max-device-width max-height max-width min-aspect-ratio min-device-width min-height min-width monochrome nav-down nav-left nav-right nav-up opacity orphans outline-color outline-style outline-width orientation outline overflow-x overflow-y overflow padding-top padding-right padding-bottom padding-left padding page page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position quotes resize resolution right richness scan size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress table-layout text-align top text-decoration text-indent text-justify text-overflow text-shadow text-transform transform transform-origin transition transition-property unicode-bidi unicode-range units-per-em vertical-align visibility voice-family volume white-space widows width widths word-break word-spacing word-wrap x-height z-index zoom'.split(' '),
VALUES: 'above absolute all alpha always antialiased aqua armenian attr aural auto avoid background baseline behind below bicubic bidi-override black blink block blue bold bolder border-box both bottom break-all break-word braille capitalize caption center center-left center-right circle close-quote code collapse color compact condensed content-box continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double ease ease-in ease-out ease-in-out embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed flipouttoleft flipouttoright flipouttotop flipouttobottom format fuchsia gray grayscale green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside inter-ideograph invert italic justify landscape large larger left-side leftwards level lighter lime linear-gradient linear line-through list-item local loud lower-alpha lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once opacity open-quote outset outside overline padding-box pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side rightwards rotate rotateX rotateY rtl run-in scale screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal text-bottom text-top text thick thin top transparent translate tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin upper-roman url visible wait white wider width w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow'.split(' '),
COLORS: 'black silver gray white maroon red purple fuchsia green lime olive yellow navy blue teal aqua'.split(' ')
});
self.addMatch(new RegMatch(Token.VARS, /^@\{[\w-]+\}/));
self.addMatch(new RegMatch(Token.VARS, /^\$[\w-]+/));
self.addMatch(new RegMatch(Token.VARS, /^\$\{[\w-]+\}/));
}).methods({
values: function() {
return this.vl;
},
colors: function() {
return this.cl;
}
}).statics({
KEYWORDS: 'appearance ascent aspect-ratio azimuth backface-visibility background-attachment background-clip background-color background-image background-origin background-position background-repeat background-size background baseline bbox border-collapse border-color border-image border-radius border-spacing border-style border-top border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width border-bottom-width border-left-width border-width border-top-left-radius border-bottom-left-radius border-top-right-radius border-bottom-right-radius border bottom box-shadow box-sizing cap-height caption-side centerline clear clip color color-index content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent device-aspect-ratio device-height device-width direction display elevation empty-cells filter float font-size-adjust font-smoothing font-family font-size font-stretch font-style font-variant font-weight font grid height interpolation-mode left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top margin-right margin-bottom margin-left margin marker-offset marks mathline max-aspect-ratio max-device-pixel-ratio max-device-width max-height max-width min-aspect-ratio min-device-pixel-ratio min-device-width min-height min-width monochrome nav-down nav-left nav-right nav-up opacity orphans outline-color outline-style outline-width orientation outline overflow-x overflow-y overflow padding-top padding-right padding-bottom padding-left padding page page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position quotes resize resolution right richness scan size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress table-layout text-align top text-decoration text-indent text-justify text-overflow text-shadow text-transform transform transform-origin transition transition-property unicode-bidi unicode-range units-per-em vertical-align visibility voice-family volume white-space widows width widths word-break word-spacing word-wrap x-height z-index zoom'.split(' '),
VALUES: 'above absolute all alpha always antialiased aqua armenian attr aural auto avoid background baseline behind below bicubic bidi-override black blink block blue bold bolder border-box both bottom break-all break-word braille capitalize caption center center-left center-right circle close-quote code collapse color compact condensed content-box continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double ease ease-in ease-out ease-in-out embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed flipouttoleft flipouttoright flipouttotop flipouttobottom format fuchsia gray grayscale green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside inter-ideograph invert italic justify landscape large larger left-side leftwards level lighter lime linear-gradient linear line-through list-item local loud lower-alpha lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once opacity open-quote outset outside overline padding-box pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side rightwards rotate rotateX rotateY rtl run-in scale screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal text-bottom text-top text thick thin top transparent translate tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin upper-roman url visible wait white wider width w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow'.split(' '),
COLORS: 'black silver gray white maroon red purple fuchsia green lime olive yellow navy blue teal aqua'.split(' ')
});
module.exports = CssRule;

@@ -78,2 +78,6 @@ var Class = require('../util/Class');

IMPORTANT: 18,
PSEUDO: 19,
UNITS: 20,
SELECTOR: 21,
ATTR: 22,
type: function(tag) {

@@ -80,0 +84,0 @@ if(character.isUndefined(types)) {

@@ -283,2 +283,4 @@ var IParser = require('../Parser');

return this.classdecl();
default:
this.error();
}

@@ -541,3 +543,3 @@ },

},
blockstmt: function() {
blockstmt: function(yYield) {
var node = new Node(Node.BLOCKSTMT);

@@ -1226,2 +1228,3 @@ node.add(this.block(null, yYield));

&& this.look.content() == '=>'
&& this.hasMoveLine == false
&& cndt.name() == Node.PRMREXPR

@@ -1228,0 +1231,0 @@ && cndt.size() == 1

@@ -7,3 +7,3 @@ var homunculus = require('../');

var Token = homunculus.getClass('token', 'js');
var Token = homunculus.getClass('token');
var Lexer = homunculus.getClass('lexer', 'js');

@@ -10,0 +10,0 @@

@@ -6,195 +6,249 @@ define(function(require, exports, module) {

var CssLexer = Lexer.extend(function(rule) {
Lexer.call(this, rule);
this.isValue = false;
this.parenthese = false;
this.inBlock = false;
this.isUrl = false;
}).methods({
//@override
scan: function(temp) {
var length = this.code.length,
count = 0;
outer:
while(this.index < length) {
if(this.cacheLine > 0 && count >= this.cacheLine) {
break;
Lexer.call(this, rule);
this.media = false;
this.import = false;
this.isValue = false;
this.parenthese = false;
this.bracket = false;
this.isNumber = false;
this.isUrl = false;
this.isKw = false;
this.isSelector = false;
this.depth = 0;
}).methods({
//@override
scan: function(temp) {
var length = this.code.length;
var count = 0;
outer:
while(this.index < length) {
if(this.cacheLine > 0 && count >= this.cacheLine) {
break;
}
this.readch();
//(之后的字符串可省略"号
if(this.parenthese && this.isUrl) {
if(!{
"'": true,
'"': true,
' ': true,
'\n': true,
'\r': true,
'\t': true,
')': true
}.hasOwnProperty(this.peek)) {
this.dealPt(temp);
this.isUrl = false;
continue outer;
}
this.readch();
for(var i = 0, matches = this.rule.matches(), len = matches.length; i < len; i++) {
var match = matches[i];
if(match.match(this.peek, this.code, this.index)) {
var token = new Token(match.tokenType(), match.content(), match.val()),
matchLen = match.content().length;
//(之后的字符串可省略"号
if(this.parenthese) {
if([Token.BLANK, Token.TAB, Token.LINE, Token.ENTER].indexOf(token.type()) != -1) {
//
}
for(var i = 0, matches = this.rule.matches(), len = matches.length; i < len; i++) {
var match = matches[i];
if(match.match(this.peek, this.code, this.index)) {
var token = new Token(match.tokenType(), match.content(), match.val(), this.index - 1);
var matchLen = match.content().length;
var s = token.content();
switch(token.type()) {
//@import和@media之后进入值状态
case Token.HEAD:
switch(s) {
case '@import':
this.import = true;
break;
case '@media':
this.media = true;
break;
}
else if(token.type() == Token.STRING) {
//
this.isSelector = false;
this.isKw = false;
this.isValue = true;
this.isNumber = false;
break;
//单位要跟在数字之后,否则便不是单位
case Token.UNITS:
if(!this.isNumber) {
continue;
}
else if(token.content() == ')') {
this.parenthese = false;
}
else {
this.dealPt(temp);
continue outer;
}
}
this.isSelector = false;
this.isKw = false;
break;
//将id区分出属性名和属性值
if(token.type() == Token.ID) {
//-webkit-
if(token.content().indexOf('-webkit-') == 0) {
if(this.rule.keyWords().hasOwnProperty(token.content().slice(8))) {
token.type(Token.KEYWORD);
}
case Token.ID:
this.isKw = false;
this.isSelector = false;
if(this.bracket) {
token.type(Token.ATTR);
}
//-moz-
else if(token.content().indexOf('-moz-') == 0) {
if(this.rule.keyWords().hasOwnProperty(token.content().slice(5))) {
token.type(Token.KEYWORD);
else if(this.isValue) {
token.type(Token.PROPERTY);
if(this.rule.colors().hasOwnProperty(s)) {
token.type(Token.NUMBER);
}
}
//-ms-
else if(token.content().indexOf('-ms-') == 0) {
if(this.rule.keyWords().hasOwnProperty(token.content().slice(4))) {
token.type(Token.KEYWORD);
else {
this.isUrl = s == 'url' || s == 'format';
}
}
//-o-
else if(token.content().indexOf('-o-') == 0) {
if(this.rule.keyWords().hasOwnProperty(token.content().slice(3))) {
token.type(Token.KEYWORD);
}
}
//ie hack也算关键字
else if(/^[*\-_]/.test(token.content().charAt(0))) {
if(this.rule.keyWords().hasOwnProperty(token.content().slice(1))) {
token.type(Token.KEYWORD);
}
}
else {
//分属性和值
if(this.rule.keyWords().hasOwnProperty(token.content())) {
if(this.isValue) {
token.type(Token.PROPERTY);
if(this.rule.keyWords().hasOwnProperty(s)) {
if(this.depth || this.media || this.import) {
token.type(Token.KEYWORD);
this.isKw = true;
}
else {
token.type(Token.KEYWORD);
token.type(Token.IGNORE);
}
}
else {
var s = token.content();
if(this.rule.colors().hasOwnProperty(s)) {
token.type(Token.NUMBER);
}
else if(this.rule.values().hasOwnProperty(s)) {
token.type(Token.PROPERTY);
}
token.type(Token.SELECTOR);
this.isSelector = true;
}
}
}
//@import和@media之后进入值状态
if(token.type() == Token.HEAD && ['@import', '@media'].indexOf(token.content()) != -1) {
this.isValue = true;
}
else if(token.type() == Token.SIGN) {
if(token.content() == ':') {
this.isValue = true;
this.isNumber = false;
break;
case Token.PSEUDO:
if(!this.isSelector) {
continue;
}
else if(token.content() == '(' && this.isUrl) {
this.parenthese = true;
break;
case Token.SELECTOR:
this.isSelector = true;
this.isKw = false;
this.isNumber = false;
break;
case Token.HACK:
if(!this.depth || !this.isValue) {
token.type(Token.IGNORE);
}
else if([';', '{', '}', '(', '='].indexOf(token.content()) > -1) {
if(token.content() == '{') {
this.inBlock = true;
}
else if(token.content() == '}') {
this.inBlock = false;
}
if(token.content() == '(') {
this.isValue = this.inBlock;
}
else {
this.isUrl = false;
break;
case Token.IMPORTANT:
if(!this.depth || !this.isValue) {
token.type(Token.IGNORE);
}
this.isUrl = false;
break;
case Token.SIGN:
this.isNumber = false;
switch(s) {
case ':':
if(this.isKw) {
this.isValue = true;
}
this.isUrl = false;
this.isKw = false;
this.isSelector = false;
break;
case '(':
if(this.media || this.import) {
this.isValue = false;
}
this.parenthese = true;
break;
case ')':
if(this.media || this.import) {
this.isValue = true;
}
this.isUrl = false;
this.parenthese = false;
case '[':
if(this.isSelector) {
this.bracket = true;
}
this.isUrl = false;
break;
case ']':
this.bracket = false;
this.isUrl = false;
break;
case ';':
this.isValue = false;
}
this.import = false;
this.isUrl = false;
break;
case '{':
this.depth++;
this.isValue = false;
this.media = false;
this.import = false;
this.isUrl = false;
break;
case '}':
this.isValue = false;
this.media = false;
this.import = false;
this.isUrl = false;
this.depth--;
break;
case '-':
case '*':
case '_':
if(this.depth && !this.isValue) {
token.type(Token.HACK);
}
this.isUrl = false;
break;
default:
this.isUrl = false;
break;
}
}
//非值状态的属性被当作id
if(token.type() == Token.PROPERTY && !this.isValue) {
token.type(Token.ID);
}
//非值状态的数字被当作id
if(token.type() == Token.NUMBER && !this.isValue && token.content().charAt(0) == '#') {
token.type(Token.ID);
}
this.isUrl = token.content() == 'url' || token.content() == 'format';
temp.push(token);
this.tokenList.push(token);
this.index += matchLen - 1;
var n = character.count(token.val(), character.LINE);
count += n;
this.totalLine += n;
if(n) {
var i = match.content().indexOf(character.LINE),
j = match.content().lastIndexOf(character.LINE);
this.colMax = Math.max(this.colMax, this.colNum + i);
this.colNum = match.content().length - j;
}
else {
this.colNum += matchLen;
}
this.colMax = Math.max(this.colMax, this.colNum);
continue outer;
break;
case Token.NUMBER:
if(!this.isValue && token.content().charAt(0) == '#') {
token.type(Token.SELECTOR);
}
else {
this.isNumber = true;
}
break;
}
}
if(this.parenthese) {
this.dealPt(temp);
//回调可自定义处理匹配的token
if(match.callback) {
match.callback(token);
}
temp.push(token);
this.tokenList.push(token);
this.index += matchLen - 1;
var n = character.count(token.val(), character.LINE);
count += n;
this.totalLine += n;
if(n) {
var i = match.content().indexOf(character.LINE);
var j = match.content().lastIndexOf(character.LINE);
this.colMax = Math.max(this.colMax, this.colNum + i);
this.colNum = match.content().length - j;
}
else {
this.colNum += matchLen;
}
this.colMax = Math.max(this.colMax, this.colNum);
continue outer;
}
//如果有未匹配的,css默认忽略,查找下一个;
var j = this.code.indexOf(';', this.index);
}
//如果有未匹配的,css默认忽略,查找下一个;
var j = this.code.indexOf(';', this.index);
if(j == -1) {
j = this.code.indexOf('}', this.index);
if(j == -1) {
j = this.code.length;
}
var s = this.code.slice(this.index - 1, ++j);
var token = new Token(Token.IGNORE, s);
temp.push(token);
this.tokenList.push(token);
this.index = j;
}
return this;
},
dealPt: function(temp) {
var k = this.code.indexOf(')', this.index);
//()未结束直接跳出
if(k == -1) {
var token = new Token(Token.IGNORE, this.code.slice(this.index - 1, this.code.length));
temp.push(token);
this.tokenList.push(token);
this.index = this.code.length;
var n = character.count(token.val(), character.LINE);
if(n > 0) {
var i = token.content().indexOf(character.LINE),
j = token.content().lastIndexOf(character.LINE);
this.colMax = Math.max(this.colMax, this.colNum + i);
this.colNum = token.content().length - j;
}
else {
this.colNum += token.content().length;
}
this.colMax = Math.max(this.colMax, this.colNum);
return;
}
var s = this.code.slice(this.index - 1, k),
reg = /[\s\r\n]+\)$/.exec(s);
//)之前的空白要判断
if(reg) {
s = s.slice(0, s.length - reg[0].length);
}
var token = new Token(Token.STRING, s);
var s = this.code.slice(this.index - 1, ++j);
var token = new Token(Token.IGNORE, s);
temp.push(token);
this.tokenList.push(token);
this.index += s.length - 1;
this.parenthese = false;
this.index = j;
}
return this;
},
dealPt: function(temp) {
var k = this.code.indexOf(')', this.index);
//()未结束直接跳出
if(k == -1) {
var token = new Token(Token.IGNORE, this.code.slice(this.index - 1, this.code.length));
temp.push(token);
this.tokenList.push(token);
this.index = this.code.length;
var n = character.count(token.val(), character.LINE);

@@ -211,5 +265,37 @@ if(n > 0) {

this.colMax = Math.max(this.colMax, this.colNum);
return;
}
});
var s = this.code.slice(this.index - 1, k);
var reg = /[\s\r\n]/.exec(s.trim());
var token;
//)之前的空白要判断
if(reg) {
token = new Token(Token.IGNORE, s);
}
else {
token = new Token(Token.STRING, s);
}
temp.push(token);
this.tokenList.push(token);
this.index += s.length - 1;
this.parenthese = false;
this.url = false;
var n = character.count(token.val(), character.LINE);
if(n > 0) {
var i = token.content().indexOf(character.LINE);
var j = token.content().lastIndexOf(character.LINE);
this.colMax = Math.max(this.colMax, this.colNum + i);
this.colNum = token.content().length - j;
}
else {
this.colNum += token.content().length;
}
this.colMax = Math.max(this.colMax, this.colNum);
},
find: function() {
//
}
});
module.exports = CssLexer;
});

@@ -47,3 +47,6 @@ define(function(require, exports, module) {

//perl风格正则
if(perlReg && this.isReg == Lexer.IS_REG && this.peek == character.SLASH && !{ '/': true, '*': true }[this.code.charAt(this.index)]) {
if(perlReg
&& this.isReg == Lexer.IS_REG
&& this.peek == character.SLASH
&& !{ '/': true, '*': true }[this.code.charAt(this.index)]) {
this.dealReg(temp, length);

@@ -59,8 +62,11 @@ this.isReg = Lexer.NOT_REG;

var error = match.error();
if(error) {
this.error(error, this.code.slice(this.index - matchLen, this.index));
}
var matchLen = match.content().length;
if(token.type() == Token.ID && this.rule.keyWords().hasOwnProperty(token.content())) {
if(token.type() == Token.ID
&& this.rule.keyWords().hasOwnProperty(token.content())) {
token.type(Token.KEYWORD);
}
temp.push(token);
this.tokenList.push(token);
//回调可自定义处理匹配的token

@@ -70,2 +76,5 @@ if(match.callback) {

}
temp.push(token);
this.tokenList.push(token);
this.index += matchLen - 1;

@@ -85,5 +94,3 @@ var n = character.count(token.val(), character.LINE);

this.colMax = Math.max(this.colMax, this.colNum);
if(error) {
this.error(error, this.code.slice(this.index - matchLen, this.index));
}
//支持perl正则需判断关键字、圆括号对除号语义的影响

@@ -127,3 +134,4 @@ if(perlReg && match.perlReg() != Lexer.IGNORE) {

if(this.peek == character.LINE) {
this.error('SyntaxError: unterminated regular expression literal ' + this.peek, this.code.slice(lastIndex, this.index));
this.error('SyntaxError: unterminated regular expression literal '
+ this.peek, this.code.slice(lastIndex, this.index));
break;

@@ -138,3 +146,4 @@ }

if(this.peek == character.LINE) {
this.error('SyntaxError: unterminated regular expression literal ' + this.peek, this.code.slice(lastIndex, this.index));
this.error('SyntaxError: unterminated regular expression literal '
+ this.peek, this.code.slice(lastIndex, this.index));
break outer;

@@ -165,3 +174,4 @@ }

if(hash.hasOwnProperty(this.peek) || !flag.hasOwnProperty(this.peek)) {
this.error('SyntaxError: invalid regular expression flag ' + this.peek, this.code.slice(lastIndex, this.index));
this.error('SyntaxError: invalid regular expression flag '
+ this.peek, this.code.slice(lastIndex, this.index));
break outer;

@@ -178,3 +188,4 @@ }

if(!res) {
this.error('SyntaxError: unterminated regular expression literal', this.code.slice(lastIndex, this.index - 1));
this.error('SyntaxError: unterminated regular expression literal',
this.code.slice(lastIndex, this.index - 1));
}

@@ -210,6 +221,4 @@ var token = new Token(Token.REG, this.code.slice(lastIndex, --this.index), lastIndex);

}
else if(Lexer.mode() === Lexer.LOOSE && !character.isUndefined(console)) {
if(console.warn) {
console.warn(s + ', line ' + this.line() + ' col ' + this.colNum + '\n' + str);
}
else if(Lexer.mode() === Lexer.LOOSE && typeof console !== void 0) {
console.warn(s + ', line ' + this.line() + ' col ' + this.colNum + '\n' + str);
}

@@ -216,0 +225,0 @@ return this;

define(function(require, exports, module) {
var Match = require('./Match');
var character = require('../../util/character');
var CompleteEqual = Match.extend(function(type, result, setPReg) {
var CompleteEqual = Match.extend(function(type, result, setPReg, ignoreCase) {
Match.call(this, type, setPReg);
this.result = result;
this.ignoreCase = ignoreCase;
}).methods({
match: function(c, code, index) {
return code.substr(--index, this.result.length) == this.result;
var s = code.substr(--index, this.result.length);
return this.ignoreCase
? s.toLowerCase() == this.result.toLowerCase()
: s == this.result;
}

@@ -11,0 +15,0 @@ });

@@ -6,2 +6,3 @@ define(function(require, exports, module) {

var CompleteEqual = require('../match/CompleteEqual');
var CharacterSet = require('../match/CharacterSet');
var RegMatch = require('../match/RegMatch');

@@ -11,100 +12,85 @@ var Token = require('../Token');

var CssRule = Rule.extend(function() {
var self = this;
Rule.call(self, CssRule.KEYWORDS);
var self = this;
Rule.call(self, CssRule.KEYWORDS);
self.vl = {};
CssRule.VALUES.forEach(function(o) {
self.vl[o] = true;
});
self.vl = {};
CssRule.VALUES.forEach(function(o) {
self.vl[o] = true;
});
self.cl = {};
CssRule.COLORS.forEach(function(o) {
self.cl[o] = true;
});
self.addMatch(new CompleteEqual(Token.BLANK, character.BLANK));
self.addMatch(new CompleteEqual(Token.TAB, character.TAB));
self.addMatch(new CompleteEqual(Token.ENTER, character.ENTER));
self.addMatch(new CompleteEqual(Token.LINE, character.LINE));
self.cl = {};
CssRule.COLORS.forEach(function(o) {
self.cl[o] = true;
});
self.addMatch(new LineSearch(Token.COMMENT, '//', '\n'));
self.addMatch(new LineSearch(Token.COMMENT, '/*', '*/', true));
self.addMatch(new LineParse(Token.STRING, '"', '"', false));
self.addMatch(new LineParse(Token.STRING, "'", "'", false));
self.addMatch(new RegMatch(Token.NUMBER, /^-\d+\.?\d*[a-z%]*/i));
self.addMatch(new CompleteEqual(Token.BLANK, character.BLANK));
self.addMatch(new CompleteEqual(Token.TAB, character.TAB));
self.addMatch(new CompleteEqual(Token.LINE, character.ENTER + character.LINE));
self.addMatch(new CompleteEqual(Token.LINE, character.ENTER));
self.addMatch(new CompleteEqual(Token.LINE, character.LINE));
self.addMatch(new CompleteEqual(Token.HACK, '\\9\\0'));
self.addMatch(new CompleteEqual(Token.HACK, '\\0'));
self.addMatch(new CompleteEqual(Token.HACK, '\\9'));
self.addMatch(new LineSearch(Token.COMMENT, '//', [character.ENTER + character.LINE, character.ENTER, character.LINE]));
self.addMatch(new LineSearch(Token.COMMENT, '/*', '*/', true));
self.addMatch(new LineParse(Token.STRING, '"', '"', false));
self.addMatch(new LineParse(Token.STRING, "'", "'", false));
self.addMatch(new RegMatch(Token.ID, /^[a-z_\-*][\w\-_]+/i));
self.addMatch(new RegMatch(Token.ID, /^(\\[a-z\d]{4})+/i));
self.addMatch(new CompleteEqual(Token.IMPORTANT, '!important'));
self.addMatch(new RegMatch(Token.NUMBER, /^-?\d+\.?\d*/i));
self.addMatch(new RegMatch(Token.NUMBER, /^\.\d+/i));
['%', 'em', 'px', 'rem', 'ex', 'ch', 'vw', 'vh', 'vm', 'cm', 'mm', 'in', 'pt', 'pc', 's', 'ms', 'Hz', 'kHz', 'fr', 'gr'].forEach(function(o) {
self.addMatch(new CompleteEqual(Token.UNITS, o, null, true));
});
self.addMatch(new RegMatch(Token.NUMBER, /^\.\d+[a-z%]*/i));
self.addMatch(new CompleteEqual(Token.HACK, '\\9\\0'));
self.addMatch(new CompleteEqual(Token.HACK, '\\0'));
self.addMatch(new CompleteEqual(Token.HACK, '\\9'));
self.addMatch(new CompleteEqual(Token.HACK, '-moz-'), null, true);
self.addMatch(new CompleteEqual(Token.HACK, '-webkit-'), null, true);
self.addMatch(new CompleteEqual(Token.HACK, '-ms-'), null, true);
self.addMatch(new CompleteEqual(Token.HACK, '-o-'), null, true);
self.addMatch(new CompleteEqual(Token.ID, '::first-letter'));
self.addMatch(new CompleteEqual(Token.ID, ':first-letter'));
self.addMatch(new CompleteEqual(Token.ID, '::first-line'));
self.addMatch(new CompleteEqual(Token.ID, '::first-line'));
self.addMatch(new CompleteEqual(Token.ID, '::before'));
self.addMatch(new CompleteEqual(Token.ID, ':before'));
self.addMatch(new CompleteEqual(Token.ID, '::after'));
self.addMatch(new CompleteEqual(Token.ID, ':after'));
self.addMatch(new CompleteEqual(Token.ID, '::selection'));
self.addMatch(new CompleteEqual(Token.ID, ':link'));
self.addMatch(new CompleteEqual(Token.ID, ':visited'));
self.addMatch(new CompleteEqual(Token.ID, ':hover'));
self.addMatch(new CompleteEqual(Token.ID, ':active'));
self.addMatch(new CompleteEqual(Token.ID, ':focus'));
self.addMatch(new RegMatch(Token.ID, /^:lang\([\w-]+\)/));
self.addMatch(new CompleteEqual(Token.ID, /^:not\([\w-]+\)/));
self.addMatch(new CompleteEqual(Token.ID, ':root'));
self.addMatch(new CompleteEqual(Token.ID, ':first-child'));
self.addMatch(new CompleteEqual(Token.ID, ':last-child'));
self.addMatch(new CompleteEqual(Token.ID, ':only-child'));
self.addMatch(new CompleteEqual(Token.ID, /^:nth-child\(\d+\)/));
self.addMatch(new CompleteEqual(Token.ID, /^:nth-last-child\(\d+\)/));
self.addMatch(new CompleteEqual(Token.ID, ':first-of-type'));
self.addMatch(new CompleteEqual(Token.ID, ':last-of-type'));
self.addMatch(new CompleteEqual(Token.ID, ':only-of-type'));
self.addMatch(new CompleteEqual(Token.ID, /^:nth-of-type\(\d+\)/));
self.addMatch(new CompleteEqual(Token.ID, /^:nth-last-of-type\(\d+\)/));
self.addMatch(new CompleteEqual(Token.ID, ':empty'));
self.addMatch(new CompleteEqual(Token.ID, ':checked'));
self.addMatch(new CompleteEqual(Token.ID, ':enabled'));
self.addMatch(new CompleteEqual(Token.ID, ':disabled'));
self.addMatch(new CompleteEqual(Token.ID, '@page:first'));
self.addMatch(new CompleteEqual(Token.ID, '@page:left'));
self.addMatch(new CompleteEqual(Token.ID, '@page:right'));
self.addMatch(new RegMatch(Token.ID, /^::?(?:-(?:moz|webkit|ms|o)-)?(?:placeholder|clear)/));
self.addMatch(new CompleteEqual(Token.ID, '&'));
self.addMatch(new RegMatch(Token.NUMBER, /^#[\da-f]{3,6}/i));
self.addMatch(new RegMatch(Token.SELECTOR, /^\.[a-z_][\w_]*/i));
self.addMatch(new RegMatch(Token.SELECTOR, /^#\w[\w\-]*/i));
self.addMatch(new RegMatch(Token.ID, /^[a-z]\w*(?:-\w+)*/i));
self.addMatch(new RegMatch(Token.STRING, /^(\\[a-z\d]{4})+/i));
self.addMatch(new CompleteEqual(Token.IMPORTANT, '!important', null, true));
self.addMatch(new RegMatch(Token.PSEUDO, /^::?(?:-(?:moz|webkit|ms|o)-)?[a-z]+(?:-[a-z]+)*(?:\(:?[\w\-]+\))?/i));
['$=', '|=', '*=', '~=', '^='].forEach(function(o) {
self.addMatch(new CompleteEqual(Token.SIGN, o));
});
self.addMatch(new CharacterSet(Token.SIGN, '&{},:();-{}>+/[]=~*_'));
['{', '}', ',', ';', '::', ':', '-', '(', ')', '>', '+', '/', '[', ']', '$=', '|=', '*=', '~=', '^=', '=', '~', '*'].forEach(function(o) {
self.addMatch(new CompleteEqual(Token.SIGN, o));
});
self.addMatch(new RegMatch(Token.HEAD, /^@[\w-]+/));
self.addMatch(new RegMatch(Token.VARS, /^@\{[\w-]+\}/));
self.addMatch(new RegMatch(Token.VARS, /^\$[\w-]+/));
self.addMatch(new RegMatch(Token.VARS, /^\$\{[\w-]+\}/));
var head = new RegMatch(Token.HEAD, /^@[\w-]+/);
head.callback = function(token) {
var s = token.content().toLowerCase();
if(!{
'@page': true,
'@import': true,
'@charset': true,
'@media': true,
'@font-face': true,
'@keyframes': true,
'@namespace': true
}.hasOwnProperty(s)) {
token.type(Token.VARS);
}
};
self.addMatch(head);
self.addMatch(new RegMatch(Token.NUMBER, /^#[\da-f]{6}/i));
self.addMatch(new RegMatch(Token.NUMBER, /^#[\da-f]{3}/i));
self.addMatch(new RegMatch(Token.NUMBER, /^\d+\.?\d*[a-z%]*/i));
self.addMatch(new RegMatch(Token.ID, /^[.#]?[a-z_][\w\-_.#]*/i));
}).methods({
values: function() {
return this.vl;
},
colors: function() {
return this.cl;
}
}).statics({
KEYWORDS: 'appearance ascent aspect-ratio azimuth backface-visibility background-attachment background-clip background-color background-image background-origin background-position background-repeat background-size background baseline bbox border-collapse border-color border-image border-radius border-spacing border-style border-top border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width border-bottom-width border-left-width border-width border-top-left-radius border-bottom-left-radius border-top-right-radius border-bottom-right-radius border bottom box-shadow box-sizing cap-height caption-side centerline clear clip color color-index content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent device-aspect-ratio device-height device-width direction display elevation empty-cells filter float font-size-adjust font-smoothing font-family font-size font-stretch font-style font-variant font-weight font grid height interpolation-mode left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top margin-right margin-bottom margin-left margin marker-offset marks mathline max-aspect-ratio max-device-width max-height max-width min-aspect-ratio min-device-width min-height min-width monochrome nav-down nav-left nav-right nav-up opacity orphans outline-color outline-style outline-width orientation outline overflow-x overflow-y overflow padding-top padding-right padding-bottom padding-left padding page page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position quotes resize resolution right richness scan size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress table-layout text-align top text-decoration text-indent text-justify text-overflow text-shadow text-transform transform transform-origin transition transition-property unicode-bidi unicode-range units-per-em vertical-align visibility voice-family volume white-space widows width widths word-break word-spacing word-wrap x-height z-index zoom'.split(' '),
VALUES: 'above absolute all alpha always antialiased aqua armenian attr aural auto avoid background baseline behind below bicubic bidi-override black blink block blue bold bolder border-box both bottom break-all break-word braille capitalize caption center center-left center-right circle close-quote code collapse color compact condensed content-box continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double ease ease-in ease-out ease-in-out embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed flipouttoleft flipouttoright flipouttotop flipouttobottom format fuchsia gray grayscale green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside inter-ideograph invert italic justify landscape large larger left-side leftwards level lighter lime linear-gradient linear line-through list-item local loud lower-alpha lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once opacity open-quote outset outside overline padding-box pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side rightwards rotate rotateX rotateY rtl run-in scale screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal text-bottom text-top text thick thin top transparent translate tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin upper-roman url visible wait white wider width w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow'.split(' '),
COLORS: 'black silver gray white maroon red purple fuchsia green lime olive yellow navy blue teal aqua'.split(' ')
});
self.addMatch(new RegMatch(Token.VARS, /^@\{[\w-]+\}/));
self.addMatch(new RegMatch(Token.VARS, /^\$[\w-]+/));
self.addMatch(new RegMatch(Token.VARS, /^\$\{[\w-]+\}/));
}).methods({
values: function() {
return this.vl;
},
colors: function() {
return this.cl;
}
}).statics({
KEYWORDS: 'appearance ascent aspect-ratio azimuth backface-visibility background-attachment background-clip background-color background-image background-origin background-position background-repeat background-size background baseline bbox border-collapse border-color border-image border-radius border-spacing border-style border-top border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width border-bottom-width border-left-width border-width border-top-left-radius border-bottom-left-radius border-top-right-radius border-bottom-right-radius border bottom box-shadow box-sizing cap-height caption-side centerline clear clip color color-index content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent device-aspect-ratio device-height device-width direction display elevation empty-cells filter float font-size-adjust font-smoothing font-family font-size font-stretch font-style font-variant font-weight font grid height interpolation-mode left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top margin-right margin-bottom margin-left margin marker-offset marks mathline max-aspect-ratio max-device-pixel-ratio max-device-width max-height max-width min-aspect-ratio min-device-pixel-ratio min-device-width min-height min-width monochrome nav-down nav-left nav-right nav-up opacity orphans outline-color outline-style outline-width orientation outline overflow-x overflow-y overflow padding-top padding-right padding-bottom padding-left padding page page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position quotes resize resolution right richness scan size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress table-layout text-align top text-decoration text-indent text-justify text-overflow text-shadow text-transform transform transform-origin transition transition-property unicode-bidi unicode-range units-per-em vertical-align visibility voice-family volume white-space widows width widths word-break word-spacing word-wrap x-height z-index zoom'.split(' '),
VALUES: 'above absolute all alpha always antialiased aqua armenian attr aural auto avoid background baseline behind below bicubic bidi-override black blink block blue bold bolder border-box both bottom break-all break-word braille capitalize caption center center-left center-right circle close-quote code collapse color compact condensed content-box continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double ease ease-in ease-out ease-in-out embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed flipouttoleft flipouttoright flipouttotop flipouttobottom format fuchsia gray grayscale green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside inter-ideograph invert italic justify landscape large larger left-side leftwards level lighter lime linear-gradient linear line-through list-item local loud lower-alpha lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once opacity open-quote outset outside overline padding-box pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side rightwards rotate rotateX rotateY rtl run-in scale screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal text-bottom text-top text thick thin top transparent translate tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin upper-roman url visible wait white wider width w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow'.split(' '),
COLORS: 'black silver gray white maroon red purple fuchsia green lime olive yellow navy blue teal aqua'.split(' ')
});
module.exports = CssRule;
});

@@ -79,2 +79,6 @@ define(function(require, exports, module) {

IMPORTANT: 18,
PSEUDO: 19,
UNITS: 20,
SELECTOR: 21,
ATTR: 22,
type: function(tag) {

@@ -81,0 +85,0 @@ if(character.isUndefined(types)) {

@@ -284,2 +284,4 @@ define(function(require, exports, module) {

return this.classdecl();
default:
this.error();
}

@@ -542,3 +544,3 @@ },

},
blockstmt: function() {
blockstmt: function(yYield) {
var node = new Node(Node.BLOCKSTMT);

@@ -1227,2 +1229,3 @@ node.add(this.block(null, yYield));

&& this.look.content() == '=>'
&& this.hasMoveLine == false
&& cndt.name() == Node.PRMREXPR

@@ -1229,0 +1232,0 @@ && cndt.size() == 1

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc