@asamuzakjp/dom-selector 4.5.0 → 4.6.0-b.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/js/parser.js"],
4
- "sourcesContent": ["/**\n * parser.js\n */\n\n/* import */\nimport { findAll, parse, toPlainObject, walk } from 'css-tree';\n\n/* constants */\nimport {\n BIT_01, BIT_02, BIT_04, BIT_08, BIT_16, BIT_32, BIT_FFFF, BIT_HYPHEN,\n DUO, EMPTY, HEX, REG_CHILD_INDEXED, REG_HEX, REG_INVALID_SELECTOR,\n REG_LANG_QUOTED, REG_LOGICAL_COMPLEX_A, REG_LOGICAL_COMPLEX_B,\n REG_LOGICAL_COMPOUND, REG_LOGICAL_EMPTY, REG_LOGICAL_KEY, REG_LOGICAL_PSEUDO,\n REG_SHADOW_PSEUDO, SELECTOR, SELECTOR_ATTR, SELECTOR_CLASS, SELECTOR_ID,\n SELECTOR_PSEUDO_CLASS, SELECTOR_PSEUDO_ELEMENT, SELECTOR_TYPE, SYNTAX_ERR,\n TYPE_FROM, TYPE_TO, U_FFFD\n} from './constant.js';\n\n/**\n * unescape selector\n * @param {string} selector - CSS selector\n * @returns {?string} - unescaped selector\n */\nexport const unescapeSelector = (selector = '') => {\n if (typeof selector === 'string' && selector.indexOf('\\\\', 0) >= 0) {\n const arr = selector.split('\\\\');\n const l = arr.length;\n for (let i = 1; i < l; i++) {\n let item = arr[i];\n if (item === '' && i === l - 1) {\n item = U_FFFD;\n } else {\n const hexExists = REG_HEX.exec(item);\n if (hexExists) {\n const [, hex] = hexExists;\n let str;\n try {\n const low = parseInt('D800', HEX);\n const high = parseInt('DFFF', HEX);\n const deci = parseInt(hex, HEX);\n if (deci === 0 || (deci >= low && deci <= high)) {\n str = U_FFFD;\n } else {\n str = String.fromCodePoint(deci);\n }\n } catch (e) {\n str = U_FFFD;\n }\n let postStr = '';\n if (item.length > hex.length) {\n postStr = item.substring(hex.length);\n }\n item = `${str}${postStr}`;\n // whitespace\n } else if (/^[\\n\\r\\f]/.test(item)) {\n item = '\\\\' + item;\n }\n }\n arr[i] = item;\n }\n selector = arr.join('');\n }\n return selector;\n};\n\n/**\n * preprocess\n * @see https://drafts.csswg.org/css-syntax-3/#input-preprocessing\n * @param {...*} args - arguments\n * @returns {string} - filtered selector string\n */\nexport const preprocess = (...args) => {\n if (!args.length) {\n throw new TypeError('1 argument required, but only 0 present.');\n }\n let [selector] = args;\n if (typeof selector === 'string') {\n let index = 0;\n while (index >= 0) {\n index = selector.indexOf('#', index);\n if (index < 0) {\n break;\n }\n const preHash = selector.substring(0, index + 1);\n let postHash = selector.substring(index + 1);\n // @see https://drafts.csswg.org/selectors/#id-selectors\n // @see https://drafts.csswg.org/css-syntax-3/#ident-token-diagram\n if (/^\\d$/.test(postHash.substring(0, 1))) {\n throw new DOMException(`Invalid selector ${selector}`, SYNTAX_ERR);\n }\n const codePoint = postHash.codePointAt(0);\n if (codePoint === BIT_HYPHEN) {\n if (/^\\d$/.test(postHash.substring(1, 2))) {\n throw new DOMException(`Invalid selector ${selector}`, SYNTAX_ERR);\n }\n // escape char above 0xFFFF\n } else if (codePoint > BIT_FFFF) {\n const str = `\\\\${codePoint.toString(HEX)} `;\n if (postHash.length === DUO) {\n postHash = str;\n } else {\n postHash = `${str}${postHash.substring(DUO)}`;\n }\n }\n selector = `${preHash}${postHash}`;\n index++;\n }\n selector = selector.replace(/\\f|\\r\\n?/g, '\\n')\n .replace(/[\\0\\uD800-\\uDFFF]|\\\\$/g, U_FFFD);\n } else if (selector === undefined || selector === null) {\n selector = Object.prototype.toString.call(selector)\n .slice(TYPE_FROM, TYPE_TO).toLowerCase();\n } else if (Array.isArray(selector)) {\n selector = selector.join(',');\n } else if (Object.prototype.hasOwnProperty.call(selector, 'toString')) {\n selector = selector.toString();\n } else {\n throw new DOMException(`Invalid selector ${selector}`, SYNTAX_ERR);\n }\n return selector;\n};\n\n/**\n * create AST from CSS selector\n * @param {string} selector - CSS selector\n * @returns {object} - AST\n */\nexport const parseSelector = selector => {\n selector = preprocess(selector);\n // invalid selectors\n if (REG_INVALID_SELECTOR.test(selector)) {\n throw new DOMException(`Invalid selector ${selector}`, SYNTAX_ERR);\n }\n let res;\n try {\n const ast = parse(selector, {\n context: 'selectorList',\n parseCustomProperty: true\n });\n res = toPlainObject(ast);\n } catch (e) {\n const { message } = e;\n // workaround for https://github.com/csstree/csstree/issues/265\n if (message === 'Identifier is expected' &&\n REG_LANG_QUOTED.test(selector)) {\n const [, lang, range] = REG_LANG_QUOTED.exec(selector);\n const escapedRange =\n range.replaceAll('*', '\\\\*').replace(/^\"/, '').replace(/\"$/, '');\n let escapedLang = lang.replace(range, escapedRange);\n if (escapedLang === ':lang()') {\n escapedLang = `:lang(${EMPTY})`;\n }\n res = parseSelector(selector.replace(lang, escapedLang));\n } else if (/^(?:Identifier|Selector) is expected$/.test(message) &&\n REG_LOGICAL_EMPTY.test(selector)) {\n const [, sel, name] = REG_LOGICAL_EMPTY.exec(selector);\n res = parseSelector(selector.replace(sel, `:${name}(${EMPTY})`));\n } else if (/^(?:\"\\]\"|Attribute selector [()\\s,=~^$*|]+) is expected$/.test(message) &&\n !selector.endsWith(']')) {\n const index = selector.lastIndexOf('[');\n const sel = selector.substring(index);\n if (sel.includes('\"')) {\n const quotes = sel.match(/\"/g).length;\n if (quotes % 2) {\n res = parseSelector(`${selector}\"]`);\n } else {\n res = parseSelector(`${selector}]`);\n }\n } else {\n res = parseSelector(`${selector}]`);\n }\n } else if (message === '\")\" is expected' && !selector.endsWith(')')) {\n res = parseSelector(`${selector})`);\n } else {\n throw new DOMException(message, SYNTAX_ERR);\n }\n }\n return res;\n};\n\n/**\n * walk AST\n * @param {object} ast - AST\n * @returns {Array.<object|undefined>} - collection of AST branches\n */\nexport const walkAST = (ast = {}) => {\n const branches = new Set();\n const info = new Map();\n const opt = {\n enter: node => {\n if (node.type === SELECTOR) {\n branches.add(node.children);\n } else if (node.type === SELECTOR_PSEUDO_CLASS) {\n info.set('hasPseudo', true);\n if (REG_LOGICAL_PSEUDO.test(node.name)) {\n info.set('hasPseudoFunc', true);\n if (node.name === 'has') {\n info.set('hasHasPseudoFunc', true);\n }\n }\n } else if (node.type === SELECTOR_PSEUDO_ELEMENT) {\n info.set('hasPseudo', true);\n if (REG_SHADOW_PSEUDO.test(node.name)) {\n info.set('hasPseudoFunc', true);\n }\n } else if (node.type === SELECTOR_ATTR && node.matcher === '|=') {\n info.set('hasHyphenSepAttr', true);\n }\n }\n };\n walk(ast, opt);\n if (info.get('hasPseudoFunc')) {\n findAll(ast, (node, item, list) => {\n if (list) {\n if (node.type === SELECTOR_PSEUDO_CLASS &&\n REG_LOGICAL_PSEUDO.test(node.name)) {\n const itemList = list.filter(i => {\n const { name, type } = i;\n const res =\n type === SELECTOR_PSEUDO_CLASS && REG_LOGICAL_PSEUDO.test(name);\n return res;\n });\n for (const { children } of itemList) {\n // SelectorList\n for (const { children: grandChildren } of children) {\n // Selector\n for (const { children: greatGrandChildren } of grandChildren) {\n if (branches.has(greatGrandChildren)) {\n branches.delete(greatGrandChildren);\n }\n }\n }\n }\n } else if (node.type === SELECTOR_PSEUDO_ELEMENT &&\n REG_SHADOW_PSEUDO.test(node.name)) {\n const itemList = list.filter(i => {\n const { name, type } = i;\n const res =\n type === SELECTOR_PSEUDO_ELEMENT && REG_SHADOW_PSEUDO.test(name);\n return res;\n });\n for (const { children } of itemList) {\n // Selector\n for (const { children: grandChildren } of children) {\n if (branches.has(grandChildren)) {\n branches.delete(grandChildren);\n }\n }\n }\n }\n }\n });\n }\n return {\n branches: [...branches],\n info: Object.fromEntries(info)\n };\n};\n\n/**\n * sort AST\n * @param {Array.<object>} asts - collection of AST\n * @returns {Array.<object>} - collection of sorted AST\n */\nexport const sortAST = asts => {\n const arr = [...asts];\n if (arr.length > 1) {\n const order = new Map([\n [SELECTOR_PSEUDO_ELEMENT, BIT_01],\n [SELECTOR_ID, BIT_02],\n [SELECTOR_CLASS, BIT_04],\n [SELECTOR_TYPE, BIT_08],\n [SELECTOR_ATTR, BIT_16],\n [SELECTOR_PSEUDO_CLASS, BIT_32]\n ]);\n arr.sort((a, b) => {\n const { type: typeA } = a;\n const { type: typeB } = b;\n const bitA = order.get(typeA);\n const bitB = order.get(typeB);\n let res;\n if (bitA === bitB) {\n res = 0;\n } else if (bitA > bitB) {\n res = 1;\n } else {\n res = -1;\n }\n return res;\n });\n }\n return arr;\n};\n\n/**\n * parse AST name - e.g. ns|E -> { prefix: ns, localName: E }\n * @param {string} selector - type selector\n * @returns {object} - node properties\n */\nexport const parseAstName = selector => {\n let prefix;\n let localName;\n if (selector && typeof selector === 'string') {\n if (selector.indexOf('|') > -1) {\n [prefix, localName] = selector.split('|');\n } else {\n prefix = '*';\n localName = selector;\n }\n } else {\n throw new DOMException(`Invalid selector ${selector}`, SYNTAX_ERR);\n }\n return {\n prefix,\n localName\n };\n};\n\n/**\n * filter selector (for nwsapi)\n * @param {string} selector - selector\n * @param {object} opt - options\n * @returns {boolean} - result\n */\nexport const filterSelector = (selector, opt = {}) => {\n if (!selector || typeof selector !== 'string') {\n return false;\n }\n // filter missing close square bracket\n if (selector.includes('[')) {\n const index = selector.lastIndexOf('[');\n const sel = selector.substring(index);\n if (sel.lastIndexOf(']') < 0) {\n return false;\n }\n }\n // filter namespaced selectors, e.g. ns|E, pseudo-element selectors and\n // attribute selectors with case flag, e.g. [attr i], and unclosed quotes\n if (/\\||::|\\[\\s*[\\w$*=^|~-]+(?:(?:\"[\\w$*=^|~\\s'-]+\"|'[\\w$*=^|~\\s\"-]+')?(?:\\s+[\\w$*=^|~-]+)+|\"[^\"\\]]{1,255}|'[^'\\]]{1,255})\\s*\\]/.test(selector)) {\n return false;\n }\n // filter pseudo-classes\n if (selector.includes(':')) {\n let reg;\n if (REG_LOGICAL_KEY.test(selector)) {\n // filter empty :is() and :where()\n if (REG_LOGICAL_EMPTY.test(selector)) {\n return false;\n }\n const { complex, descendant } = opt;\n if (complex && descendant) {\n reg = REG_LOGICAL_COMPLEX_A;\n } else if (complex) {\n reg = REG_LOGICAL_COMPLEX_B;\n } else {\n reg = REG_LOGICAL_COMPOUND;\n }\n } else {\n reg = REG_CHILD_INDEXED;\n }\n if (reg.test(selector)) {\n return false;\n }\n }\n return true;\n};\n\n/* export */\nexport { generate as generateCSS } from 'css-tree';\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * parser.js\n */\n\n/* import */\nimport { findAll, parse, toPlainObject, walk } from 'css-tree';\n\n/* constants */\nimport {\n BIT_01, BIT_02, BIT_04, BIT_08, BIT_16, BIT_32, BIT_FFFF, BIT_HYPHEN,\n DUO, EMPTY, HEX, REG_CHILD_INDEXED, REG_HEX, REG_INVALID_SELECTOR,\n REG_LANG_QUOTED, REG_LOGICAL_COMPLEX_A, REG_LOGICAL_COMPLEX_B,\n REG_LOGICAL_COMPOUND, REG_LOGICAL_EMPTY, REG_LOGICAL_KEY, REG_LOGICAL_PSEUDO,\n REG_SHADOW_PSEUDO, SELECTOR, SELECTOR_ATTR, SELECTOR_CLASS, SELECTOR_ID,\n SELECTOR_PSEUDO_CLASS, SELECTOR_PSEUDO_ELEMENT, SELECTOR_TYPE, SYNTAX_ERR,\n TYPE_FROM, TYPE_TO, U_FFFD\n} from './constant.js';\n\n/**\n * unescape selector\n * @param {string} selector - CSS selector\n * @returns {?string} - unescaped selector\n */\nexport const unescapeSelector = (selector = '') => {\n if (typeof selector === 'string' && selector.indexOf('\\\\', 0) >= 0) {\n const arr = selector.split('\\\\');\n const l = arr.length;\n for (let i = 1; i < l; i++) {\n let item = arr[i];\n if (item === '' && i === l - 1) {\n item = U_FFFD;\n } else {\n const hexExists = REG_HEX.exec(item);\n if (hexExists) {\n const [, hex] = hexExists;\n let str;\n try {\n const low = parseInt('D800', HEX);\n const high = parseInt('DFFF', HEX);\n const deci = parseInt(hex, HEX);\n if (deci === 0 || (deci >= low && deci <= high)) {\n str = U_FFFD;\n } else {\n str = String.fromCodePoint(deci);\n }\n } catch (e) {\n str = U_FFFD;\n }\n let postStr = '';\n if (item.length > hex.length) {\n postStr = item.substring(hex.length);\n }\n item = `${str}${postStr}`;\n // whitespace\n } else if (/^[\\n\\r\\f]/.test(item)) {\n item = '\\\\' + item;\n }\n }\n arr[i] = item;\n }\n selector = arr.join('');\n }\n return selector;\n};\n\n/**\n * preprocess\n * @see https://drafts.csswg.org/css-syntax-3/#input-preprocessing\n * @param {...*} args - arguments\n * @returns {string} - filtered selector string\n */\nexport const preprocess = (...args) => {\n if (!args.length) {\n throw new TypeError('1 argument required, but only 0 present.');\n }\n let [selector] = args;\n if (typeof selector === 'string') {\n let index = 0;\n while (index >= 0) {\n index = selector.indexOf('#', index);\n if (index < 0) {\n break;\n }\n const preHash = selector.substring(0, index + 1);\n let postHash = selector.substring(index + 1);\n // @see https://drafts.csswg.org/selectors/#id-selectors\n // @see https://drafts.csswg.org/css-syntax-3/#ident-token-diagram\n if (/^\\d$/.test(postHash.substring(0, 1))) {\n throw new DOMException(`Invalid selector ${selector}`, SYNTAX_ERR);\n }\n const codePoint = postHash.codePointAt(0);\n if (codePoint === BIT_HYPHEN) {\n if (/^\\d$/.test(postHash.substring(1, 2))) {\n throw new DOMException(`Invalid selector ${selector}`, SYNTAX_ERR);\n }\n // escape char above 0xFFFF\n } else if (codePoint > BIT_FFFF) {\n const str = `\\\\${codePoint.toString(HEX)} `;\n if (postHash.length === DUO) {\n postHash = str;\n } else {\n postHash = `${str}${postHash.substring(DUO)}`;\n }\n }\n selector = `${preHash}${postHash}`;\n index++;\n }\n selector = selector.replace(/\\f|\\r\\n?/g, '\\n')\n .replace(/[\\0\\uD800-\\uDFFF]|\\\\$/g, U_FFFD);\n } else if (selector === undefined || selector === null) {\n selector = Object.prototype.toString.call(selector)\n .slice(TYPE_FROM, TYPE_TO).toLowerCase();\n } else if (Array.isArray(selector)) {\n selector = selector.join(',');\n } else if (Object.prototype.hasOwnProperty.call(selector, 'toString')) {\n selector = selector.toString();\n } else {\n throw new DOMException(`Invalid selector ${selector}`, SYNTAX_ERR);\n }\n return selector;\n};\n\n/**\n * create AST from CSS selector\n * @param {string} selector - CSS selector\n * @returns {object} - AST\n */\nexport const parseSelector = selector => {\n selector = preprocess(selector);\n // invalid selectors\n if (REG_INVALID_SELECTOR.test(selector)) {\n throw new DOMException(`Invalid selector ${selector}`, SYNTAX_ERR);\n }\n let res;\n try {\n const ast = parse(selector, {\n context: 'selectorList',\n parseCustomProperty: true\n });\n res = toPlainObject(ast);\n } catch (e) {\n const { message } = e;\n // workaround for https://github.com/csstree/csstree/issues/265\n if (message === 'Identifier is expected' &&\n REG_LANG_QUOTED.test(selector)) {\n const [, lang, range] = REG_LANG_QUOTED.exec(selector);\n const escapedRange =\n range.replaceAll('*', '\\\\*').replace(/^\"/, '').replace(/\"$/, '');\n let escapedLang = lang.replace(range, escapedRange);\n if (escapedLang === ':lang()') {\n escapedLang = `:lang(${EMPTY})`;\n }\n res = parseSelector(selector.replace(lang, escapedLang));\n } else if (/^(?:Identifier|Selector) is expected$/.test(message) &&\n REG_LOGICAL_EMPTY.test(selector)) {\n const [, sel, name] = REG_LOGICAL_EMPTY.exec(selector);\n res = parseSelector(selector.replace(sel, `:${name}(${EMPTY})`));\n } else if (/^(?:\"\\]\"|Attribute selector [()\\s,=~^$*|]+) is expected$/.test(message) &&\n !selector.endsWith(']')) {\n const index = selector.lastIndexOf('[');\n const sel = selector.substring(index);\n if (sel.includes('\"')) {\n const quotes = sel.match(/\"/g).length;\n if (quotes % 2) {\n res = parseSelector(`${selector}\"]`);\n } else {\n res = parseSelector(`${selector}]`);\n }\n } else {\n res = parseSelector(`${selector}]`);\n }\n } else if (message === '\")\" is expected' && !selector.endsWith(')')) {\n res = parseSelector(`${selector})`);\n } else {\n throw new DOMException(message, SYNTAX_ERR);\n }\n }\n return res;\n};\n\n/**\n * walk AST\n * @param {object} ast - AST\n * @returns {Array.<object|undefined>} - collection of AST branches\n */\nexport const walkAST = (ast = {}) => {\n const branches = new Set();\n const info = new Map();\n const opt = {\n enter: node => {\n if (node.type === SELECTOR) {\n branches.add(node.children);\n } else if (node.type === SELECTOR_PSEUDO_CLASS) {\n info.set('hasPseudo', true);\n if (REG_LOGICAL_PSEUDO.test(node.name)) {\n info.set('hasPseudoFunc', true);\n if (node.name === 'has') {\n info.set('hasHasPseudoFunc', true);\n }\n }\n } else if (node.type === SELECTOR_PSEUDO_ELEMENT) {\n info.set('hasPseudo', true);\n if (REG_SHADOW_PSEUDO.test(node.name)) {\n info.set('hasPseudoFunc', true);\n }\n } else if (node.type === SELECTOR_ATTR && node.matcher === '|=') {\n info.set('hasHyphenSepAttr', true);\n }\n }\n };\n walk(ast, opt);\n if (info.get('hasPseudoFunc')) {\n findAll(ast, (node, item, list) => {\n if (list) {\n if (node.type === SELECTOR_PSEUDO_CLASS &&\n REG_LOGICAL_PSEUDO.test(node.name)) {\n const itemList = list.filter(i => {\n const { name, type } = i;\n const res =\n type === SELECTOR_PSEUDO_CLASS && REG_LOGICAL_PSEUDO.test(name);\n return res;\n });\n for (const { children } of itemList) {\n // SelectorList\n for (const { children: grandChildren } of children) {\n // Selector\n for (const { children: greatGrandChildren } of grandChildren) {\n if (branches.has(greatGrandChildren)) {\n branches.delete(greatGrandChildren);\n }\n }\n }\n }\n } else if (node.type === SELECTOR_PSEUDO_ELEMENT &&\n REG_SHADOW_PSEUDO.test(node.name)) {\n const itemList = list.filter(i => {\n const { name, type } = i;\n const res =\n type === SELECTOR_PSEUDO_ELEMENT && REG_SHADOW_PSEUDO.test(name);\n return res;\n });\n for (const { children } of itemList) {\n // Selector\n for (const { children: grandChildren } of children) {\n if (branches.has(grandChildren)) {\n branches.delete(grandChildren);\n }\n }\n }\n }\n }\n });\n }\n return {\n branches: [...branches],\n info: Object.fromEntries(info)\n };\n};\n\n/**\n * sort AST\n * @param {Array.<object>} asts - collection of AST\n * @returns {Array.<object>} - collection of sorted AST\n */\nexport const sortAST = asts => {\n const arr = [...asts];\n if (arr.length > 1) {\n const order = new Map([\n [SELECTOR_PSEUDO_ELEMENT, BIT_01],\n [SELECTOR_ID, BIT_02],\n [SELECTOR_CLASS, BIT_04],\n [SELECTOR_TYPE, BIT_08],\n [SELECTOR_ATTR, BIT_16],\n [SELECTOR_PSEUDO_CLASS, BIT_32]\n ]);\n arr.sort((a, b) => {\n const { type: typeA } = a;\n const { type: typeB } = b;\n const bitA = order.get(typeA);\n const bitB = order.get(typeB);\n let res;\n if (bitA === bitB) {\n res = 0;\n } else if (bitA > bitB) {\n res = 1;\n } else {\n res = -1;\n }\n return res;\n });\n }\n return arr;\n};\n\n/**\n * parse AST name - e.g. ns|E -> { prefix: ns, localName: E }\n * @param {string} selector - type selector\n * @returns {object} - node properties\n */\nexport const parseAstName = selector => {\n let prefix;\n let localName;\n if (selector && typeof selector === 'string') {\n if (selector.indexOf('|') > -1) {\n [prefix, localName] = selector.split('|');\n } else {\n prefix = '*';\n localName = selector;\n }\n } else {\n throw new DOMException(`Invalid selector ${selector}`, SYNTAX_ERR);\n }\n return {\n prefix,\n localName\n };\n};\n\n/**\n * filter selector (for nwsapi)\n * @param {string} selector - selector\n * @param {object} opt - options\n * @returns {boolean} - result\n */\nexport const filterSelector = (selector, opt = {}) => {\n if (!selector || typeof selector !== 'string') {\n return false;\n }\n // filter missing close square bracket\n if (selector.includes('[')) {\n const index = selector.lastIndexOf('[');\n const sel = selector.substring(index);\n if (sel.lastIndexOf(']') < 0) {\n return false;\n }\n }\n // filter namespaced selectors, e.g. ns|E\n // filter pseudo-element selectors\n // filter attribute selectors with case flag, e.g. [attr i]\n // filter unclosed quotes\n if (/\\||::|\\[\\s*[\\w$*=^|~-]+(?:(?:\"[\\w$*=^|~\\s'-]+\"|'[\\w$*=^|~\\s\"-]+')?(?:\\s+[\\w$*=^|~-]+)+|\"[^\"\\]]{1,255}|'[^'\\]]{1,255})\\s*\\]/.test(selector)) {\n return false;\n }\n // filter pseudo-classes\n if (selector.includes(':')) {\n let reg;\n if (REG_LOGICAL_KEY.test(selector)) {\n // filter empty :is() and :where()\n if (REG_LOGICAL_EMPTY.test(selector)) {\n return false;\n }\n const { complex, descendant } = opt;\n if (complex && descendant) {\n reg = REG_LOGICAL_COMPLEX_A;\n } else if (complex) {\n reg = REG_LOGICAL_COMPLEX_B;\n } else {\n reg = REG_LOGICAL_COMPOUND;\n }\n } else {\n reg = REG_CHILD_INDEXED;\n }\n if (reg.test(selector)) {\n return false;\n }\n }\n return true;\n};\n\n/* export */\nexport { generate as generateCSS } from 'css-tree';\n"],
5
+ "mappings": "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",
6
6
  "names": ["parser_exports", "__export", "filterSelector", "parseAstName", "parseSelector", "preprocess", "sortAST", "unescapeSelector", "walkAST", "__toCommonJS", "import_css_tree", "import_constant", "selector", "arr", "l", "item", "hexExists", "hex", "str", "low", "high", "deci", "postStr", "args", "index", "preHash", "postHash", "codePoint", "res", "ast", "e", "message", "lang", "range", "escapedRange", "escapedLang", "sel", "name", "branches", "info", "node", "list", "itemList", "i", "type", "children", "grandChildren", "greatGrandChildren", "asts", "order", "a", "b", "typeA", "typeB", "bitA", "bitB", "prefix", "localName", "opt", "reg", "complex", "descendant"]
