Skip to content

Commit

Permalink
Refactor to improve bundle size
Browse files Browse the repository at this point in the history
  • Loading branch information
wooorm committed Oct 30, 2020
1 parent afebbaa commit d48ac1c
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 223 deletions.
106 changes: 50 additions & 56 deletions lib/any.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,30 @@
module.exports = match

var zwitch = require('zwitch')
var needsIndex = require('./pseudo').needsIndex
var pseudo = require('./pseudo')
var test = require('./test')
var nest = require('./nest')

var type = zwitch('type')
var handlers = type.handlers

type.unknown = unknownType
type.invalid = invalidType
handlers.selectors = selectors
handlers.ruleSet = ruleSet
handlers.rule = rule
var type = zwitch('type', {
unknown: unknownType,
invalid: invalidType,
handlers: {
selectors: selectors,
ruleSet: ruleSet,
rule: rule
}
})

function match(query, node, state) {
return query && node ? type(query, node, state) : []
}

function selectors(query, node, state) {
var collect = collector(state.one)
var ruleSets = query.selectors
var length = ruleSets.length
var index = -1

while (++index < length) {
collect(ruleSet(ruleSets[index], node, state))
while (++index < query.selectors.length) {
collect(ruleSet(query.selectors[index], node, state))
}

return collect.result
Expand All @@ -39,22 +38,27 @@ function ruleSet(query, node, state) {

function rule(query, tree, state) {
var collect = collector(state.one)
var options = {
scopeNodes: tree.type === 'root' ? tree.children : [tree],
iterator: match,
one: state.one,
shallow: state.shallow
}

if (state.shallow && query.rule) {
throw new Error('Expected selector without nesting')
}

nest(query, tree, 0, null, configure(query, options))
nest(
query,
tree,
0,
null,
configure(query, {
scopeNodes: tree.type === 'root' ? tree.children : [tree],
iterator: iterator,
one: state.one,
shallow: state.shallow
})
)

return collect.result

function match(query, node, index, parent, state) {
function iterator(query, node, index, parent, state) {
if (test(query, node, index, parent, state)) {
if (query.rule) {
nest(query.rule, node, index, parent, configure(query.rule, state))
Expand All @@ -64,21 +68,20 @@ function rule(query, tree, state) {
}
}
}
}

function configure(query, state) {
var pseudos = query.pseudos
var length = pseudos && pseudos.length
var index = -1
function configure(query, state) {
var pseudos = query.pseudos || []
var index = -1

while (++index < length) {
if (needsIndex.indexOf(pseudos[index].name) !== -1) {
state.index = true
break
}
while (++index < pseudos.length) {
if (pseudo.needsIndex.indexOf(pseudos[index].name) > -1) {
state.index = true
break
}

return state
}

return state
}

/* istanbul ignore next - Shouldn’t be invoked, all data is handled. */
Expand All @@ -100,35 +103,26 @@ function collector(one) {
return collect

/* Append nodes to array, filtering out duplicates. */
function collect(source) {
if ('length' in source) {
collectAll()
} else {
collectOne(source)
}

function collectAll() {
var length = source.length
var index = -1
function collect(node) {
var index = -1

while (++index < length) {
collectOne(source[index])
if ('length' in node) {
while (++index < node.length) {
collectOne(node[index])
}
} else {
collectOne(node)
}
}

function collectOne(node) {
if (one) {
/* istanbul ignore if - shouldn’t happen, safeguards performance problems. */
if (found) {
throw new Error('Cannot collect multiple nodes')
}

found = true
}
function collectOne(node) {
if (one) {
/* istanbul ignore if - shouldn’t happen, safeguards performance problems. */
if (found) throw new Error('Cannot collect multiple nodes')

if (result.indexOf(node) === -1) {
result.push(node)
}
found = true
}

if (result.indexOf(node) < 0) result.push(node)
}
}
71 changes: 29 additions & 42 deletions lib/attribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,65 +4,56 @@ module.exports = match

var zwitch = require('zwitch')

var handle = zwitch('operator')
var handlers = handle.handlers

handle.unknown = unknownOperator
handle.invalid = exists
handlers['='] = exact
handlers['^='] = begins
handlers['$='] = ends
handlers['*='] = containsString
handlers['~='] = containsArray
var handle = zwitch('operator', {
unknown: unknownOperator,
invalid: exists,
handlers: {
'=': exact,
'^=': begins,
'$=': ends,
'*=': containsString,
'~=': containsArray
}
})

function match(query, node) {
var attrs = query.attrs
var length = attrs.length
var index = -1
var attr

while (++index < length) {
attr = attrs[index]

if (!handle(attr, node)) {
return false
}
while (++index < attrs.length) {
if (!handle(attrs[index], node)) return false
}

return true
}

// [attr]
function exists(query, node) {
return has(node, query.name)
return node[query.name] != null
}

// [attr=value]
function exact(query, node) {
return has(node, query.name) && String(node[query.name]) === query.value
return node[query.name] != null && String(node[query.name]) === query.value
}

// [attr~=value]
function containsArray(query, node) {
var value

if (has(node, query.name)) {
value = node[query.name]

// If this is an array, and the query is contained in it, return true.
if (
typeof value === 'object' &&
'length' in value &&
value.indexOf(query.value) !== -1
) {
return true
}

// For all other values, return whether this is an exact match.
return String(value) === query.value
var value = node[query.name]

if (value == null) return false

// If this is an array, and the query is contained in it, return true.
if (
typeof value === 'object' &&
'length' in value &&
value.indexOf(query.value) > -1
) {
return true
}

return false
// For all other values, return whether this is an exact match.
return String(value) === query.value
}

// [attr^=value]
Expand All @@ -88,14 +79,10 @@ function ends(query, node) {
// [attr*=value]
function containsString(query, node) {
var value = node[query.name]
return typeof value === 'string' && value.indexOf(query.value) !== -1
return typeof value === 'string' && value.indexOf(query.value) > -1
}

/* istanbul ignore next - Shouldn’t be invoked, Parser throws an error instead. */
function unknownOperator(query) {
throw new Error('Unknown operator `' + query.operator + '`')
}

function has(node, name) {
return node[name] !== null && node[name] !== undefined
}
Loading

0 comments on commit d48ac1c

Please sign in to comment.