@asamuzakjp/dom-selector
Advanced tools
Comparing version 0.8.1 to 0.9.2
@@ -44,3 +44,3 @@ { | ||
}, | ||
"version": "0.8.1" | ||
"version": "0.9.2" | ||
} |
@@ -6,2 +6,3 @@ # DOM Selector | ||
[![npm (scoped)](https://img.shields.io/npm/v/@asamuzakjp/dom-selector)](https://www.npmjs.com/package/@asamuzakjp/dom-selector) | ||
<!-- | ||
@@ -14,3 +15,2 @@ [![release](https://img.shields.io/github/v/release/asamuzaK/domSelector)](https://github.com/asamuzaK/domSelector/releases) | ||
## Install | ||
@@ -22,3 +22,2 @@ | ||
## Usage | ||
@@ -34,61 +33,61 @@ | ||
#### Table of Contents | ||
### matches(selector, node, opt) | ||
- [matches][1] | ||
- [Parameters][2] | ||
- [closest][3] | ||
- [Parameters][4] | ||
- [querySelector][5] | ||
- [Parameters][6] | ||
- [querySelectorAll][7] | ||
- [Parameters][8] | ||
matches - [Element.matches()][64] | ||
### matches(selector, node) | ||
Implementation of [Element.matches()][62]. | ||
#### Parameters | ||
- `selector` **[string][56]** CSS selector | ||
- `node` **[object][57]** Referenced Element node | ||
- `selector` **[string][59]** CSS selector | ||
- `node` **[object][60]** Element node | ||
- `opt` **[object][60]?** options | ||
- `opt.globalObject` **[object][60]?** global object, e.g. `window`, `globalThis` | ||
- `opt.jsdom` **[boolean][61]?** is jsdom | ||
Returns **[boolean][58]** Result | ||
Returns **[boolean][61]** result | ||
### closest(selector, node) | ||
### closest(selector, node, opt) | ||
Implementation of [Element.closest()][63]. | ||
closest - [Element.closest()][65] | ||
#### Parameters | ||
- `selector` **[string][56]** CSS selector | ||
- `node` **[object][57]** Referenced Element node | ||
- `selector` **[string][59]** CSS selector | ||
- `node` **[object][60]** Element node | ||
- `opt` **[object][60]?** options | ||
- `opt.globalObject` **[object][60]?** global object, e.g. `window`, `globalThis` | ||
- `opt.jsdom` **[boolean][61]?** is jsdom | ||
Returns **[object][57]?** Matched node | ||
Returns **[object][60]?** matched node | ||
### querySelector(selector, refPoint) | ||
### querySelector(selector, refPoint, opt) | ||
Implementation of [Document.querySelector()][64], [Element.querySelector()][65]. | ||
querySelector - [Document.querySelector()][66], [DocumentFragment.querySelector()][67], [Element.querySelector()][68] | ||
#### Parameters | ||
- `selector` **[string][56]** CSS selector | ||
- `refPoint` **[object][57]** Reference point. Document or Element node | ||
- `selector` **[string][59]** CSS selector | ||
- `refPoint` **[object][60]** Document, DocumentFragment or Element node | ||
- `opt` **[object][60]?** options | ||
- `opt.globalObject` **[object][60]?** global object, e.g. `window`, `globalThis` | ||
- `opt.jsdom` **[boolean][61]?** is jsdom | ||
Returns **[object][57]?** Matched node | ||
Returns **[object][60]?** matched node | ||
### querySelectorAll(selector, refPoint) | ||
### querySelectorAll(selector, refPoint, opt) | ||
Implementation of [Document.querySelectorAll()][66], [Element.querySelectorAll()][67]. | ||
**NOTE**: returns [Array][59], not [NodeList][61]. | ||
querySelectorAll - [Document.querySelectorAll()][69], [Document.querySelectorAll()][70], [Element.querySelectorAll()][71] | ||
**NOTE**: returns Array, not NodeList | ||
#### Parameters | ||
- `selector` **[string][56]** CSS selector | ||
- `refPoint` **[object][57]** Reference point. Document or Element node | ||
- `selector` **[string][59]** CSS selector | ||
- `refPoint` **[object][60]** Document, DocumentFragment or Element node | ||
- `opt` **[object][60]?** options | ||
- `opt.globalObject` **[object][60]?** global object, e.g. `window`, `globalThis` | ||
- `opt.jsdom` **[boolean][61]?** is jsdom | ||
Returns **[Array][59]<([object][57] \| [undefined][60])>** Array of matched nodes | ||
Returns **[Array][62]<([object][60] \| [undefined][63])>** array of matched nodes | ||
@@ -112,13 +111,14 @@ | ||
[8]: #parameters-3 | ||
[56]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String | ||
[57]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object | ||
[58]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean | ||
[59]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array | ||
[60]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined | ||
[61]: https://developer.mozilla.org/docs/Web/API/NodeList | ||
[62]: https://developer.mozilla.org/docs/Web/API/Element/matches | ||
[63]: https://developer.mozilla.org/docs/Web/API/Element/closest | ||
[64]: https://developer.mozilla.org/docs/Web/API/Document/querySelector | ||
[65]: https://developer.mozilla.org/docs/Web/API/Element/querySelector | ||
[66]: https://developer.mozilla.org/docs/Web/API/Document/querySelectorAll | ||
[67]: https://developer.mozilla.org/docs/Web/API/Element/querySelectorAll | ||
[59]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String | ||
[60]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object | ||
[61]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean | ||
[62]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array | ||
[63]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined | ||
[64]: https://developer.mozilla.org/docs/Web/API/Element/matches | ||
[65]: https://developer.mozilla.org/docs/Web/API/Element/closest | ||
[66]: https://developer.mozilla.org/docs/Web/API/Document/querySelector | ||
[67]: https://developer.mozilla.org/docs/Web/API/DocumentFragment/querySelector | ||
[68]: https://developer.mozilla.org/docs/Web/API/Element/querySelector | ||
[69]: https://developer.mozilla.org/docs/Web/API/Document/querySelectorAll | ||
[70]: https://developer.mozilla.org/docs/Web/API/DocumentFragment/querySelectorAll | ||
[71]: https://developer.mozilla.org/docs/Web/API/Element/querySelectorAll |
@@ -16,6 +16,9 @@ /*! | ||
* @param {object} node - Element node | ||
* @param {object} [opt] - options | ||
* @param {object} [opt.globalObject] - global object | ||
* @param {boolean} [opt.jsdom] - is jsdom | ||
* @returns {boolean} - result | ||
*/ | ||
const matches = (selector, node) => { | ||
const matcher = new Matcher(selector, node); | ||
const matches = (selector, node, opt) => { | ||
const matcher = new Matcher(selector, node, opt); | ||
return matcher.matches(); | ||
@@ -28,6 +31,9 @@ }; | ||
* @param {object} node - Element node | ||
* @param {object} [opt] - options | ||
* @param {object} [opt.globalObject] - global object | ||
* @param {boolean} [opt.jsdom] - is jsdom | ||
* @returns {?object} - matched node | ||
*/ | ||
const closest = (selector, node) => { | ||
const matcher = new Matcher(selector, node); | ||
const closest = (selector, node, opt) => { | ||
const matcher = new Matcher(selector, node, opt); | ||
return matcher.closest(); | ||
@@ -40,6 +46,9 @@ }; | ||
* @param {object} refPoint - Document or Element node | ||
* @param {object} [opt] - options | ||
* @param {object} [opt.globalObject] - global object | ||
* @param {boolean} [opt.jsdom] - is jsdom | ||
* @returns {?object} - matched node | ||
*/ | ||
const querySelector = (selector, refPoint) => { | ||
const matcher = new Matcher(selector, refPoint); | ||
const querySelector = (selector, refPoint, opt) => { | ||
const matcher = new Matcher(selector, refPoint, opt); | ||
return matcher.querySelector(); | ||
@@ -53,6 +62,9 @@ }; | ||
* @param {object} refPoint - Document or Element node | ||
* @param {object} [opt] - options | ||
* @param {object} [opt.globalObject] - global object | ||
* @param {boolean} [opt.jsdom] - is jsdom | ||
* @returns {Array.<object|undefined>} - array of matched nodes | ||
*/ | ||
const querySelectorAll = (selector, refPoint) => { | ||
const matcher = new Matcher(selector, refPoint); | ||
const querySelectorAll = (selector, refPoint, opt) => { | ||
const matcher = new Matcher(selector, refPoint, opt); | ||
return matcher.querySelectorAll(); | ||
@@ -59,0 +71,0 @@ }; |
@@ -7,2 +7,3 @@ /** | ||
/* import */ | ||
const _DOMException = require('domexception/webidl2js-wrapper'); | ||
const DOMException = require('./domexception.js'); | ||
@@ -350,4 +351,8 @@ const { generateCSS, parseSelector, walkAST } = require('./parser.js'); | ||
attributes?.length) { | ||
if (typeof astFlags === 'string' && !/^[is]$/i.test(astFlags)) { | ||
throw new DOMException('invalid attribute selector', 'SyntaxError'); | ||
} | ||
const { name: astAttrName } = astName; | ||
const caseInsensitive = !(astFlags && /^s$/i.test(astFlags)); | ||
const caseInsensitive = | ||
!(typeof astFlags === 'string' && /^s$/i.test(astFlags)); | ||
const attrValues = []; | ||
@@ -889,2 +894,4 @@ const l = attributes.length; | ||
#document; | ||
#global; | ||
#jsdom; | ||
#node; | ||
@@ -897,6 +904,12 @@ #selector; | ||
* @param {object} refPoint - reference point | ||
* @param {object} [opt] - options | ||
* @param {object} [opt.globalObject] - global object | ||
* @param {boolean} [opt.jsdom] - is jsdom | ||
*/ | ||
constructor(selector, refPoint) { | ||
constructor(selector, refPoint, opt = {}) { | ||
const { globalObject, jsdom } = opt; | ||
this.#ast = parseSelector(selector); | ||
this.#document = refPoint?.ownerDocument ?? refPoint; | ||
this.#global = globalObject || globalThis; | ||
this.#jsdom = !!jsdom; | ||
this.#node = refPoint; | ||
@@ -907,2 +920,14 @@ this.#selector = selector; | ||
/** | ||
* create DOMException | ||
* @param {string} msg - message | ||
* @param {string} name - name | ||
* @throws | ||
*/ | ||
_createDOMException(msg, name) { | ||
if (this.#jsdom) { | ||
throw _DOMException.create(this.#global, [msg, name]); | ||
} | ||
} | ||
/** | ||
* create iterator | ||
@@ -1351,4 +1376,13 @@ * @param {object} ast - AST | ||
matches() { | ||
const arr = this._match(this.#ast, this.#document); | ||
const res = arr.length && arr.includes(this.#node); | ||
let res; | ||
try { | ||
const arr = this._match(this.#ast, this.#document); | ||
res = arr.length && arr.includes(this.#node); | ||
} catch (e) { | ||
if (e instanceof DOMException && this.#jsdom) { | ||
res = this._createDOMException(e.message, e.name); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
return !!res; | ||
@@ -1362,11 +1396,19 @@ } | ||
closest() { | ||
const arr = this._match(this.#ast, this.#document); | ||
let node = this.#node; | ||
let res; | ||
while (node) { | ||
if (arr.includes(node)) { | ||
res = node; | ||
break; | ||
try { | ||
const arr = this._match(this.#ast, this.#document); | ||
let node = this.#node; | ||
while (node) { | ||
if (arr.includes(node)) { | ||
res = node; | ||
break; | ||
} | ||
node = node.parentNode; | ||
} | ||
node = node.parentNode; | ||
} catch (e) { | ||
if (e instanceof DOMException && this.#jsdom) { | ||
res = this._createDOMException(e.message, e.name); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
@@ -1381,10 +1423,19 @@ return res || null; | ||
querySelector() { | ||
const arr = this._match(this.#ast, this.#node); | ||
if (arr.length) { | ||
const i = arr.findIndex(node => node === this.#node); | ||
if (i >= 0) { | ||
arr.splice(i, 1); | ||
let res; | ||
try { | ||
const arr = this._match(this.#ast, this.#node); | ||
if (arr.length) { | ||
const i = arr.findIndex(node => node === this.#node); | ||
if (i >= 0) { | ||
arr.splice(i, 1); | ||
} | ||
} | ||
[res] = arr; | ||
} catch (e) { | ||
if (e instanceof DOMException && this.#jsdom) { | ||
res = this._createDOMException(e.message, e.name); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
const [res] = arr; | ||
return res || null; | ||
@@ -1399,10 +1450,21 @@ } | ||
querySelectorAll() { | ||
const arr = this._match(this.#ast, this.#node); | ||
if (arr.length) { | ||
const i = arr.findIndex(node => node === this.#node); | ||
if (i >= 0) { | ||
arr.splice(i, 1); | ||
const res = []; | ||
try { | ||
const arr = this._match(this.#ast, this.#node); | ||
if (arr.length) { | ||
const i = arr.findIndex(node => node === this.#node); | ||
if (i >= 0) { | ||
arr.splice(i, 1); | ||
} | ||
} | ||
const a = new Set(arr); | ||
res.push(...a); | ||
} catch (e) { | ||
if (e instanceof DOMException && this.#jsdom) { | ||
res.push(this._createDOMException(e.message, e.name)); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
return [...new Set(arr)]; | ||
return res; | ||
} | ||
@@ -1409,0 +1471,0 @@ }; |
@@ -8,6 +8,6 @@ /** | ||
const { generate, parse, toPlainObject, walk } = require('css-tree'); | ||
const { SELECTOR } = require('./constant.js'); | ||
const DOMException = require('./domexception.js'); | ||
/* constants */ | ||
const { SELECTOR } = require('./constant.js'); | ||
const TYPE_FROM = 8; | ||
@@ -28,4 +28,3 @@ const TYPE_TO = -1; | ||
if (typeof selector !== 'string' || selector === '' || | ||
selector.startsWith('>') || selector.endsWith(',') || | ||
selector.includes('= ')) { | ||
/^\s*>/.test(selector) || /,\s*$/.test(selector)) { | ||
throw new DOMException(`invalid selector ${selector}`, 'SyntaxError'); | ||
@@ -32,0 +31,0 @@ } |
@@ -1,4 +0,16 @@ | ||
export function closest(selector: string, node: object): object | null; | ||
export function matches(selector: string, node: object): boolean; | ||
export function querySelector(selector: string, refPoint: object): object | null; | ||
export function querySelectorAll(selector: string, refPoint: object): Array<object | undefined>; | ||
export function closest(selector: string, node: object, opt?: { | ||
globalObject?: object; | ||
jsdom?: boolean; | ||
}): object | null; | ||
export function matches(selector: string, node: object, opt?: { | ||
globalObject?: object; | ||
jsdom?: boolean; | ||
}): boolean; | ||
export function querySelector(selector: string, refPoint: object, opt?: { | ||
globalObject?: object; | ||
jsdom?: boolean; | ||
}): object | null; | ||
export function querySelectorAll(selector: string, refPoint: object, opt?: { | ||
globalObject?: object; | ||
jsdom?: boolean; | ||
}): Array<object | undefined>; |
export class Matcher { | ||
constructor(selector: string, refPoint: object); | ||
constructor(selector: string, refPoint: object, opt?: { | ||
globalObject?: object; | ||
jsdom?: boolean; | ||
}); | ||
_createDOMException(msg: string, name: string): void; | ||
_createIterator(ast?: object, root?: object): object; | ||
@@ -4,0 +8,0 @@ _parseAST(ast: object, node: object): Array<object | undefined>; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
58579
1714