7
7
  }
package/package.json CHANGED
@@ -38,7 +38,7 @@
38
38
  "eslint": "^8.57.0",
39
39
  "eslint-config-standard": "^17.1.0",
40
40
  "eslint-plugin-import": "^2.29.1",
41
- "eslint-plugin-jsdoc": "^48.5.0",
41
+ "eslint-plugin-jsdoc": "^48.5.2",
42
42
  "eslint-plugin-regexp": "^2.6.0",
43
43
  "eslint-plugin-unicorn": "^54.0.0",
44
44
  "happy-dom": "^14.12.3",
@@ -60,5 +60,5 @@
60
60
  "tsc": "node scripts/index clean --dir=types -i && npx tsc",
61
61
  "update-wpt": "git submodule update --init --recursive --remote"
62
62
  },
63
- "version": "4.5.0"
63
+ "version": "4.6.0-b.1"
64
64
  }
@@ -64,7 +64,7 @@ export const ANB =
64
64
  // N_TH: excludes An+B with selector list, e.g. :nth-child(2n+1 of .foo)
65
65
  export const N_TH =
66
66
  `nth-(?:last-)?(?:child|of-type)\\(\\s*(?:even|odd|${ANB})\\s*\\)`;
67
- // SUB_TYPE: attr, id, class, pseudo-class
67
+ // SUB_TYPE: attr, id, class, pseudo-class, note that [foo|=bar] is excluded
68
68
  export const SUB_TYPE = '\\[[^|\\]]+\\]|[#.:][\\w-]+';
