jails-js 6.4.1 → 6.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,14 @@
1
1
  import { uuid, decodeHTML } from './utils'
2
2
 
3
- const templates = {}
4
-
5
3
  const config = {
6
4
  tags: ['{{', '}}']
7
5
  }
8
6
 
7
+ const templates = {}
8
+ const booleanAttrs = /html-(allowfullscreen|async|autofocus|autoplay|checked|controls|default|defer|disabled|formnovalidate|inert|ismap|itemscope|loop|multiple|muted|nomodule|novalidate|open|playsinline|readonly|required|reversed|selected)="(.*?)"/g
9
+ const htmlAttr = /html-([^\s]*?)="(.*?)"/g
10
+ const tagExpr = () => new RegExp(`\\${config.tags[0]}(.+?)\\${config.tags[1]}`, 'g')
11
+
9
12
  export const templateConfig = (newconfig) => {
10
13
  Object.assign( config, newconfig )
11
14
  }
@@ -40,44 +43,36 @@ export const compile = ( html ) => {
40
43
  `)
41
44
  }
42
45
 
43
- const tagElements = ( target, keys, components ) => {
44
- target
45
- .querySelectorAll( keys.toString() )
46
- .forEach((node) => {
47
- const name = node.localName
48
- if( name === 'template' ) {
49
- return tagElements( node.content, keys, components )
50
- }
51
- if( node.getAttribute('html-if') && !node.id ) {
52
- node.id = uuid()
53
- }
54
- if( name in components ) {
55
- node.setAttribute('tplid', uuid())
56
- }
57
- })
58
- }
46
+ const tagElements = (target, keys, components) => {
47
+ const isComponent = key => key in components
48
+ const selector = keys.join(',')
59
49
 
60
- const transformAttributes = ( html ) => {
61
-
62
- const regexTags = new RegExp(`\\${config.tags[0]}(.+?)\\${config.tags[1]}`, 'g')
50
+ target.querySelectorAll(selector).forEach(node => {
51
+ if (node.localName === 'template') {
52
+ tagElements(node.content, keys, components)
53
+ return
54
+ }
55
+ if (node.hasAttribute('html-if') && !node.id) {
56
+ node.id = uuid()
57
+ }
58
+ if (isComponent(node.localName)) {
59
+ node.setAttribute('tplid', uuid())
60
+ }
61
+ })
62
+ }
63
63
 
64
+ const transformAttributes = (html) => {
64
65
  return html
65
66
  .replace(/jails___scope-id/g, '%%_=$scopeid_%%')
66
- .replace(regexTags, '%%_=$1_%%')
67
- // Booleans
68
- // https://meiert.com/en/blog/boolean-attributes-of-html/
69
- .replace(/html-(allowfullscreen|async|autofocus|autoplay|checked|controls|default|defer|disabled|formnovalidate|inert|ismap|itemscope|loop|multiple|muted|nomodule|novalidate|open|playsinline|readonly|required|reversed|selected)=\"(.*?)\"/g, `%%_if(safe(function(){ return $2 })){_%%$1%%_}_%%`)
70
- // The rest
71
- .replace(/html-([^\s]*?)=\"(.*?)\"/g, (all, key, value) => {
72
- if (key === 'key' || key === 'model' || key === 'scopeid' ) {
73
- return all
74
- }
67
+ .replace(tagExpr(), '%%_=$1_%%')
68
+ .replace(booleanAttrs, `%%_if(safe(function(){ return $2 })){_%%$1%%_}_%%`)
69
+ .replace(htmlAttr, (all, key, value) => {
70
+ if (['key', 'model', 'scopeid'].includes(key)) return all
75
71
  if (value) {
76
72
  value = value.replace(/^{|}$/g, '')
77
73
  return `${key}="%%_=safe(function(){ return ${value} })_%%"`
78
- } else {
79
- return all
80
74
  }
75
+ return all
81
76
  })
82
77
  }
83
78
 
@@ -156,32 +151,27 @@ const setTemplates = ( clone, components ) => {
156
151
  }
157
152
 
158
153
  const removeTemplateTagsRecursively = (node) => {
154
+ const walker = document.createTreeWalker(node, NodeFilter.SHOW_ELEMENT, {
155
+ acceptNode: el => el.tagName === 'TEMPLATE' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP
156
+ })
159
157
 
160
- // Get all <template> elements within the node
161
- const templates = node.querySelectorAll('template')
162
-
163
- templates.forEach((template) => {
158
+ const templatesToRemove = []
164
159
 
165
- if( template.getAttribute('html-if') || template.getAttribute('html-inner') ) {
166
- return
160
+ while (walker.nextNode()) {
161
+ const tpl = walker.currentNode
162
+ if (!tpl.hasAttribute('html-if') && !tpl.hasAttribute('html-inner')) {
163
+ templatesToRemove.push(tpl)
167
164
  }
165
+ }
168
166
 
169
- // Process any nested <template> tags within this <template> first
170
- removeTemplateTagsRecursively(template.content)
171
-
172
- // Get the parent of the <template> tag
167
+ for (const template of templatesToRemove) {
173
168
  const parent = template.parentNode
169
+ if (!parent) continue
174
170
 
175
- if (parent) {
176
- // Move all child nodes from the <template>'s content to its parent
177
- const content = template.content
178
- while (content.firstChild) {
179
- parent.insertBefore(content.firstChild, template)
180
- }
181
- // Remove the <template> tag itself
182
- parent.removeChild(template)
183
- }
184
- })
171
+ const frag = document.createDocumentFragment()
172
+ frag.append(...template.content.childNodes)
173
+ parent.replaceChild(frag, template)
174
+ }
185
175
  }
186
176
 
187
177
  const wrap = (open, node, close) => {