Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
brainfood
/
astro-wt
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
2b0bc0ee
authored
10 months ago
by
Adam Heath
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Many updates, working on adding typescript, and direct node rendering.
1 parent
2faeafaa
master
...
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
95 additions
and
65 deletions
lib/api.ts
lib/astro.ts
lib/children.astro
lib/custom.astro
lib/html.ts
lib/render.astro → lib/match.astro
lib/node.astro
lib/replace.astro
src/layouts/base.astro
lib/api.ts
View file @
2b0bc0e
...
...
@@ -2,7 +2,12 @@ import { configureStore } from '@reduxjs/toolkit'
import
{
createSlice
}
from
'@reduxjs/toolkit'
import
{
createApi
,
fetchBaseQuery
}
from
'@reduxjs/toolkit/query'
import
{
parseHtml
}
from
'./html.js'
import
{
parseHtml
}
from
'./html.ts'
interface
SiteConfig
{
name
:
string
,
baseUrl
:
string
,
}
export
const
configSlice
=
createSlice
({
name
:
'config'
,
...
...
@@ -30,7 +35,7 @@ const siteBaseQuery = async (args, api, options) => {
}
export
const
sitePageSlice
=
createApi
({
reducerPath
:
'
moqui
'
,
reducerPath
:
'
pages
'
,
tagTypes
:
[
'Page'
],
keepUnusedDataFor
:
60
,
refetchOnReconnect
:
true
,
...
...
@@ -65,17 +70,16 @@ export const store = configureStore({
]),
})
export
const
getSitePage
=
async
(
site
,
page
)
=>
{
export
const
getSitePage
=
async
(
site
:
string
,
page
:
string
)
=>
{
const
result
=
await
store
.
dispatch
(
sitePageSlice
.
endpoints
.
getPage
.
initiate
({
site
,
page
}))
if
(
result
.
data
)
result
.
doc
=
parseHtml
(
result
.
data
)
return
result
}
export
const
setSiteConfig
=
(
site
Def
)
=>
{
return
store
.
dispatch
(
configSlice
.
actions
.
setSiteConfig
(
site
Def
))
export
const
setSiteConfig
=
(
site
Config
:
SiteConfig
)
=>
{
return
store
.
dispatch
(
configSlice
.
actions
.
setSiteConfig
(
site
Config
))
}
export
const
getSiteBaseUrl
=
(
name
)
=>
{
export
const
getSiteBaseUrl
=
(
name
:
string
):
string
=>
{
return
configSlice
.
selectors
.
getSiteBaseUrl
(
store
.
getState
(),
name
)
}
...
...
This diff is collapsed.
Click to expand it.
lib/astro.ts
View file @
2b0bc0e
import
Children
from
'./children.astro'
import
Custom
from
'./custom.astro'
import
Render
from
'./render.astro'
import
Match
from
'./match.astro'
import
Node
from
'./node.astro'
import
Replace
from
'./replace.astro'
export
{
Children
,
Custom
,
Render
,
Replace
}
export
{
Children
,
Custom
,
Match
,
Node
,
Replace
}
...
...
This diff is collapsed.
Click to expand it.
lib/children.astro
View file @
2b0bc0e
---
import
Render, { slotPassThrough } from './render
.astro'
import
Match from './match
.astro'
const { props: { debug, parent, children, replacers, slotHandler } } = Astro
const slotCallback = slotPassThrough(Astro)
const { props: { parent, children, debug = false, replacers, slotHandler } } = Astro
//console.log('Children:render', { parent, children, replacers })
---
{
Array.isArray(children) ?
children.map((child, index) => <
Render debug={debug} parent={parent} node={child} index={index
} replacers={replacers} slotHandler={slotHandler}/>)
children.map((child, index) => <
Match parent={parent} node={child} index={index} debug={debug
} replacers={replacers} slotHandler={slotHandler}/>)
: !children ? ''
: <
Render debug={debug} parent={parent} node={children} index={0
} replacers={replacers} slotHandler={slotHandler}/>
: <
Match parent={parent} node={children} index={0} debug={debug
} replacers={replacers} slotHandler={slotHandler}/>
}
...
...
This diff is collapsed.
Click to expand it.
lib/custom.astro
View file @
2b0bc0e
---
import { slotPassThrough } from './render.astro'
import Children from './children.astro'
const { props: { wrap = false, wrapAttributes = {}, node, replacers, slotHandler } } = Astro
const { name: Name, attributes, children } = node
const CustomName = `custom-${Name}`
const slotCallback = slotPassThrough(Astro)
//console.log('Got custom match', node)
---
...
...
This diff is collapsed.
Click to expand it.
lib/html.ts
View file @
2b0bc0e
import
nodeUtil
from
'util'
import
NodeCache
from
'node-cache'
import
type
{
NodeType
}
from
'ultrahtml'
import
{
parse
as
umParse
,
render
as
umRender
,
transform
as
umTransform
,
__unsafeHTML
,
parse
as
ultraParse
,
ELEMENT_NODE
,
TEXT_NODE
,
walkSync
,
}
from
'ultrahtml'
import
type
{
AST
}
from
'parsel-js'
import
{
parse
as
elParse
,
specificity
as
getSpecificity
,
...
...
@@ -19,21 +18,37 @@ import {
import
{
parsedHtmlCache
,
selectorCache
,
findNodeCache
}
from
'./cache.js'
export
const
fixAttributes
=
(
attributes
,
options
=
{
mapClassname
:
true
})
=>
{
const
{
mapClassname
}
=
options
if
(
!
mapClassname
)
return
attributes
const
{
class
:
className
,
...
rest
}
=
attributes
return
{
...
rest
,
className
}
}
export
const
appendClasses
=
(
node
,
extraClasses
)
=>
{
if
(
!
node
.
attributes
.
class
&&
!
extraClasses
)
return
node
const
{
attributes
:
{
class
:
className
,
...
attributes
}
=
{}
}
=
node
return
{
...
node
,
attributes
:
{
...
attributes
,
class
:
`
${
className
?
className
+
' '
:
''
}${
extraClasses
}
`
}
}
}
// TODO: implement a parent/child/element cache
const
filterChildElements
=
(
parent
)
=>
parent
?.
children
?.
filter
(
n
=>
n
.
type
===
ELEMENT_NODE
)
||
[]
const
nthChildPos
=
(
node
,
parent
)
=>
filterChildElements
(
parent
).
findIndex
((
child
)
=>
child
===
node
);
const
makeNthChildPosMatcher
=
(
ast
)
=>
{
type
Matcher
=
(
context
,
node
,
parent
,
i
,
debug
)
=>
boolean
type
AttrValueMatch
=
(
string
)
=>
string
const
makeNthChildPosMatcher
=
(
ast
:
AST
):
Matcher
=>
{
const
{
argument
}
=
ast
const
n
=
Number
(
argument
)
if
(
!
Number
.
isNaN
(
n
))
{
return
(
context
,
node
,
parent
,
i
)
=>
{
return
(
context
,
node
,
parent
,
i
,
debug
)
=>
{
return
i
===
n
}
}
switch
(
argument
)
{
case
'odd'
:
return
(
context
,
node
,
parent
,
i
)
=>
Math
.
abs
(
i
%
2
)
===
1
return
(
context
,
node
,
parent
,
i
,
debug
)
=>
Math
.
abs
(
i
%
2
)
===
1
case
'even'
:
return
(
context
,
node
,
parent
,
i
)
=>
i
%
2
===
0
default
:
{
...
...
@@ -56,7 +71,7 @@ const makeNthChildPosMatcher = (ast) => {
}
}
const
getAttrValueMatch
=
(
value
,
operator
=
'='
,
caseSenstive
)
=>
{
const
getAttrValueMatch
=
(
value
:
string
,
operator
:
string
=
'='
,
caseSenstive
:
boolean
):
AttrValueMatch
=>
{
if
(
value
===
undefined
)
return
(
attrValue
)
=>
attrValue
!==
undefined
const
isCaseInsenstive
=
caseSensitive
===
'i'
if
(
isCaseInsensitive
)
value
=
value
.
toLowerCase
()
...
...
@@ -78,11 +93,11 @@ const getAttrValueMatch = (value, operator = '=', caseSenstive) => {
return
(
attrValue
)
=>
false
}
const
compileMatcher
=
(
ast
,
selector
)
=>
{
const
compileMatcher
=
(
ast
:
AST
,
selector
:
string
):
Matcher
=>
{
let
counter
=
0
const
neededContext
=
[]
const
makeMatcher
=
(
ast
)
=>
{
const
makeMatcher
=
(
ast
:
AST
)
=>
{
//console.log('makeMatcher', ast)
switch
(
ast
.
type
)
{
case
'list'
:
{
...
...
@@ -206,7 +221,7 @@ const compileMatcher = (ast, selector) => {
const
nthChildMatcher
=
makeNthChildPosMatcher
(
ast
)
return
(
context
,
node
,
parent
,
i
,
debug
)
=>
{
const
pos
=
nthChildPos
(
node
,
parent
)
+
1
return
nthChildMatcher
(
context
,
node
,
parent
,
pos
)
return
nthChildMatcher
(
context
,
node
,
parent
,
pos
,
debug
)
}
}
default
:
...
...
@@ -239,25 +254,25 @@ const compileMatcher = (ast, selector) => {
}
}
export
const
createMatcher
=
(
selector
)
=>
{
export
const
createMatcher
=
(
selector
:
string
)
=>
{
const
matcherCreater
=
selectorCache
.
get
(
selector
)
if
(
false
&&
matcher
)
return
matcherCreater
()
if
(
false
&&
matcher
Creater
)
return
matcherCreater
()
const
ast
=
elParse
(
selector
)
//
console.log('createMatcher', nodeUtil.inspect({ selector, ast }, { depth: null, colors: true }))
console
.
log
(
'createMatcher'
,
nodeUtil
.
inspect
({
selector
,
ast
},
{
depth
:
null
,
colors
:
true
}))
const
newMatcherCreater
=
compileMatcher
(
ast
,
selector
)
selectorCache
.
set
(
selector
,
newMatcherCreater
)
return
newMatcherCreater
()
}
export
const
parseHtml
=
(
html
)
=>
{
export
const
parseHtml
=
(
html
:
string
)
=>
{
const
cached
=
parsedHtmlCache
.
get
(
html
)
if
(
cached
)
return
cached
const
doc
=
u
m
Parse
(
html
)
const
doc
=
u
ltra
Parse
(
html
)
parsedHtmlCache
.
set
(
html
,
doc
)
return
doc
}
export
const
findNode
=
(
doc
,
selector
)
=>
{
export
const
findNode
=
(
doc
:
NodeType
,
selector
:
string
)
=>
{
if
(
!
selector
)
return
doc
let
docCache
=
findNodeCache
.
get
(
doc
)
if
(
!
docCache
)
{
...
...
This diff is collapsed.
Click to expand it.
lib/
render
.astro
→
lib/
match
.astro
View file @
2b0bc0e
---
import { ELEMENT_NODE, TEXT_NODE } from 'ultrahtml'
import
Children from './children
.astro'
import
Node from './node
.astro'
export const slotPassThrough = (Astro) => (slotName, node) => {
console.log('calling slot', { slotName, node, Astro })
return Astro.slots.render('default', [ slotName, node ])
}
const { props: { debug = false, parent = null, node, index = 0, replacers, slotHandler } } = Astro
const { props: { parent = null, node, index = 0, debug = false, replacers, slotHandler } } = Astro
const { name: Name, attributes } = node
if (debug) {
...
...
@@ -22,17 +17,8 @@ for (const [ matcher, handler ] of replacers) {
}
}
//const slotCallback = slotPassThrough(Astro)
---
{
slotName ? slotHandler(slotName, node)
: node.type === TEXT_NODE ? <Fragment set:html={node.value}/>
: node.type === ELEMENT_NODE ? (
node.isSelfClosingTag ? <Name {...attributes}/>
: <Name {...attributes}>
<Children parent={node} children={node.children} replacers={replacers} slotHandler={slotHandler}/>
</Name>
) : (
<Children parent={node} children={node.children} replacers={replacers} slotHandler={slotHandler}/>
)
: <Node parent={parent} node={node} index={index} debug={debug} replacers={replacers} slotHandler={slotHandler}/>
}
...
...
This diff is collapsed.
Click to expand it.
lib/node.astro
0 → 100644
View file @
2b0bc0e
---
import { ELEMENT_NODE, TEXT_NODE } from 'ultrahtml'
import Children from './children.astro'
const { props: { parent = null, node, index = 0, debug = false, replacers, slotHandler } } = Astro
const { name: Name, attributes } = node
if (debug) {
console.log('Node.astro:debug', {node})
}
---
{
node.type === TEXT_NODE ? <Fragment set:html={node.value}/>
: node.type === ELEMENT_NODE ? (
node.isSelfClosingTag ? <Name {...attributes}/>
: <Name {...attributes}>
<Children parent={node} children={node.children} debug={debug} replacers={replacers} slotHandler={slotHandler}/>
</Name>
) : (
<Children parent={node} children={node.children} debug={debug} replacers={replacers} slotHandler={slotHandler}/>
)
}
This diff is collapsed.
Click to expand it.
lib/replace.astro
View file @
2b0bc0e
---
import html from '@resources/provider-portal.html?raw'
import { walkSync } from 'ultrahtml'
import { parseHtml, createMatcher, findNode } from './html.
j
s'
import
Render from './render
.astro'
import { parseHtml, createMatcher, findNode } from './html.
t
s'
import
Match from './match
.astro'
const { props } = Astro
const { html,
mapClassname = tru
e, xpath, replacements = {} } = props
const { html,
debug = fals
e, xpath, replacements = {} } = props
const doc = props.node ? props.node : parseHtml(props.html)
const node = xpath ? findNode(doc, xpath) : doc
const replacers = Object.entries(replacements).map(([ selector, handler ]) => [ createMatcher(selector), handler ])
const fixAttributes = ({ attributes }) => {
if (!mapClassname) return attributes
const { class: className, ...rest } = attributes
return { ...rest, className }
}
const slotHandler = (slotName, node) => {
const attributes = fixAttributes(node)
return Astro.slots.render(slotName, [ { ...node, attributes }, { slotHandler, replacers } ] )
return Astro.slots.render(slotName, [ node, { slotHandler, replacers } ] )
}
---
<
Render node={node
} replacers={replacers} slotHandler={slotHandler}/>
<
Match node={node} debug={debug
} replacers={replacers} slotHandler={slotHandler}/>
...
...
This diff is collapsed.
Click to expand it.
src/layouts/base.astro
View file @
2b0bc0e
---
import { getSitePage } from '@lib/api.ts'
import { Replace } from '@lib/astro.ts'
import { appendClasses } from '@lib/html.ts'
import { Node, Replace } from '@lib/astro.ts'
import '@config.ts'
const { data: layoutHtml } = await getSitePage('msd', '/')
const layoutReplacements = {
['body']: 'body',
['.hero-section']: 'content',
['.content-section']: 'DELETE',
['.content-section-4']: 'DELETE',
...
...
@@ -14,7 +16,17 @@ const layoutReplacements = {
//['.navbar.w-nav:nth-of-type(n + 1)']: 'DELETE',
}
---
<Replace
debug={true}
html={layoutHtml} replacements={layoutReplacements}>
<Replace html={layoutHtml} replacements={layoutReplacements}>
<define slot="DELETE">{(node) => ''}</define>
<define slot='content'>{(node) => <slot/>}</define>
<define slot='body'>{(node, context) => <Node {...context} node={appendClasses(node, 'astro')} parent={node.parent}/>}</define>
<define slot='content'>{(node) => <div><slot/></div>}</define>
</Replace>
<style>
.astro {}
a.w-webflow-badge {
display:none;
}
:global(a.w-webflow-badge) {
display:none;
}
</style>
...
...
This diff is collapsed.
Click to expand it.
Please
register
or
sign in
to post a comment