69
69
  // TAG_TYPE: *, tag
70
70
  export const TAG_TYPE = '\\*|[A-Za-z][\\w-]*';
@@ -4,6 +4,7 @@
4
4
 
5
5
  /* import */
6
6
  import bidiFactory from 'bidi-js';
7
+ import isCustomElementName from 'is-potential-custom-element-name';
7
8
 
8
9
  /* constants */
9
10
  import {
@@ -83,12 +84,11 @@ export const resolveContent = node => {
83
84
  * @returns {?object} - current node
84
85
  */
85
86
  export const traverseNode = (node, walker) => {
87
+ let current;
86
88
  if (!node || !node.nodeType) {
87
89
  // throws
88
90
  verifyNode(node);
89
- }
90
- let current;
91
- if (walker?.currentNode) {
91
+ } else if (walker?.currentNode) {
92
92
  let refNode = walker.currentNode;
93
93
  if (refNode === node) {
94
94
  current = refNode;
@@ -126,19 +126,53 @@ export const traverseNode = (node, walker) => {
126
126
  return current ?? null;
127
127
  };
128
128
 
129
+ /**
130
+ * is custom element
131
+ * @param {object} node - Element node
132
+ * @param {object} opt - options
133
+ * @returns {boolean} - result;
134
+ */
135
+ export const isCustomElement = (node, opt = {}) => {
136
+ let bool;
137
+ if (!node || !node.nodeType) {
138
+ // throws
139
+ verifyNode(node);
140
+ } else if (node.nodeType === ELEMENT_NODE) {
141
+ const { localName, ownerDocument } = node;
142
+ const { formAssociated } = opt;
143
+ const window = ownerDocument.defaultView;
144
+ let elmConstructor;
145
+ const attr = node.getAttribute('is');
146
+ if (attr) {
147
+ elmConstructor =
148
+ isCustomElementName(attr) && window.customElements.get(attr);
149
+ } else {
150
+ elmConstructor =
151
+ isCustomElementName(localName) && window.customElements.get(localName);
152
+ }
153
+ if (elmConstructor) {
154
+ if (formAssociated) {
155
+ bool = elmConstructor.formAssociated;
156
+ } else {
157
+ bool = true;
158
+ }
159
+ }
160
+ }
161
+ return !!bool;
162
+ };
163
+
129
164
  /**
130
165
  * is in shadow tree
131
166
  * @param {object} node - node
132
167
  * @returns {boolean} - result;
133
168
  */
134
169
  export const isInShadowTree = node => {
135
- if (!node || !node.type) {
170
+ let bool;
171
+ if (!node || !node.nodeType) {
136
172
  // throws
137
173
  verifyNode(node);
138
- }
139
- let bool;
140
- if (node.nodeType === ELEMENT_NODE ||
141
- node.nodeType === DOCUMENT_FRAGMENT_NODE) {
174
+ } else if (node.nodeType === ELEMENT_NODE ||
175
+ node.nodeType === DOCUMENT_FRAGMENT_NODE) {
142
176
  let refNode = node;
143
177
  while (refNode) {
144
178
  const { host, mode, nodeType, parentNode } = refNode;
@@ -159,12 +193,11 @@ export const isInShadowTree = node => {
159
193
  * @returns {?string} - text content
160
194
  */
161
195
  export const getSlottedTextContent = node => {
196
+ let res;
162
197
  if (!node || !node.nodeType) {
163
198
  // throws
164
199
  verifyNode(node);
165
- }
166
- let res;
167
- if (node.localName === 'slot' && isInShadowTree(node)) {
200
+ } else if (node.localName === 'slot' && isInShadowTree(node)) {
168
201
  const nodes = node.assignedNodes();
169
202
  if (nodes.length) {
170
203
  for (const item of nodes) {
@@ -187,12 +220,11 @@ export const getSlottedTextContent = node => {
187
220
  * @returns {?string} - 'ltr' / 'rtl'
188
221
  */
189
222
  export const getDirectionality = node => {
223
+ let res;
190
224
  if (!node || !node.nodeType) {
191
225
  // throws
192
226
  verifyNode(node);
193
- }
194
- let res;
195
- if (node.nodeType === ELEMENT_NODE) {
227
+ } else if (node.nodeType === ELEMENT_NODE) {
196
228
  const { dir: nodeDir, localName, parentNode } = node;
197
229
  const { getEmbeddingLevels } = bidiFactory();
198
230
  if (REG_DIR.test(nodeDir)) {
@@ -312,12 +344,11 @@ export const getDirectionality = node => {
312
344
  * @returns {boolean} - result
313
345
  */
314
346
  export const isContentEditable = node => {
347
+ let res;
315
348
  if (!node || !node.nodeType) {
316
349
  // throws
317
350
  verifyNode(node);
318
- }
319
- let res;
320
- if (node.nodeType === ELEMENT_NODE) {
351
+ } else if (node.nodeType === ELEMENT_NODE) {
321
352
  if (typeof node.isContentEditable === 'boolean') {
322
353
  res = node.isContentEditable;
323
354
  } else if (node.ownerDocument.designMode === 'on') {
@@ -348,12 +379,17 @@ export const isContentEditable = node => {
348
379
  * @returns {?string} - namespace URI
349
380
  */
350
381
  export const getNamespaceURI = (ns, node) => {
351
- if (!node || !node.nodeType) {
352
- // throws
353
- verifyNode(node);
354
- }
355
382
  let res;
356
- if (ns && typeof ns === 'string' && node.nodeType === ELEMENT_NODE) {
383
+ if (typeof ns !== 'string' || !node || !node.nodeType) {
384
+ if (typeof ns !== 'string') {
385
+ const type = Object.prototype.toString.call(ns).slice(TYPE_FROM, TYPE_TO);
386
+ const msg = `Unexpected type ${type}`;
387
+ throw new TypeError(msg);
388
+ } else {
389
+ // throws
390
+ verifyNode(node);
391
+ }
392
+ } else if (ns && node.nodeType === ELEMENT_NODE) {
357
393
  const { attributes } = node;
358
394
  for (const attr of attributes) {
359
395
  const { name, namespaceURI, prefix, value } = attr;
@@ -401,15 +437,15 @@ export const isNamespaceDeclared = (ns = '', node = {}) => {
401
437
  * @returns {boolean} - result
402
438
  */
403
439
  export const isPreceding = (nodeA, nodeB) => {
440
+ let res;
404
441
  if (!nodeA || !nodeA.nodeType) {
405
442
  // throws
406
443
  verifyNode(nodeA);
407
444
  } else if (!nodeB || !nodeB.nodeType) {
408
445
  // throws
409
446
  verifyNode(nodeB);
410
- }
411
- let res;
412
- if (nodeA.nodeType === ELEMENT_NODE && nodeB.nodeType === ELEMENT_NODE) {
447
+ } else if (nodeA.nodeType === ELEMENT_NODE &&
448
+ nodeB.nodeType === ELEMENT_NODE) {
413
449
  const posBit = nodeB.compareDocumentPosition(nodeA);
414
450
  res = posBit & DOCUMENT_POSITION_PRECEDING ||
415
451
  posBit & DOCUMENT_POSITION_CONTAINS;
package/src/js/finder.js CHANGED
@@ -3,11 +3,10 @@
3
3
  */
4
4
 
5
5
  /* import */
6
- import isCustomElementName from 'is-potential-custom-element-name';
7
6
  import nwsapi from '@asamuzakjp/nwsapi';
8
7
  import {
9
- isContentEditable, isInShadowTree, resolveContent, sortNodes, traverseNode,
10
- verifyNode
8
+ isContentEditable, isCustomElement, isInShadowTree, resolveContent,
9
+ sortNodes, traverseNode, verifyNode
11
10
  } from './dom-util.js';
12
11
  import { matcher } from './matcher.js';
13
12
  import {
@@ -875,6 +874,15 @@ export class Finder {
875
874
  }
876
875
  break;
877
876
  }
877
+ case 'state': {
878
+ if (isCustomElement(node)) {
879
+ const [{ value: stateValue }] = astChildren;
880
+ if (stateValue && node[stateValue]) {
881
+ matched.add(node);
882
+ }
883
+ }
884
+ break;
885
+ }
878
886
  case 'current':
879
887
  case 'nth-col':
880
888
  case 'nth-last-col': {
@@ -1065,7 +1073,8 @@ export class Finder {
1065
1073
  break;
1066
1074
  }
1067
1075
  case 'disabled': {
1068
- if (REG_FORM_CTRL.test(localName) || isCustomElementName(localName)) {
1076
+ if (REG_FORM_CTRL.test(localName) ||
1077
+ isCustomElement(node, { formAssociated: true })) {
1069
1078
  if (node.disabled || node.hasAttribute('disabled')) {
1070
1079
  matched.add(node);
1071
1080
  } else {
@@ -1092,7 +1101,7 @@ export class Finder {
1092
1101
  }
1093
1102
  case 'enabled': {
1094
1103
  if ((REG_FORM_CTRL.test(localName) ||
1095
- isCustomElementName(localName)) &&
1104
+ isCustomElement(node, { formAssociated: true })) &&
1096
1105
  !(node.disabled && node.hasAttribute('disabled'))) {
1097
1106
  matched.add(node);
1098
1107
  }
@@ -1561,14 +1570,8 @@ export class Finder {
1561
1570
  break;
1562
1571
  }
1563
1572
  case 'defined': {
1564
- const attr = node.getAttribute('is');
1565
- if (attr) {
1566
- if (isCustomElementName(attr) &&
1567
- this.#window.customElements.get(attr)) {
1568
- matched.add(node);
1569
- }
1570
- } else if (isCustomElementName(localName)) {
1571
- if (this.#window.customElements.get(localName)) {
1573
+ if (node.hasAttribute('is') || localName.includes('-')) {
1574
+ if (isCustomElement(node)) {
1572
1575
  matched.add(node);
1573
1576
  }
1574
1577
  // NOTE: MathMLElement not implemented in jsdom
package/src/js/parser.js CHANGED
@@ -334,8 +334,10 @@ export const filterSelector = (selector, opt = {}) => {
334
334
  return false;
335
335
  }
336
336
  }
337
- // filter namespaced selectors, e.g. ns|E, pseudo-element selectors and
338
- // attribute selectors with case flag, e.g. [attr i], and unclosed quotes
337
+ // filter namespaced selectors, e.g. ns|E
338
+ // filter pseudo-element selectors
339
+ // filter attribute selectors with case flag, e.g. [attr i]
340
+ // filter unclosed quotes
339
341
  if (/\||::|\[\s*[\w$*=^|~-]+(?:(?:"[\w$*=^|~\s'-]+"|'[\w$*=^|~\s"-]+')?(?:\s+[\w$*=^|~-]+)+|"[^"\]]{1,255}|'[^'\]]{1,255})\s*\]/.test(selector)) {
340
342
  return false;
341
343
  }
@@ -1,6 +1,7 @@
1
1
  export function verifyNode(node: any): object;
2
2
  export function resolveContent(node: object): Array<object>;
3
3
  export function traverseNode(node: object, walker: object): object | null;
4
+ export function isCustomElement(node: object, opt?: object): boolean;
4
5
  export function isInShadowTree(node: object): boolean;
5
6
  export function getSlottedTextContent(node: object): string | null;
6
7
  export function getDirectionality(node: object): string | null;