wip
This commit is contained in:
parent
fd211731cc
commit
9e279064d6
@ -2,6 +2,7 @@
|
|||||||
* @module YXml
|
* @module YXml
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { XmlElement } from 'yjs'
|
||||||
import {
|
import {
|
||||||
YXmlEvent,
|
YXmlEvent,
|
||||||
YXmlElement,
|
YXmlElement,
|
||||||
@ -14,7 +15,7 @@ import {
|
|||||||
YXmlFragmentRefID,
|
YXmlFragmentRefID,
|
||||||
callTypeObservers,
|
callTypeObservers,
|
||||||
transact,
|
transact,
|
||||||
AbstractUpdateDecoder, AbstractUpdateEncoder, Doc, ContentType, Transaction, Item, YXmlText, YXmlHook, Snapshot // eslint-disable-line
|
AbstractUpdateDecoder, AbstractUpdateEncoder, Doc, ID, ContentType, Transaction, Item, YXmlText, YXmlHook, Snapshot // eslint-disable-line
|
||||||
} from '../internals.js'
|
} from '../internals.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,6 +30,13 @@ import {
|
|||||||
* @typedef {string} CSS_Selector
|
* @typedef {string} CSS_Selector
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} Filters
|
||||||
|
* @property {CSS_Selector|undefined} Filters.tagname
|
||||||
|
* @property {ID|undefined} Filters.id
|
||||||
|
* @property {Record<string, any>|undefined} Filters.attributes
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dom filter function.
|
* Dom filter function.
|
||||||
*
|
*
|
||||||
@ -98,7 +106,7 @@ export class YXmlTreeWalker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (n !== null && (n.deleted || !this._filter(/** @type {ContentType} */ (n.content).type)))
|
} while (n !== null && (n.deleted || !this._filter(/** @type {ContentType} */(n.content).type)))
|
||||||
}
|
}
|
||||||
this._firstCall = false
|
this._firstCall = false
|
||||||
if (n === null) {
|
if (n === null) {
|
||||||
@ -140,7 +148,7 @@ export class YXmlFragment extends AbstractType {
|
|||||||
*/
|
*/
|
||||||
_integrate (y, item) {
|
_integrate (y, item) {
|
||||||
super._integrate(y, item)
|
super._integrate(y, item)
|
||||||
this.insert(0, /** @type {Array<any>} */ (this._prelimContent))
|
this.insert(0, /** @type {Array<any>} */(this._prelimContent))
|
||||||
this._prelimContent = null
|
this._prelimContent = null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,19 +187,57 @@ export class YXmlFragment extends AbstractType {
|
|||||||
*
|
*
|
||||||
* Query support:
|
* Query support:
|
||||||
* - tagname
|
* - tagname
|
||||||
* TODO:
|
|
||||||
* - id
|
* - id
|
||||||
|
* TODO:
|
||||||
* - attribute
|
* - attribute
|
||||||
*
|
*
|
||||||
* @param {CSS_Selector} query The query on the children.
|
* @param {CSS_Selector|Filters} query The query on the children.
|
||||||
* @return {YXmlElement|YXmlText|YXmlHook|null} The first element that matches the query or null.
|
* @return {YXmlElement|YXmlText|YXmlHook|null} The first element that matches the query or null.
|
||||||
*
|
*
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
querySelector (query) {
|
querySelector (query) {
|
||||||
query = query.toUpperCase()
|
/**
|
||||||
// @ts-ignore
|
* @type {Filters}
|
||||||
const iterator = new YXmlTreeWalker(this, element => element.nodeName && element.nodeName.toUpperCase() === query)
|
*/
|
||||||
|
let filters = {}
|
||||||
|
|
||||||
|
// Allow passing a string to query the tagname for backwards compatability
|
||||||
|
if (typeof query === 'string') {
|
||||||
|
filters.tagname = query.toUpperCase()
|
||||||
|
} else {
|
||||||
|
filters = query
|
||||||
|
}
|
||||||
|
|
||||||
|
const iterator = new YXmlTreeWalker(this, element => {
|
||||||
|
// @ts-ignore
|
||||||
|
if (filters.tagname && element.nodeName && element.nodeName.toUpperCase() === filters.tagname) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters.id && element._item && element._item.id === filters.id) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters.attributes && element instanceof XmlElement) {
|
||||||
|
const attributes = element.getAttributes()
|
||||||
|
const keys = Object.keys(filters.attributes)
|
||||||
|
|
||||||
|
// All passed attributes must match to count as a match
|
||||||
|
for (const key of keys) {
|
||||||
|
if (filters.attributes[key] !== attributes[key]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// accounts for passing an empty object as a filter
|
||||||
|
if (keys.length > 1) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
})
|
||||||
const next = iterator.next()
|
const next = iterator.next()
|
||||||
if (next.done) {
|
if (next.done) {
|
||||||
return null
|
return null
|
||||||
|
Loading…
x
Reference in New Issue
Block a user