Add additional filter options to querySelectorAll too

This commit is contained in:
Tom Moor 2020-10-12 11:30:19 -07:00
parent ccc32617d9
commit ad6b138129
2 changed files with 39 additions and 24 deletions

View File

@ -195,6 +195,41 @@ export class YXmlFragment extends AbstractType {
* @public
*/
querySelector (query) {
const iterator = new YXmlTreeWalker(this, this._walkFilter(query))
const next = iterator.next()
if (next.done) {
return null
} else {
return next.value
}
}
/**
* Returns all YXmlElements that match the query.
* Similar to Dom's {@link querySelectorAll}.
*
* Query support:
* - tagname
* - id
* - attributes
*
* @param {CSS_Selector|Filters} query The query on the children.
* @return {Array<YXmlElement|YXmlText|YXmlHook|null>} The elements that match this query.
*
* @public
*/
querySelectorAll (query) {
return Array.from(new YXmlTreeWalker(this, this._walkFilter(query)))
}
/**
* Creates filter function to run against children when walking tree.
*
* @param {CSS_Selector|Filters} query The query on the children.
* @return {function(AbstractType<any>):boolean}
*/
_walkFilter (query) {
/**
* @type {Filters}
*/
@ -211,7 +246,7 @@ export class YXmlFragment extends AbstractType {
filters.tagname = filters.tagname.toUpperCase()
}
const iterator = new YXmlTreeWalker(this, element => {
return element => {
// @ts-ignore
if (filters.tagname && element.nodeName && element.nodeName.toUpperCase() === filters.tagname) {
return true
@ -239,32 +274,9 @@ export class YXmlFragment extends AbstractType {
}
return false
})
const next = iterator.next()
if (next.done) {
return null
} else {
return next.value
}
}
/**
* Returns all YXmlElements that match the query.
* Similar to Dom's {@link querySelectorAll}.
*
* @todo Does not yet support all queries. Currently only query by tagName.
*
* @param {CSS_Selector} query The query on the children
* @return {Array<YXmlElement|YXmlText|YXmlHook|null>} The elements that match this query.
*
* @public
*/
querySelectorAll (query) {
query = query.toUpperCase()
// @ts-ignore
return Array.from(new YXmlTreeWalker(this, element => element.nodeName && element.nodeName.toUpperCase() === query))
}
/**
* Creates YXmlEvent and calls observers.
*

View File

@ -72,6 +72,9 @@ export const testTreewalker = tc => {
t.assert(allParagraphs.length === 2, 'found exactly two paragraphs')
t.assert(allParagraphs[0] === paragraph1, 'querySelectorAll found paragraph1')
t.assert(allParagraphs[1] === paragraph2, 'querySelectorAll found paragraph2')
t.assert(xml0.querySelectorAll({ tagname: 'p' }).length === 2, 'found exactly two paragraphs by tagname')
t.assert(xml0.querySelectorAll({ id: paragraph1ID })[0] === paragraph1, 'querySelectorAll found paragraph1 by id')
t.assert(xml0.querySelectorAll({ attributes: { custom: '123' } })[0] === paragraph1, 'querySelectorAll found paragraph1 by attribute')
t.assert(xml0.querySelector('p') === paragraph1, 'querySelector found paragraph1 by string query')
t.assert(xml0.querySelector({ tagname: 'p' }) === paragraph1, 'querySelector found paragraph1 by tagname')
t.assert(xml0.querySelector({ id: paragraph1ID }) === paragraph1, 'querySelector found paragraph1 by id')