754d6092 by Adam Heath

Adjustments are now done centrally, inside the node proxy, instead of

ad-hoc in Match.
1 parent 20070e45
1 --- 1 ---
2 import Match from './match.astro' 2 import Match from './match.astro'
3 3
4 const { props: { parent, children, debug = 0, replacers, slotHandler, adjuster } } = Astro 4 const { props: { parent, children, debug = 0, replacers, slotHandler } } = Astro
5 5
6 //console.log('Children:render', { parent, children, replacers }) 6 //console.log('Children:render', { parent, children, replacers })
7 if (debug) { 7 if (debug) {
...@@ -11,7 +11,7 @@ const nextDebug = debug ? debug - 1 : 0 ...@@ -11,7 +11,7 @@ const nextDebug = debug ? debug - 1 : 0
11 --- 11 ---
12 { 12 {
13 Array.isArray(children) ? 13 Array.isArray(children) ?
14 children.map((child, index) => <Match parent={parent} node={child} index={index} debug={nextDebug} replacers={replacers} slotHandler={slotHandler} adjuster={adjuster}/>) 14 children.map((child, index) => <Match parent={parent} node={child} index={index} debug={nextDebug} replacers={replacers} slotHandler={slotHandler}/>)
15 : !children ? '' 15 : !children ? ''
16 : <Match parent={parent} node={children} index={0} debug={nextDebug} replacers={replacers} slotHandler={slotHandler} adjuster={adjuster}/> 16 : <Match parent={parent} node={children} index={0} debug={nextDebug} replacers={replacers} slotHandler={slotHandler}/>
17 } 17 }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
2 2
3 import Children from './children.astro' 3 import Children from './children.astro'
4 4
5 const { props: { wrap = false, wrapAttributes = {}, node, replacers, slotHandler, adjuster } } = Astro 5 const { props: { wrap = false, wrapAttributes = {}, node, replacers, slotHandler } } = Astro
6 const { name: Name, attributes, children } = node 6 const { name: Name, attributes, children } = node
7 7
8 const CustomName = `custom-${Name}` 8 const CustomName = `custom-${Name}`
...@@ -15,14 +15,14 @@ const CustomName = `custom-${Name}` ...@@ -15,14 +15,14 @@ const CustomName = `custom-${Name}`
15 { 15 {
16 node.isSelfClosingTag ? <Name {...attributes}/> 16 node.isSelfClosingTag ? <Name {...attributes}/>
17 : <Name {...attributes}> 17 : <Name {...attributes}>
18 <Children parent={node} children={children} replacers={replacers} slotHandler={slotHandler} adjuster={adjuster}/> 18 <Children parent={node} children={children} replacers={replacers} slotHandler={slotHandler}/>
19 </Name> 19 </Name>
20 } 20 }
21 </CustomName> 21 </CustomName>
22 ) : ( 22 ) : (
23 node.isSelfClosingTag ? <CustomName {...attributes}/> 23 node.isSelfClosingTag ? <CustomName {...attributes}/>
24 : <CustomName {...attributes}> 24 : <CustomName {...attributes}>
25 <Children parent={node} children={children} replacers={replacers} slotHandler={slotHandler} adjuster={adjuster}/> 25 <Children parent={node} children={children} replacers={replacers} slotHandler={slotHandler}/>
26 </CustomName> 26 </CustomName>
27 ) 27 )
28 } 28 }
......
...@@ -344,7 +344,7 @@ class NodeProxyHandler { ...@@ -344,7 +344,7 @@ class NodeProxyHandler {
344 #options 344 #options
345 #cache 345 #cache
346 #parent 346 #parent
347 constructor(options = {}, parent = null) { 347 constructor(options, parent = null) {
348 this.#options = options 348 this.#options = options
349 this.#cache = {} 349 this.#cache = {}
350 this.#parent = parent 350 this.#parent = parent
...@@ -369,7 +369,7 @@ class NodeProxyHandler { ...@@ -369,7 +369,7 @@ class NodeProxyHandler {
369 case 'parent': 369 case 'parent':
370 return this.#parent 370 return this.#parent
371 case 'children': 371 case 'children':
372 return this.#cache[ prop ] = origValue.map((child) => proxyNode(child, this.#options, this)) 372 return this.#cache[ prop ] = origValue.map((child, index) => proxyNode(child, this.#options, this, index))
373 default: 373 default:
374 if (typeof origValue === 'function') { 374 if (typeof origValue === 'function') {
375 return this.#cache[ prop ] = (...args) => { 375 return this.#cache[ prop ] = (...args) => {
...@@ -381,8 +381,10 @@ class NodeProxyHandler { ...@@ -381,8 +381,10 @@ class NodeProxyHandler {
381 } 381 }
382 } 382 }
383 383
384 const proxyNode = (node, options, parent) => { 384 const proxyNode = (node, options = {}, parent = null, index = 0) => {
385 return new Proxy(node, new NodeProxyHandler(options, parent)) 385 const { adjuster = (node, parent, index) => node } = options
386 const adjusted = adjuster(node, parent, index)
387 return new Proxy(adjusted, new NodeProxyHandler(options, parent))
386 } 388 }
387 389
388 export const parseHtml = (html: string, options): NodeType => { 390 export const parseHtml = (html: string, options): NodeType => {
......
...@@ -2,17 +2,16 @@ ...@@ -2,17 +2,16 @@
2 import { ELEMENT_NODE, TEXT_NODE } from 'ultrahtml' 2 import { ELEMENT_NODE, TEXT_NODE } from 'ultrahtml'
3 import Node from './node.astro' 3 import Node from './node.astro'
4 4
5 const { props: { parent = null, node, index = 0, debug = 0, replacers, slotHandler, adjuster } } = Astro 5 const { props: { parent = null, node, index = 0, debug = 0, replacers, slotHandler } } = Astro
6 const { name: Name, attributes } = node 6 const { name: Name, attributes } = node
7 7
8 const fixedNode = adjuster(node, parent, index)
9 if (debug) { 8 if (debug) {
10 console.log('trying to match against', {fixedNode}) 9 console.log('trying to match against', {node})
11 } 10 }
12 let slotName 11 let slotName
13 for (const [ matcher, handler ] of replacers) { 12 for (const [ matcher, handler ] of replacers) {
14 if (debug) console.log('attempting matcher', matcher.toString()) 13 if (debug) console.log('attempting matcher', matcher.toString())
15 if (matcher(fixedNode, parent, index, false)) { 14 if (matcher(node, parent, index, false)) {
16 if (debug) console.log('matched') 15 if (debug) console.log('matched')
17 slotName = handler 16 slotName = handler
18 } 17 }
...@@ -21,6 +20,6 @@ for (const [ matcher, handler ] of replacers) { ...@@ -21,6 +20,6 @@ for (const [ matcher, handler ] of replacers) {
21 const nextDebug = debug ? debug - 1 : 0 20 const nextDebug = debug ? debug - 1 : 0
22 --- 21 ---
23 { 22 {
24 slotName ? slotHandler(slotName, fixedNode) 23 slotName ? slotHandler(slotName, node)
25 : <Node parent={parent} node={fixedNode} index={index} debug={nextDebug} replacers={replacers} slotHandler={slotHandler} adjuster={adjuster}/> 24 : <Node parent={parent} node={node} index={index} debug={nextDebug} replacers={replacers} slotHandler={slotHandler}/>
26 } 25 }
......
...@@ -16,7 +16,7 @@ interface Props { ...@@ -16,7 +16,7 @@ interface Props {
16 } 16 }
17 17
18 18
19 const { props: { parent = null, node, index = 0, debug = 0, replacers, slotHandler, adjuster } } = Astro 19 const { props: { parent = null, node, index = 0, debug = 0, replacers, slotHandler } } = Astro
20 const { name: Name, attributes } = node 20 const { name: Name, attributes } = node
21 21
22 if (debug) { 22 if (debug) {
...@@ -32,7 +32,7 @@ const nextDebug = debug ? debug - 1 : 0 ...@@ -32,7 +32,7 @@ const nextDebug = debug ? debug - 1 : 0
32 : node.type === ELEMENT_NODE ? ( 32 : node.type === ELEMENT_NODE ? (
33 node.isSelfClosingTag ? <Name {...attributes}/> 33 node.isSelfClosingTag ? <Name {...attributes}/>
34 : <Name {...attributes}> 34 : <Name {...attributes}>
35 <Children parent={node} children={node.children} debug={nextDebug} replacers={replacers} slotHandler={slotHandler} adjuster={adjuster}/> 35 <Children parent={node} children={node.children} debug={nextDebug} replacers={replacers} slotHandler={slotHandler}/>
36 </Name> 36 </Name>
37 ) : '' 37 ) : ''
38 } 38 }
......
...@@ -14,9 +14,7 @@ interface Props { ...@@ -14,9 +14,7 @@ interface Props {
14 14
15 const { props } = Astro 15 const { props } = Astro
16 const { html, debug = 0, xpath, replacements = {}, adjustments = {} } = props 16 const { html, debug = 0, xpath, replacements = {}, adjustments = {} } = props
17 const doc = props.node ? props.node : parseHtml(props.html)
18 17
19 const node = xpath ? findNode(doc, xpath) : doc
20 const replacers = Object.entries(replacements).map(([ selector, handler ]) => [ createMatcher(selector), handler ]) 18 const replacers = Object.entries(replacements).map(([ selector, handler ]) => [ createMatcher(selector), handler ])
21 19
22 const adjustmentsCompiled = Object.entries(adjustments).map(([ selector, handler ]) => [ createMatcher(selector), handler ]) 20 const adjustmentsCompiled = Object.entries(adjustments).map(([ selector, handler ]) => [ createMatcher(selector), handler ])
...@@ -29,9 +27,12 @@ const adjuster = (node, parent, index) => { ...@@ -29,9 +27,12 @@ const adjuster = (node, parent, index) => {
29 return node 27 return node
30 } 28 }
31 29
30 const doc = props.node ? props.node : parseHtml(props.html, { adjuster })
31 const node = xpath ? findNode(doc, xpath) : doc
32
32 const slotHandler: SlotHandler = (slotName, node) => { 33 const slotHandler: SlotHandler = (slotName, node) => {
33 return Astro.slots.render(slotName, [ node, { slotHandler, replacers, adjuster } ] ) 34 return Astro.slots.render(slotName, [ node, { slotHandler, replacers } ] )
34 } 35 }
35 const nextDebug = debug ? debug - 1 : 0 36 const nextDebug = debug ? debug - 1 : 0
36 --- 37 ---
37 <Match node={node} debug={nextDebug} replacers={replacers} slotHandler={slotHandler} adjuster={adjuster}/> 38 <Match node={node} debug={nextDebug} replacers={replacers} slotHandler={slotHandler}/>
......