@symbo.ls/utils 3.2.3 → 3.14.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.
Files changed (122) hide show
  1. package/LICENSE +25 -12
  2. package/README.md +106 -0
  3. package/array.js +162 -0
  4. package/cache.js +7 -0
  5. package/cdn.js +83 -0
  6. package/component.js +25 -0
  7. package/cookie.js +71 -0
  8. package/{src/detectHeight.js → detectHeight.js} +3 -3
  9. package/dist/cjs/array.js +168 -0
  10. package/dist/cjs/browser.js +0 -2
  11. package/dist/cjs/cache.js +26 -0
  12. package/dist/cjs/cdn.js +85 -0
  13. package/dist/cjs/component.js +45 -0
  14. package/dist/cjs/cookie.js +75 -0
  15. package/dist/cjs/date.js +1 -3
  16. package/dist/cjs/detectHeight.js +4 -6
  17. package/dist/cjs/element.js +136 -0
  18. package/dist/cjs/env.js +43 -0
  19. package/dist/cjs/events.js +39 -0
  20. package/dist/cjs/extends.js +434 -0
  21. package/dist/cjs/fibonacci.js +1 -3
  22. package/dist/cjs/files.js +1 -3
  23. package/dist/cjs/function.js +114 -0
  24. package/dist/cjs/globals.js +30 -0
  25. package/dist/cjs/if.js +48 -0
  26. package/dist/cjs/index.js +38 -425
  27. package/dist/cjs/key.js +38 -0
  28. package/dist/cjs/keys.js +201 -0
  29. package/dist/cjs/load.js +5 -7
  30. package/dist/cjs/log.js +34 -0
  31. package/dist/cjs/metadata.js +310 -0
  32. package/dist/cjs/methods.js +599 -0
  33. package/dist/cjs/node.js +35 -0
  34. package/dist/cjs/object.js +634 -0
  35. package/dist/cjs/projectKeys.js +35 -0
  36. package/dist/cjs/props.js +282 -0
  37. package/dist/cjs/scaling.js +5 -169
  38. package/dist/cjs/scope.js +44 -0
  39. package/dist/cjs/sharedLibraries.js +146 -0
  40. package/dist/cjs/state.js +173 -0
  41. package/dist/cjs/string-extra.js +72 -0
  42. package/dist/cjs/string.js +183 -0
  43. package/dist/cjs/style.js +1 -3
  44. package/dist/cjs/tags.js +220 -0
  45. package/dist/cjs/triggerEvent.js +112 -0
  46. package/dist/cjs/types.js +74 -0
  47. package/dist/cjs/update.js +42 -0
  48. package/dist/esm/array.js +148 -0
  49. package/dist/esm/browser.js +14 -0
  50. package/dist/esm/cache.js +6 -0
  51. package/dist/esm/cdn.js +65 -0
  52. package/dist/esm/component.js +25 -0
  53. package/dist/esm/cookie.js +55 -0
  54. package/dist/esm/date.js +11 -0
  55. package/dist/esm/detectHeight.js +42 -0
  56. package/dist/esm/element.js +116 -0
  57. package/dist/esm/env.js +23 -0
  58. package/dist/esm/events.js +19 -0
  59. package/dist/esm/extends.js +414 -0
  60. package/dist/esm/fibonacci.js +10 -0
  61. package/dist/esm/files.js +4 -0
  62. package/dist/esm/function.js +94 -0
  63. package/dist/esm/globals.js +10 -0
  64. package/dist/esm/if.js +28 -0
  65. package/dist/esm/index.js +37 -0
  66. package/dist/esm/key.js +18 -0
  67. package/dist/esm/keys.js +181 -0
  68. package/dist/esm/load.js +151 -0
  69. package/dist/esm/log.js +14 -0
  70. package/dist/esm/metadata.js +290 -0
  71. package/dist/esm/methods.js +569 -0
  72. package/dist/esm/node.js +15 -0
  73. package/dist/esm/object.js +621 -0
  74. package/dist/esm/projectKeys.js +16 -0
  75. package/dist/esm/props.js +262 -0
  76. package/dist/esm/scaling.js +15 -0
  77. package/dist/esm/scope.js +24 -0
  78. package/dist/esm/sharedLibraries.js +126 -0
  79. package/dist/esm/state.js +163 -0
  80. package/dist/esm/string-extra.js +52 -0
  81. package/dist/esm/string.js +163 -0
  82. package/dist/esm/style.js +20 -0
  83. package/dist/esm/tags.js +200 -0
  84. package/dist/esm/triggerEvent.js +92 -0
  85. package/dist/esm/types.js +54 -0
  86. package/dist/esm/update.js +22 -0
  87. package/dist/iife/index.js +5818 -0
  88. package/element.js +148 -0
  89. package/env.js +15 -0
  90. package/events.js +19 -0
  91. package/extends.js +519 -0
  92. package/function.js +145 -0
  93. package/globals.js +8 -0
  94. package/if.js +30 -0
  95. package/index.js +41 -0
  96. package/key.js +20 -0
  97. package/keys.js +176 -0
  98. package/log.js +12 -0
  99. package/metadata.js +392 -0
  100. package/methods.js +636 -0
  101. package/node.js +37 -0
  102. package/object.js +803 -0
  103. package/package.json +38 -22
  104. package/projectKeys.js +30 -0
  105. package/props.js +327 -0
  106. package/{src/scaling.js → scaling.js} +1 -1
  107. package/scope.js +32 -0
  108. package/sharedLibraries.js +184 -0
  109. package/state.js +203 -0
  110. package/{src/index.js → string-extra.js} +11 -17
  111. package/string.js +206 -0
  112. package/tags.js +176 -0
  113. package/triggerEvent.js +102 -0
  114. package/types.js +55 -0
  115. package/update.js +27 -0
  116. package/dist/cjs/package.json +0 -4
  117. /package/{src/browser.js → browser.js} +0 -0
  118. /package/{src/date.js → date.js} +0 -0
  119. /package/{src/fibonacci.js → fibonacci.js} +0 -0
  120. /package/{src/files.js → files.js} +0 -0
  121. /package/{src/load.js → load.js} +0 -0
  122. /package/{src/style.js → style.js} +0 -0
