2024-03-28 02:00:41 +00:00
function _iterableToArrayLimit ( arr , i ) {
var _i = null == arr ? null : "undefined" != typeof Symbol && arr [ Symbol . iterator ] || arr [ "@@iterator" ] ;
if ( null != _i ) {
var _s ,
_e ,
_x ,
_r ,
_arr = [ ] ,
_n = ! 0 ,
_d = ! 1 ;
try {
if ( _x = ( _i = _i . call ( arr ) ) . next , 0 === i ) {
if ( Object ( _i ) !== _i ) return ;
_n = ! 1 ;
} else for ( ; ! ( _n = ( _s = _x . call ( _i ) ) . done ) && ( _arr . push ( _s . value ) , _arr . length !== i ) ; _n = ! 0 ) ;
} catch ( err ) {
_d = ! 0 , _e = err ;
} finally {
try {
if ( ! _n && null != _i . return && ( _r = _i . return ( ) , Object ( _r ) !== _r ) ) return ;
} finally {
if ( _d ) throw _e ;
}
}
return _arr ;
}
}
2020-08-25 23:57:08 +00:00
function _typeof ( obj ) {
"@babel/helpers - typeof" ;
2024-03-28 02:00:41 +00:00
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol . iterator ? function ( obj ) {
return typeof obj ;
} : function ( obj ) {
return obj && "function" == typeof Symbol && obj . constructor === Symbol && obj !== Symbol . prototype ? "symbol" : typeof obj ;
} , _typeof ( obj ) ;
2020-08-25 23:57:08 +00:00
}
function _slicedToArray ( arr , i ) {
return _arrayWithHoles ( arr ) || _iterableToArrayLimit ( arr , i ) || _unsupportedIterableToArray ( arr , i ) || _nonIterableRest ( ) ;
}
function _toConsumableArray ( arr ) {
return _arrayWithoutHoles ( arr ) || _iterableToArray ( arr ) || _unsupportedIterableToArray ( arr ) || _nonIterableSpread ( ) ;
}
function _arrayWithoutHoles ( arr ) {
if ( Array . isArray ( arr ) ) return _arrayLikeToArray ( arr ) ;
}
function _arrayWithHoles ( arr ) {
if ( Array . isArray ( arr ) ) return arr ;
}
function _iterableToArray ( iter ) {
2024-03-28 02:00:41 +00:00
if ( typeof Symbol !== "undefined" && iter [ Symbol . iterator ] != null || iter [ "@@iterator" ] != null ) return Array . from ( iter ) ;
2020-08-25 23:57:08 +00:00
}
function _unsupportedIterableToArray ( o , minLen ) {
if ( ! o ) return ;
if ( typeof o === "string" ) return _arrayLikeToArray ( o , minLen ) ;
var n = Object . prototype . toString . call ( o ) . slice ( 8 , - 1 ) ;
if ( n === "Object" && o . constructor ) n = o . constructor . name ;
2021-02-26 03:58:33 +00:00
if ( n === "Map" || n === "Set" ) return Array . from ( o ) ;
2020-08-25 23:57:08 +00:00
if ( n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/ . test ( n ) ) return _arrayLikeToArray ( o , minLen ) ;
}
function _arrayLikeToArray ( arr , len ) {
if ( len == null || len > arr . length ) len = arr . length ;
for ( var i = 0 , arr2 = new Array ( len ) ; i < len ; i ++ ) arr2 [ i ] = arr [ i ] ;
return arr2 ;
}
function _nonIterableSpread ( ) {
throw new TypeError ( "Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method." ) ;
}
function _nonIterableRest ( ) {
throw new TypeError ( "Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method." ) ;
}
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : { } ;
function createCommonjsModule ( fn , module ) {
return module = { exports : { } } , fn ( module , module . exports ) , module . exports ;
}
var estraverse = createCommonjsModule ( function ( module , exports ) {
/ *
Copyright ( C ) 2012 - 2013 Yusuke Suzuki < utatane . tea @ gmail . com >
Copyright ( C ) 2012 Ariya Hidayat < ariya . hidayat @ gmail . com >
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions are met :
* Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
* Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in the
documentation and / or other materials provided with the distribution .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED . IN NO EVENT SHALL < COPYRIGHT HOLDER > BE LIABLE FOR ANY
DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
/*jslint vars:false, bitwise:true*/
/*jshint indent:4*/
/*global exports:true*/
( function clone ( exports ) {
var Syntax , VisitorOption , VisitorKeys , BREAK , SKIP , REMOVE ;
function deepCopy ( obj ) {
var ret = { } ,
2024-03-28 02:00:41 +00:00
key ,
val ;
2020-08-25 23:57:08 +00:00
for ( key in obj ) {
if ( obj . hasOwnProperty ( key ) ) {
val = obj [ key ] ;
if ( typeof val === 'object' && val !== null ) {
ret [ key ] = deepCopy ( val ) ;
} else {
ret [ key ] = val ;
}
}
}
return ret ;
2024-03-28 02:00:41 +00:00
}
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// based on LLVM libc++ upper_bound / lower_bound
// MIT License
2020-08-25 23:57:08 +00:00
function upperBound ( array , func ) {
var diff , len , i , current ;
len = array . length ;
i = 0 ;
while ( len ) {
diff = len >>> 1 ;
current = i + diff ;
if ( func ( array [ current ] ) ) {
len = diff ;
} else {
i = current + 1 ;
len -= diff + 1 ;
}
}
return i ;
}
Syntax = {
AssignmentExpression : 'AssignmentExpression' ,
AssignmentPattern : 'AssignmentPattern' ,
ArrayExpression : 'ArrayExpression' ,
ArrayPattern : 'ArrayPattern' ,
ArrowFunctionExpression : 'ArrowFunctionExpression' ,
AwaitExpression : 'AwaitExpression' ,
// CAUTION: It's deferred to ES7.
BlockStatement : 'BlockStatement' ,
BinaryExpression : 'BinaryExpression' ,
BreakStatement : 'BreakStatement' ,
CallExpression : 'CallExpression' ,
CatchClause : 'CatchClause' ,
2021-02-26 03:58:33 +00:00
ChainExpression : 'ChainExpression' ,
2020-08-25 23:57:08 +00:00
ClassBody : 'ClassBody' ,
ClassDeclaration : 'ClassDeclaration' ,
ClassExpression : 'ClassExpression' ,
ComprehensionBlock : 'ComprehensionBlock' ,
// CAUTION: It's deferred to ES7.
ComprehensionExpression : 'ComprehensionExpression' ,
// CAUTION: It's deferred to ES7.
ConditionalExpression : 'ConditionalExpression' ,
ContinueStatement : 'ContinueStatement' ,
DebuggerStatement : 'DebuggerStatement' ,
DirectiveStatement : 'DirectiveStatement' ,
DoWhileStatement : 'DoWhileStatement' ,
EmptyStatement : 'EmptyStatement' ,
ExportAllDeclaration : 'ExportAllDeclaration' ,
ExportDefaultDeclaration : 'ExportDefaultDeclaration' ,
ExportNamedDeclaration : 'ExportNamedDeclaration' ,
ExportSpecifier : 'ExportSpecifier' ,
ExpressionStatement : 'ExpressionStatement' ,
ForStatement : 'ForStatement' ,
ForInStatement : 'ForInStatement' ,
ForOfStatement : 'ForOfStatement' ,
FunctionDeclaration : 'FunctionDeclaration' ,
FunctionExpression : 'FunctionExpression' ,
GeneratorExpression : 'GeneratorExpression' ,
// CAUTION: It's deferred to ES7.
Identifier : 'Identifier' ,
IfStatement : 'IfStatement' ,
ImportExpression : 'ImportExpression' ,
ImportDeclaration : 'ImportDeclaration' ,
ImportDefaultSpecifier : 'ImportDefaultSpecifier' ,
ImportNamespaceSpecifier : 'ImportNamespaceSpecifier' ,
ImportSpecifier : 'ImportSpecifier' ,
Literal : 'Literal' ,
LabeledStatement : 'LabeledStatement' ,
LogicalExpression : 'LogicalExpression' ,
MemberExpression : 'MemberExpression' ,
MetaProperty : 'MetaProperty' ,
MethodDefinition : 'MethodDefinition' ,
ModuleSpecifier : 'ModuleSpecifier' ,
NewExpression : 'NewExpression' ,
ObjectExpression : 'ObjectExpression' ,
ObjectPattern : 'ObjectPattern' ,
2024-03-28 02:00:41 +00:00
PrivateIdentifier : 'PrivateIdentifier' ,
2020-08-25 23:57:08 +00:00
Program : 'Program' ,
Property : 'Property' ,
2024-03-28 02:00:41 +00:00
PropertyDefinition : 'PropertyDefinition' ,
2020-08-25 23:57:08 +00:00
RestElement : 'RestElement' ,
ReturnStatement : 'ReturnStatement' ,
SequenceExpression : 'SequenceExpression' ,
SpreadElement : 'SpreadElement' ,
Super : 'Super' ,
SwitchStatement : 'SwitchStatement' ,
SwitchCase : 'SwitchCase' ,
TaggedTemplateExpression : 'TaggedTemplateExpression' ,
TemplateElement : 'TemplateElement' ,
TemplateLiteral : 'TemplateLiteral' ,
ThisExpression : 'ThisExpression' ,
ThrowStatement : 'ThrowStatement' ,
TryStatement : 'TryStatement' ,
UnaryExpression : 'UnaryExpression' ,
UpdateExpression : 'UpdateExpression' ,
VariableDeclaration : 'VariableDeclaration' ,
VariableDeclarator : 'VariableDeclarator' ,
WhileStatement : 'WhileStatement' ,
WithStatement : 'WithStatement' ,
YieldExpression : 'YieldExpression'
} ;
VisitorKeys = {
AssignmentExpression : [ 'left' , 'right' ] ,
AssignmentPattern : [ 'left' , 'right' ] ,
ArrayExpression : [ 'elements' ] ,
ArrayPattern : [ 'elements' ] ,
ArrowFunctionExpression : [ 'params' , 'body' ] ,
AwaitExpression : [ 'argument' ] ,
// CAUTION: It's deferred to ES7.
BlockStatement : [ 'body' ] ,
BinaryExpression : [ 'left' , 'right' ] ,
BreakStatement : [ 'label' ] ,
CallExpression : [ 'callee' , 'arguments' ] ,
CatchClause : [ 'param' , 'body' ] ,
2021-02-26 03:58:33 +00:00
ChainExpression : [ 'expression' ] ,
2020-08-25 23:57:08 +00:00
ClassBody : [ 'body' ] ,
ClassDeclaration : [ 'id' , 'superClass' , 'body' ] ,
ClassExpression : [ 'id' , 'superClass' , 'body' ] ,
ComprehensionBlock : [ 'left' , 'right' ] ,
// CAUTION: It's deferred to ES7.
ComprehensionExpression : [ 'blocks' , 'filter' , 'body' ] ,
// CAUTION: It's deferred to ES7.
ConditionalExpression : [ 'test' , 'consequent' , 'alternate' ] ,
ContinueStatement : [ 'label' ] ,
DebuggerStatement : [ ] ,
DirectiveStatement : [ ] ,
DoWhileStatement : [ 'body' , 'test' ] ,
EmptyStatement : [ ] ,
ExportAllDeclaration : [ 'source' ] ,
ExportDefaultDeclaration : [ 'declaration' ] ,
ExportNamedDeclaration : [ 'declaration' , 'specifiers' , 'source' ] ,
ExportSpecifier : [ 'exported' , 'local' ] ,
ExpressionStatement : [ 'expression' ] ,
ForStatement : [ 'init' , 'test' , 'update' , 'body' ] ,
ForInStatement : [ 'left' , 'right' , 'body' ] ,
ForOfStatement : [ 'left' , 'right' , 'body' ] ,
FunctionDeclaration : [ 'id' , 'params' , 'body' ] ,
FunctionExpression : [ 'id' , 'params' , 'body' ] ,
GeneratorExpression : [ 'blocks' , 'filter' , 'body' ] ,
// CAUTION: It's deferred to ES7.
Identifier : [ ] ,
IfStatement : [ 'test' , 'consequent' , 'alternate' ] ,
ImportExpression : [ 'source' ] ,
ImportDeclaration : [ 'specifiers' , 'source' ] ,
ImportDefaultSpecifier : [ 'local' ] ,
ImportNamespaceSpecifier : [ 'local' ] ,
ImportSpecifier : [ 'imported' , 'local' ] ,
Literal : [ ] ,
LabeledStatement : [ 'label' , 'body' ] ,
LogicalExpression : [ 'left' , 'right' ] ,
MemberExpression : [ 'object' , 'property' ] ,
MetaProperty : [ 'meta' , 'property' ] ,
MethodDefinition : [ 'key' , 'value' ] ,
ModuleSpecifier : [ ] ,
NewExpression : [ 'callee' , 'arguments' ] ,
ObjectExpression : [ 'properties' ] ,
ObjectPattern : [ 'properties' ] ,
2024-03-28 02:00:41 +00:00
PrivateIdentifier : [ ] ,
2020-08-25 23:57:08 +00:00
Program : [ 'body' ] ,
Property : [ 'key' , 'value' ] ,
2024-03-28 02:00:41 +00:00
PropertyDefinition : [ 'key' , 'value' ] ,
2020-08-25 23:57:08 +00:00
RestElement : [ 'argument' ] ,
ReturnStatement : [ 'argument' ] ,
SequenceExpression : [ 'expressions' ] ,
SpreadElement : [ 'argument' ] ,
Super : [ ] ,
SwitchStatement : [ 'discriminant' , 'cases' ] ,
SwitchCase : [ 'test' , 'consequent' ] ,
TaggedTemplateExpression : [ 'tag' , 'quasi' ] ,
TemplateElement : [ ] ,
TemplateLiteral : [ 'quasis' , 'expressions' ] ,
ThisExpression : [ ] ,
ThrowStatement : [ 'argument' ] ,
TryStatement : [ 'block' , 'handler' , 'finalizer' ] ,
UnaryExpression : [ 'argument' ] ,
UpdateExpression : [ 'argument' ] ,
VariableDeclaration : [ 'declarations' ] ,
VariableDeclarator : [ 'id' , 'init' ] ,
WhileStatement : [ 'test' , 'body' ] ,
WithStatement : [ 'object' , 'body' ] ,
YieldExpression : [ 'argument' ]
2024-03-28 02:00:41 +00:00
} ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// unique id
2020-08-25 23:57:08 +00:00
BREAK = { } ;
SKIP = { } ;
REMOVE = { } ;
VisitorOption = {
Break : BREAK ,
Skip : SKIP ,
Remove : REMOVE
} ;
function Reference ( parent , key ) {
this . parent = parent ;
this . key = key ;
}
Reference . prototype . replace = function replace ( node ) {
this . parent [ this . key ] = node ;
} ;
Reference . prototype . remove = function remove ( ) {
if ( Array . isArray ( this . parent ) ) {
this . parent . splice ( this . key , 1 ) ;
return true ;
} else {
this . replace ( null ) ;
return false ;
}
} ;
function Element ( node , path , wrap , ref ) {
this . node = node ;
this . path = path ;
this . wrap = wrap ;
this . ref = ref ;
}
2024-03-28 02:00:41 +00:00
function Controller ( ) { }
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// API:
2020-08-25 23:57:08 +00:00
// return property path array from root to current node
Controller . prototype . path = function path ( ) {
var i , iz , j , jz , result , element ;
function addToPath ( result , path ) {
if ( Array . isArray ( path ) ) {
for ( j = 0 , jz = path . length ; j < jz ; ++ j ) {
result . push ( path [ j ] ) ;
}
} else {
result . push ( path ) ;
}
2024-03-28 02:00:41 +00:00
}
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// root node
2020-08-25 23:57:08 +00:00
if ( ! this . _ _current . path ) {
return null ;
2024-03-28 02:00:41 +00:00
}
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// first node is sentinel, second node is root element
2020-08-25 23:57:08 +00:00
result = [ ] ;
for ( i = 2 , iz = this . _ _leavelist . length ; i < iz ; ++ i ) {
element = this . _ _leavelist [ i ] ;
addToPath ( result , element . path ) ;
}
addToPath ( result , this . _ _current . path ) ;
return result ;
2024-03-28 02:00:41 +00:00
} ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// API:
// return type of current node
2020-08-25 23:57:08 +00:00
Controller . prototype . type = function ( ) {
var node = this . current ( ) ;
return node . type || this . _ _current . wrap ;
2024-03-28 02:00:41 +00:00
} ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// API:
// return array of parent elements
2020-08-25 23:57:08 +00:00
Controller . prototype . parents = function parents ( ) {
2024-03-28 02:00:41 +00:00
var i , iz , result ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// first node is sentinel
2020-08-25 23:57:08 +00:00
result = [ ] ;
for ( i = 1 , iz = this . _ _leavelist . length ; i < iz ; ++ i ) {
result . push ( this . _ _leavelist [ i ] . node ) ;
}
return result ;
2024-03-28 02:00:41 +00:00
} ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// API:
// return current node
2020-08-25 23:57:08 +00:00
Controller . prototype . current = function current ( ) {
return this . _ _current . node ;
} ;
Controller . prototype . _ _execute = function _ _execute ( callback , element ) {
var previous , result ;
result = undefined ;
previous = this . _ _current ;
this . _ _current = element ;
this . _ _state = null ;
if ( callback ) {
result = callback . call ( this , element . node , this . _ _leavelist [ this . _ _leavelist . length - 1 ] . node ) ;
}
this . _ _current = previous ;
return result ;
2024-03-28 02:00:41 +00:00
} ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// API:
// notify control skip / break
2020-08-25 23:57:08 +00:00
Controller . prototype . notify = function notify ( flag ) {
this . _ _state = flag ;
2024-03-28 02:00:41 +00:00
} ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// API:
// skip child nodes of current node
2020-08-25 23:57:08 +00:00
Controller . prototype . skip = function ( ) {
this . notify ( SKIP ) ;
2024-03-28 02:00:41 +00:00
} ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// API:
// break traversals
2020-08-25 23:57:08 +00:00
Controller . prototype [ 'break' ] = function ( ) {
this . notify ( BREAK ) ;
2024-03-28 02:00:41 +00:00
} ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// API:
// remove node
2020-08-25 23:57:08 +00:00
Controller . prototype . remove = function ( ) {
this . notify ( REMOVE ) ;
} ;
Controller . prototype . _ _initialize = function ( root , visitor ) {
this . visitor = visitor ;
this . root = root ;
this . _ _worklist = [ ] ;
this . _ _leavelist = [ ] ;
this . _ _current = null ;
this . _ _state = null ;
this . _ _fallback = null ;
if ( visitor . fallback === 'iteration' ) {
this . _ _fallback = Object . keys ;
} else if ( typeof visitor . fallback === 'function' ) {
this . _ _fallback = visitor . fallback ;
}
this . _ _keys = VisitorKeys ;
if ( visitor . keys ) {
this . _ _keys = Object . assign ( Object . create ( this . _ _keys ) , visitor . keys ) ;
}
} ;
function isNode ( node ) {
if ( node == null ) {
return false ;
}
return typeof node === 'object' && typeof node . type === 'string' ;
}
function isProperty ( nodeType , key ) {
return ( nodeType === Syntax . ObjectExpression || nodeType === Syntax . ObjectPattern ) && 'properties' === key ;
}
function candidateExistsInLeaveList ( leavelist , candidate ) {
for ( var i = leavelist . length - 1 ; i >= 0 ; -- i ) {
if ( leavelist [ i ] . node === candidate ) {
return true ;
}
}
return false ;
}
Controller . prototype . traverse = function traverse ( root , visitor ) {
var worklist , leavelist , element , node , nodeType , ret , key , current , current2 , candidates , candidate , sentinel ;
this . _ _initialize ( root , visitor ) ;
2024-03-28 02:00:41 +00:00
sentinel = { } ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// reference
2020-08-25 23:57:08 +00:00
worklist = this . _ _worklist ;
2024-03-28 02:00:41 +00:00
leavelist = this . _ _leavelist ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// initialize
2020-08-25 23:57:08 +00:00
worklist . push ( new Element ( root , null , null , null ) ) ;
leavelist . push ( new Element ( null , null , null , null ) ) ;
while ( worklist . length ) {
element = worklist . pop ( ) ;
if ( element === sentinel ) {
element = leavelist . pop ( ) ;
ret = this . _ _execute ( visitor . leave , element ) ;
if ( this . _ _state === BREAK || ret === BREAK ) {
return ;
}
continue ;
}
if ( element . node ) {
ret = this . _ _execute ( visitor . enter , element ) ;
if ( this . _ _state === BREAK || ret === BREAK ) {
return ;
}
worklist . push ( sentinel ) ;
leavelist . push ( element ) ;
if ( this . _ _state === SKIP || ret === SKIP ) {
continue ;
}
node = element . node ;
nodeType = node . type || element . wrap ;
candidates = this . _ _keys [ nodeType ] ;
if ( ! candidates ) {
if ( this . _ _fallback ) {
candidates = this . _ _fallback ( node ) ;
} else {
throw new Error ( 'Unknown node type ' + nodeType + '.' ) ;
}
}
current = candidates . length ;
while ( ( current -= 1 ) >= 0 ) {
key = candidates [ current ] ;
candidate = node [ key ] ;
if ( ! candidate ) {
continue ;
}
if ( Array . isArray ( candidate ) ) {
current2 = candidate . length ;
while ( ( current2 -= 1 ) >= 0 ) {
if ( ! candidate [ current2 ] ) {
continue ;
}
if ( candidateExistsInLeaveList ( leavelist , candidate [ current2 ] ) ) {
continue ;
}
if ( isProperty ( nodeType , candidates [ current ] ) ) {
element = new Element ( candidate [ current2 ] , [ key , current2 ] , 'Property' , null ) ;
} else if ( isNode ( candidate [ current2 ] ) ) {
element = new Element ( candidate [ current2 ] , [ key , current2 ] , null , null ) ;
} else {
continue ;
}
worklist . push ( element ) ;
}
} else if ( isNode ( candidate ) ) {
if ( candidateExistsInLeaveList ( leavelist , candidate ) ) {
continue ;
}
worklist . push ( new Element ( candidate , key , null , null ) ) ;
}
}
}
}
} ;
Controller . prototype . replace = function replace ( root , visitor ) {
var worklist , leavelist , node , nodeType , target , element , current , current2 , candidates , candidate , sentinel , outer , key ;
function removeElem ( element ) {
var i , key , nextElem , parent ;
if ( element . ref . remove ( ) ) {
// When the reference is an element of an array.
key = element . ref . key ;
2024-03-28 02:00:41 +00:00
parent = element . ref . parent ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// If removed from array, then decrease following items' keys.
2020-08-25 23:57:08 +00:00
i = worklist . length ;
while ( i -- ) {
nextElem = worklist [ i ] ;
if ( nextElem . ref && nextElem . ref . parent === parent ) {
if ( nextElem . ref . key < key ) {
break ;
}
-- nextElem . ref . key ;
}
}
}
}
this . _ _initialize ( root , visitor ) ;
2024-03-28 02:00:41 +00:00
sentinel = { } ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// reference
2020-08-25 23:57:08 +00:00
worklist = this . _ _worklist ;
2024-03-28 02:00:41 +00:00
leavelist = this . _ _leavelist ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// initialize
2020-08-25 23:57:08 +00:00
outer = {
root : root
} ;
element = new Element ( root , null , null , new Reference ( outer , 'root' ) ) ;
worklist . push ( element ) ;
leavelist . push ( element ) ;
while ( worklist . length ) {
element = worklist . pop ( ) ;
if ( element === sentinel ) {
element = leavelist . pop ( ) ;
2024-03-28 02:00:41 +00:00
target = this . _ _execute ( visitor . leave , element ) ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// node may be replaced with null,
// so distinguish between undefined and null in this place
2020-08-25 23:57:08 +00:00
if ( target !== undefined && target !== BREAK && target !== SKIP && target !== REMOVE ) {
// replace
element . ref . replace ( target ) ;
}
if ( this . _ _state === REMOVE || target === REMOVE ) {
removeElem ( element ) ;
}
if ( this . _ _state === BREAK || target === BREAK ) {
return outer . root ;
}
continue ;
}
2024-03-28 02:00:41 +00:00
target = this . _ _execute ( visitor . enter , element ) ;
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// node may be replaced with null,
2020-08-25 23:57:08 +00:00
// so distinguish between undefined and null in this place
if ( target !== undefined && target !== BREAK && target !== SKIP && target !== REMOVE ) {
// replace
element . ref . replace ( target ) ;
element . node = target ;
}
if ( this . _ _state === REMOVE || target === REMOVE ) {
removeElem ( element ) ;
element . node = null ;
}
if ( this . _ _state === BREAK || target === BREAK ) {
return outer . root ;
2024-03-28 02:00:41 +00:00
}
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// node may be null
2020-08-25 23:57:08 +00:00
node = element . node ;
if ( ! node ) {
continue ;
}
worklist . push ( sentinel ) ;
leavelist . push ( element ) ;
if ( this . _ _state === SKIP || target === SKIP ) {
continue ;
}
nodeType = node . type || element . wrap ;
candidates = this . _ _keys [ nodeType ] ;
if ( ! candidates ) {
if ( this . _ _fallback ) {
candidates = this . _ _fallback ( node ) ;
} else {
throw new Error ( 'Unknown node type ' + nodeType + '.' ) ;
}
}
current = candidates . length ;
while ( ( current -= 1 ) >= 0 ) {
key = candidates [ current ] ;
candidate = node [ key ] ;
if ( ! candidate ) {
continue ;
}
if ( Array . isArray ( candidate ) ) {
current2 = candidate . length ;
while ( ( current2 -= 1 ) >= 0 ) {
if ( ! candidate [ current2 ] ) {
continue ;
}
if ( isProperty ( nodeType , candidates [ current ] ) ) {
element = new Element ( candidate [ current2 ] , [ key , current2 ] , 'Property' , new Reference ( candidate , current2 ) ) ;
} else if ( isNode ( candidate [ current2 ] ) ) {
element = new Element ( candidate [ current2 ] , [ key , current2 ] , null , new Reference ( candidate , current2 ) ) ;
} else {
continue ;
}
worklist . push ( element ) ;
}
} else if ( isNode ( candidate ) ) {
worklist . push ( new Element ( candidate , key , null , new Reference ( node , key ) ) ) ;
}
}
}
return outer . root ;
} ;
function traverse ( root , visitor ) {
var controller = new Controller ( ) ;
return controller . traverse ( root , visitor ) ;
}
function replace ( root , visitor ) {
var controller = new Controller ( ) ;
return controller . replace ( root , visitor ) ;
}
function extendCommentRange ( comment , tokens ) {
var target ;
target = upperBound ( tokens , function search ( token ) {
return token . range [ 0 ] > comment . range [ 0 ] ;
} ) ;
comment . extendedRange = [ comment . range [ 0 ] , comment . range [ 1 ] ] ;
if ( target !== tokens . length ) {
comment . extendedRange [ 1 ] = tokens [ target ] . range [ 0 ] ;
}
target -= 1 ;
if ( target >= 0 ) {
comment . extendedRange [ 0 ] = tokens [ target ] . range [ 1 ] ;
}
return comment ;
}
function attachComments ( tree , providedComments , tokens ) {
// At first, we should calculate extended comment ranges.
var comments = [ ] ,
2024-03-28 02:00:41 +00:00
comment ,
len ,
i ,
cursor ;
2020-08-25 23:57:08 +00:00
if ( ! tree . range ) {
throw new Error ( 'attachComments needs range information' ) ;
2024-03-28 02:00:41 +00:00
}
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// tokens array is empty, we attach comments to tree as 'leadingComments'
2020-08-25 23:57:08 +00:00
if ( ! tokens . length ) {
if ( providedComments . length ) {
for ( i = 0 , len = providedComments . length ; i < len ; i += 1 ) {
comment = deepCopy ( providedComments [ i ] ) ;
comment . extendedRange = [ 0 , tree . range [ 0 ] ] ;
comments . push ( comment ) ;
}
tree . leadingComments = comments ;
}
return tree ;
}
for ( i = 0 , len = providedComments . length ; i < len ; i += 1 ) {
comments . push ( extendCommentRange ( deepCopy ( providedComments [ i ] ) , tokens ) ) ;
2024-03-28 02:00:41 +00:00
}
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// This is based on John Freeman's implementation.
2020-08-25 23:57:08 +00:00
cursor = 0 ;
traverse ( tree , {
enter : function ( node ) {
var comment ;
while ( cursor < comments . length ) {
comment = comments [ cursor ] ;
if ( comment . extendedRange [ 1 ] > node . range [ 0 ] ) {
break ;
}
if ( comment . extendedRange [ 1 ] === node . range [ 0 ] ) {
if ( ! node . leadingComments ) {
node . leadingComments = [ ] ;
}
node . leadingComments . push ( comment ) ;
comments . splice ( cursor , 1 ) ;
} else {
cursor += 1 ;
}
2024-03-28 02:00:41 +00:00
}
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// already out of owned node
2020-08-25 23:57:08 +00:00
if ( cursor === comments . length ) {
return VisitorOption . Break ;
}
if ( comments [ cursor ] . extendedRange [ 0 ] > node . range [ 1 ] ) {
return VisitorOption . Skip ;
}
}
} ) ;
cursor = 0 ;
traverse ( tree , {
leave : function ( node ) {
var comment ;
while ( cursor < comments . length ) {
comment = comments [ cursor ] ;
if ( node . range [ 1 ] < comment . extendedRange [ 0 ] ) {
break ;
}
if ( node . range [ 1 ] === comment . extendedRange [ 0 ] ) {
if ( ! node . trailingComments ) {
node . trailingComments = [ ] ;
}
node . trailingComments . push ( comment ) ;
comments . splice ( cursor , 1 ) ;
} else {
cursor += 1 ;
}
2024-03-28 02:00:41 +00:00
}
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
// already out of owned node
2020-08-25 23:57:08 +00:00
if ( cursor === comments . length ) {
return VisitorOption . Break ;
}
if ( comments [ cursor ] . extendedRange [ 0 ] > node . range [ 1 ] ) {
return VisitorOption . Skip ;
}
}
} ) ;
return tree ;
}
exports . Syntax = Syntax ;
exports . traverse = traverse ;
exports . replace = replace ;
exports . attachComments = attachComments ;
exports . VisitorKeys = VisitorKeys ;
exports . VisitorOption = VisitorOption ;
exports . Controller = Controller ;
exports . cloneEnvironment = function ( ) {
return clone ( { } ) ;
} ;
return exports ;
} ) ( exports ) ;
/* vim: set sw=4 ts=4 et tw=80 : */
} ) ;
var parser = createCommonjsModule ( function ( module ) {
/ *
* Generated by PEG . js 0.10 . 0.
*
* http : //pegjs.org/
* /
( function ( root , factory ) {
if ( module . exports ) {
module . exports = factory ( ) ;
}
} ) ( commonjsGlobal , function ( ) {
function peg$subclass ( child , parent ) {
function ctor ( ) {
this . constructor = child ;
}
ctor . prototype = parent . prototype ;
child . prototype = new ctor ( ) ;
}
function peg$SyntaxError ( message , expected , found , location ) {
this . message = message ;
this . expected = expected ;
this . found = found ;
this . location = location ;
this . name = "SyntaxError" ;
if ( typeof Error . captureStackTrace === "function" ) {
Error . captureStackTrace ( this , peg$SyntaxError ) ;
}
}
peg$subclass ( peg$SyntaxError , Error ) ;
peg$SyntaxError . buildMessage = function ( expected , found ) {
var DESCRIBE _EXPECTATION _FNS = {
literal : function literal ( expectation ) {
return "\"" + literalEscape ( expectation . text ) + "\"" ;
} ,
"class" : function _class ( expectation ) {
var escapedParts = "" ,
2024-03-28 02:00:41 +00:00
i ;
2020-08-25 23:57:08 +00:00
for ( i = 0 ; i < expectation . parts . length ; i ++ ) {
escapedParts += expectation . parts [ i ] instanceof Array ? classEscape ( expectation . parts [ i ] [ 0 ] ) + "-" + classEscape ( expectation . parts [ i ] [ 1 ] ) : classEscape ( expectation . parts [ i ] ) ;
}
return "[" + ( expectation . inverted ? "^" : "" ) + escapedParts + "]" ;
} ,
any : function any ( expectation ) {
return "any character" ;
} ,
end : function end ( expectation ) {
return "end of input" ;
} ,
other : function other ( expectation ) {
return expectation . description ;
}
} ;
function hex ( ch ) {
return ch . charCodeAt ( 0 ) . toString ( 16 ) . toUpperCase ( ) ;
}
function literalEscape ( s ) {
return s . replace ( /\\/g , '\\\\' ) . replace ( /"/g , '\\"' ) . replace ( /\0/g , '\\0' ) . replace ( /\t/g , '\\t' ) . replace ( /\n/g , '\\n' ) . replace ( /\r/g , '\\r' ) . replace ( /[\x00-\x0F]/g , function ( ch ) {
return '\\x0' + hex ( ch ) ;
} ) . replace ( /[\x10-\x1F\x7F-\x9F]/g , function ( ch ) {
return '\\x' + hex ( ch ) ;
} ) ;
}
function classEscape ( s ) {
return s . replace ( /\\/g , '\\\\' ) . replace ( /\]/g , '\\]' ) . replace ( /\^/g , '\\^' ) . replace ( /-/g , '\\-' ) . replace ( /\0/g , '\\0' ) . replace ( /\t/g , '\\t' ) . replace ( /\n/g , '\\n' ) . replace ( /\r/g , '\\r' ) . replace ( /[\x00-\x0F]/g , function ( ch ) {
return '\\x0' + hex ( ch ) ;
} ) . replace ( /[\x10-\x1F\x7F-\x9F]/g , function ( ch ) {
return '\\x' + hex ( ch ) ;
} ) ;
}
function describeExpectation ( expectation ) {
return DESCRIBE _EXPECTATION _FNS [ expectation . type ] ( expectation ) ;
}
function describeExpected ( expected ) {
var descriptions = new Array ( expected . length ) ,
2024-03-28 02:00:41 +00:00
i ,
j ;
2020-08-25 23:57:08 +00:00
for ( i = 0 ; i < expected . length ; i ++ ) {
descriptions [ i ] = describeExpectation ( expected [ i ] ) ;
}
descriptions . sort ( ) ;
if ( descriptions . length > 0 ) {
for ( i = 1 , j = 1 ; i < descriptions . length ; i ++ ) {
if ( descriptions [ i - 1 ] !== descriptions [ i ] ) {
descriptions [ j ] = descriptions [ i ] ;
j ++ ;
}
}
descriptions . length = j ;
}
switch ( descriptions . length ) {
case 1 :
return descriptions [ 0 ] ;
case 2 :
return descriptions [ 0 ] + " or " + descriptions [ 1 ] ;
default :
return descriptions . slice ( 0 , - 1 ) . join ( ", " ) + ", or " + descriptions [ descriptions . length - 1 ] ;
}
}
function describeFound ( found ) {
return found ? "\"" + literalEscape ( found ) + "\"" : "end of input" ;
}
return "Expected " + describeExpected ( expected ) + " but " + describeFound ( found ) + " found." ;
} ;
function peg$parse ( input , options ) {
options = options !== void 0 ? options : { } ;
var peg$FAILED = { } ,
2024-03-28 02:00:41 +00:00
peg$startRuleFunctions = {
start : peg$parsestart
} ,
peg$startRuleFunction = peg$parsestart ,
peg$c0 = function peg$c0 ( ss ) {
return ss . length === 1 ? ss [ 0 ] : {
type : 'matches' ,
selectors : ss
2020-08-25 23:57:08 +00:00
} ;
2024-03-28 02:00:41 +00:00
} ,
peg$c1 = function peg$c1 ( ) {
return void 0 ;
} ,
peg$c2 = " " ,
peg$c3 = peg$literalExpectation ( " " , false ) ,
peg$c4 = /^[^ [\],():#!=><~+.]/ ,
peg$c5 = peg$classExpectation ( [ " " , "[" , "]" , "," , "(" , ")" , ":" , "#" , "!" , "=" , ">" , "<" , "~" , "+" , "." ] , true , false ) ,
peg$c6 = function peg$c6 ( i ) {
return i . join ( '' ) ;
} ,
peg$c7 = ">" ,
peg$c8 = peg$literalExpectation ( ">" , false ) ,
peg$c9 = function peg$c9 ( ) {
return 'child' ;
} ,
peg$c10 = "~" ,
peg$c11 = peg$literalExpectation ( "~" , false ) ,
peg$c12 = function peg$c12 ( ) {
return 'sibling' ;
} ,
peg$c13 = "+" ,
peg$c14 = peg$literalExpectation ( "+" , false ) ,
peg$c15 = function peg$c15 ( ) {
return 'adjacent' ;
} ,
peg$c16 = function peg$c16 ( ) {
return 'descendant' ;
} ,
peg$c17 = "," ,
peg$c18 = peg$literalExpectation ( "," , false ) ,
peg$c19 = function peg$c19 ( s , ss ) {
return [ s ] . concat ( ss . map ( function ( s ) {
return s [ 3 ] ;
} ) ) ;
} ,
peg$c20 = function peg$c20 ( a , ops ) {
return ops . reduce ( function ( memo , rhs ) {
return {
type : rhs [ 0 ] ,
left : memo ,
right : rhs [ 1 ]
} ;
} , a ) ;
} ,
peg$c21 = "!" ,
peg$c22 = peg$literalExpectation ( "!" , false ) ,
peg$c23 = function peg$c23 ( subject , as ) {
var b = as . length === 1 ? as [ 0 ] : {
type : 'compound' ,
selectors : as
} ;
if ( subject ) b . subject = true ;
return b ;
} ,
peg$c24 = "*" ,
peg$c25 = peg$literalExpectation ( "*" , false ) ,
peg$c26 = function peg$c26 ( a ) {
return {
type : 'wildcard' ,
value : a
} ;
} ,
peg$c27 = "#" ,
peg$c28 = peg$literalExpectation ( "#" , false ) ,
peg$c29 = function peg$c29 ( i ) {
return {
type : 'identifier' ,
value : i
} ;
} ,
peg$c30 = "[" ,
peg$c31 = peg$literalExpectation ( "[" , false ) ,
peg$c32 = "]" ,
peg$c33 = peg$literalExpectation ( "]" , false ) ,
peg$c34 = function peg$c34 ( v ) {
return v ;
} ,
peg$c35 = /^[><!]/ ,
peg$c36 = peg$classExpectation ( [ ">" , "<" , "!" ] , false , false ) ,
peg$c37 = "=" ,
peg$c38 = peg$literalExpectation ( "=" , false ) ,
peg$c39 = function peg$c39 ( a ) {
return ( a || '' ) + '=' ;
} ,
peg$c40 = /^[><]/ ,
peg$c41 = peg$classExpectation ( [ ">" , "<" ] , false , false ) ,
peg$c42 = "." ,
peg$c43 = peg$literalExpectation ( "." , false ) ,
peg$c44 = function peg$c44 ( a , as ) {
return [ ] . concat . apply ( [ a ] , as ) . join ( '' ) ;
} ,
peg$c45 = function peg$c45 ( name , op , value ) {
return {
type : 'attribute' ,
name : name ,
operator : op ,
value : value
} ;
} ,
peg$c46 = function peg$c46 ( name ) {
return {
type : 'attribute' ,
name : name
} ;
} ,
peg$c47 = "\"" ,
peg$c48 = peg$literalExpectation ( "\"" , false ) ,
peg$c49 = /^[^\\"]/ ,
peg$c50 = peg$classExpectation ( [ "\\" , "\"" ] , true , false ) ,
peg$c51 = "\\" ,
peg$c52 = peg$literalExpectation ( "\\" , false ) ,
peg$c53 = peg$anyExpectation ( ) ,
peg$c54 = function peg$c54 ( a , b ) {
return a + b ;
} ,
peg$c55 = function peg$c55 ( d ) {
return {
type : 'literal' ,
value : strUnescape ( d . join ( '' ) )
} ;
} ,
peg$c56 = "'" ,
peg$c57 = peg$literalExpectation ( "'" , false ) ,
peg$c58 = /^[^\\']/ ,
peg$c59 = peg$classExpectation ( [ "\\" , "'" ] , true , false ) ,
peg$c60 = /^[0-9]/ ,
peg$c61 = peg$classExpectation ( [ [ "0" , "9" ] ] , false , false ) ,
peg$c62 = function peg$c62 ( a , b ) {
// Can use `a.flat().join('')` once supported
var leadingDecimals = a ? [ ] . concat . apply ( [ ] , a ) . join ( '' ) : '' ;
return {
type : 'literal' ,
value : parseFloat ( leadingDecimals + b . join ( '' ) )
} ;
} ,
peg$c63 = function peg$c63 ( i ) {
return {
type : 'literal' ,
value : i
} ;
} ,
peg$c64 = "type(" ,
peg$c65 = peg$literalExpectation ( "type(" , false ) ,
peg$c66 = /^[^ )]/ ,
peg$c67 = peg$classExpectation ( [ " " , ")" ] , true , false ) ,
peg$c68 = ")" ,
peg$c69 = peg$literalExpectation ( ")" , false ) ,
peg$c70 = function peg$c70 ( t ) {
return {
type : 'type' ,
value : t . join ( '' )
} ;
} ,
peg$c71 = /^[imsu]/ ,
peg$c72 = peg$classExpectation ( [ "i" , "m" , "s" , "u" ] , false , false ) ,
peg$c73 = "/" ,
peg$c74 = peg$literalExpectation ( "/" , false ) ,
peg$c75 = /^[^\/]/ ,
peg$c76 = peg$classExpectation ( [ "/" ] , true , false ) ,
peg$c77 = function peg$c77 ( d , flgs ) {
return {
type : 'regexp' ,
value : new RegExp ( d . join ( '' ) , flgs ? flgs . join ( '' ) : '' )
} ;
} ,
peg$c78 = function peg$c78 ( i , is ) {
return {
type : 'field' ,
name : is . reduce ( function ( memo , p ) {
return memo + p [ 0 ] + p [ 1 ] ;
} , i )
} ;
} ,
peg$c79 = ":not(" ,
peg$c80 = peg$literalExpectation ( ":not(" , false ) ,
peg$c81 = function peg$c81 ( ss ) {
return {
type : 'not' ,
selectors : ss
} ;
} ,
peg$c82 = ":matches(" ,
peg$c83 = peg$literalExpectation ( ":matches(" , false ) ,
peg$c84 = function peg$c84 ( ss ) {
return {
type : 'matches' ,
selectors : ss
} ;
} ,
peg$c85 = ":has(" ,
peg$c86 = peg$literalExpectation ( ":has(" , false ) ,
peg$c87 = function peg$c87 ( ss ) {
return {
type : 'has' ,
selectors : ss
} ;
} ,
peg$c88 = ":first-child" ,
peg$c89 = peg$literalExpectation ( ":first-child" , false ) ,
peg$c90 = function peg$c90 ( ) {
return nth ( 1 ) ;
} ,
peg$c91 = ":last-child" ,
peg$c92 = peg$literalExpectation ( ":last-child" , false ) ,
peg$c93 = function peg$c93 ( ) {
return nthLast ( 1 ) ;
} ,
peg$c94 = ":nth-child(" ,
peg$c95 = peg$literalExpectation ( ":nth-child(" , false ) ,
peg$c96 = function peg$c96 ( n ) {
return nth ( parseInt ( n . join ( '' ) , 10 ) ) ;
} ,
peg$c97 = ":nth-last-child(" ,
peg$c98 = peg$literalExpectation ( ":nth-last-child(" , false ) ,
peg$c99 = function peg$c99 ( n ) {
return nthLast ( parseInt ( n . join ( '' ) , 10 ) ) ;
} ,
peg$c100 = ":" ,
peg$c101 = peg$literalExpectation ( ":" , false ) ,
peg$c102 = function peg$c102 ( c ) {
return {
type : 'class' ,
name : c
} ;
} ,
peg$currPos = 0 ,
peg$posDetailsCache = [ {
line : 1 ,
column : 1
} ] ,
peg$maxFailPos = 0 ,
peg$maxFailExpected = [ ] ,
peg$resultsCache = { } ,
peg$result ;
2020-08-25 23:57:08 +00:00
if ( "startRule" in options ) {
if ( ! ( options . startRule in peg$startRuleFunctions ) ) {
throw new Error ( "Can't start parsing from rule \"" + options . startRule + "\"." ) ;
}
peg$startRuleFunction = peg$startRuleFunctions [ options . startRule ] ;
}
function peg$literalExpectation ( text , ignoreCase ) {
return {
type : "literal" ,
text : text ,
ignoreCase : ignoreCase
} ;
}
function peg$classExpectation ( parts , inverted , ignoreCase ) {
return {
type : "class" ,
parts : parts ,
inverted : inverted ,
ignoreCase : ignoreCase
} ;
}
function peg$anyExpectation ( ) {
return {
type : "any"
} ;
}
function peg$endExpectation ( ) {
return {
type : "end"
} ;
}
function peg$computePosDetails ( pos ) {
var details = peg$posDetailsCache [ pos ] ,
2024-03-28 02:00:41 +00:00
p ;
2020-08-25 23:57:08 +00:00
if ( details ) {
return details ;
} else {
p = pos - 1 ;
while ( ! peg$posDetailsCache [ p ] ) {
p -- ;
}
details = peg$posDetailsCache [ p ] ;
details = {
line : details . line ,
column : details . column
} ;
while ( p < pos ) {
if ( input . charCodeAt ( p ) === 10 ) {
details . line ++ ;
details . column = 1 ;
} else {
details . column ++ ;
}
p ++ ;
}
peg$posDetailsCache [ pos ] = details ;
return details ;
}
}
function peg$computeLocation ( startPos , endPos ) {
var startPosDetails = peg$computePosDetails ( startPos ) ,
2024-03-28 02:00:41 +00:00
endPosDetails = peg$computePosDetails ( endPos ) ;
2020-08-25 23:57:08 +00:00
return {
start : {
offset : startPos ,
line : startPosDetails . line ,
column : startPosDetails . column
} ,
end : {
offset : endPos ,
line : endPosDetails . line ,
column : endPosDetails . column
}
} ;
}
function peg$fail ( expected ) {
if ( peg$currPos < peg$maxFailPos ) {
return ;
}
if ( peg$currPos > peg$maxFailPos ) {
peg$maxFailPos = peg$currPos ;
peg$maxFailExpected = [ ] ;
}
peg$maxFailExpected . push ( expected ) ;
}
function peg$buildStructuredError ( expected , found , location ) {
return new peg$SyntaxError ( peg$SyntaxError . buildMessage ( expected , found ) , expected , found , location ) ;
}
function peg$parsestart ( ) {
var s0 , s1 , s2 , s3 ;
var key = peg$currPos * 30 + 0 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
s1 = peg$parse _ ( ) ;
if ( s1 !== peg$FAILED ) {
s2 = peg$parseselectors ( ) ;
if ( s2 !== peg$FAILED ) {
s3 = peg$parse _ ( ) ;
if ( s3 !== peg$FAILED ) {
s1 = peg$c0 ( s2 ) ;
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
if ( s0 === peg$FAILED ) {
s0 = peg$currPos ;
s1 = peg$parse _ ( ) ;
if ( s1 !== peg$FAILED ) {
s1 = peg$c1 ( ) ;
}
s0 = s1 ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parse _ ( ) {
var s0 , s1 ;
var key = peg$currPos * 30 + 1 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = [ ] ;
if ( input . charCodeAt ( peg$currPos ) === 32 ) {
s1 = peg$c2 ;
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
peg$fail ( peg$c3 ) ;
}
}
while ( s1 !== peg$FAILED ) {
s0 . push ( s1 ) ;
if ( input . charCodeAt ( peg$currPos ) === 32 ) {
s1 = peg$c2 ;
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
peg$fail ( peg$c3 ) ;
}
}
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parseidentifierName ( ) {
var s0 , s1 , s2 ;
var key = peg$currPos * 30 + 2 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
s1 = [ ] ;
if ( peg$c4 . test ( input . charAt ( peg$currPos ) ) ) {
s2 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s2 = peg$FAILED ;
{
peg$fail ( peg$c5 ) ;
}
}
if ( s2 !== peg$FAILED ) {
while ( s2 !== peg$FAILED ) {
s1 . push ( s2 ) ;
if ( peg$c4 . test ( input . charAt ( peg$currPos ) ) ) {
s2 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s2 = peg$FAILED ;
{
peg$fail ( peg$c5 ) ;
}
}
}
} else {
s1 = peg$FAILED ;
}
if ( s1 !== peg$FAILED ) {
s1 = peg$c6 ( s1 ) ;
}
s0 = s1 ;
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parsebinaryOp ( ) {
var s0 , s1 , s2 , s3 ;
var key = peg$currPos * 30 + 3 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
s1 = peg$parse _ ( ) ;
if ( s1 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 62 ) {
s2 = peg$c7 ;
peg$currPos ++ ;
} else {
s2 = peg$FAILED ;
{
peg$fail ( peg$c8 ) ;
}
}
if ( s2 !== peg$FAILED ) {
s3 = peg$parse _ ( ) ;
if ( s3 !== peg$FAILED ) {
s1 = peg$c9 ( ) ;
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
if ( s0 === peg$FAILED ) {
s0 = peg$currPos ;
s1 = peg$parse _ ( ) ;
if ( s1 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 126 ) {
s2 = peg$c10 ;
peg$currPos ++ ;
} else {
s2 = peg$FAILED ;
{
peg$fail ( peg$c11 ) ;
}
}
if ( s2 !== peg$FAILED ) {
s3 = peg$parse _ ( ) ;
if ( s3 !== peg$FAILED ) {
s1 = peg$c12 ( ) ;
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
if ( s0 === peg$FAILED ) {
s0 = peg$currPos ;
s1 = peg$parse _ ( ) ;
if ( s1 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 43 ) {
s2 = peg$c13 ;
peg$currPos ++ ;
} else {
s2 = peg$FAILED ;
{
peg$fail ( peg$c14 ) ;
}
}
if ( s2 !== peg$FAILED ) {
s3 = peg$parse _ ( ) ;
if ( s3 !== peg$FAILED ) {
s1 = peg$c15 ( ) ;
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
if ( s0 === peg$FAILED ) {
s0 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 32 ) {
s1 = peg$c2 ;
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
peg$fail ( peg$c3 ) ;
}
}
if ( s1 !== peg$FAILED ) {
s2 = peg$parse _ ( ) ;
if ( s2 !== peg$FAILED ) {
s1 = peg$c16 ( ) ;
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
}
}
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parseselectors ( ) {
var s0 , s1 , s2 , s3 , s4 , s5 , s6 , s7 ;
var key = peg$currPos * 30 + 4 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
s1 = peg$parseselector ( ) ;
if ( s1 !== peg$FAILED ) {
s2 = [ ] ;
s3 = peg$currPos ;
s4 = peg$parse _ ( ) ;
if ( s4 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 44 ) {
s5 = peg$c17 ;
peg$currPos ++ ;
} else {
s5 = peg$FAILED ;
{
peg$fail ( peg$c18 ) ;
}
}
if ( s5 !== peg$FAILED ) {
s6 = peg$parse _ ( ) ;
if ( s6 !== peg$FAILED ) {
s7 = peg$parseselector ( ) ;
if ( s7 !== peg$FAILED ) {
s4 = [ s4 , s5 , s6 , s7 ] ;
s3 = s4 ;
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
while ( s3 !== peg$FAILED ) {
s2 . push ( s3 ) ;
s3 = peg$currPos ;
s4 = peg$parse _ ( ) ;
if ( s4 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 44 ) {
s5 = peg$c17 ;
peg$currPos ++ ;
} else {
s5 = peg$FAILED ;
{
peg$fail ( peg$c18 ) ;
}
}
if ( s5 !== peg$FAILED ) {
s6 = peg$parse _ ( ) ;
if ( s6 !== peg$FAILED ) {
s7 = peg$parseselector ( ) ;
if ( s7 !== peg$FAILED ) {
s4 = [ s4 , s5 , s6 , s7 ] ;
s3 = s4 ;
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
}
if ( s2 !== peg$FAILED ) {
s1 = peg$c19 ( s1 , s2 ) ;
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parseselector ( ) {
var s0 , s1 , s2 , s3 , s4 , s5 ;
var key = peg$currPos * 30 + 5 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
s1 = peg$parsesequence ( ) ;
if ( s1 !== peg$FAILED ) {
s2 = [ ] ;
s3 = peg$currPos ;
s4 = peg$parsebinaryOp ( ) ;
if ( s4 !== peg$FAILED ) {
s5 = peg$parsesequence ( ) ;
if ( s5 !== peg$FAILED ) {
s4 = [ s4 , s5 ] ;
s3 = s4 ;
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
while ( s3 !== peg$FAILED ) {
s2 . push ( s3 ) ;
s3 = peg$currPos ;
s4 = peg$parsebinaryOp ( ) ;
if ( s4 !== peg$FAILED ) {
s5 = peg$parsesequence ( ) ;
if ( s5 !== peg$FAILED ) {
s4 = [ s4 , s5 ] ;
s3 = s4 ;
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
}
if ( s2 !== peg$FAILED ) {
s1 = peg$c20 ( s1 , s2 ) ;
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parsesequence ( ) {
var s0 , s1 , s2 , s3 ;
var key = peg$currPos * 30 + 6 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 33 ) {
s1 = peg$c21 ;
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
peg$fail ( peg$c22 ) ;
}
}
if ( s1 === peg$FAILED ) {
s1 = null ;
}
if ( s1 !== peg$FAILED ) {
s2 = [ ] ;
s3 = peg$parseatom ( ) ;
if ( s3 !== peg$FAILED ) {
while ( s3 !== peg$FAILED ) {
s2 . push ( s3 ) ;
s3 = peg$parseatom ( ) ;
}
} else {
s2 = peg$FAILED ;
}
if ( s2 !== peg$FAILED ) {
s1 = peg$c23 ( s1 , s2 ) ;
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parseatom ( ) {
var s0 ;
var key = peg$currPos * 30 + 7 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$parsewildcard ( ) ;
if ( s0 === peg$FAILED ) {
s0 = peg$parseidentifier ( ) ;
if ( s0 === peg$FAILED ) {
s0 = peg$parseattr ( ) ;
if ( s0 === peg$FAILED ) {
s0 = peg$parsefield ( ) ;
if ( s0 === peg$FAILED ) {
s0 = peg$parsenegation ( ) ;
if ( s0 === peg$FAILED ) {
s0 = peg$parsematches ( ) ;
if ( s0 === peg$FAILED ) {
s0 = peg$parsehas ( ) ;
if ( s0 === peg$FAILED ) {
s0 = peg$parsefirstChild ( ) ;
if ( s0 === peg$FAILED ) {
s0 = peg$parselastChild ( ) ;
if ( s0 === peg$FAILED ) {
s0 = peg$parsenthChild ( ) ;
if ( s0 === peg$FAILED ) {
s0 = peg$parsenthLastChild ( ) ;
if ( s0 === peg$FAILED ) {
s0 = peg$parseclass ( ) ;
}
}
}
}
}
}
}
}
}
}
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parsewildcard ( ) {
var s0 , s1 ;
var key = peg$currPos * 30 + 8 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 42 ) {
s1 = peg$c24 ;
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
peg$fail ( peg$c25 ) ;
}
}
if ( s1 !== peg$FAILED ) {
s1 = peg$c26 ( s1 ) ;
}
s0 = s1 ;
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parseidentifier ( ) {
var s0 , s1 , s2 ;
var key = peg$currPos * 30 + 9 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 35 ) {
s1 = peg$c27 ;
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
peg$fail ( peg$c28 ) ;
}
}
if ( s1 === peg$FAILED ) {
s1 = null ;
}
if ( s1 !== peg$FAILED ) {
s2 = peg$parseidentifierName ( ) ;
if ( s2 !== peg$FAILED ) {
s1 = peg$c29 ( s2 ) ;
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parseattr ( ) {
var s0 , s1 , s2 , s3 , s4 , s5 ;
var key = peg$currPos * 30 + 10 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 91 ) {
s1 = peg$c30 ;
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
peg$fail ( peg$c31 ) ;
}
}
if ( s1 !== peg$FAILED ) {
s2 = peg$parse _ ( ) ;
if ( s2 !== peg$FAILED ) {
s3 = peg$parseattrValue ( ) ;
if ( s3 !== peg$FAILED ) {
s4 = peg$parse _ ( ) ;
if ( s4 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 93 ) {
s5 = peg$c32 ;
peg$currPos ++ ;
} else {
s5 = peg$FAILED ;
{
peg$fail ( peg$c33 ) ;
}
}
if ( s5 !== peg$FAILED ) {
s1 = peg$c34 ( s3 ) ;
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parseattrOps ( ) {
var s0 , s1 , s2 ;
var key = peg$currPos * 30 + 11 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
if ( peg$c35 . test ( input . charAt ( peg$currPos ) ) ) {
s1 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
peg$fail ( peg$c36 ) ;
}
}
if ( s1 === peg$FAILED ) {
s1 = null ;
}
if ( s1 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 61 ) {
s2 = peg$c37 ;
peg$currPos ++ ;
} else {
s2 = peg$FAILED ;
{
peg$fail ( peg$c38 ) ;
}
}
if ( s2 !== peg$FAILED ) {
s1 = peg$c39 ( s1 ) ;
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
if ( s0 === peg$FAILED ) {
if ( peg$c40 . test ( input . charAt ( peg$currPos ) ) ) {
s0 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s0 = peg$FAILED ;
{
peg$fail ( peg$c41 ) ;
}
}
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parseattrEqOps ( ) {
var s0 , s1 , s2 ;
var key = peg$currPos * 30 + 12 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 33 ) {
s1 = peg$c21 ;
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
peg$fail ( peg$c22 ) ;
}
}
if ( s1 === peg$FAILED ) {
s1 = null ;
}
if ( s1 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 61 ) {
s2 = peg$c37 ;
peg$currPos ++ ;
} else {
s2 = peg$FAILED ;
{
peg$fail ( peg$c38 ) ;
}
}
if ( s2 !== peg$FAILED ) {
s1 = peg$c39 ( s1 ) ;
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parseattrName ( ) {
2021-02-26 03:58:33 +00:00
var s0 , s1 , s2 , s3 , s4 , s5 ;
2020-08-25 23:57:08 +00:00
var key = peg$currPos * 30 + 13 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
2021-02-26 03:58:33 +00:00
s1 = peg$parseidentifierName ( ) ;
if ( s1 !== peg$FAILED ) {
s2 = [ ] ;
s3 = peg$currPos ;
2020-08-25 23:57:08 +00:00
if ( input . charCodeAt ( peg$currPos ) === 46 ) {
2021-02-26 03:58:33 +00:00
s4 = peg$c42 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
2021-02-26 03:58:33 +00:00
s4 = peg$FAILED ;
2020-08-25 23:57:08 +00:00
{
peg$fail ( peg$c43 ) ;
}
}
2021-02-26 03:58:33 +00:00
if ( s4 !== peg$FAILED ) {
s5 = peg$parseidentifierName ( ) ;
if ( s5 !== peg$FAILED ) {
s4 = [ s4 , s5 ] ;
s3 = s4 ;
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
while ( s3 !== peg$FAILED ) {
s2 . push ( s3 ) ;
s3 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 46 ) {
s4 = peg$c42 ;
peg$currPos ++ ;
} else {
s4 = peg$FAILED ;
{
peg$fail ( peg$c43 ) ;
2020-08-25 23:57:08 +00:00
}
}
2021-02-26 03:58:33 +00:00
if ( s4 !== peg$FAILED ) {
s5 = peg$parseidentifierName ( ) ;
if ( s5 !== peg$FAILED ) {
s4 = [ s4 , s5 ] ;
s3 = s4 ;
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
2020-08-25 23:57:08 +00:00
}
2021-02-26 03:58:33 +00:00
if ( s2 !== peg$FAILED ) {
s1 = peg$c44 ( s1 , s2 ) ;
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
2020-08-25 23:57:08 +00:00
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parseattrValue ( ) {
var s0 , s1 , s2 , s3 , s4 , s5 ;
var key = peg$currPos * 30 + 14 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
s1 = peg$parseattrName ( ) ;
if ( s1 !== peg$FAILED ) {
s2 = peg$parse _ ( ) ;
if ( s2 !== peg$FAILED ) {
s3 = peg$parseattrEqOps ( ) ;
if ( s3 !== peg$FAILED ) {
s4 = peg$parse _ ( ) ;
if ( s4 !== peg$FAILED ) {
s5 = peg$parsetype ( ) ;
if ( s5 === peg$FAILED ) {
s5 = peg$parseregex ( ) ;
}
if ( s5 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c45 ( s1 , s3 , s5 ) ;
2020-08-25 23:57:08 +00:00
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
if ( s0 === peg$FAILED ) {
s0 = peg$currPos ;
s1 = peg$parseattrName ( ) ;
if ( s1 !== peg$FAILED ) {
s2 = peg$parse _ ( ) ;
if ( s2 !== peg$FAILED ) {
s3 = peg$parseattrOps ( ) ;
if ( s3 !== peg$FAILED ) {
s4 = peg$parse _ ( ) ;
if ( s4 !== peg$FAILED ) {
s5 = peg$parsestring ( ) ;
if ( s5 === peg$FAILED ) {
s5 = peg$parsenumber ( ) ;
if ( s5 === peg$FAILED ) {
s5 = peg$parsepath ( ) ;
}
}
if ( s5 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c45 ( s1 , s3 , s5 ) ;
2020-08-25 23:57:08 +00:00
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
if ( s0 === peg$FAILED ) {
s0 = peg$currPos ;
s1 = peg$parseattrName ( ) ;
if ( s1 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c46 ( s1 ) ;
2020-08-25 23:57:08 +00:00
}
s0 = s1 ;
}
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parsestring ( ) {
var s0 , s1 , s2 , s3 , s4 , s5 ;
var key = peg$currPos * 30 + 15 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 34 ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c47 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c48 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s1 !== peg$FAILED ) {
s2 = [ ] ;
2021-02-26 03:58:33 +00:00
if ( peg$c49 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s3 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s3 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c50 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s3 === peg$FAILED ) {
s3 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 92 ) {
2021-02-26 03:58:33 +00:00
s4 = peg$c51 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s4 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c52 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s4 !== peg$FAILED ) {
if ( input . length > peg$currPos ) {
s5 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s5 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c53 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s5 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s4 = peg$c54 ( s4 , s5 ) ;
2020-08-25 23:57:08 +00:00
s3 = s4 ;
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
}
while ( s3 !== peg$FAILED ) {
s2 . push ( s3 ) ;
2021-02-26 03:58:33 +00:00
if ( peg$c49 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s3 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s3 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c50 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s3 === peg$FAILED ) {
s3 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 92 ) {
2021-02-26 03:58:33 +00:00
s4 = peg$c51 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s4 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c52 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s4 !== peg$FAILED ) {
if ( input . length > peg$currPos ) {
s5 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s5 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c53 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s5 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s4 = peg$c54 ( s4 , s5 ) ;
2020-08-25 23:57:08 +00:00
s3 = s4 ;
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
}
}
if ( s2 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 34 ) {
2021-02-26 03:58:33 +00:00
s3 = peg$c47 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s3 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c48 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s3 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c55 ( s2 ) ;
2020-08-25 23:57:08 +00:00
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
if ( s0 === peg$FAILED ) {
s0 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 39 ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c56 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c57 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s1 !== peg$FAILED ) {
s2 = [ ] ;
2021-02-26 03:58:33 +00:00
if ( peg$c58 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s3 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s3 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c59 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s3 === peg$FAILED ) {
s3 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 92 ) {
2021-02-26 03:58:33 +00:00
s4 = peg$c51 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s4 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c52 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s4 !== peg$FAILED ) {
if ( input . length > peg$currPos ) {
s5 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s5 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c53 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s5 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s4 = peg$c54 ( s4 , s5 ) ;
2020-08-25 23:57:08 +00:00
s3 = s4 ;
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
}
while ( s3 !== peg$FAILED ) {
s2 . push ( s3 ) ;
2021-02-26 03:58:33 +00:00
if ( peg$c58 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s3 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s3 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c59 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s3 === peg$FAILED ) {
s3 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 92 ) {
2021-02-26 03:58:33 +00:00
s4 = peg$c51 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s4 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c52 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s4 !== peg$FAILED ) {
if ( input . length > peg$currPos ) {
s5 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s5 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c53 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s5 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s4 = peg$c54 ( s4 , s5 ) ;
2020-08-25 23:57:08 +00:00
s3 = s4 ;
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
} else {
peg$currPos = s3 ;
s3 = peg$FAILED ;
}
}
}
if ( s2 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 39 ) {
2021-02-26 03:58:33 +00:00
s3 = peg$c56 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s3 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c57 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s3 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c55 ( s2 ) ;
2020-08-25 23:57:08 +00:00
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parsenumber ( ) {
var s0 , s1 , s2 , s3 ;
var key = peg$currPos * 30 + 16 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
s1 = peg$currPos ;
s2 = [ ] ;
2021-02-26 03:58:33 +00:00
if ( peg$c60 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s3 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s3 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c61 ) ;
2020-08-25 23:57:08 +00:00
}
}
while ( s3 !== peg$FAILED ) {
s2 . push ( s3 ) ;
2021-02-26 03:58:33 +00:00
if ( peg$c60 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s3 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s3 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c61 ) ;
2020-08-25 23:57:08 +00:00
}
}
}
if ( s2 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 46 ) {
s3 = peg$c42 ;
peg$currPos ++ ;
} else {
s3 = peg$FAILED ;
{
peg$fail ( peg$c43 ) ;
}
}
if ( s3 !== peg$FAILED ) {
s2 = [ s2 , s3 ] ;
s1 = s2 ;
} else {
peg$currPos = s1 ;
s1 = peg$FAILED ;
}
} else {
peg$currPos = s1 ;
s1 = peg$FAILED ;
}
if ( s1 === peg$FAILED ) {
s1 = null ;
}
if ( s1 !== peg$FAILED ) {
s2 = [ ] ;
2021-02-26 03:58:33 +00:00
if ( peg$c60 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s3 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s3 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c61 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s3 !== peg$FAILED ) {
while ( s3 !== peg$FAILED ) {
s2 . push ( s3 ) ;
2021-02-26 03:58:33 +00:00
if ( peg$c60 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s3 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s3 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c61 ) ;
2020-08-25 23:57:08 +00:00
}
}
}
} else {
s2 = peg$FAILED ;
}
if ( s2 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c62 ( s1 , s2 ) ;
2020-08-25 23:57:08 +00:00
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parsepath ( ) {
var s0 , s1 ;
var key = peg$currPos * 30 + 17 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
s1 = peg$parseidentifierName ( ) ;
if ( s1 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c63 ( s1 ) ;
2020-08-25 23:57:08 +00:00
}
s0 = s1 ;
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parsetype ( ) {
var s0 , s1 , s2 , s3 , s4 , s5 ;
var key = peg$currPos * 30 + 18 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
2021-02-26 03:58:33 +00:00
if ( input . substr ( peg$currPos , 5 ) === peg$c64 ) {
s1 = peg$c64 ;
2020-08-25 23:57:08 +00:00
peg$currPos += 5 ;
} else {
s1 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c65 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s1 !== peg$FAILED ) {
s2 = peg$parse _ ( ) ;
if ( s2 !== peg$FAILED ) {
s3 = [ ] ;
2021-02-26 03:58:33 +00:00
if ( peg$c66 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s4 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s4 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c67 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s4 !== peg$FAILED ) {
while ( s4 !== peg$FAILED ) {
s3 . push ( s4 ) ;
2021-02-26 03:58:33 +00:00
if ( peg$c66 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s4 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s4 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c67 ) ;
2020-08-25 23:57:08 +00:00
}
}
}
} else {
s3 = peg$FAILED ;
}
if ( s3 !== peg$FAILED ) {
s4 = peg$parse _ ( ) ;
if ( s4 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 41 ) {
2021-02-26 03:58:33 +00:00
s5 = peg$c68 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s5 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c69 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s5 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c70 ( s3 ) ;
2020-08-25 23:57:08 +00:00
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parseflags ( ) {
var s0 , s1 ;
var key = peg$currPos * 30 + 19 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = [ ] ;
2021-02-26 03:58:33 +00:00
if ( peg$c71 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s1 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c72 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s1 !== peg$FAILED ) {
while ( s1 !== peg$FAILED ) {
s0 . push ( s1 ) ;
2021-02-26 03:58:33 +00:00
if ( peg$c71 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s1 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c72 ) ;
2020-08-25 23:57:08 +00:00
}
}
}
} else {
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parseregex ( ) {
var s0 , s1 , s2 , s3 , s4 ;
var key = peg$currPos * 30 + 20 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 47 ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c73 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c74 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s1 !== peg$FAILED ) {
s2 = [ ] ;
2021-02-26 03:58:33 +00:00
if ( peg$c75 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s3 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s3 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c76 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s3 !== peg$FAILED ) {
while ( s3 !== peg$FAILED ) {
s2 . push ( s3 ) ;
2021-02-26 03:58:33 +00:00
if ( peg$c75 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s3 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s3 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c76 ) ;
2020-08-25 23:57:08 +00:00
}
}
}
} else {
s2 = peg$FAILED ;
}
if ( s2 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 47 ) {
2021-02-26 03:58:33 +00:00
s3 = peg$c73 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s3 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c74 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s3 !== peg$FAILED ) {
s4 = peg$parseflags ( ) ;
if ( s4 === peg$FAILED ) {
s4 = null ;
}
if ( s4 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c77 ( s2 , s4 ) ;
2020-08-25 23:57:08 +00:00
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parsefield ( ) {
var s0 , s1 , s2 , s3 , s4 , s5 , s6 ;
var key = peg$currPos * 30 + 21 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 46 ) {
s1 = peg$c42 ;
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
peg$fail ( peg$c43 ) ;
}
}
if ( s1 !== peg$FAILED ) {
s2 = peg$parseidentifierName ( ) ;
if ( s2 !== peg$FAILED ) {
s3 = [ ] ;
s4 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 46 ) {
s5 = peg$c42 ;
peg$currPos ++ ;
} else {
s5 = peg$FAILED ;
{
peg$fail ( peg$c43 ) ;
}
}
if ( s5 !== peg$FAILED ) {
s6 = peg$parseidentifierName ( ) ;
if ( s6 !== peg$FAILED ) {
s5 = [ s5 , s6 ] ;
s4 = s5 ;
} else {
peg$currPos = s4 ;
s4 = peg$FAILED ;
}
} else {
peg$currPos = s4 ;
s4 = peg$FAILED ;
}
while ( s4 !== peg$FAILED ) {
s3 . push ( s4 ) ;
s4 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 46 ) {
s5 = peg$c42 ;
peg$currPos ++ ;
} else {
s5 = peg$FAILED ;
{
peg$fail ( peg$c43 ) ;
}
}
if ( s5 !== peg$FAILED ) {
s6 = peg$parseidentifierName ( ) ;
if ( s6 !== peg$FAILED ) {
s5 = [ s5 , s6 ] ;
s4 = s5 ;
} else {
peg$currPos = s4 ;
s4 = peg$FAILED ;
}
} else {
peg$currPos = s4 ;
s4 = peg$FAILED ;
}
}
if ( s3 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c78 ( s2 , s3 ) ;
2020-08-25 23:57:08 +00:00
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parsenegation ( ) {
var s0 , s1 , s2 , s3 , s4 , s5 ;
var key = peg$currPos * 30 + 22 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
2021-02-26 03:58:33 +00:00
if ( input . substr ( peg$currPos , 5 ) === peg$c79 ) {
s1 = peg$c79 ;
2020-08-25 23:57:08 +00:00
peg$currPos += 5 ;
} else {
s1 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c80 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s1 !== peg$FAILED ) {
s2 = peg$parse _ ( ) ;
if ( s2 !== peg$FAILED ) {
s3 = peg$parseselectors ( ) ;
if ( s3 !== peg$FAILED ) {
s4 = peg$parse _ ( ) ;
if ( s4 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 41 ) {
2021-02-26 03:58:33 +00:00
s5 = peg$c68 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s5 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c69 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s5 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c81 ( s3 ) ;
2020-08-25 23:57:08 +00:00
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parsematches ( ) {
var s0 , s1 , s2 , s3 , s4 , s5 ;
var key = peg$currPos * 30 + 23 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
2021-02-26 03:58:33 +00:00
if ( input . substr ( peg$currPos , 9 ) === peg$c82 ) {
s1 = peg$c82 ;
2020-08-25 23:57:08 +00:00
peg$currPos += 9 ;
} else {
s1 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c83 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s1 !== peg$FAILED ) {
s2 = peg$parse _ ( ) ;
if ( s2 !== peg$FAILED ) {
s3 = peg$parseselectors ( ) ;
if ( s3 !== peg$FAILED ) {
s4 = peg$parse _ ( ) ;
if ( s4 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 41 ) {
2021-02-26 03:58:33 +00:00
s5 = peg$c68 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s5 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c69 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s5 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c84 ( s3 ) ;
2020-08-25 23:57:08 +00:00
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parsehas ( ) {
var s0 , s1 , s2 , s3 , s4 , s5 ;
var key = peg$currPos * 30 + 24 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
2021-02-26 03:58:33 +00:00
if ( input . substr ( peg$currPos , 5 ) === peg$c85 ) {
s1 = peg$c85 ;
2020-08-25 23:57:08 +00:00
peg$currPos += 5 ;
} else {
s1 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c86 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s1 !== peg$FAILED ) {
s2 = peg$parse _ ( ) ;
if ( s2 !== peg$FAILED ) {
s3 = peg$parseselectors ( ) ;
if ( s3 !== peg$FAILED ) {
s4 = peg$parse _ ( ) ;
if ( s4 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 41 ) {
2021-02-26 03:58:33 +00:00
s5 = peg$c68 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s5 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c69 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s5 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c87 ( s3 ) ;
2020-08-25 23:57:08 +00:00
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parsefirstChild ( ) {
var s0 , s1 ;
var key = peg$currPos * 30 + 25 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
2021-02-26 03:58:33 +00:00
if ( input . substr ( peg$currPos , 12 ) === peg$c88 ) {
s1 = peg$c88 ;
2020-08-25 23:57:08 +00:00
peg$currPos += 12 ;
} else {
s1 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c89 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s1 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c90 ( ) ;
2020-08-25 23:57:08 +00:00
}
s0 = s1 ;
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parselastChild ( ) {
var s0 , s1 ;
var key = peg$currPos * 30 + 26 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
2021-02-26 03:58:33 +00:00
if ( input . substr ( peg$currPos , 11 ) === peg$c91 ) {
s1 = peg$c91 ;
2020-08-25 23:57:08 +00:00
peg$currPos += 11 ;
} else {
s1 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c92 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s1 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c93 ( ) ;
2020-08-25 23:57:08 +00:00
}
s0 = s1 ;
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parsenthChild ( ) {
var s0 , s1 , s2 , s3 , s4 , s5 ;
var key = peg$currPos * 30 + 27 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
2021-02-26 03:58:33 +00:00
if ( input . substr ( peg$currPos , 11 ) === peg$c94 ) {
s1 = peg$c94 ;
2020-08-25 23:57:08 +00:00
peg$currPos += 11 ;
} else {
s1 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c95 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s1 !== peg$FAILED ) {
s2 = peg$parse _ ( ) ;
if ( s2 !== peg$FAILED ) {
s3 = [ ] ;
2021-02-26 03:58:33 +00:00
if ( peg$c60 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s4 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s4 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c61 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s4 !== peg$FAILED ) {
while ( s4 !== peg$FAILED ) {
s3 . push ( s4 ) ;
2021-02-26 03:58:33 +00:00
if ( peg$c60 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s4 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s4 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c61 ) ;
2020-08-25 23:57:08 +00:00
}
}
}
} else {
s3 = peg$FAILED ;
}
if ( s3 !== peg$FAILED ) {
s4 = peg$parse _ ( ) ;
if ( s4 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 41 ) {
2021-02-26 03:58:33 +00:00
s5 = peg$c68 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s5 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c69 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s5 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c96 ( s3 ) ;
2020-08-25 23:57:08 +00:00
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parsenthLastChild ( ) {
var s0 , s1 , s2 , s3 , s4 , s5 ;
var key = peg$currPos * 30 + 28 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
2021-02-26 03:58:33 +00:00
if ( input . substr ( peg$currPos , 16 ) === peg$c97 ) {
s1 = peg$c97 ;
2020-08-25 23:57:08 +00:00
peg$currPos += 16 ;
} else {
s1 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c98 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s1 !== peg$FAILED ) {
s2 = peg$parse _ ( ) ;
if ( s2 !== peg$FAILED ) {
s3 = [ ] ;
2021-02-26 03:58:33 +00:00
if ( peg$c60 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s4 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s4 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c61 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s4 !== peg$FAILED ) {
while ( s4 !== peg$FAILED ) {
s3 . push ( s4 ) ;
2021-02-26 03:58:33 +00:00
if ( peg$c60 . test ( input . charAt ( peg$currPos ) ) ) {
2020-08-25 23:57:08 +00:00
s4 = input . charAt ( peg$currPos ) ;
peg$currPos ++ ;
} else {
s4 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c61 ) ;
2020-08-25 23:57:08 +00:00
}
}
}
} else {
s3 = peg$FAILED ;
}
if ( s3 !== peg$FAILED ) {
s4 = peg$parse _ ( ) ;
if ( s4 !== peg$FAILED ) {
if ( input . charCodeAt ( peg$currPos ) === 41 ) {
2021-02-26 03:58:33 +00:00
s5 = peg$c68 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s5 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c69 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s5 !== peg$FAILED ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c99 ( s3 ) ;
2020-08-25 23:57:08 +00:00
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function peg$parseclass ( ) {
var s0 , s1 , s2 ;
var key = peg$currPos * 30 + 29 ,
2024-03-28 02:00:41 +00:00
cached = peg$resultsCache [ key ] ;
2020-08-25 23:57:08 +00:00
if ( cached ) {
peg$currPos = cached . nextPos ;
return cached . result ;
}
s0 = peg$currPos ;
if ( input . charCodeAt ( peg$currPos ) === 58 ) {
2021-02-26 03:58:33 +00:00
s1 = peg$c100 ;
2020-08-25 23:57:08 +00:00
peg$currPos ++ ;
} else {
s1 = peg$FAILED ;
{
2021-02-26 03:58:33 +00:00
peg$fail ( peg$c101 ) ;
2020-08-25 23:57:08 +00:00
}
}
if ( s1 !== peg$FAILED ) {
2024-03-28 02:00:41 +00:00
s2 = peg$parseidentifierName ( ) ;
2020-08-25 23:57:08 +00:00
if ( s2 !== peg$FAILED ) {
2024-03-28 02:00:41 +00:00
s1 = peg$c102 ( s2 ) ;
2020-08-25 23:57:08 +00:00
s0 = s1 ;
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
} else {
peg$currPos = s0 ;
s0 = peg$FAILED ;
}
peg$resultsCache [ key ] = {
nextPos : peg$currPos ,
result : s0
} ;
return s0 ;
}
function nth ( n ) {
return {
type : 'nth-child' ,
index : {
type : 'literal' ,
value : n
}
} ;
}
function nthLast ( n ) {
return {
type : 'nth-last-child' ,
index : {
type : 'literal' ,
value : n
}
} ;
}
function strUnescape ( s ) {
return s . replace ( /\\(.)/g , function ( match , ch ) {
switch ( ch ) {
case 'b' :
return '\b' ;
case 'f' :
return '\f' ;
case 'n' :
return '\n' ;
case 'r' :
return '\r' ;
case 't' :
return '\t' ;
case 'v' :
return '\v' ;
default :
return ch ;
}
} ) ;
}
peg$result = peg$startRuleFunction ( ) ;
if ( peg$result !== peg$FAILED && peg$currPos === input . length ) {
return peg$result ;
} else {
if ( peg$result !== peg$FAILED && peg$currPos < input . length ) {
peg$fail ( peg$endExpectation ( ) ) ;
}
throw peg$buildStructuredError ( peg$maxFailExpected , peg$maxFailPos < input . length ? input . charAt ( peg$maxFailPos ) : null , peg$maxFailPos < input . length ? peg$computeLocation ( peg$maxFailPos , peg$maxFailPos + 1 ) : peg$computeLocation ( peg$maxFailPos , peg$maxFailPos ) ) ;
}
}
return {
SyntaxError : peg$SyntaxError ,
parse : peg$parse
} ;
} ) ;
} ) ;
/ * *
* @ typedef { "LEFT_SIDE" | "RIGHT_SIDE" } Side
* /
var LEFT _SIDE = 'LEFT_SIDE' ;
var RIGHT _SIDE = 'RIGHT_SIDE' ;
2024-03-28 02:00:41 +00:00
2020-08-25 23:57:08 +00:00
/ * *
* @ external AST
* @ see https : //esprima.readthedocs.io/en/latest/syntax-tree-format.html
* /
/ * *
* One of the rules of ` grammar.pegjs `
* @ typedef { PlainObject } SelectorAST
* @ see grammar . pegjs
* /
/ * *
* The ` sequence ` production of ` grammar.pegjs `
* @ typedef { PlainObject } SelectorSequenceAST
* /
/ * *
* Get the value of a property which may be multiple levels down
* in the object .
* @ param { ? PlainObject } obj
2024-03-28 02:00:41 +00:00
* @ param { string [ ] } keys
2020-08-25 23:57:08 +00:00
* @ returns { undefined | boolean | string | number | external : AST }
* /
2024-03-28 02:00:41 +00:00
function getPath ( obj , keys ) {
for ( var i = 0 ; i < keys . length ; ++ i ) {
if ( obj == null ) {
return obj ;
2021-02-26 03:58:33 +00:00
}
2024-03-28 02:00:41 +00:00
obj = obj [ keys [ i ] ] ;
2020-08-25 23:57:08 +00:00
}
return obj ;
}
2024-03-28 02:00:41 +00:00
2020-08-25 23:57:08 +00:00
/ * *
* Determine whether ` node ` can be reached by following ` path ` ,
* starting at ` ancestor ` .
* @ param { ? external : AST } node
* @ param { ? external : AST } ancestor
* @ param { string [ ] } path
2024-03-28 02:00:41 +00:00
* @ param { Integer } fromPathIndex
2020-08-25 23:57:08 +00:00
* @ returns { boolean }
* /
2024-03-28 02:00:41 +00:00
function inPath ( node , ancestor , path , fromPathIndex ) {
var current = ancestor ;
for ( var i = fromPathIndex ; i < path . length ; ++ i ) {
if ( current == null ) {
return false ;
}
var field = current [ path [ i ] ] ;
if ( Array . isArray ( field ) ) {
for ( var k = 0 ; k < field . length ; ++ k ) {
if ( inPath ( node , field [ k ] , path , i + 1 ) ) {
2021-02-26 03:58:33 +00:00
return true ;
}
2020-08-25 23:57:08 +00:00
}
2024-03-28 02:00:41 +00:00
return false ;
2020-08-25 23:57:08 +00:00
}
2024-03-28 02:00:41 +00:00
current = field ;
2020-08-25 23:57:08 +00:00
}
2024-03-28 02:00:41 +00:00
return node === current ;
2020-08-25 23:57:08 +00:00
}
2024-03-28 02:00:41 +00:00
2021-02-26 03:58:33 +00:00
/ * *
2024-03-28 02:00:41 +00:00
* A generated matcher function for a selector .
* @ typedef { function } SelectorMatcher
* /
2021-02-26 03:58:33 +00:00
/ * *
2024-03-28 02:00:41 +00:00
* A WeakMap for holding cached matcher functions for selectors .
* @ type { WeakMap < SelectorAST , SelectorMatcher > }
* /
var MATCHER _CACHE = typeof WeakMap === 'function' ? new WeakMap ( ) : null ;
2021-02-26 03:58:33 +00:00
2020-08-25 23:57:08 +00:00
/ * *
2024-03-28 02:00:41 +00:00
* Look up a matcher function for ` selector ` in the cache .
* If it does not exist , generate it with ` generateMatcher ` and add it to the cache .
* In engines without WeakMap , the caching is skipped and matchers are generated with every call .
2020-08-25 23:57:08 +00:00
* @ param { ? SelectorAST } selector
2024-03-28 02:00:41 +00:00
* @ returns { SelectorMatcher }
2020-08-25 23:57:08 +00:00
* /
2024-03-28 02:00:41 +00:00
function getMatcher ( selector ) {
if ( selector == null ) {
return function ( ) {
return true ;
} ;
2020-08-25 23:57:08 +00:00
}
2024-03-28 02:00:41 +00:00
if ( MATCHER _CACHE != null ) {
var matcher = MATCHER _CACHE . get ( selector ) ;
if ( matcher != null ) {
return matcher ;
}
matcher = generateMatcher ( selector ) ;
MATCHER _CACHE . set ( selector , matcher ) ;
return matcher ;
2020-08-25 23:57:08 +00:00
}
2024-03-28 02:00:41 +00:00
return generateMatcher ( selector ) ;
}
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
/ * *
* Create a matcher function for ` selector ` ,
* @ param { ? SelectorAST } selector
* @ returns { SelectorMatcher }
* /
function generateMatcher ( selector ) {
2020-08-25 23:57:08 +00:00
switch ( selector . type ) {
case 'wildcard' :
2024-03-28 02:00:41 +00:00
return function ( ) {
return true ;
} ;
2020-08-25 23:57:08 +00:00
case 'identifier' :
2024-03-28 02:00:41 +00:00
{
var value = selector . value . toLowerCase ( ) ;
return function ( node , ancestry , options ) {
var nodeTypeKey = options && options . nodeTypeKey || 'type' ;
return value === node [ nodeTypeKey ] . toLowerCase ( ) ;
} ;
}
2020-08-25 23:57:08 +00:00
case 'field' :
{
var path = selector . name . split ( '.' ) ;
2024-03-28 02:00:41 +00:00
return function ( node , ancestry ) {
var ancestor = ancestry [ path . length - 1 ] ;
return inPath ( node , ancestor , path , 0 ) ;
} ;
2020-08-25 23:57:08 +00:00
}
case 'matches' :
2024-03-28 02:00:41 +00:00
{
var matchers = selector . selectors . map ( getMatcher ) ;
return function ( node , ancestry , options ) {
for ( var i = 0 ; i < matchers . length ; ++ i ) {
if ( matchers [ i ] ( node , ancestry , options ) ) {
return true ;
}
2021-02-26 03:58:33 +00:00
}
2024-03-28 02:00:41 +00:00
return false ;
} ;
2020-08-25 23:57:08 +00:00
}
case 'compound' :
2024-03-28 02:00:41 +00:00
{
var _matchers = selector . selectors . map ( getMatcher ) ;
return function ( node , ancestry , options ) {
for ( var i = 0 ; i < _matchers . length ; ++ i ) {
if ( ! _matchers [ i ] ( node , ancestry , options ) ) {
return false ;
}
2021-02-26 03:58:33 +00:00
}
2024-03-28 02:00:41 +00:00
return true ;
} ;
2020-08-25 23:57:08 +00:00
}
case 'not' :
2024-03-28 02:00:41 +00:00
{
var _matchers2 = selector . selectors . map ( getMatcher ) ;
return function ( node , ancestry , options ) {
for ( var i = 0 ; i < _matchers2 . length ; ++ i ) {
if ( _matchers2 [ i ] ( node , ancestry , options ) ) {
return false ;
}
2021-02-26 03:58:33 +00:00
}
2024-03-28 02:00:41 +00:00
return true ;
} ;
2020-08-25 23:57:08 +00:00
}
case 'has' :
{
2024-03-28 02:00:41 +00:00
var _matchers3 = selector . selectors . map ( getMatcher ) ;
return function ( node , ancestry , options ) {
var result = false ;
var a = [ ] ;
estraverse . traverse ( node , {
enter : function enter ( node , parent ) {
if ( parent != null ) {
a . unshift ( parent ) ;
}
for ( var i = 0 ; i < _matchers3 . length ; ++ i ) {
if ( _matchers3 [ i ] ( node , a , options ) ) {
result = true ;
this [ "break" ] ( ) ;
return ;
}
}
} ,
leave : function leave ( ) {
a . shift ( ) ;
} ,
keys : options && options . visitorKeys ,
fallback : options && options . fallback || 'iteration'
} ) ;
return result ;
} ;
2020-08-25 23:57:08 +00:00
}
case 'child' :
2024-03-28 02:00:41 +00:00
{
var left = getMatcher ( selector . left ) ;
var right = getMatcher ( selector . right ) ;
return function ( node , ancestry , options ) {
if ( ancestry . length > 0 && right ( node , ancestry , options ) ) {
return left ( ancestry [ 0 ] , ancestry . slice ( 1 ) , options ) ;
}
return false ;
} ;
2020-08-25 23:57:08 +00:00
}
case 'descendant' :
2024-03-28 02:00:41 +00:00
{
var _left = getMatcher ( selector . left ) ;
var _right = getMatcher ( selector . right ) ;
return function ( node , ancestry , options ) {
if ( _right ( node , ancestry , options ) ) {
for ( var i = 0 , l = ancestry . length ; i < l ; ++ i ) {
if ( _left ( ancestry [ i ] , ancestry . slice ( i + 1 ) , options ) ) {
return true ;
}
}
2020-08-25 23:57:08 +00:00
}
2024-03-28 02:00:41 +00:00
return false ;
} ;
2020-08-25 23:57:08 +00:00
}
case 'attribute' :
{
2024-03-28 02:00:41 +00:00
var _path = selector . name . split ( '.' ) ;
2020-08-25 23:57:08 +00:00
switch ( selector . operator ) {
case void 0 :
2024-03-28 02:00:41 +00:00
return function ( node ) {
return getPath ( node , _path ) != null ;
} ;
2020-08-25 23:57:08 +00:00
case '=' :
switch ( selector . value . type ) {
case 'regexp' :
2024-03-28 02:00:41 +00:00
return function ( node ) {
var p = getPath ( node , _path ) ;
return typeof p === 'string' && selector . value . value . test ( p ) ;
} ;
2020-08-25 23:57:08 +00:00
case 'literal' :
2024-03-28 02:00:41 +00:00
{
var literal = "" . concat ( selector . value . value ) ;
return function ( node ) {
return literal === "" . concat ( getPath ( node , _path ) ) ;
} ;
}
2020-08-25 23:57:08 +00:00
case 'type' :
2024-03-28 02:00:41 +00:00
return function ( node ) {
return selector . value . value === _typeof ( getPath ( node , _path ) ) ;
} ;
2020-08-25 23:57:08 +00:00
}
throw new Error ( "Unknown selector value type: " . concat ( selector . value . type ) ) ;
case '!=' :
switch ( selector . value . type ) {
case 'regexp' :
2024-03-28 02:00:41 +00:00
return function ( node ) {
return ! selector . value . value . test ( getPath ( node , _path ) ) ;
} ;
2020-08-25 23:57:08 +00:00
case 'literal' :
2024-03-28 02:00:41 +00:00
{
var _literal = "" . concat ( selector . value . value ) ;
return function ( node ) {
return _literal !== "" . concat ( getPath ( node , _path ) ) ;
} ;
}
2020-08-25 23:57:08 +00:00
case 'type' :
2024-03-28 02:00:41 +00:00
return function ( node ) {
return selector . value . value !== _typeof ( getPath ( node , _path ) ) ;
} ;
2020-08-25 23:57:08 +00:00
}
throw new Error ( "Unknown selector value type: " . concat ( selector . value . type ) ) ;
case '<=' :
2024-03-28 02:00:41 +00:00
return function ( node ) {
return getPath ( node , _path ) <= selector . value . value ;
} ;
2020-08-25 23:57:08 +00:00
case '<' :
2024-03-28 02:00:41 +00:00
return function ( node ) {
return getPath ( node , _path ) < selector . value . value ;
} ;
2020-08-25 23:57:08 +00:00
case '>' :
2024-03-28 02:00:41 +00:00
return function ( node ) {
return getPath ( node , _path ) > selector . value . value ;
} ;
2020-08-25 23:57:08 +00:00
case '>=' :
2024-03-28 02:00:41 +00:00
return function ( node ) {
return getPath ( node , _path ) >= selector . value . value ;
} ;
2020-08-25 23:57:08 +00:00
}
throw new Error ( "Unknown operator: " . concat ( selector . operator ) ) ;
}
case 'sibling' :
2024-03-28 02:00:41 +00:00
{
var _left2 = getMatcher ( selector . left ) ;
var _right2 = getMatcher ( selector . right ) ;
return function ( node , ancestry , options ) {
return _right2 ( node , ancestry , options ) && sibling ( node , _left2 , ancestry , LEFT _SIDE , options ) || selector . left . subject && _left2 ( node , ancestry , options ) && sibling ( node , _right2 , ancestry , RIGHT _SIDE , options ) ;
} ;
}
2020-08-25 23:57:08 +00:00
case 'adjacent' :
2024-03-28 02:00:41 +00:00
{
var _left3 = getMatcher ( selector . left ) ;
var _right3 = getMatcher ( selector . right ) ;
return function ( node , ancestry , options ) {
return _right3 ( node , ancestry , options ) && adjacent ( node , _left3 , ancestry , LEFT _SIDE , options ) || selector . right . subject && _left3 ( node , ancestry , options ) && adjacent ( node , _right3 , ancestry , RIGHT _SIDE , options ) ;
} ;
}
2020-08-25 23:57:08 +00:00
case 'nth-child' :
2024-03-28 02:00:41 +00:00
{
var nth = selector . index . value ;
var _right4 = getMatcher ( selector . right ) ;
return function ( node , ancestry , options ) {
return _right4 ( node , ancestry , options ) && nthChild ( node , ancestry , nth , options ) ;
} ;
}
2020-08-25 23:57:08 +00:00
case 'nth-last-child' :
2024-03-28 02:00:41 +00:00
{
var _nth = - selector . index . value ;
var _right5 = getMatcher ( selector . right ) ;
return function ( node , ancestry , options ) {
return _right5 ( node , ancestry , options ) && nthChild ( node , ancestry , _nth , options ) ;
} ;
}
2020-08-25 23:57:08 +00:00
case 'class' :
2024-03-28 02:00:41 +00:00
{
return function ( node , ancestry , options ) {
if ( options && options . matchClass ) {
return options . matchClass ( selector . name , node , ancestry ) ;
}
if ( options && options . nodeTypeKey ) return false ;
var name = selector . name . toLowerCase ( ) ;
switch ( name ) {
case 'statement' :
if ( node . type . slice ( - 9 ) === 'Statement' ) return true ;
// fallthrough: interface Declaration <: Statement { }
case 'declaration' :
return node . type . slice ( - 11 ) === 'Declaration' ;
case 'pattern' :
if ( node . type . slice ( - 7 ) === 'Pattern' ) return true ;
// fallthrough: interface Expression <: Node, Pattern { }
case 'expression' :
return node . type . slice ( - 10 ) === 'Expression' || node . type . slice ( - 7 ) === 'Literal' || node . type === 'Identifier' && ( ancestry . length === 0 || ancestry [ 0 ] . type !== 'MetaProperty' ) || node . type === 'MetaProperty' ;
case 'function' :
return node . type === 'FunctionDeclaration' || node . type === 'FunctionExpression' || node . type === 'ArrowFunctionExpression' ;
}
throw new Error ( "Unknown class name: " . concat ( selector . name ) ) ;
} ;
}
}
throw new Error ( "Unknown selector type: " . concat ( selector . type ) ) ;
}
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
/ * *
* @ callback TraverseOptionFallback
* @ param { external : AST } node The given node .
* @ returns { string [ ] } An array of visitor keys for the given node .
* /
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
/ * *
* @ callback ClassMatcher
* @ param { string } className The name of the class to match .
* @ param { external : AST } node The node to match against .
* @ param { Array < external : AST > } ancestry The ancestry of the node .
* @ returns { boolean } True if the node matches the class , false if not .
* /
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
/ * *
* @ typedef { object } ESQueryOptions
* @ property { string } [ nodeTypeKey = "type" ] By passing ` nodeTypeKey ` , we can allow other ASTs to use ESQuery .
* @ property { { [ nodeType : string ] : string [ ] } } [ visitorKeys ] By passing ` visitorKeys ` mapping , we can extend the properties of the nodes that traverse the node .
* @ property { TraverseOptionFallback } [ fallback ] By passing ` fallback ` option , we can control the properties of traversing nodes when encountering unknown nodes .
* @ property { ClassMatcher } [ matchClass ] By passing ` matchClass ` option , we can customize the interpretation of classes .
* /
2020-08-25 23:57:08 +00:00
2024-03-28 02:00:41 +00:00
/ * *
* Given a ` node ` and its ancestors , determine if ` node ` is matched
* by ` selector ` .
* @ param { ? external : AST } node
* @ param { ? SelectorAST } selector
* @ param { external : AST [ ] } [ ancestry = [ ] ]
* @ param { ESQueryOptions } [ options ]
* @ throws { Error } Unknowns ( operator , class name , selector type , or
* selector value type )
* @ returns { boolean }
* /
function matches ( node , selector , ancestry , options ) {
if ( ! selector ) {
return true ;
2020-08-25 23:57:08 +00:00
}
2024-03-28 02:00:41 +00:00
if ( ! node ) {
return false ;
}
if ( ! ancestry ) {
ancestry = [ ] ;
}
return getMatcher ( selector ) ( node , ancestry , options ) ;
2020-08-25 23:57:08 +00:00
}
2024-03-28 02:00:41 +00:00
2021-02-26 03:58:33 +00:00
/ * *
* Get visitor keys of a given node .
* @ param { external : AST } node The AST node to get keys .
* @ param { ESQueryOptions | undefined } options
* @ returns { string [ ] } Visitor keys of the node .
* /
function getVisitorKeys ( node , options ) {
2024-03-28 02:00:41 +00:00
var nodeTypeKey = options && options . nodeTypeKey || 'type' ;
var nodeType = node [ nodeTypeKey ] ;
2021-02-26 03:58:33 +00:00
if ( options && options . visitorKeys && options . visitorKeys [ nodeType ] ) {
return options . visitorKeys [ nodeType ] ;
}
if ( estraverse . VisitorKeys [ nodeType ] ) {
return estraverse . VisitorKeys [ nodeType ] ;
}
if ( options && typeof options . fallback === 'function' ) {
return options . fallback ( node ) ;
2024-03-28 02:00:41 +00:00
}
// 'iteration' fallback
2021-02-26 03:58:33 +00:00
return Object . keys ( node ) . filter ( function ( key ) {
2024-03-28 02:00:41 +00:00
return key !== nodeTypeKey ;
2021-02-26 03:58:33 +00:00
} ) ;
}
2024-03-28 02:00:41 +00:00
2021-02-26 03:58:33 +00:00
/ * *
* Check whether the given value is an ASTNode or not .
* @ param { any } node The value to check .
2024-03-28 02:00:41 +00:00
* @ param { ESQueryOptions | undefined } options The options to use .
2021-02-26 03:58:33 +00:00
* @ returns { boolean } ` true ` if the value is an ASTNode .
* /
2024-03-28 02:00:41 +00:00
function isNode ( node , options ) {
var nodeTypeKey = options && options . nodeTypeKey || 'type' ;
return node !== null && _typeof ( node ) === 'object' && typeof node [ nodeTypeKey ] === 'string' ;
2021-02-26 03:58:33 +00:00
}
2024-03-28 02:00:41 +00:00
2020-08-25 23:57:08 +00:00
/ * *
* Determines if the given node has a sibling that matches the
2024-03-28 02:00:41 +00:00
* given selector matcher .
2020-08-25 23:57:08 +00:00
* @ param { external : AST } node
2024-03-28 02:00:41 +00:00
* @ param { SelectorMatcher } matcher
2020-08-25 23:57:08 +00:00
* @ param { external : AST [ ] } ancestry
* @ param { Side } side
2021-02-26 03:58:33 +00:00
* @ param { ESQueryOptions | undefined } options
2020-08-25 23:57:08 +00:00
* @ returns { boolean }
* /
2024-03-28 02:00:41 +00:00
function sibling ( node , matcher , ancestry , side , options ) {
2020-08-25 23:57:08 +00:00
var _ancestry = _slicedToArray ( ancestry , 1 ) ,
2024-03-28 02:00:41 +00:00
parent = _ancestry [ 0 ] ;
2020-08-25 23:57:08 +00:00
if ( ! parent ) {
return false ;
}
2021-02-26 03:58:33 +00:00
var keys = getVisitorKeys ( parent , options ) ;
2024-03-28 02:00:41 +00:00
for ( var i = 0 ; i < keys . length ; ++ i ) {
var listProp = parent [ keys [ i ] ] ;
if ( Array . isArray ( listProp ) ) {
var startIndex = listProp . indexOf ( node ) ;
if ( startIndex < 0 ) {
continue ;
}
var lowerBound = void 0 ,
upperBound = void 0 ;
if ( side === LEFT _SIDE ) {
lowerBound = 0 ;
upperBound = startIndex ;
} else {
lowerBound = startIndex + 1 ;
upperBound = listProp . length ;
}
for ( var k = lowerBound ; k < upperBound ; ++ k ) {
if ( isNode ( listProp [ k ] , options ) && matcher ( listProp [ k ] , ancestry , options ) ) {
return true ;
2020-08-25 23:57:08 +00:00
}
}
}
}
return false ;
}
2024-03-28 02:00:41 +00:00
2020-08-25 23:57:08 +00:00
/ * *
* Determines if the given node has an adjacent sibling that matches
2024-03-28 02:00:41 +00:00
* the given selector matcher .
2020-08-25 23:57:08 +00:00
* @ param { external : AST } node
2024-03-28 02:00:41 +00:00
* @ param { SelectorMatcher } matcher
2020-08-25 23:57:08 +00:00
* @ param { external : AST [ ] } ancestry
* @ param { Side } side
2021-02-26 03:58:33 +00:00
* @ param { ESQueryOptions | undefined } options
2020-08-25 23:57:08 +00:00
* @ returns { boolean }
* /
2024-03-28 02:00:41 +00:00
function adjacent ( node , matcher , ancestry , side , options ) {
2020-08-25 23:57:08 +00:00
var _ancestry2 = _slicedToArray ( ancestry , 1 ) ,
2024-03-28 02:00:41 +00:00
parent = _ancestry2 [ 0 ] ;
2020-08-25 23:57:08 +00:00
if ( ! parent ) {
return false ;
}
2021-02-26 03:58:33 +00:00
var keys = getVisitorKeys ( parent , options ) ;
2024-03-28 02:00:41 +00:00
for ( var i = 0 ; i < keys . length ; ++ i ) {
var listProp = parent [ keys [ i ] ] ;
if ( Array . isArray ( listProp ) ) {
var idx = listProp . indexOf ( node ) ;
if ( idx < 0 ) {
continue ;
}
if ( side === LEFT _SIDE && idx > 0 && isNode ( listProp [ idx - 1 ] , options ) && matcher ( listProp [ idx - 1 ] , ancestry , options ) ) {
return true ;
}
if ( side === RIGHT _SIDE && idx < listProp . length - 1 && isNode ( listProp [ idx + 1 ] , options ) && matcher ( listProp [ idx + 1 ] , ancestry , options ) ) {
return true ;
2020-08-25 23:57:08 +00:00
}
}
}
return false ;
}
/ * *
2024-03-28 02:00:41 +00:00
* Determines if the given node is the ` nth ` child .
* If ` nth ` is negative then the position is counted
* from the end of the list of children .
2020-08-25 23:57:08 +00:00
* @ param { external : AST } node
* @ param { external : AST [ ] } ancestry
2024-03-28 02:00:41 +00:00
* @ param { Integer } nth
2021-02-26 03:58:33 +00:00
* @ param { ESQueryOptions | undefined } options
2020-08-25 23:57:08 +00:00
* @ returns { boolean }
* /
2024-03-28 02:00:41 +00:00
function nthChild ( node , ancestry , nth , options ) {
if ( nth === 0 ) {
return false ;
}
2020-08-25 23:57:08 +00:00
var _ancestry3 = _slicedToArray ( ancestry , 1 ) ,
2024-03-28 02:00:41 +00:00
parent = _ancestry3 [ 0 ] ;
2020-08-25 23:57:08 +00:00
if ( ! parent ) {
return false ;
}
2021-02-26 03:58:33 +00:00
var keys = getVisitorKeys ( parent , options ) ;
2024-03-28 02:00:41 +00:00
for ( var i = 0 ; i < keys . length ; ++ i ) {
var listProp = parent [ keys [ i ] ] ;
if ( Array . isArray ( listProp ) ) {
var idx = nth < 0 ? listProp . length + nth : nth - 1 ;
if ( idx >= 0 && idx < listProp . length && listProp [ idx ] === node ) {
return true ;
2020-08-25 23:57:08 +00:00
}
}
}
return false ;
}
2024-03-28 02:00:41 +00:00
2020-08-25 23:57:08 +00:00
/ * *
* For each selector node marked as a subject , find the portion of the
* selector that the subject must match .
* @ param { SelectorAST } selector
* @ param { SelectorAST } [ ancestor ] Defaults to ` selector `
* @ returns { SelectorAST [ ] }
* /
function subjects ( selector , ancestor ) {
if ( selector == null || _typeof ( selector ) != 'object' ) {
return [ ] ;
}
if ( ancestor == null ) {
ancestor = selector ;
}
var results = selector . subject ? [ ancestor ] : [ ] ;
2024-03-28 02:00:41 +00:00
var keys = Object . keys ( selector ) ;
for ( var i = 0 ; i < keys . length ; ++ i ) {
var p = keys [ i ] ;
var sel = selector [ p ] ;
2020-08-25 23:57:08 +00:00
results . push . apply ( results , _toConsumableArray ( subjects ( sel , p === 'left' ? sel : ancestor ) ) ) ;
}
return results ;
}
2024-03-28 02:00:41 +00:00
2020-08-25 23:57:08 +00:00
/ * *
* @ callback TraverseVisitor
* @ param { ? external : AST } node
* @ param { ? external : AST } parent
* @ param { external : AST [ ] } ancestry
* /
/ * *
* From a JS AST and a selector AST , collect all JS AST nodes that
* match the selector .
* @ param { external : AST } ast
* @ param { ? SelectorAST } selector
* @ param { TraverseVisitor } visitor
2021-02-26 03:58:33 +00:00
* @ param { ESQueryOptions } [ options ]
2020-08-25 23:57:08 +00:00
* @ returns { external : AST [ ] }
* /
2021-02-26 03:58:33 +00:00
function traverse ( ast , selector , visitor , options ) {
2020-08-25 23:57:08 +00:00
if ( ! selector ) {
return ;
}
var ancestry = [ ] ;
2024-03-28 02:00:41 +00:00
var matcher = getMatcher ( selector ) ;
var altSubjects = subjects ( selector ) . map ( getMatcher ) ;
2020-08-25 23:57:08 +00:00
estraverse . traverse ( ast , {
enter : function enter ( node , parent ) {
if ( parent != null ) {
ancestry . unshift ( parent ) ;
}
2024-03-28 02:00:41 +00:00
if ( matcher ( node , ancestry , options ) ) {
2020-08-25 23:57:08 +00:00
if ( altSubjects . length ) {
for ( var i = 0 , l = altSubjects . length ; i < l ; ++ i ) {
2024-03-28 02:00:41 +00:00
if ( altSubjects [ i ] ( node , ancestry , options ) ) {
2020-08-25 23:57:08 +00:00
visitor ( node , parent , ancestry ) ;
}
for ( var k = 0 , m = ancestry . length ; k < m ; ++ k ) {
var succeedingAncestry = ancestry . slice ( k + 1 ) ;
2024-03-28 02:00:41 +00:00
if ( altSubjects [ i ] ( ancestry [ k ] , succeedingAncestry , options ) ) {
2020-08-25 23:57:08 +00:00
visitor ( ancestry [ k ] , parent , succeedingAncestry ) ;
}
}
}
} else {
visitor ( node , parent , ancestry ) ;
}
}
} ,
leave : function leave ( ) {
ancestry . shift ( ) ;
} ,
2021-02-26 03:58:33 +00:00
keys : options && options . visitorKeys ,
fallback : options && options . fallback || 'iteration'
2020-08-25 23:57:08 +00:00
} ) ;
}
2024-03-28 02:00:41 +00:00
2020-08-25 23:57:08 +00:00
/ * *
* From a JS AST and a selector AST , collect all JS AST nodes that
* match the selector .
* @ param { external : AST } ast
* @ param { ? SelectorAST } selector
2021-02-26 03:58:33 +00:00
* @ param { ESQueryOptions } [ options ]
2020-08-25 23:57:08 +00:00
* @ returns { external : AST [ ] }
* /
2021-02-26 03:58:33 +00:00
function match ( ast , selector , options ) {
2020-08-25 23:57:08 +00:00
var results = [ ] ;
traverse ( ast , selector , function ( node ) {
results . push ( node ) ;
2021-02-26 03:58:33 +00:00
} , options ) ;
2020-08-25 23:57:08 +00:00
return results ;
}
2024-03-28 02:00:41 +00:00
2020-08-25 23:57:08 +00:00
/ * *
* Parse a selector string and return its AST .
* @ param { string } selector
* @ returns { SelectorAST }
* /
function parse ( selector ) {
return parser . parse ( selector ) ;
}
2024-03-28 02:00:41 +00:00
2020-08-25 23:57:08 +00:00
/ * *
* Query the code AST using the selector string .
* @ param { external : AST } ast
* @ param { string } selector
2021-02-26 03:58:33 +00:00
* @ param { ESQueryOptions } [ options ]
2020-08-25 23:57:08 +00:00
* @ returns { external : AST [ ] }
* /
2021-02-26 03:58:33 +00:00
function query ( ast , selector , options ) {
return match ( ast , parse ( selector ) , options ) ;
2020-08-25 23:57:08 +00:00
}
query . parse = parse ;
query . match = match ;
query . traverse = traverse ;
query . matches = matches ;
query . query = query ;
export default query ;