react / wstein / node_modules / jest-cli / node_modules / jsdom / node_modules / cssom / lib / CSSValueExpression.js
81143 views//.CommonJS1var CSSOM = {2CSSValue: require('./CSSValue').CSSValue3};4///CommonJS567/**8* @constructor9* @see http://msdn.microsoft.com/en-us/library/ms537634(v=vs.85).aspx10*11*/12CSSOM.CSSValueExpression = function CSSValueExpression(token, idx) {13this._token = token;14this._idx = idx;15};1617CSSOM.CSSValueExpression.prototype = new CSSOM.CSSValue;18CSSOM.CSSValueExpression.prototype.constructor = CSSOM.CSSValueExpression;1920/**21* parse css expression() value22*23* @return {Object}24* - error:25* or26* - idx:27* - expression:28*29* Example:30*31* .selector {32* zoom: expression(documentElement.clientWidth > 1000 ? '1000px' : 'auto');33* }34*/35CSSOM.CSSValueExpression.prototype.parse = function() {36var token = this._token,37idx = this._idx;3839var character = '',40expression = '',41error = '',42info,43paren = [];444546for (; ; ++idx) {47character = token.charAt(idx);4849// end of token50if (character == '') {51error = 'css expression error: unfinished expression!';52break;53}5455switch(character) {56case '(':57paren.push(character);58expression += character;59break;6061case ')':62paren.pop(character);63expression += character;64break;6566case '/':67if (info = this._parseJSComment(token, idx)) { // comment?68if (info.error) {69error = 'css expression error: unfinished comment in expression!';70} else {71idx = info.idx;72// ignore the comment73}74} else if (info = this._parseJSRexExp(token, idx)) { // regexp75idx = info.idx;76expression += info.text;77} else { // other78expression += character;79}80break;8182case "'":83case '"':84info = this._parseJSString(token, idx, character);85if (info) { // string86idx = info.idx;87expression += info.text;88} else {89expression += character;90}91break;9293default:94expression += character;95break;96}9798if (error) {99break;100}101102// end of expression103if (paren.length == 0) {104break;105}106}107108var ret;109if (error) {110ret = {111error: error112}113} else {114ret = {115idx: idx,116expression: expression117}118}119120return ret;121};122123124/**125*126* @return {Object|false}127* - idx:128* - text:129* or130* - error:131* or132* false133*134*/135CSSOM.CSSValueExpression.prototype._parseJSComment = function(token, idx) {136var nextChar = token.charAt(idx + 1),137text;138139if (nextChar == '/' || nextChar == '*') {140var startIdx = idx,141endIdx,142commentEndChar;143144if (nextChar == '/') { // line comment145commentEndChar = '\n';146} else if (nextChar == '*') { // block comment147commentEndChar = '*/';148}149150endIdx = token.indexOf(commentEndChar, startIdx + 1 + 1);151if (endIdx !== -1) {152endIdx = endIdx + commentEndChar.length - 1;153text = token.substring(idx, endIdx + 1);154return {155idx: endIdx,156text: text157}158} else {159error = 'css expression error: unfinished comment in expression!';160return {161error: error162}163}164} else {165return false;166}167};168169170/**171*172* @return {Object|false}173* - idx:174* - text:175* or176* false177*178*/179CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx, sep) {180var endIdx = this._findMatchedIdx(token, idx, sep),181text;182183if (endIdx === -1) {184return false;185} else {186text = token.substring(idx, endIdx + sep.length);187188return {189idx: endIdx,190text: text191}192}193};194195196/**197* parse regexp in css expression198*199* @return {Object|false}200* - idx:201* - regExp:202* or203* false204*/205206/*207208all legal RegExp209210/a/211(/a/)212[/a/]213[12, /a/]214215!/a/216217+/a/218-/a/219* /a/220/ /a/221%/a/222223===/a/224!==/a/225==/a/226!=/a/227>/a/228>=/a/229</a/230<=/a/231232&/a/233|/a/234^/a/235~/a/236<</a/237>>/a/238>>>/a/239240&&/a/241||/a/242?/a/243=/a/244,/a/245246delete /a/247in /a/248instanceof /a/249new /a/250typeof /a/251void /a/252253*/254CSSOM.CSSValueExpression.prototype._parseJSRexExp = function(token, idx) {255var before = token.substring(0, idx).replace(/\s+$/, ""),256legalRegx = [257/^$/,258/\($/,259/\[$/,260/\!$/,261/\+$/,262/\-$/,263/\*$/,264/\/\s+/,265/\%$/,266/\=$/,267/\>$/,268/\<$/,269/\&$/,270/\|$/,271/\^$/,272/\~$/,273/\?$/,274/\,$/,275/delete$/,276/in$/,277/instanceof$/,278/new$/,279/typeof$/,280/void$/,281];282283var isLegal = legalRegx.some(function(reg) {284return reg.test(before);285});286287if (!isLegal) {288return false;289} else {290var sep = '/';291292// same logic as string293return this._parseJSString(token, idx, sep);294}295};296297298/**299*300* find next sep(same line) index in `token`301*302* @return {Number}303*304*/305CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep) {306var startIdx = idx,307endIdx;308309var NOT_FOUND = -1;310311while(true) {312endIdx = token.indexOf(sep, startIdx + 1);313314if (endIdx === -1) { // not found315endIdx = NOT_FOUND;316break;317} else {318var text = token.substring(idx + 1, endIdx),319matched = text.match(/\\+$/);320if (!matched || matched[0] % 2 == 0) { // not escaped321break;322} else {323startIdx = endIdx;324}325}326}327328// boundary must be in the same line(js sting or regexp)329var nextNewLineIdx = token.indexOf('\n', idx + 1);330if (nextNewLineIdx < endIdx) {331endIdx = NOT_FOUND;332}333334335return endIdx;336}337338339340341//.CommonJS342exports.CSSValueExpression = CSSOM.CSSValueExpression;343///CommonJS344345346