This is probably beyond the scope in terms of complexity for moxi, but it won't hurt to demonstrate the idea.
Right now for q() in allows for scoping on a selector, but not a relative selector. ex. q('last .row in closest table') would fail since mkq doesn't handle closest table. This also forces the user to read from right to left.
If we drop in and this we could do: q('closest table -> last .row').
Better yet we can continue the traversal q('closest table -> last .row -> last td').
Or say for a form q('next form -> input').arr().forEach(el=>el.toggleAttribute('disabled')).
It would also mean dropping the one() helper function.
Here is what mkqf (mkq helper function selector) looks like:
mkqf={
closest:(s,c,t)=>(c||t).closest(s),
first:(s,c,_)=>(c||doc).querySelector(s),
last:(s,c,_)=>[...(c||doc).querySelectorAll(s)].at(-1),
next:(s,c,t)=>[...doc.querySelectorAll(s)].find(el=>(c||t).compareDocumentPosition(el) & 4),
prev:(s,c,t)=>[...doc.querySelectorAll(s)].findLast(el=>(c||t).compareDocumentPosition(el) & 2),
split:cmd=>cmd.split(/\s*->\s*/).filter(Boolean),
run:(cmd,c,t)=>{
const [,fn,s] = cmd.match(/^(closest|first|last|next|prev)\s+(.+)$/)||[]
return [fn,fn ? mkqf[fn](s,c,t) : (c||doc).querySelector(cmd)]
}
},
Changed mkq:
mkq = ctx=>sel=>{
if (typeof sel != "string") return proxy(sel.nodeType ? [sel] : [...sel])
const cmds = mkqf.split(sel)
let i = 0
for (const cmd of cmds) {
const [fn, res] = mkqf.run(cmd, ++i > 1 ? ctx : undefined, ctx)
if (i == cmds.length) return proxy(fn ? (res ? [res] : []) : [...(i > 1 ? ctx : doc).querySelectorAll(cmd)])
if (!(ctx = res)) break
}
return proxy([])
},
If mkqf is exposed as qf to the document fixi could use the moxi function for its relative selectors:
document.addEventListener("fx:config", e => {//Moxi Relative Selectors
let c, t = e.target
for (const cmd of qf.split(t.getAttribute("fx-target")||"")) {
if (!(e.detail.cfg.target = c = qf.run(cmd, c, t)[1])) break
}
})
Traversal is a nice convenience for users, but entirely optional as it's easy to fork and change the code for ourselves.
Here's my modded implementation of Moxi + Fixi that's using the new method: https://github.com/figuerom16/fixi/blob/master/mofix.js
Feel free to close the issue if it's out of scope/undesired. Thank you for making the project!
This is probably beyond the scope in terms of complexity for moxi, but it won't hurt to demonstrate the idea.
Right now for
q()inallows for scoping on a selector, but not a relative selector. ex.q('last .row in closest table')would fail since mkq doesn't handle closest table. This also forces the user to read from right to left.If we drop
inandthiswe could do:q('closest table -> last .row').Better yet we can continue the traversal
q('closest table -> last .row -> last td').Or say for a form
q('next form -> input').arr().forEach(el=>el.toggleAttribute('disabled')).It would also mean dropping the
one()helper function.Here is what
mkqf(mkqhelper function selector) looks like:Changed
mkq:If
mkqfis exposed asqfto the document fixi could use the moxi function for its relative selectors:Traversal is a nice convenience for users, but entirely optional as it's easy to fork and change the code for ourselves.
Here's my modded implementation of Moxi + Fixi that's using the new method: https://github.com/figuerom16/fixi/blob/master/mofix.js
Feel free to close the issue if it's out of scope/undesired. Thank you for making the project!