simplyview 3.0.0 → 3.0.2

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/src/bind.mjs CHANGED
@@ -192,10 +192,8 @@ class SimplyBind {
192
192
  }
193
193
  }
194
194
  if (!matches) {
195
- // no data-bind-match is set, so return this template is currentItem is truthy
196
- if (currentItem) {
197
- return t
198
- }
195
+ // no data-bind-match is set, so return this template
196
+ return t
199
197
  }
200
198
  }
201
199
  let template = Array.from(templates).find(templateMatches)
@@ -385,7 +383,7 @@ export function transformArrayByTemplates(context) {
385
383
 
386
384
  /**
387
385
  * Renders an object value by applying templates for each entry (Object.entries)
388
- * Replaces or removes existing DOM children if needed
386
+ * Replaces,moves or removes existing DOM children if needed
389
387
  * Reuses (doesn't touch) DOM children if template doesn't change
390
388
  */
391
389
  export function transformObjectByTemplates(context) {
@@ -397,61 +395,41 @@ export function transformObjectByTemplates(context) {
397
395
  const attribute = this.options.attribute
398
396
  context.list = value
399
397
 
400
- let list = Object.entries(value)
401
- let items = el.querySelectorAll(':scope > ['+attribute+'-key]')
402
- let current = 0
403
- let skipped = 0
404
- for (let item of items) {
405
- if (current>=list.length) {
406
- break
398
+ let items = Array.from(el.querySelectorAll(':scope > ['+attribute+'-key]'))
399
+ for (let key in context.list) {
400
+ context.index = key
401
+ let item = items.shift()
402
+ if (!item) { // more properties than rendered items
403
+ el.appendChild(this.applyTemplate(context))
404
+ continue
407
405
  }
408
- let key = list[current][0]
409
- current++
410
- let keypath = path+'.'+key
411
- // check that all data-bind params start with current json path or a '#', otherwise replaceChild
412
- let needsReplacement
413
- const databind = item.getAttribute(attribute)
414
- if (databind && databind.substr(0, keypath.length)!=keypath) {
415
- needsReplacement=true
416
- } else {
417
- let bindings = Array.from(item.querySelectorAll(`[${attribute}]`))
418
- needsReplacement = bindings.find(b => {
419
- const db = b.getAttribute(attribute)
420
- return (db.substr(0,5)!=='#root' && db.substr(0, keypath.length)!==keypath)
421
- })
422
- if (!needsReplacement) {
423
- if (item.$bindTemplate) {
424
- let newTemplate = this.findTemplate(templates, value[key])
425
- if (newTemplate != item.$bindTemplate){
426
- needsReplacement = true
427
- if (!newTemplate) {
428
- skipped++
429
- }
430
- }
406
+ if (item.getAttribute[attribute+'-key']!=key) {
407
+ // next item doesn't match key
408
+ items.unshift(item) // put item back for next cycle
409
+ let outOfOrderItem = el.querySelector(':scope > ['+attribute+'-key="'+key+'"]') //FIXME: escape key
410
+ if (!outOfOrderItem) {
411
+ let clone = this.applyTemplate(context)
412
+ if (clone.firstElementChild) {
413
+ el.insertBefore(clone, item)
431
414
  }
415
+ continue // new template doesn't need replacement, so continue
416
+ } else {
417
+ el.insertBefore(outOfOrderItem, item)
418
+ item = outOfOrderItem // check needsreplacement next
419
+ items = items.filter(i => i!=outOfOrderItem)
432
420
  }
433
421
  }
434
- if (needsReplacement) {
435
- context.index = key
422
+ let newTemplate = this.findTemplate(templates, value[key])
423
+ if (newTemplate != item.$bindTemplate){
436
424
  let clone = this.applyTemplate(context)
437
425
  el.replaceChild(clone, item)
438
426
  }
439
427
  }
440
- items = el.querySelectorAll(':scope > ['+attribute+'-key]')
441
- let length = items.length + skipped
442
- if (length>list.length) {
443
- while (length>list.length) {
444
- let child = el.querySelectorAll(':scope > :not(template)')?.[length-1]
445
- child?.remove()
446
- length--
447
- }
448
- } else if (length < list.length) {
449
- while (length < list.length) {
450
- context.index = list[length][0]
451
- el.appendChild(this.applyTemplate(context))
452
- length++
453
- }
454
- }
428
+ // clean up remaining items
429
+ while (items.length) {
430
+ item = items.shift()
431
+ item.remove()
432
+ }
455
433
  }
456
434
 
457
435
  /**
@@ -567,6 +545,10 @@ export function transformElement(context) {
567
545
  const value = context.value
568
546
 
569
547
  if (!matchValue(el.innerHTML, value)) {
570
- el.innerHTML = ''+value
548
+ if (typeof value=='undefined' || value==null) {
549
+ el.innerHTML = ''
550
+ } else {
551
+ el.innerHTML = ''+value
552
+ }
571
553
  }
572
554
  }
package/src/changes.md ADDED
@@ -0,0 +1,18 @@
1
+ # changes
2
+
3
+ removed:
4
+ - render, observe
5
+ these are replaced with bind.mjs and state.mjs (signal, effect)
6
+ - view
7
+ replaced by state.mjs (signal)
8
+ - collect
9
+ replaced by state.mjs (effect)
10
+ - keyboard
11
+ renamed to key.mjs
12
+ - path
13
+ was never used, use jsonPointer instead if you need it
14
+ - viewmodel
15
+ replaced wiht model.mjs
16
+ - resize
17
+ use @container queries instead
18
+
package/src/include.mjs CHANGED
@@ -53,7 +53,7 @@ const waitForPreviousScripts = async () => {
53
53
  // that triggers the Promise.resolve method
54
54
  return new Promise(function(resolve) {
55
55
  var next = globalThis.document.createElement('script')
56
- next.src = rebaseHref('simply.include.next.js', currentScriptURL)
56
+ next.src = "javascript:document.dispatchEvent(new Event('simply-include-next'))"
57
57
  next.async = false
58
58
  globalThis.document.addEventListener('simply-include-next', () => {
59
59
  head.removeChild(next)
@@ -1 +0,0 @@
1
- document.dispatchEvent(new Event('simply-include-next'));