Add feature to 'adjust' nodes before matching against them. This can be
used to change values of attributes, as an example.
Showing
5 changed files
with
29 additions
and
17 deletions
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 } } = Astro | 4 | const { props: { parent, children, debug = 0, replacers, slotHandler, adjuster } } = 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}/>) | 14 | children.map((child, index) => <Match parent={parent} node={child} index={index} debug={nextDebug} replacers={replacers} slotHandler={slotHandler} adjuster={adjuster}/>) |
15 | : !children ? '' | 15 | : !children ? '' |
16 | : <Match parent={parent} node={children} index={0} debug={nextDebug} replacers={replacers} slotHandler={slotHandler}/> | 16 | : <Match parent={parent} node={children} index={0} debug={nextDebug} replacers={replacers} slotHandler={slotHandler} adjuster={adjuster}/> |
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 } } = Astro | 5 | const { props: { wrap = false, wrapAttributes = {}, node, replacers, slotHandler, adjuster } } = 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}/> | 18 | <Children parent={node} children={children} replacers={replacers} slotHandler={slotHandler} adjuster={adjuster}/> |
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}/> | 25 | <Children parent={node} children={children} replacers={replacers} slotHandler={slotHandler} adjuster={adjuster}/> |
26 | </CustomName> | 26 | </CustomName> |
27 | ) | 27 | ) |
28 | } | 28 | } | ... | ... |
... | @@ -2,16 +2,17 @@ | ... | @@ -2,16 +2,17 @@ |
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 } } = Astro | 5 | const { props: { parent = null, node, index = 0, debug = 0, replacers, slotHandler, adjuster } } = Astro |
6 | const { name: Name, attributes } = node | 6 | const { name: Name, attributes } = node |
7 | 7 | ||
8 | const fixedNode = adjuster(node, parent, index) | ||
8 | if (debug) { | 9 | if (debug) { |
9 | console.log('trying to match against', {node}) | 10 | console.log('trying to match against', {fixedNode}) |
10 | } | 11 | } |
11 | let slotName | 12 | let slotName |
12 | for (const [ matcher, handler ] of replacers) { | 13 | for (const [ matcher, handler ] of replacers) { |
13 | if (debug) console.log('attempting matcher', matcher.toString()) | 14 | if (debug) console.log('attempting matcher', matcher.toString()) |
14 | if (matcher(node, parent, index, false)) { | 15 | if (matcher(fixedNode, parent, index, false)) { |
15 | if (debug) console.log('matched') | 16 | if (debug) console.log('matched') |
16 | slotName = handler | 17 | slotName = handler |
17 | } | 18 | } |
... | @@ -20,6 +21,6 @@ for (const [ matcher, handler ] of replacers) { | ... | @@ -20,6 +21,6 @@ for (const [ matcher, handler ] of replacers) { |
20 | const nextDebug = debug ? debug - 1 : 0 | 21 | const nextDebug = debug ? debug - 1 : 0 |
21 | --- | 22 | --- |
22 | { | 23 | { |
23 | slotName ? slotHandler(slotName, node) | 24 | slotName ? slotHandler(slotName, fixedNode) |
24 | : <Node parent={parent} node={node} index={index} debug={nextDebug} replacers={replacers} slotHandler={slotHandler}/> | 25 | : <Node parent={parent} node={fixedNode} index={index} debug={nextDebug} replacers={replacers} slotHandler={slotHandler} adjuster={adjuster}/> |
25 | } | 26 | } | ... | ... |
... | @@ -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 } } = Astro | 19 | const { props: { parent = null, node, index = 0, debug = 0, replacers, slotHandler, adjuster } } = Astro |
20 | const { name: Name, attributes } = node | 20 | const { name: Name, attributes } = node |
21 | 21 | ||
22 | if (debug) { | 22 | if (debug) { |
... | @@ -29,9 +29,9 @@ const nextDebug = debug ? debug - 1 : 0 | ... | @@ -29,9 +29,9 @@ const nextDebug = debug ? debug - 1 : 0 |
29 | : node.type === ELEMENT_NODE ? ( | 29 | : node.type === ELEMENT_NODE ? ( |
30 | node.isSelfClosingTag ? <Name {...attributes}/> | 30 | node.isSelfClosingTag ? <Name {...attributes}/> |
31 | : <Name {...attributes}> | 31 | : <Name {...attributes}> |
32 | <Children parent={node} children={node.children} debug={nextDebug} replacers={replacers} slotHandler={slotHandler}/> | 32 | <Children parent={node} children={node.children} debug={nextDebug} replacers={replacers} slotHandler={slotHandler} adjuster={adjuster}/> |
33 | </Name> | 33 | </Name> |
34 | ) : ( | 34 | ) : ( |
35 | <Children parent={node} children={node.children} debug={nextDebug} replacers={replacers} slotHandler={slotHandler}/> | 35 | <Children parent={node} children={node.children} debug={nextDebug} replacers={replacers} slotHandler={slotHandler} adjuster={adjuster}/> |
36 | ) | 36 | ) |
37 | } | 37 | } | ... | ... |
... | @@ -10,18 +10,29 @@ interface Props { | ... | @@ -10,18 +10,29 @@ interface Props { |
10 | debug?: number, | 10 | debug?: number, |
11 | xpath?: string, | 11 | xpath?: string, |
12 | replacements?: Replacements, | 12 | replacements?: Replacements, |
13 | adjustments?: any, | ||
13 | } | 14 | } |
14 | 15 | ||
15 | const { props } = Astro | 16 | const { props } = Astro |
16 | const { html, debug = 0, xpath, replacements = {} } = props | 17 | const { html, debug = 0, xpath, replacements = {}, adjustments = {} } = props |
17 | const doc = props.node ? props.node : parseHtml(props.html) | 18 | const doc = props.node ? props.node : parseHtml(props.html) |
18 | 19 | ||
19 | const node = xpath ? findNode(doc, xpath) : doc | 20 | const node = xpath ? findNode(doc, xpath) : doc |
20 | const replacers = Object.entries(replacements).map(([ selector, handler ]) => [ createMatcher(selector), handler ]) | 21 | const replacers = Object.entries(replacements).map(([ selector, handler ]) => [ createMatcher(selector), handler ]) |
21 | 22 | ||
23 | const adjustmentsCompiled = Object.entries(adjustments).map(([ selector, handler ]) => [ createMatcher(selector), handler ]) | ||
24 | const adjuster = (node, parent, index) => { | ||
25 | for (const [ matcher, handler ] of adjustmentsCompiled) { | ||
26 | if (matcher(node, parent, index, false)) { | ||
27 | node = handler(node) | ||
28 | } | ||
29 | } | ||
30 | return node | ||
31 | } | ||
32 | |||
22 | const slotHandler: SlotHandler = (slotName, node) => { | 33 | const slotHandler: SlotHandler = (slotName, node) => { |
23 | return Astro.slots.render(slotName, [ node, { slotHandler, replacers } ] ) | 34 | return Astro.slots.render(slotName, [ node, { slotHandler, replacers, adjuster } ] ) |
24 | } | 35 | } |
25 | const nextDebug = debug ? debug - 1 : 0 | 36 | const nextDebug = debug ? debug - 1 : 0 |
26 | --- | 37 | --- |
27 | <Match node={node} debug={nextDebug} replacers={replacers} slotHandler={slotHandler}/> | 38 | <Match node={node} debug={nextDebug} replacers={replacers} slotHandler={slotHandler} adjuster={adjuster}/> | ... | ... |
-
Please register or sign in to post a comment