package/state.js ADDED
@@ -0,0 +1,203 @@
1
+ 'use strict'
2
+
3
+ import { addProtoToArray } from './array.js'
4
+ import { STATE_METHODS } from './keys.js'
5
+ import {
6
+ deepClone,
7
+ deepMerge,
8
+ overwriteDeep,
9
+ overwriteShallow
10
+ } from './object.js'
11
+ import {
12
+ is,
13
+ isObject,
14
+ isObjectLike,
15
+ isString
16
+ } from './types.js'
17
+
18
+ export const checkForStateTypes = element => {
19
+ const { state: orig, props, __ref: ref } = element
20
+ const state = props?.state || orig
21
+ if (is(state)('string', 'number')) {
22
+ ref.__state = state
23
+ return { value: state }
24
+ } else if (state === true) {
25
+ ref.__state = element.key
26
+ return {}
27
+ } else if (state) {
28
+ ref.__hasRootState = true
29
+ return state
30
+ } else {
31
+ return false
32
+ }
33
+ }
34
+
35
+ export const getRootStateInKey = (stateKey, parentState) => {
36
+ if (!stateKey.includes('~/')) return
37
+ const arr = stateKey.split('~/')
38
+ if (arr.length > 1) return parentState.root
39
+ }
40
+
41
+ export const getParentStateInKey = (stateKey, parentState) => {
42
+ if (!stateKey.includes('../')) return
43
+ const arr = stateKey.split('../')
44
+ const arrLength = arr.length - 1
45
+ for (let i = 0; i < arrLength; i++) {
46
+ if (!parentState.parent) return null
47
+ parentState = parentState.parent
48
+ }
49
+ return parentState
50
+ }
51
+
52
+ export const getChildStateInKey = (stateKey, parentState, options = {}) => {
53
+ const arr = isString(stateKey) ? stateKey.split('/') : [stateKey]
54
+ const arrLength = arr.length - 1
55
+ for (let i = 0; i < arrLength; i++) {
56
+ const childKey = arr[i]
57
+ const grandChildKey = arr[i + 1]
58
+
59
+ if (childKey === '__proto__' || grandChildKey === '__proto__') return
60
+
61
+ let childInParent = parentState[childKey]
62
+ if (!childInParent) childInParent = parentState[childKey] = {} // check for array
63
+ if (!childInParent[grandChildKey]) childInParent[grandChildKey] = {} // check for array
64
+
65
+ stateKey = grandChildKey
66
+ parentState = childInParent
67
+ }
68
+ if (options.returnParent) return parentState
69
+ return parentState[stateKey]
70
+ }
71
+
72
+ export const findInheritedState = (element, parent, options = {}) => {
73
+ const ref = element.__ref
74
+ let stateKey = ref.__state
75
+ if (!checkIfInherits(element)) return
76
+
77
+ const rootState = getRootStateInKey(stateKey, parent.state)
78
+ let parentState = parent.state
79
+
80
+ if (rootState) {
81
+ parentState = rootState
82
+ stateKey = stateKey.replaceAll('~/', '')
83
+ } else {
84
+ const findGrandParentState = getParentStateInKey(stateKey, parent.state)
85
+ if (findGrandParentState) {
86
+ parentState = findGrandParentState
87
+ stateKey = stateKey.replaceAll('../', '')
88
+ }
89
+ }
90
+
91
+ if (!parentState) return
92
+ return getChildStateInKey(stateKey, parentState, options)
93
+ }
94
+
95
+ export const createInheritedState = (element, parent) => {
96
+ const ref = element.__ref
97
+ const inheritedState = findInheritedState(element, parent)
98
+ if (inheritedState === undefined) return element.state
99
+
100
+ if (is(inheritedState)('object', 'array')) {
101
+ return deepClone(inheritedState)
102
+ } else if (is(inheritedState)('string', 'number', 'boolean')) {
103
+ ref.__stateType = typeof inheritedState
104
+ return { value: inheritedState }
105
+ }
106
+
107
+ console.warn(ref.__state, 'is not present. Replacing with', {})
108
+ }
109
+
110
+ export const checkIfInherits = element => {
111
+ const { __ref: ref } = element
112
+ const stateKey = ref?.__state
113
+ if (stateKey && is(stateKey)('number', 'string', 'boolean')) return true
114
+ return false
115
+ }
116
+
117
+ export const isState = function (state) {
118
+ if (!isObjectLike(state)) return false
119
+ return Boolean(
120
+ state.update &&
121
+ state.parse &&
122
+ state.clean &&
123
+ state.create &&
124
+ state.parent &&
125
+ state.destroy &&
126
+ state.rootUpdate &&
127
+ state.parentUpdate &&
128
+ state.keys &&
129
+ state.values &&
130
+ state.toggle &&
131
+ state.replace &&
132
+ state.quietUpdate &&
133
+ state.quietReplace &&
134
+ state.add &&
135
+ state.apply &&
136
+ state.applyReplace &&
137
+ state.setByPath &&
138
+ state.setPathCollection &&
139
+ state.removeByPath &&
140
+ state.removePathCollection &&
141
+ state.getByPath &&
142
+ state.applyFunction &&
143
+ state.__element &&
144
+ state.__children
145
+ )
146
+ }
147
+
148
+ export const createNestedObjectByKeyPath = (path, value) => {
149
+ if (!path) {
150
+ return value || {}
151
+ }
152
+ const keys = path.split('/')
153
+ const obj = {}
154
+ let ref = obj
155
+ const lastIdx = keys.length - 1
156
+ for (let i = 0; i <= lastIdx; i++) {
157
+ ref[keys[i]] = i === lastIdx ? value || {} : {}
158
+ ref = ref[keys[i]]
159
+ }
160
+ return obj
161
+ }
162
+
163
+ export const applyDependentState = (element, state) => {
164
+ const { __element } = state
165
+ const origState = __element?.state
166
+ if (!origState) return
167
+ const dependentState = deepClone(origState, STATE_METHODS)
168
+ const newDepends = { [element.key]: dependentState }
169
+
170
+ const __depends = isObject(origState.__depends)
171
+ ? { ...origState.__depends, ...newDepends }
172
+ : newDepends
173
+
174
+ if (Array.isArray(origState)) {
175
+ addProtoToArray(origState, {
176
+ ...Object.getPrototypeOf(origState),
177
+ __depends
178
+ })
179
+ } else {
180
+ Object.setPrototypeOf(origState, {
181
+ ...Object.getPrototypeOf(origState),
182
+ __depends
183
+ })
184
+ }
185
+
186
+ return dependentState
187
+ }
188
+
189
+ export const overwriteState = (state, obj, options = {}) => {
190
+ const { overwrite } = options
191
+ if (!overwrite) return
192
+
193
+ const shallow = overwrite === 'shallow'
194
+ const merge = overwrite === 'merge'
195
+
196
+ if (merge) {
197
+ deepMerge(state, obj, STATE_METHODS)
198
+ return
199
+ }
200
+
201
+ const overwriteFunc = shallow ? overwriteShallow : overwriteDeep
202
+ overwriteFunc(state, obj, STATE_METHODS)
203
+ }
@@ -1,15 +1,8 @@
1
1
  'use strict'
