domql 1.5.96 → 1.5.98

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.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "domql",
3
3
  "description": "DOM rendering Javascript framework at early stage.",
4
4
  "author": "symbo.ls",
5
- "version": "1.5.96",
5
+ "version": "1.5.98",
6
6
  "repository": "https://github.com/domql/domql",
7
7
  "publishConfig": {
8
8
  "registry": "https://registry.npmjs.org"
@@ -20,7 +20,9 @@ export const transformEmotionStyle = (emotion, live) => {
20
20
  export const transformEmotionClass = (emotion, live) => {
21
21
  return (params, element, state, flag) => {
22
22
  if (element.style && !flag) return
23
- const { __class, __classNames } = element
23
+ const { __ref } = element
24
+ const { __class, __classNames } = __ref
25
+
24
26
  if (!isObjectLike(params)) return
25
27
 
26
28
  for (const key in params) {
@@ -11,12 +11,13 @@ import createProps from './props'
11
11
  import update from './update'
12
12
  import { on } from '../event'
13
13
  import { assignClass } from './mixins/classList'
14
- import { isObject, isFunction, isNumber, isString, createID, isNode, exec } from '../utils'
14
+ import { isObject, isFunction, isString, createID, isNode, exec } from '../utils'
15
15
  import { remove, lookup, setProps, log, keys, parse, parseDeep, spotByPath, nextElement, previousElement, isMethod } from './methods'
16
16
  import cacheNode, { detectTag } from './cache'
17
17
  import { registry } from './mixins'
18
18
  import { throughInitialExec } from './iterate'
19
19
  import OPTIONS from './options'
20
+ import { is } from '@domql/utils'
20
21
  // import { overwrite, clone, fillTheRest } from '../utils'
21
22
 
22
23
  const ENV = process.env.NODE_ENV
@@ -45,165 +46,110 @@ const create = (element, parent, key, options = OPTIONS.create || {}) => {
45
46
  if (isNode(parent)) parent = root[`${key}_parent`] = { key: ':root', node: parent }
46
47
 
47
48
  // if element is STRING
48
- if (isString(element) || isNumber(element)) {
49
- const extendTag = element.extend && element.extend.tag
50
- const childExtendTag = parent.childExtend && parent.childExtend.tag
51
- const isKeyValidHTMLTag = ((nodes.body.indexOf(key) > -1) && key)
52
- element = {
53
- text: element,
54
- tag: extendTag || childExtendTag || isKeyValidHTMLTag || 'string'
55
- }
49
+ if (checkIfPrimitive(element)) {
50
+ element = applyValueAsText(element, parent, key)
56
51
  }
57
52
 
58
53
  // define KEY
59
54
  const assignedKey = (element.key || key || createID()).toString()
60
55
 
61
- const { extend, props, state, childExtend, childProps } = element
62
-
63
- if (isKeyComponent(assignedKey)) {
64
- const hasComponentAttrs = extend || childExtend || props || state || element.on
65
- const componentKey = assignedKey.split('_')[0]
66
- if (!hasComponentAttrs || childProps) {
67
- parent[assignedKey] = element = {
68
- extend: componentKey || assignedKey,
69
- props: { ...element }
70
- }
71
- } else if (!extend || extend === true) {
72
- parent[assignedKey] = element = {
73
- ...element,
74
- extend: componentKey || assignedKey
75
- }
76
- }
56
+ if (checkIfKeyIsComponent(assignedKey)) {
57
+ element = applyKeyComponentAsExtend(element, parent, assignedKey)
77
58
  }
78
59
 
79
60
  // Responsive rendering
80
61
  // TODO: move as define plugin
81
- if (assignedKey.slice(0, 1) === '@') {
82
- if (props) {
83
- props.display = 'none'
84
- if (props[assignedKey]) props[assignedKey].display = props.display
85
- else props[assignedKey] = { display: props.display || 'block' }
86
- } else {
87
- parent[assignedKey] = element = {
88
- ...element,
89
- props: {
90
- display: 'none',
91
- [assignedKey]: { display: 'block' }
92
- }
93
- }
94
- }
62
+ if (checkIfMedia(assignedKey)) {
63
+ element = applyMediaProps(element, parent, assignedKey)
95
64
  }
96
65
 
66
+ const __ref = element.__ref = { origin: element } // eslint-disable-line
67
+
97
68
  // assign context
98
- if (options.context && !root.context && !element.context) root.context = options.context
99
- if (!element.context) element.context = parent.context || options.context || root.context
69
+ applyContext(element, parent, options)
100
70
  const { context } = element
101
71
 
102
- if (context && context.components) {
103
- const { components } = context
104
- const { extend } = element
105
- const execExtend = exec(extend, element)
106
- if (isString(execExtend)) {
107
- if (components[execExtend]) element.extend = components[execExtend]
108
- else {
109
- if ((ENV === 'test' || ENV === 'development') && options.verbose) {
110
- console.warn(execExtend, 'is not in library', components, element)
111
- console.warn('replacing with ', {})
112
- }
113
- element.extend = {}
114
- }
115
- }
116
- }
72
+ if (context && context.components) applyComponentFromContext(element, parent, options)
73
+
74
+ // create EXTEND inheritance
75
+ applyExtend(element, parent, options)
76
+
77
+ // create and assign a KEY
78
+ element.key = assignedKey
117
79
 
118
80
  // Only resolve extends, skip everything else
119
- if (options.onlyResolveExtends) {
120
- applyExtend(element, parent, options)
121
- element.key = assignedKey
122
- element.tag = detectTag(element)
123
-
124
- if (!element.__exec) element.__exec = {}
125
- if (!element.__attr) element.__attr = {}
126
- if (!element.__ifFalsy) createProps(element, parent)
127
- element.state = createState(element, parent, { skip: true })
128
-
129
- throughInitialExec(element)
130
-
131
- for (const param in element) {
132
- const prop = element[param]
133
- if (isMethod(param) || isObject(registry[param]) || prop === undefined) continue
134
-
135
- const hasDefined = element.define && element.define[param]
136
- const ourParam = registry[param]
137
- const hasOptionsDefine = options.define && options.define[param]
138
- if (ourParam && !hasOptionsDefine) {
139
- continue // if (isFunction(ourParam)) ourParam(prop, element, element.node, options)
140
- } else if (element[param] && !hasDefined && !hasOptionsDefine) {
141
- create(exec(prop, element), element, param, options)
142
- }
143
- }
81
+ if (options.onlyResolveExtends) return resolveExtends(element, parent, options)
144
82
 
145
- // createNode(element, options)
83
+ if (Object.keys(options).length) {
84
+ registry.defaultOptions = options
85
+ if (options.ignoreChildExtend) delete options.ignoreChildExtend
86
+ }
146
87
 
147
- delete element.parent
148
- delete element.update
149
- delete element.__element
88
+ addCaching(element, parent)
150
89
 
151
- // added by createProps
152
- delete element.__props
153
- delete element.props.__element
154
- delete element.props.update
90
+ addMethods(element, parent)
155
91
 
156
- // added by createState
157
- delete element.state.__element
158
- delete element.state.__element
159
- delete element.__hasRootState
92
+ // enable STATE
93
+ element.state = createState(element, parent)
160
94
 
161
- return element
95
+ // don't render IF in condition
96
+ checkIf(element, parent)
97
+
98
+ // if it already HAS a NODE
99
+ if (element.node && __ref.__if) { // TODO: check on if
100
+ return assignNode(element, parent, assignedKey)
162
101
  }
163
102
 
164
- // create EXTEND inheritance
165
- applyExtend(element, parent, options)
103
+ // apply props settings
104
+ if (__ref.__if) createProps(element, parent)
166
105
 
167
- if (Object.keys(options).length) {
168
- registry.defaultOptions = options
169
- if (options.ignoreChildExtend) delete options.ignoreChildExtend
106
+ // run `on.init`
107
+ if (element.on && isFunction(element.on.init)) {
108
+ on.init(element.on.init, element, element.state)
170
109
  }
171
110
 
172
- // create and assign a KEY
173
- element.key = assignedKey
111
+ // run `on.beforeClassAssign`
112
+ if (element.on && isFunction(element.on.beforeClassAssign)) {
113
+ on.beforeClassAssign(element.on.beforeClassAssign, element, element.state)
114
+ }
174
115
 
175
- // enable TRANSFORM in data
176
- if (!element.transform) element.transform = {}
116
+ // generate a CLASS name
117
+ assignClass(element)
177
118
 
178
- // enable CACHING
179
- if (!element.__cached) element.__cached = {}
119
+ // CREATE a real NODE
120
+ createNode(element, options)
180
121
 
181
- // enable EXEC
182
- if (!element.__exec) element.__exec = {}
122
+ if (!__ref.__if) return element
183
123
 
184
- // enable CLASS CACHING
185
- if (!element.__class) element.__class = {}
186
- if (!element.__classNames) element.__classNames = {}
124
+ // assign NODE
125
+ assignNode(element, parent, key)
187
126
 
188
- // enable CLASS CACHING
189
- if (!element.__attr) element.__attr = {}
127
+ // run `on.render`
128
+ if (element.on && isFunction(element.on.render)) {
129
+ on.render(element.on.render, element, element.state)
130
+ }
190
131
 
191
- // enable CHANGES storing
192
- if (!element.__changes) element.__changes = []
132
+ if (parent.__ref && parent.__ref.__children) parent.__ref.__children.push(element.key)
133
+ // console.groupEnd(element.key)
193
134
 
194
- // enable CHANGES storing
195
- if (!element.__children) element.__children = []
135
+ return element
136
+ }
196
137
 
197
- // Add _root element property
198
- const hasRoot = parent && parent.key === ':root'
199
- if (!element.__root) element.__root = hasRoot ? element : parent.__root
138
+ const checkIfPrimitive = (element) => {
139
+ return is(element)('string', 'number')
140
+ }
200
141
 
201
- // set the PATH array
202
- if (ENV === 'test' || ENV === 'development') {
203
- if (!parent.path) parent.path = []
204
- element.path = parent.path.concat(assignedKey)
142
+ const applyValueAsText = (element, parent, key) => {
143
+ const extendTag = element.extend && element.extend.tag
144
+ const childExtendTag = parent.childExtend && parent.childExtend.tag
145
+ const isKeyValidHTMLTag = ((nodes.body.indexOf(key) > -1) && key)
146
+ return {
147
+ text: element,
148
+ tag: extendTag || childExtendTag || isKeyValidHTMLTag || 'string'
205
149
  }
150
+ }
206
151
 
152
+ const addMethods = (element, parent) => {
207
153
  // assign METHODS
208
154
  element.set = set
209
155
  element.update = update
@@ -220,61 +166,109 @@ const create = (element, parent, key, options = OPTIONS.create || {}) => {
220
166
  if (ENV === 'test' || ENV === 'development') {
221
167
  element.log = log
222
168
  }
169
+ }
223
170
 
224
- // enable STATE
225
- element.state = createState(element, parent)
171
+ const applyContext = (element, parent, options) => {
172
+ if (options.context && !root.context && !element.context) root.context = options.context
173
+ if (!element.context) element.context = parent.context || options.context || root.context
174
+ }
175
+
176
+ const checkIf = (element, parent) => {
177
+ const { __ref } = element
226
178
 
227
- // don't render IF in condition
228
179
  if (isFunction(element.if)) {
229
180
  // TODO: move as fragment
230
- if (!element.if(element, element.state)) {
181
+ const ifPassed = element.if(element, element.state)
182
+ if (!ifPassed) {
231
183
  const ifFragment = cacheNode({ tag: 'fragment' })
232
- element.__ifFragment = appendNode(ifFragment, parent.node)
233
- element.__ifFalsy = true
234
- }
235
- }
184
+ __ref.__ifFragment = appendNode(ifFragment, parent.node)
185
+ delete __ref.__if
186
+ } else __ref.__if = true
187
+ } else __ref.__if = true
188
+ }
236
189
 
237
- // if it already HAS a NODE
238
- if (element.node && !element.__ifFalsy) { // TODO: check on if
239
- return assignNode(element, parent, assignedKey)
240
- }
190
+ const addCaching = (element, parent) => {
191
+ const { __ref } = element
241
192
 
242
- // apply props settings
243
- if (!element.__ifFalsy) createProps(element, parent)
193
+ // enable TRANSFORM in data
194
+ if (!element.transform) element.transform = {}
244
195
 
245
- // run `on.init`
246
- if (element.on && isFunction(element.on.init)) {
247
- on.init(element.on.init, element, element.state)
248
- }
196
+ // enable CACHING
197
+ if (!__ref.__cached) __ref.__cached = {}
249
198
 
250
- // run `on.beforeClassAssign`
251
- if (element.on && isFunction(element.on.beforeClassAssign)) {
252
- on.beforeClassAssign(element.on.beforeClassAssign, element, element.state)
199
+ // enable EXEC
200
+ if (!__ref.__exec) __ref.__exec = {}
201
+
202
+ // enable CLASS CACHING
203
+ if (!__ref.__class) __ref.__class = {}
204
+ if (!__ref.__classNames) __ref.__classNames = {}
205
+
206
+ // enable CLASS CACHING
207
+ if (!__ref.__attr) __ref.__attr = {}
208
+
209
+ // enable CHANGES storing
210
+ if (!__ref.__changes) __ref.__changes = []
211
+
212
+ // enable CHANGES storing
213
+ if (!__ref.__children) __ref.__children = []
214
+
215
+ // Add _root element property
216
+ const hasRoot = parent && parent.key === ':root'
217
+ if (!element.__root) element.__root = hasRoot ? element : parent.__root
218
+
219
+ // set the PATH array
220
+ if (ENV === 'test' || ENV === 'development') {
221
+ if (!parent.path) parent.path = []
222
+ element.path = parent.path.concat(element.key)
253
223
  }
224
+ }
254
225
 
255
- // generate a CLASS name
256
- assignClass(element)
226
+ const resolveExtends = (element, parent, options) => {
227
+ const { __ref } = element
228
+ element.tag = detectTag(element)
257
229
 
258
- // CREATE a real NODE
259
- createNode(element, options)
230
+ if (!__ref.__exec) __ref.__exec = {}
231
+ if (!__ref.__attr) __ref.__attr = {}
232
+ if (__ref.__if) createProps(element, parent)
233
+ element.state = createState(element, parent, { skip: true })
260
234
 
261
- if (element.__ifFalsy) return element
235
+ throughInitialExec(element)
262
236
 
263
- // assign NODE
264
- assignNode(element, parent, key)
237
+ for (const param in element) {
238
+ const prop = element[param]
239
+ if (isMethod(param) || isObject(registry[param]) || prop === undefined) continue
265
240
 
266
- // run `on.render`
267
- if (element.on && isFunction(element.on.render)) {
268
- on.render(element.on.render, element, element.state)
241
+ const hasDefined = element.define && element.define[param]
242
+ const ourParam = registry[param]
243
+ const hasOptionsDefine = options.define && options.define[param]
244
+ if (ourParam && !hasOptionsDefine) {
245
+ continue // if (isFunction(ourParam)) ourParam(prop, element, element.node, options)
246
+ } else if (element[param] && !hasDefined && !hasOptionsDefine) {
247
+ create(exec(prop, element), element, param, options)
248
+ }
269
249
  }
270
250
 
271
- if (parent.__children) parent.__children.push(element.key)
272
- // console.groupEnd(element.key)
251
+ // createNode(element, options)
252
+
253
+ delete element.parent
254
+ delete element.update
255
+ delete element.__element
256
+
257
+ // added by createProps
258
+ delete element.__props // TODO: check with NikaOto and remove
259
+ delete element.props.__element
260
+ delete element.props.update
261
+
262
+ // added by createState
263
+ delete element.state.__element
264
+ delete element.state.__element
265
+ delete element.__hasRootState // TODO: check with NikaOto and remove
266
+ delete element.__ref
273
267
 
274
268
  return element
275
269
  }
276
270
 
277
- export const isKeyComponent = (key) => {
271
+ const checkIfKeyIsComponent = (key) => {
278
272
  const isFirstKeyString = isString(key)
279
273
  if (!isFirstKeyString) return
280
274
 
@@ -283,4 +277,62 @@ export const isKeyComponent = (key) => {
283
277
  return /^[A-Z]*$/.test(firstCharKey)
284
278
  }
285
279
 
280
+ const extendizeByKey = (element, parent, key) => {
281
+ const { extend, props, state, childExtend, childProps } = element
282
+ const hasComponentAttrs = extend || childExtend || props || state || element.on
283
+ const componentKey = key.split('_')[0]
284
+ if (!hasComponentAttrs || childProps) {
285
+ return {
286
+ extend: componentKey || key,
287
+ props: { ...element }
288
+ }
289
+ } else if (!extend || extend === true) {
290
+ return {
291
+ ...element,
292
+ extend: componentKey || key
293
+ }
294
+ }
295
+ }
296
+
297
+ const applyKeyComponentAsExtend = (element, parent, key) => {
298
+ return extendizeByKey(element, parent, key) || element
299
+ }
300
+
301
+ const applyComponentFromContext = (element, parent, options) => {
302
+ const { context } = element
303
+ const { components } = context
304
+ const { extend } = element
305
+ const execExtend = exec(extend, element)
306
+ if (isString(execExtend)) {
307
+ if (components[execExtend]) element.extend = components[execExtend]
308
+ else {
309
+ if ((ENV === 'test' || ENV === 'development') && options.verbose) {
310
+ console.warn(execExtend, 'is not in library', components, element)
311
+ console.warn('replacing with ', {})
312
+ }
313
+ element.extend = {}
314
+ }
315
+ }
316
+ }
317
+
318
+ const checkIfMedia = (key) => key.slice(0, 1) === '@'
319
+
320
+ const applyMediaProps = (element, parent, key) => {
321
+ const { props } = element
322
+ if (props) {
323
+ props.display = 'none'
324
+ if (props[key]) props[key].display = props.display
325
+ else props[key] = { display: props.display || 'block' }
326
+ return element
327
+ } else {
328
+ return {
329
+ ...element,
330
+ props: {
331
+ display: 'none',
332
+ [key]: { display: 'block' }
333
+ }
334
+ }
335
+ }
336
+ }
337
+
286
338
  export default create
@@ -11,7 +11,7 @@ const ENV = process.env.NODE_ENV
11
11
  export const applyExtend = (element, parent, options = {}) => {
12
12
  if (isFunction(element)) element = exec(element, parent)
13
13
 
14
- let { extend, props, context } = element
14
+ let { extend, props, context, __ref } = element
15
15
  const COMPONENTS = (context && context.components) || options.components
16
16
 
17
17
  if (isString(extend)) extend = COMPONENTS[extend]
@@ -53,7 +53,7 @@ export const applyExtend = (element, parent, options = {}) => {
53
53
  stack = [].concat(stack, defaultOptionsExtend)
54
54
  }
55
55
 
56
- element.__extend = stack
56
+ __ref.__extend = stack
57
57
  let mergedExtend = cloneAndMergeArrayExtend(stack)
58
58
 
59
59
  const component = exec(element.component || mergedExtend.component, element)
@@ -22,17 +22,20 @@ export const applyEvents = element => {
22
22
  }
23
23
 
24
24
  export const throughInitialExec = element => {
25
+ const { __ref } = element
26
+ const { __exec } = __ref
25
27
  for (const param in element) {
26
28
  const prop = element[param]
27
29
  if (isFunction(prop) && !isMethod(param)) {
28
- element.__exec[param] = prop
30
+ __exec[param] = prop
29
31
  element[param] = prop(element, element.state)
30
32
  }
31
33
  }
32
34
  }
33
35
 
34
36
  export const throughUpdatedExec = (element, options) => {
35
- const { __exec } = element
37
+ const { __ref } = element
38
+ const { __exec, __cached } = __ref
36
39
  const changes = {}
37
40
 
38
41
  for (const param in __exec) {
@@ -43,7 +46,7 @@ export const throughUpdatedExec = (element, options) => {
43
46
  if (prop && prop.node && (isString(newExec) || isNumber(newExec))) {
44
47
  overwrite(prop, { text: newExec }, options)
45
48
  } else if (newExec !== prop) {
46
- element.__cached[param] = changes[param] = prop
49
+ __cached[param] = changes[param] = prop
47
50
  element[param] = newExec
48
51
  }
49
52
  }
@@ -52,7 +55,8 @@ export const throughUpdatedExec = (element, options) => {
52
55
  }
53
56
 
54
57
  export const throughInitialDefine = (element) => {
55
- const { define, context } = element
58
+ const { define, context, __ref } = element
59
+ const { __exec, __cached } = __ref
56
60
 
57
61
  let obj = {}
58
62
  if (isObject(define)) obj = { ...define }
@@ -62,18 +66,19 @@ export const throughInitialDefine = (element) => {
62
66
  let prop = element[param]
63
67
 
64
68
  if (isFunction(prop) && !isMethod(param)) {
65
- element.__exec[param] = prop
69
+ __exec[param] = prop
66
70
  element[param] = prop = exec(prop, element)
67
71
  }
68
72
 
69
- element.__cached[param] = prop
73
+ __cached[param] = prop
70
74
  element[param] = obj[param](prop, element, element.state)
71
75
  }
72
76
  return element
73
77
  }
74
78
 
75
79
  export const throughUpdatedDefine = (element) => {
76
- const { context, define, __exec } = element
80
+ const { context, define, __ref } = element
81
+ const { __exec, __cached } = __ref
77
82
  const changes = {}
78
83
 
79
84
  let obj = {}
@@ -82,8 +87,8 @@ export const throughUpdatedDefine = (element) => {
82
87
 
83
88
  for (const param in obj) {
84
89
  const execParam = __exec[param]
85
- if (execParam) element.__cached[param] = execParam(element, element.state)
86
- const cached = exec(element.__cached[param], element)
90
+ if (execParam) __cached[param] = execParam(element, element.state)
91
+ const cached = exec(__cached[param], element)
87
92
  element[param] = obj[param](cached, element, element.state)
88
93
  }
89
94
  return changes
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  import { isFunction, isObjectLike } from '../utils'
4
- import { registry, parseFilters } from './mixins'
4
+ import { parseFilters, registry } from './mixins'
5
5
  import root from './root'
6
6
 
7
7
  const ENV = process.env.NODE_ENV
@@ -130,7 +130,7 @@ export const isMethod = function (param) {
130
130
  export const nextElement = function () {
131
131
  const element = this
132
132
  const { key, parent } = element
133
- const { __children } = parent
133
+ const { __children } = parent.__ref
134
134
 
135
135
  const currentIndex = __children.indexOf(key)
136
136
  const nextChild = __children[currentIndex + 1]
@@ -142,7 +142,7 @@ export const nextElement = function () {
142
142
  export const previousElement = function (el) {
143
143
  const element = el || this
144
144
  const { key, parent } = element
145
- const { __children } = parent
145
+ const { __children } = parent.__ref
146
146
 
147
147
  if (!__children) return
148
148
 
@@ -7,7 +7,8 @@ import { exec, report } from '../../utils'
7
7
  * Recursively add attributes to a DOM node
8
8
  */
9
9
  export default (params, element, node) => {
10
- const { __attr } = element
10
+ const { __ref } = element
11
+ const { __attr } = __ref
11
12
  if (isNot('object')) report('HTMLInvalidAttr', params)
12
13
  if (params) {
13
14
  for (const attr in params) {
@@ -9,6 +9,7 @@ import set from '../set'
9
9
  export default (param, element, node, options) => {
10
10
  if (param && element) {
11
11
  if (param.__hash === element.content.__hash && element.content.update) {
12
+ if (!element.content.__ref) element.content.__ref = {}
12
13
  element.content.update(param)
13
14
  } else {
14
15
  set.call(element, param, options)
@@ -8,12 +8,13 @@ import { exec } from '../../utils'
8
8
  */
9
9
  export default (param, element, node) => {
10
10
  const prop = exec(param, element)
11
- if (prop !== element.__html) {
11
+ const { __ref } = element
12
+ if (prop !== __ref.__html) {
12
13
  // const parser = new window.DOMParser()
13
14
  // param = parser.parseFromString(param, 'text/html')
14
15
  if (node.nodeName === 'SVG') node.textContent = prop
15
16
  else node.innerHTML = prop
16
17
 
17
- element.__html = prop
18
+ __ref.__html = prop
18
19
  }
19
20
  }
@@ -1,14 +1,9 @@
1
1
  'use strict'
2
2
 
3
3
  import {
4
- attr,
5
- style,
6
- text,
7
- html,
8
- content,
9
- data,
10
- classList,
11
- state
4
+ attr, classList, content,
5
+ data, html, state, style,
6
+ text
12
7
  } from '.'
13
8
 
14
9
  export default {
@@ -29,30 +24,10 @@ export default {
29
24
  if: {},
30
25
  define: {},
31
26
  transform: {},
27
+ __ref: {},
32
28
  __hash: {},
33
- __componentKey: {},
34
- __cached: {},
35
- __defined: {},
36
- __exec: {},
37
- __changes: {},
38
- __trash: {},
39
29
  __root: {},
40
- __props: {},
41
- __extend: {},
42
- __ifFragment: {},
43
- __children: {},
44
- __ifFalsy: {},
45
30
  __text: {},
46
- __element: {},
47
- __html: {},
48
- __class: {},
49
- __className: {},
50
- __classNames: {},
51
- __attr: {},
52
- __state: {},
53
- __stateType: {},
54
- __currentSnapshot: {},
55
- __hasRootState: {},
56
31
  nextElement: {},
57
32
  previousElement: {},
58
33
  key: {},
@@ -81,7 +56,7 @@ export default {
81
56
  export const parseFilters = {
82
57
  elementKeys: [
83
58
  'tag', 'text', 'style', 'attr', 'class', 'state', 'class',
84
- 'data', 'content', 'html'
59
+ 'data', 'content', 'html', 'on'
85
60
  // TODO: 'props' ?
86
61
  ],
87
62
  propsKeys: ['__element'],
@@ -30,14 +30,14 @@ const ENV = process.env.NODE_ENV
30
30
 
31
31
  export const createNode = (element, options) => {
32
32
  // create and assign a node
33
- let { node, tag, context } = element
33
+ let { node, tag, context, __ref } = element
34
34
 
35
35
  let isNewNode
36
36
 
37
37
  if (!node) {
38
38
  isNewNode = true
39
39
 
40
- if (element.__ifFalsy) return element
40
+ if (!__ref.__if) return element
41
41
 
42
42
  if (tag === 'shadow') {
43
43
  node = element.node = element.parent.node.attachShadow({ mode: 'open' })
@@ -56,7 +56,7 @@ export const createNode = (element, options) => {
56
56
  if (isFunction(node.setAttribute)) node.setAttribute('key', element.key)
57
57
  }
58
58
 
59
- if (element.__ifFalsy) return element
59
+ if (!__ref.__if) return element
60
60
 
61
61
  // iterate through all given params
62
62
  if (element.tag !== 'string' || element.tag !== 'fragment') {
@@ -2,9 +2,9 @@
2
2
 
3
3
  import { deepClone, deepMerge, exec, isArray, isObject, isString } from '../utils'
4
4
 
5
- const initProps = (element, parent) => {
6
- const { props } = element
7
- const propsStack = []
5
+ const createPropsStack = (element, parent) => {
6
+ const { props, __ref } = element
7
+ const propsStack = __ref.propsStack = []
8
8
 
9
9
  const isMatch = isString(props) && props.indexOf('match') > -1
10
10
  const matchParent = parent.props && parent.props[element.key]
@@ -41,8 +41,8 @@ const initProps = (element, parent) => {
41
41
  propsStack.push(matchParentValue)
42
42
  } else if (props) propsStack.push(props)
43
43
 
44
- if (isArray(element.__extend)) {
45
- element.__extend.map(extend => {
44
+ if (isArray(__ref.__extend)) {
45
+ __ref.__extend.map(extend => {
46
46
  if (extend.props) propsStack.push(extend.props)
47
47
  return extend.props
48
48
  })
@@ -69,10 +69,11 @@ export const syncProps = (props, element) => {
69
69
  }
70
70
 
71
71
  const createProps = function (element, parent, cached) {
72
- const propsStack = cached || initProps(element, parent)
72
+ const propsStack = cached || createPropsStack(element, parent)
73
+ const { __ref } = element
73
74
 
74
75
  if (propsStack.length) {
75
- element.__props = propsStack
76
+ __ref.__props = propsStack
76
77
  syncProps(propsStack, element)
77
78
  element.props.update = update
78
79
  } else inheritProps(element, parent)
@@ -81,9 +82,10 @@ const createProps = function (element, parent, cached) {
81
82
  }
82
83
 
83
84
  export const updateProps = (newProps, element, parent) => {
84
- let propsStack = element.__props
85
+ const { __ref } = element
86
+ let propsStack = __ref.__props
85
87
 
86
- if (newProps) propsStack = element.__props = [].concat(newProps, propsStack)
88
+ if (newProps) propsStack = __ref.__props = [].concat(newProps, propsStack)
87
89
 
88
90
  if (propsStack) syncProps(propsStack, element)
89
91
  else inheritProps(element, parent)
@@ -7,13 +7,15 @@ import OPTIONS from './options'
7
7
 
8
8
  export const removeContentElement = function (el) {
9
9
  const element = el || this
10
+ const { __ref } = element
11
+
10
12
  if (element.content) {
11
13
  if (element.content.node) {
12
14
  if (element.content.tag === 'fragment') element.node.innerHTML = ''
13
15
  else element.node.removeChild(element.content.node)
14
16
  }
15
17
 
16
- const { __cached } = element
18
+ const { __cached } = __ref
17
19
  if (__cached && __cached.content) {
18
20
  if (__cached.content.tag === 'fragment') __cached.content.parent.node.innerHTML = ''
19
21
  else if (__cached.content && isFunction(__cached.content.remove)) __cached.content.remove()
@@ -25,10 +27,11 @@ export const removeContentElement = function (el) {
25
27
 
26
28
  const set = function (params, options = {}, el) {
27
29
  const element = el || this
30
+ const __contentRef = element.content && element.content.__ref
28
31
 
29
32
  const isEqual = isEqualDeep(params, element.content)
30
33
  // console.error(params)
31
- if (isEqual && element.content.__cached) return element
34
+ if (isEqual && __contentRef && __contentRef.__cached) return element
32
35
  removeContentElement(element)
33
36
 
34
37
  if (params) {
@@ -5,15 +5,9 @@ import { deepClone, exec, overwriteShallow, overwriteDeep } from '../utils'
5
5
  import { is, isObject, isFunction, isUndefined } from '@domql/utils'
6
6
 
7
7
  export const IGNORE_STATE_PARAMS = [
8
- <<<<<<< HEAD
9
- 'update', 'parse', 'clean', 'create', 'parent', '__element', '__depends',
10
- '__ref', '__root', '__components', '__extend', '__cached', '__projectSystem',
11
- '__projectState', '__projectComponents', '__projectPages', '__projectFiddles',
12
- =======
13
8
  'update', 'parse', 'clean', 'create', 'parent', '__element', '__depends', '__ref', '__root',
14
- '__components', '__extend', '__cached',
9
+ '__components',
15
10
  '__projectSystem', '__projectState', '__projectComponents', '__projectPages', '__projectSnippets',
16
- >>>>>>> 5e4dd98 (fiddle > snippets)
17
11
  'projectStateUpdate', 'projectSystemUpdate'
18
12
  ]
19
13
 
@@ -57,6 +51,7 @@ export const projectStateUpdate = function (obj, options = {}) {
57
51
  export const updateState = function (obj, options = {}) {
58
52
  const state = this
59
53
  const element = state.__element
54
+ const __elementRef = element.__ref
60
55
  state.parent = element.parent.state
61
56
 
62
57
  if (!state.__element) createState(element, element.parent)
@@ -67,13 +62,13 @@ export const updateState = function (obj, options = {}) {
67
62
  if (initReturns === false) return
68
63
  }
69
64
 
70
- const stateKey = element.__state
65
+ const stateKey = __elementRef.__state
71
66
  if (stateKey) {
72
67
  // TODO: check for double parent
73
68
  if (state.parent && state.parent[stateKey]) {
74
69
  const keyInParentState = state.parent[stateKey]
75
70
  if (keyInParentState && !options.stopStatePropogation) {
76
- if (element.__stateType === 'string') {
71
+ if (__elementRef.__stateType === 'string') {
77
72
  return state.parent.update({ [stateKey]: obj.value }, options)
78
73
  }
79
74
  return state.parent.update({ [stateKey]: obj }, options)
@@ -105,16 +100,16 @@ export const updateState = function (obj, options = {}) {
105
100
  export const createState = function (element, parent, opts) {
106
101
  const skip = (opts && opts.skip) ? opts.skip : false
107
102
 
108
- let { state, __root } = element
103
+ let { state, __root, __ref: __elementRef } = element
109
104
 
110
105
  if (isFunction(state)) state = exec(state, element)
111
106
 
112
107
  if (is(state)('string', 'number')) {
113
- element.__state = state
108
+ __elementRef.__state = state
114
109
  state = {}
115
110
  }
116
111
  if (state === true) {
117
- element.__state = element.key
112
+ __elementRef.__state = element.key
118
113
  state = {}
119
114
  }
120
115
 
@@ -122,7 +117,7 @@ export const createState = function (element, parent, opts) {
122
117
  if (parent && parent.state) return parent.state
123
118
  return {}
124
119
  } else {
125
- element.__hasRootState = true
120
+ __elementRef.__hasRootState = true
126
121
  }
127
122
 
128
123
  // run `on.init`
@@ -130,7 +125,7 @@ export const createState = function (element, parent, opts) {
130
125
  on.stateInit(element.on.stateInit, element, element.state)
131
126
  }
132
127
 
133
- let stateKey = element.__state
128
+ let stateKey = __elementRef.__state
134
129
  if (stateKey) {
135
130
  let parentState = parent.state
136
131
  const parentKeysArr = stateKey.split('../')
@@ -154,7 +149,7 @@ export const createState = function (element, parent, opts) {
154
149
  state = deepClone(keyInParentState)
155
150
  } else if (is(keyInParentState)('string', 'number')) {
156
151
  state = { value: keyInParentState }
157
- element.__stateType = 'string'
152
+ __elementRef.__stateType = 'string'
158
153
  } else if (isUndefined(keyInParentState)) {
159
154
  console.warn(stateKey, 'is not in present', 'replacing with ', {})
160
155
  state = {}
@@ -1,16 +1,15 @@
1
1
  'use strict'
2
2
 
3
- import { overwrite, isFunction, isObject, isString, isNumber, createSnapshotId, merge } from '../utils'
4
- import { registry } from './mixins'
3
+ import { window } from '@domql/globals'
4
+ import { diff } from '@domql/utils'
5
5
  import { on } from '../event'
6
- import { isMethod } from './methods'
6
+ import { createSnapshotId, isFunction, isNumber, isObject, isString, merge, overwrite } from '../utils'
7
+ import create from './create'
7
8
  import { throughUpdatedDefine, throughUpdatedExec } from './iterate'
8
- import { appendNode } from './assign'
9
- import { createNode } from './node'
9
+ import { isMethod } from './methods'
10
+ import { registry } from './mixins'
10
11
  import { updateProps } from './props'
11
12
  import createState from './state'
12
- import { diff } from '@domql/utils'
13
- import { window } from '@domql/globals'
14
13
 
15
14
  const snapshot = {
16
15
  snapshotId: createSnapshotId
@@ -28,15 +27,18 @@ const update = function (params = {}, options = UPDATE_DEFAULT_OPTIONS) {
28
27
  const element = this
29
28
  const { parent, node, context } = element
30
29
 
30
+ let __ref = element.__ref
31
+ if (!__ref) __ref = element.__ref = {}
32
+
31
33
  const { currentSnapshot, calleeElement } = options
32
34
  if (!calleeElement) {
33
- element.__currentSnapshot = snapshot.snapshotId()
35
+ __ref.__currentSnapshot = snapshot.snapshotId()
34
36
  }
35
- const snapshotOnCallee = element.__currentSnapshot || (calleeElement && calleeElement.__currentSnapshot)
37
+
38
+ const snapshotOnCallee = __ref.__currentSnapshot ||
39
+ (calleeElement && calleeElement.__ref && calleeElement.__currentSnapshot)
36
40
  if (snapshotOnCallee && currentSnapshot < snapshotOnCallee) {
37
- // console.log(calleeElement)
38
- // console.log(currentSnapshot, snapshotOnCallee, 'cancelling')
39
- // return
41
+ // TODO: stop previous update
40
42
  }
41
43
 
42
44
  if (isString(params) || isNumber(params)) {
@@ -46,21 +48,27 @@ const update = function (params = {}, options = UPDATE_DEFAULT_OPTIONS) {
46
48
  if (isFunction(element.if)) {
47
49
  // TODO: move as fragment
48
50
  const ifPassed = element.if(element, element.state)
49
-
50
- if (ifPassed) delete element.__ifFalsy
51
- if (element.__ifFalsy && ifPassed) {
52
- createNode(element)
53
- appendNode(element.node, element.__ifFragment)
51
+ const itWasFalse = !__ref.__if
52
+
53
+ if (ifPassed) __ref.__if = true
54
+ if (itWasFalse && ifPassed) {
55
+ delete element.__hash
56
+ if (!__ref.__hasRootState || __ref.__state) delete element.state
57
+ const created = create(element, element.parent, element.key)
58
+ if (!options.preventUpdate && element.on && isFunction(element.on.update)) {
59
+ on.update(element.on.update, created, created.state)
60
+ }
61
+ return created
54
62
  } else if (element.node && !ifPassed) {
55
63
  element.node.remove()
56
- element.__ifFalsy = true
64
+ delete __ref.__if
57
65
  }
58
66
  }
59
67
 
60
- if (element.__state) {
61
- const keyInParentState = parent.state[element.__state]
68
+ if (__ref.__state) {
69
+ const keyInParentState = parent.state[__ref.__state]
62
70
  if (keyInParentState) {
63
- const newState = element.__stateType === 'string'
71
+ const newState = __ref.__stateType === 'string'
64
72
  ? createState(element, parent)
65
73
  : createState(element, parent)
66
74
  const changes = diff(newState.parse(), element.state.parse())
@@ -77,9 +85,9 @@ const update = function (params = {}, options = UPDATE_DEFAULT_OPTIONS) {
77
85
  on.stateUpdated(element.on.stateUpdated, element, element.state, changes)
78
86
  }
79
87
  }
80
- } else if (!element.__hasRootState) element.state = (parent && parent.state) || {}
88
+ } else if (!__ref.__hasRootState) element.state = (parent && parent.state) || {}
81
89
 
82
- if (!element.__ifFalsy && !options.preventPropsUpdate) updateProps(params.props, element, parent)
90
+ if (__ref.__if && !options.preventPropsUpdate) updateProps(params.props, element, parent)
83
91
 
84
92
  if (element.on && isFunction(element.on.initUpdate) && !options.ignoreInitUpdate) {
85
93
  const whatinitreturns = on.initUpdate(element.on.initUpdate, element, element.state)
@@ -95,7 +103,7 @@ const update = function (params = {}, options = UPDATE_DEFAULT_OPTIONS) {
95
103
  element.__stackChanges.push(stackChanges)
96
104
  }
97
105
 
98
- if (element.__ifFalsy) return false
106
+ if (!__ref.__if) return false
99
107
  if (!node) {
100
108
  // return createNode(element, options)
101
109
  return
@@ -121,7 +121,7 @@ export const clone = obj => {
121
121
  /**
122
122
  * Deep cloning of object
123
123
  */
124
- export const deepClone = (obj, excluding = ['parent', 'node', '__element', 'state', '__root', '__cached', 'context']) => {
124
+ export const deepClone = (obj, excluding = ['parent', 'node', '__element', 'state', '__root', '__cached', 'context', 'extend', '__ref']) => {
125
125
  const o = isArray(obj) ? [] : {}
126
126
  for (const prop in obj) {
127
127
  if (excluding.indexOf(prop) > -1) continue
@@ -161,25 +161,27 @@ export const isEqualDeep = (param, element) => {
161
161
  */
162
162
  export const overwrite = (element, params, options) => {
163
163
  const changes = {}
164
+ const { __ref } = element
165
+ const { __exec, __cached } = __ref
164
166
 
165
167
  for (const e in params) {
166
- if (e === 'props' || e === 'state') continue
168
+ if (e === 'props' || e === 'state' || e === '__ref') continue
167
169
 
168
170
  const elementProp = element[e]
169
171
  const paramsProp = params[e]
170
172
 
171
173
  if (paramsProp !== undefined) {
172
- element.__cached[e] = changes[e] = elementProp
174
+ __cached[e] = changes[e] = elementProp
173
175
  element[e] = paramsProp
174
176
  }
175
177
 
176
- if (options.cleanExec) delete element.__exec[e]
178
+ if (options.cleanExec) delete __exec[e]
177
179
  }
178
180
 
179
181
  return changes
180
182
  }
181
183
 
182
- export const overwriteShallow = (obj, params, excluding = ['node', '__root']) => {
184
+ export const overwriteShallow = (obj, params, excluding = ['node', '__root', '__ref']) => {
183
185
  for (const e in params) {
184
186
  if (excluding.indexOf(e) > -1) continue
185
187
  obj[e] = params[e]
@@ -190,7 +192,7 @@ export const overwriteShallow = (obj, params, excluding = ['node', '__root']) =>
190
192
  /**
191
193
  * Overwrites DEEPly object properties with another
192
194
  */
193
- export const overwriteDeep = (obj, params, excluding = ['node', '__root']) => {
195
+ export const overwriteDeep = (obj, params, excluding = ['node', '__root', '__ref']) => {
194
196
  for (const e in params) {
195
197
  if (excluding.indexOf(e) > -1) continue
196
198
  const objProp = obj[e]
@@ -215,7 +217,7 @@ export const mergeIfExisted = (a, b) => {
215
217
  /**
216
218
  * Merges array extends
217
219
  */
218
- export const mergeArray = (arr, excluding = ['parent', 'node', '__element', 'state', '__root', '__cached', 'context']) => {
220
+ export const mergeArray = (arr, excluding = ['parent', 'node', '__element', 'state', '__root', '__cached', 'context', '__ref']) => {
219
221
  return arr.reduce((a, c) => deepMerge(a, deepClone(c, excluding)), {})
220
222
  }
221
223