2
2
 
3
- import { isString, isObject, isArray, isNumber } from '@domql/utils'
3
+ import { isString, isObject, isArray, isNumber } from './types.js'
4
4
 
5
- export * from './browser.js'
6
- export * from './scaling.js'
7
- export * from './date.js'
8
- export * from './fibonacci.js'
9
- export * from './load.js'
10
- export * from './files.js'
11
-
12
- export const copyStringToClipboard = async str => {
5
+ export const copyStringToClipboard = async (str) => {
13
6
  try {
14
7
  await navigator.clipboard.writeText(str)
15
8
  } catch (err) {
@@ -17,7 +10,7 @@ export const copyStringToClipboard = async str => {
17
10
  }
18
11
  }
19
12
 
20
- export const copyJavaScriptToClipboard = async jsCode => {
13
+ export const copyJavaScriptToClipboard = async (jsCode) => {
21
14
  try {
22
15
  // Create a Blob for the JavaScript code with the 'text/javascript' MIME type
23
16
  const blob = new Blob([jsCode], { type: 'text/javascript' })
@@ -34,25 +27,26 @@ export const copyJavaScriptToClipboard = async jsCode => {
34
27
  }
35
28
  }
36
29
 
37
- export const removeChars = str => {
30
+ export const removeChars = (str) => {
38
31
  return str.replace(/[^a-zA-Z0-9_]/g, '')
39
32
  }
40
33
 
41
- export const toCamelCase = str => {
34
+ export const toCamelCase = (str) => {
35
+ if (typeof str !== 'string') str = String(str || '')
42
36
  return str
43
37
  .replace(/(?:^\w|[A-Z]|\b\w)/g, function (word, index) {
44
38
  return index === 0 ? word.toLowerCase() : word.toUpperCase()
45
39
  })
46
- .replaceAll(/\s+/g, '')
40
+ .replace(/\s+/g, '')
47
41
  }
48
42
 
49
- export const toTitleCase = str =>
43
+ export const toTitleCase = (str) =>
50
44
  str &&
51
- str.replace(/\w\S*/g, txt => {
45
+ str.replace(/\w\S*/g, (txt) => {
52
46
  return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
53
47
  })
54
48
 
55
- export const toDashCase = val =>
49
+ export const toDashCase = (val) =>
56
50
  val
57
51
  .replace(/[^a-zA-Z0-9]/g, ' ') // Replace non-alphanumeric characters with spaces
58
52
  .trim() // Remove leading and trailing spaces
@@ -67,7 +61,7 @@ export const toDescriptionCase = (str = '') => {
67
61
  return result.charAt(0).toUpperCase() + result.slice(1)
68
62
  }
69
63
 
70
- export const arrayzeValue = val => {
64
+ export const arrayzeValue = (val) => {
71
65
  if (isArray(val)) return val
72
66
  if (isString(val)) return val.split(' ')
73
67
  if (isObject(val)) return Object.values(val)
package/string.js ADDED
@@ -0,0 +1,206 @@
1
+ 'use strict'
2
+
3
+ export const stringIncludesAny = (str, characters) => {
4
+ for (const char of characters) {
5
+ if (str.includes(char)) {
6
+ return true
7
+ }
8
+ }
9
+ return false
10
+ }
11
+
12
+ export const trimStringFromSymbols = (str, characters) => {
13
+ // Create a regular expression pattern to match the specified symbols
14
+ const pattern = new RegExp(`[${characters.join('\\')}]`, 'g')
15
+
16
+ // Replace matched symbols with an empty string
17
+ return str.replace(pattern, '')
18
+ }
19
+
20
+ /**
21
+ * Replaces placeholders in a string with corresponding {{ }} values from an object.
22
+ *
23
+ * @param {string} str - The string containing placeholders to replace.
24
+ * @param {object} state - The object containing the values to substitute.
25
+ * @returns {string} The modified string with placeholders replaced by values from the object.
26
+ */
27
+ const brackRegex = {
28
+ 2: /{{\s*((?:\.\.\/)*)([\w\d.]+)\s*(?:\|\s*([\w\d.]+))?\s*}}/g,
29
+ 3: /{{{(\s*(?:\.\.\/)*)([\w\d.]+)\s*(?:\|\s*([\w\d.]+))?\s*}}}/g
30
+ }
31
+
32
+ const getNestedValue = (obj, path) => {
33
+ return path.split('.').reduce((acc, part) => {
34
+ return acc?.[part]
35
+ }, obj)
36
+ }
37
+
38
+ export function replaceLiteralsWithObjectFields (str, state, options = {}) {
39
+ const { bracketsLength = 2 } = options
40
+ const bracketPattern = bracketsLength === 3 ? '{{{' : '{{'
41
+ if (!str.includes(bracketPattern)) return str
42
+
43
+ const reg = brackRegex[bracketsLength]
44
+ const obj = state || this.state || {}
45
+
46
+ const element = this
47
+
48
+ return str.replace(reg, (_, parentPath, variable, filter) => {
49
+ const key = variable.trim()
50
+
51
+ // Pipe filter: {{ key | filterName }}
52
+ // Always passes the raw key to the filter — the filter is responsible for resolution
53
+ if (filter) {
54
+ const ctx = element?.context
55
+ const filterFn = ctx?.functions?.[filter] || ctx?.utils?.[filter] || ctx?.methods?.[filter] || ctx?.snippets?.[filter] || element?.[filter]
56
+ if (filterFn && typeof filterFn === 'function') {
57
+ try {
58
+ return String(filterFn.call(element, key) ?? '')
59
+ } catch (e) { return '' }
60
+ }
61
+ return ''
62
+ }
63
+
64
+ if (parentPath) {
65
+ const parentLevels = (parentPath.match(/\.\.\//g) || []).length
66
+ let parentState = obj
67
+
68
+ for (let i = 0; i < parentLevels; i++) {
69
+ if (!parentState || !parentState.parent) return ''
70
+ parentState = parentState.parent
71
+ }
72
+
73
+ // If the variable is 'parent', return the value property
74
+ if (key === 'parent') {
75
+ return String(parentState.value ?? '')
76
+ }
77
+
78
+ const value = getNestedValue(parentState, key)
79
+ return String(value ?? '')
80
+ } else {
81
+ // Check state value first
82
+ const value = getNestedValue(obj, key)
83
+ if (value != null) return String(value)
84
+
85
+ // Fall back to polyglot translations for current language
86
+ const poly = element?.context?.polyglot
87
+ if (poly?.translations) {
88
+ const lang = obj?.root?.lang || obj?.lang || element?.context?.state?.lang || poly.defaultLang || 'en'
89
+ const langT = poly.translations[lang]
90
+ if (langT) {
91
+ const tValue = getNestedValue(langT, key)
92
+ if (tValue != null && typeof tValue !== 'object') return String(tValue)
93
+ // Search nested sections (e.g. ka.nav.about for key 'about')
94
+ for (const section in langT) {
95
+ const sectionData = langT[section]
96
+ if (sectionData && typeof sectionData === 'object' && !Array.isArray(sectionData)) {
97
+ const nested = getNestedValue(sectionData, key)
98
+ if (nested != null && typeof nested !== 'object') return String(nested)
99
+ }
100
+ }
101
+ }
102
+ // Check top-level translations
103
+ const topValue = getNestedValue(poly.translations, key)
104
+ if (topValue != null && typeof topValue !== 'object') return String(topValue)
105
+ }
106
+ return ''
107
+ }
108
+ })
109
+ }
110
+
111
+ export const lowercaseFirstLetter = inputString => {
112
+ return `${inputString.charAt(0).toLowerCase()}${inputString.slice(1)}`
113
+ }
114
+
115
+ export const findKeyPosition = (str, key) => {
116
+ const lines = str.split('\n')
117
+ let startLineNumber = -1
118
+ let endLineNumber = -1
119
+ let startColumn = -1
120
+ let endColumn = -1
121
+
122
+ const keyPattern = new RegExp(`\\b${key}\\b\\s*:\\s*`)
123
+ let braceCount = 0
124
+ let foundKey = false
125
+
126
+ for (let i = 0; i < lines.length; i++) {
127
+ if (keyPattern.test(lines[i]) && !foundKey) {
128
+ foundKey = true
129
+ startLineNumber = i + 1
130
+ startColumn = lines[i].indexOf(key) + 1
131
+
132
+ // Check if the value is an empty object
133
+ if (lines[i].includes('{}')) {
134
+ endLineNumber = startLineNumber
135
+ endColumn = lines[i].indexOf('{}') + 3
136
+ break
137
+ }
138
+
139
+ // Check if the value starts with '{' (object) or '[' (array)
140
+ const line = lines[i].slice(startColumn + key.length)
141
+ if (line.includes('{') || line.includes('[')) {
142
+ braceCount = 1
143
+ } else {
144
+ endLineNumber = i + 1
145
+ endColumn = lines[i].length + 1
146
+ break
147
+ }
148
+ } else if (foundKey) {
149
+ braceCount += (lines[i].match(/{/g) || []).length
150
+ braceCount += (lines[i].match(/\[/g) || []).length
151
+ braceCount -= (lines[i].match(/}/g) || []).length
152
+ braceCount -= (lines[i].match(/]/g) || []).length
153
+
154
+ // If braceCount is 0 and we find the end of the object/array
155
+ if (braceCount === 0) {
156
+ endLineNumber = i + 1
157
+ endColumn =
158
+ lines[i].lastIndexOf('}') !== -1
159
+ ? lines[i].lastIndexOf('}') + 2
160
+ : lines[i].length + 1
161
+ break
162
+ }
163
+ }
164
+ }
165
+
166
+ return {
167
+ startColumn,
168
+ endColumn,
169
+ startLineNumber,
170
+ endLineNumber
171
+ }
172
+ }
173
+
174
+ const RE_OCTAL = /\\([0-7]{1,3})/g
175
+
176
+ export const replaceOctalEscapeSequences = str => {
177
+ return str.replace(RE_OCTAL, (_, p1) => String.fromCharCode(parseInt(p1, 8)))
178
+ }
179
+
180
+ export const encodeNewlines = str => {
181
+ return str
182
+ .replace(/\n/g, '/////n')
183
+ .replace(/`/g, '/////tilde')
184
+ .replace(/\$/g, '/////dlrsgn')
185
+ }
186
+
187
+ export const decodeNewlines = encodedStr => {
188
+ return encodedStr
189
+ .replace(/\/\/\/\/\/n/g, '\n')
190
+ .replace(/\/\/\/\/\/tilde/g, '`')
191
+ .replace(/\/\/\/\/\/dlrsgn/g, '$')
192
+ }
193
+
194
+ const RE_NON_ALNUM = /[^a-zA-Z0-9\s]/g
195
+
196
+ export const customEncodeURIComponent = str => {
197
+ return str.replace(RE_NON_ALNUM, char =>
198
+ '%' + char.charCodeAt(0).toString(16).toUpperCase()
199
+ )
200
+ }
201
+
202
+ export const customDecodeURIComponent = encodedStr => {
203
+ return encodedStr.replace(/%[0-9A-Fa-f]{2}/g, match =>
204
+ String.fromCharCode(parseInt(match.slice(1), 16))
205
+ )
206
+ }
package/tags.js ADDED
@@ -0,0 +1,176 @@
1
+ 'use strict'
2
+
3
+ export const HTML_TAGS = {
4
+ root: ['body', 'html'],
5
+
6
+ head: ['title', 'base', 'meta', 'style', 'noscript', 'script'],
7
+
8
+ body: new Set([
9
+ 'string',
10
+ 'style',
11
+ 'fragment',
12
+ 'a',
13
+ 'abbr',
14
+ 'acronym',
15
+ 'address',
16
+ 'applet',
17
+ 'area',
18
+ 'article',
19
+ 'aside',
20
+ 'audio',
21
+ 'b',
22
+ 'basefont',
23
+ 'bdi',
24
+ 'bdo',
25
+ 'big',
26
+ 'blockquote',
27
+ 'br',
28
+ 'button',
29
+ 'canvas',
30
+ 'caption',
31
+ 'center',
32
+ 'cite',
33
+ 'code',
34
+ 'search',
35
+ 'col',
36
+ 'colgroup',
37
+ 'data',
38
+ 'datalist',
39
+ 'dd',
40
+ 'del',
41
+ 'details',
42
+ 'dfn',
43
+ 'dialog',
44
+ 'dir',
45
+ 'div',
46
+ 'dl',
47
+ 'dt',
48
+ 'em',
49
+ 'embed',
50
+ 'fieldset',
51
+ 'figcaption',
52
+ 'figure',
53
+ 'font',
54
+ 'footer',
55
+ 'form',
56
+ 'frame',
57
+ 'frameset',
58
+ 'h1',
59
+ 'h2',
60
+ 'h3',
61
+ 'h4',
62
+ 'h5',
63
+ 'h6',
64
+ 'head',
65
+ 'header',
66
+ 'hr',
67
+ 'i',
68
+ 'iframe',
69
+ 'img',
70
+ 'input',
71
+ 'ins',
72
+ 'kbd',
73
+ 'label',
74
+ 'legend',
75
+ 'li',
76
+ 'link',
77
+ 'main',
78
+ 'map',
79
+ 'mark',
80
+ 'meter',
81
+ 'nav',
82
+ 'noframes',
83
+ 'noscript',
84
+ 'object',
85
+ 'ol',
86
+ 'optgroup',
87
+ 'option',
88
+ 'output',
89
+ 'p',
90
+ 'param',
91
+ 'picture',
92
+ 'pre',
93
+ 'progress',
94
+ 'hgroup',
95
+ 'q',
96
+ 'rp',
97
+ 'rt',
98
+ 'ruby',
99
+ 's',
100
+ 'samp',
101
+ 'script',
102
+ 'section',
103
+ 'select',
104
+ 'small',
105
+ 'source',
106
+ 'span',
107
+ 'strike',
108
+ 'strong',
109
+ 'sub',
110
+ 'summary',
111
+ 'sup',
112
+ 'table',
113
+ 'tbody',
114
+ 'td',
115
+ 'template',
116
+ 'hgroup',
117
+ 'textarea',
118
+ 'tfoot',
119
+ 'th',
120
+ 'thead',
121
+ 'time',
122
+ 'tr',
123
+ 'track',
124
+ 'tt',
125
+ 'u',
126
+ 'ul',
127
+ 'var',
128
+ 'video',
129
+ 'wbr',
130
+
131
+ // SVG
132
+ 'svg',
133
+ 'path',
134
+ 'circle',
135
+ 'ellipse',
136
+ 'line',
137
+ 'polygon',
138
+ 'polyline',
139
+ 'rect',
140
+ 'g',
141
+ 'defs',
142
+ 'symbol',
143
+ 'use',
144
+ 'text',
145
+ 'tspan',
146
+ 'image',
147
+ 'clipPath',
148
+ 'mask',
149
+ 'pattern',
150
+ 'marker',
151
+ 'linearGradient',
152
+ 'radialGradient',
153
+ 'stop',
154
+ 'filter',
155
+ 'feGaussianBlur',
156
+ 'feOffset',
157
+ 'feMerge',
158
+ 'feMergeNode',
159
+ 'feBlend',
160
+ 'feColorMatrix',
161
+ 'feFlood',
162
+ 'feComposite',
163
+ 'foreignObject'
164
+ ])
165
+ }
166
+
167
+ export const SVG_TAGS = new Set([
168
+ 'svg', 'path', 'circle', 'ellipse', 'line', 'polygon', 'polyline',
169
+ 'rect', 'g', 'defs', 'symbol', 'use', 'text', 'tspan', 'image',
170
+ 'clipPath', 'mask', 'pattern', 'marker', 'linearGradient',
171
+ 'radialGradient', 'stop', 'filter', 'feGaussianBlur', 'feOffset',
172
+ 'feMerge', 'feMergeNode', 'feBlend', 'feColorMatrix', 'feFlood',
173
+ 'feComposite', 'foreignObject'
174
+ ])
175
+
176
+ export const isValidHtmlTag = arg => HTML_TAGS.body.has(arg)