wallace 0.13.0 → 0.14.1

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/lib/component.js CHANGED
@@ -35,7 +35,8 @@ const ComponentPrototype = {
35
35
  const watches = this._w,
36
36
  props = this.props,
37
37
  previous = this._p,
38
- elements = this._e;
38
+ elements = this._e,
39
+ stash = this._s;
39
40
  /*
40
41
  Watches is an array of objects with keys:
41
42
  e: the element index (number)
@@ -61,7 +62,7 @@ const ComponentPrototype = {
61
62
  shouldBeVisible = displayToggle.r ? lookupTrue : !lookupTrue;
62
63
  detacher = displayToggle.d;
63
64
  if (detacher) {
64
- detacher.apply(element, shouldBeVisible, elements, this._s);
65
+ detacher.apply(element, shouldBeVisible, elements, stash);
65
66
  } else {
66
67
  element.hidden = !shouldBeVisible;
67
68
  }
@@ -74,7 +75,7 @@ const ComponentPrototype = {
74
75
  callbacks = watch.c;
75
76
  for (let key in callbacks) {
76
77
  if (key === NO_LOOKUP) {
77
- callbacks[key](element, props, this);
78
+ callbacks[key](element, props, this, stash);
78
79
  } else {
79
80
  const oldValue = prev[key],
80
81
  newValue = this._q[key](props, this);
package/lib/detacher.js CHANGED
@@ -9,18 +9,17 @@ export function Detacher(i, e, s) {
9
9
  }
10
10
 
11
11
  Detacher.prototype.apply = function (element, shouldBeVisible, elements, stash) {
12
- let adjustedIndex;
13
12
  const index = this.i,
14
13
  parent = elements[this.e],
15
- detachedElementCache = stash[this.s];
16
- let offset = detachedElementCache.get(index) || 0;
17
- if (shouldBeVisible && offset === -1) {
18
- adjustedIndex = countOffset(detachedElementCache, index);
14
+ offsetTracker = stash[this.s];
15
+ let ownOffset = offsetTracker.get(index) || 0;
16
+ if (shouldBeVisible && ownOffset === -1) {
17
+ const adjustedIndex = countOffset(offsetTracker, index);
19
18
  parent.insertBefore(element, parent.childNodes[adjustedIndex]);
20
- offset = 0;
21
- } else if (!shouldBeVisible && offset === 0) {
19
+ ownOffset = 0;
20
+ } else if (!shouldBeVisible && ownOffset === 0) {
22
21
  parent.removeChild(element);
23
- offset = -1;
22
+ ownOffset = -1;
24
23
  }
25
- detachedElementCache.set(index, offset);
24
+ offsetTracker.set(index, ownOffset);
26
25
  };
package/lib/index.js CHANGED
@@ -10,5 +10,6 @@ export { KeyedRepeater } from "./repeaters/keyed";
10
10
  export { SequentialRepeater } from "./repeaters/sequential";
11
11
  export { Router, route } from "./router";
12
12
  export { getStub } from "./stubs";
13
+ export { toDateString } from "./toDateString";
13
14
  export { findElement, onEvent } from "./utils";
14
15
  export { watch, protect } from "./watch";
package/lib/offsetter.js CHANGED
@@ -1,6 +1,6 @@
1
- export function countOffset(detachedElementCache, index) {
1
+ export function countOffset(offsetTracker, index) {
2
2
  let offset = 0;
3
- for (let [key, value] of detachedElementCache.entries()) {
3
+ for (let [key, value] of offsetTracker.entries()) {
4
4
  if (key >= index) break;
5
5
  offset += value;
6
6
  }
@@ -7,17 +7,16 @@ import { countOffset } from "../offsetter";
7
7
  * if allowRepeaterSiblings is false the last two parameters are removed.
8
8
  */
9
9
  export function KeyedRepeater(componentDefinition, key, adjustmentTracker, initialIndex) {
10
- this.def = componentDefinition;
11
- if (wallaceConfig.flags.allowRepeaterSiblings) {
12
- this.at = adjustmentTracker;
13
- this.ii = initialIndex;
14
- }
15
- this.keys = []; // array of keys as last set.
16
- this.pool = {}; // pool of component instances.
10
+ this.d = componentDefinition;
11
+ this.k = []; // array of keys as last set.
17
12
  if (typeof key === "function") {
18
- this.kf = key;
13
+ this.f = key;
19
14
  } else {
20
- this.kn = key;
15
+ this.n = key;
16
+ }
17
+ if (wallaceConfig.flags.allowRepeaterSiblings) {
18
+ this.a = adjustmentTracker;
19
+ this.i = initialIndex;
21
20
  }
22
21
  }
23
22
 
@@ -25,29 +24,30 @@ export function KeyedRepeater(componentDefinition, key, adjustmentTracker, initi
25
24
  * Updates the element's childNodes to match the items.
26
25
  * Performance is important.
27
26
  *
28
- * @param {DOMElement} e - The DOM element to patch.
27
+ * @param {DOMElement} parent - The DOM element to patch.
29
28
  * @param {Array} items - Array of items which will be passed as props.
29
+ * @param {Map} pool - pool of component instances.
30
30
  * @param {any} ctrl - The parent item's controller.
31
31
  */
32
- KeyedRepeater.prototype.patch = function (e, items, ctrl) {
33
- const pool = this.pool,
34
- componentDefinition = this.def,
35
- keyName = this.kn,
36
- keyFn = this.kf,
37
- childNodes = e.childNodes,
32
+ KeyedRepeater.prototype.patch = function (parent, items, pool, ctrl) {
33
+ const componentDefinition = this.d,
34
+ keyName = this.n,
35
+ keyFn = this.f,
36
+ useKeyName = keyName !== undefined,
37
+ childNodes = parent.childNodes,
38
38
  itemsLength = items.length,
39
- previousKeys = this.keys,
39
+ previousKeys = this.k,
40
40
  previousKeysLength = previousKeys.length,
41
41
  newKeys = [],
42
42
  previousKeysSet = new Set(previousKeys),
43
- adjustmentTracker = this.at,
44
- initialIndex = this.ii,
45
43
  frag = document.createDocumentFragment();
46
44
 
47
45
  let item,
48
46
  el,
49
47
  itemKey,
50
48
  component,
49
+ initialIndex,
50
+ offsetTracker,
51
51
  endAnchor = null,
52
52
  adjustment = 0,
53
53
  anchor = null,
@@ -58,8 +58,10 @@ KeyedRepeater.prototype.patch = function (e, items, ctrl) {
58
58
  i = itemsLength - 1;
59
59
 
60
60
  if (wallaceConfig.flags.allowRepeaterSiblings) {
61
- if (adjustmentTracker) {
62
- adjustment = countOffset(adjustmentTracker, initialIndex);
61
+ offsetTracker = this.a;
62
+ initialIndex = this.i;
63
+ if (offsetTracker) {
64
+ adjustment = countOffset(offsetTracker, initialIndex);
63
65
  endAnchor = childNodes[previousKeysLength + adjustment] || null;
64
66
  anchor = endAnchor;
65
67
  untouched = false;
@@ -69,8 +71,11 @@ KeyedRepeater.prototype.patch = function (e, items, ctrl) {
69
71
  // Working backwards saves us having to track moves.
70
72
  while (i >= 0) {
71
73
  item = items[i];
72
- itemKey = keyName ? item[keyName] : keyFn(item);
73
- component = pool[itemKey] || (pool[itemKey] = new componentDefinition());
74
+ itemKey = useKeyName ? item[keyName] : keyFn(item);
75
+ if (!(component = pool.get(itemKey))) {
76
+ component = new componentDefinition();
77
+ pool.set(itemKey, component);
78
+ }
74
79
  component.render(item, ctrl);
75
80
  el = component.el;
76
81
  if (untouched && !previousKeysSet.has(itemKey)) {
@@ -80,7 +85,7 @@ KeyedRepeater.prototype.patch = function (e, items, ctrl) {
80
85
  offset++;
81
86
  } else {
82
87
  if (itemKey !== previousKeys[i + offset]) {
83
- e.insertBefore(el, anchor);
88
+ parent.insertBefore(el, anchor);
84
89
  untouched = false;
85
90
  }
86
91
  anchor = el;
@@ -91,20 +96,20 @@ KeyedRepeater.prototype.patch = function (e, items, ctrl) {
91
96
  }
92
97
 
93
98
  if (append) {
94
- e.insertBefore(frag, endAnchor);
99
+ parent.insertBefore(frag, endAnchor);
95
100
  }
96
101
 
97
102
  let toStrip = previousKeysSet.size;
98
103
  while (toStrip > 0) {
99
- e.removeChild(childNodes[adjustment]);
104
+ parent.removeChild(childNodes[adjustment]);
100
105
  toStrip--;
101
106
  }
102
107
 
103
- this.keys = newKeys.reverse();
108
+ this.k = newKeys.reverse();
104
109
 
105
110
  if (wallaceConfig.flags.allowRepeaterSiblings) {
106
- if (adjustmentTracker) {
107
- adjustmentTracker.set(initialIndex, itemsLength - 1);
111
+ if (offsetTracker) {
112
+ offsetTracker.set(initialIndex, itemsLength - 1);
108
113
  }
109
114
  }
110
115
  };
@@ -7,13 +7,12 @@ import { countOffset } from "../offsetter";
7
7
  * if allowRepeaterSiblings is false the last two parameters are removed.
8
8
  */
9
9
  export function SequentialRepeater(componentDefinition, adjustmentTracker, initialIndex) {
10
- this.def = componentDefinition;
10
+ this.d = componentDefinition;
11
+ this.c = 0; // Child count
11
12
  if (wallaceConfig.flags.allowRepeaterSiblings) {
12
- this.at = adjustmentTracker;
13
- this.ii = initialIndex;
13
+ this.a = adjustmentTracker;
14
+ this.i = initialIndex;
14
15
  }
15
- this.pool = []; // pool of component instances
16
- this.cc = 0; // Child count
17
16
  }
18
17
 
19
18
  /**
@@ -22,27 +21,30 @@ export function SequentialRepeater(componentDefinition, adjustmentTracker, initi
22
21
  *
23
22
  * @param {DOMElement} parent - The DOM element to patch.
24
23
  * @param {Array} items - Array of items which will be passed as props.
24
+ * @param {Array} pool - pool of component instances.
25
25
  * @param {any} ctrl - The parent item's controller.
26
26
  */
27
- SequentialRepeater.prototype.patch = function (parent, items, ctrl) {
28
- const pool = this.pool,
29
- componentDefinition = this.def,
30
- childNodes = parent.childNodes,
27
+ SequentialRepeater.prototype.patch = function (parent, items, pool, ctrl) {
28
+ const componentDefinition = this.d,
29
+ previousChildCount = this.c,
31
30
  itemsLength = items.length,
32
- previousChildCount = this.cc,
33
- initialIndex = this.ii,
34
- adjustmentTracker = this.at;
31
+ childNodes = parent.childNodes;
32
+
35
33
  let i = 0,
36
34
  offset = 0,
37
35
  component,
38
36
  nextElement,
37
+ initialIndex,
38
+ offsetTracker,
39
39
  endOfRange = previousChildCount,
40
40
  poolCount = pool.length;
41
41
 
42
42
  if (wallaceConfig.flags.allowRepeaterSiblings) {
43
- if (adjustmentTracker) {
43
+ initialIndex = this.i;
44
+ offsetTracker = this.a;
45
+ if (offsetTracker) {
44
46
  // The repeat element has siblings
45
- offset = countOffset(adjustmentTracker, initialIndex);
47
+ offset = countOffset(offsetTracker, initialIndex);
46
48
  endOfRange += offset;
47
49
  nextElement = childNodes[endOfRange] || null;
48
50
  }
@@ -61,7 +63,7 @@ SequentialRepeater.prototype.patch = function (parent, items, ctrl) {
61
63
  }
62
64
  i++;
63
65
  }
64
- this.cc = itemsLength;
66
+ this.c = itemsLength;
65
67
 
66
68
  let removeAtIndex = offset + previousChildCount - 1;
67
69
  const stopatIndex = offset + itemsLength - 1;
@@ -69,8 +71,8 @@ SequentialRepeater.prototype.patch = function (parent, items, ctrl) {
69
71
  parent.removeChild(childNodes[i]);
70
72
  }
71
73
  if (wallaceConfig.flags.allowRepeaterSiblings) {
72
- if (adjustmentTracker) {
73
- adjustmentTracker.set(initialIndex, itemsLength - 1);
74
+ if (offsetTracker) {
75
+ offsetTracker.set(initialIndex, itemsLength - 1);
74
76
  }
75
77
  }
76
78
  };
@@ -0,0 +1 @@
1
+ export const toDateString = date => date.toISOString().slice(0, 10);
package/lib/types.d.ts CHANGED
@@ -529,7 +529,8 @@ performance and bundle size:
529
529
  2. allowCtrl - enables use of `ctrl` in components.
530
530
  3. allowMethods - adds the `methods` helper to components.
531
531
  4. allowParts - enables use of parts.
532
- 5. allowStubs - enables the use of stubs.
532
+ 5. allowRepeaterSiblings - allows repeaters to have siblings.
533
+ 6. allowStubs - enables the use of stubs.
533
534
 
534
535
  These flags default to true, unless you specify `flags` in the plugin config, in which
535
536
  case they default to false and you need to explicitly enable those you want:
@@ -840,46 +841,29 @@ interface DirectiveAttributes extends AllDomEvents {
840
841
  /**
841
842
  * ## Wallace directive: bind
842
843
  *
843
- * Sets up two-way binding:
844
- *
845
- * 1. It uses the expression as the element's value.
846
- * 2. It assigns the value back to the expression when the element's `change` event
847
- * fires.
848
- *
849
- * So this:
844
+ * Sets up two way binding between an input and data:
850
845
  *
851
846
  * ```
852
- * const MyComponent = ({name}) => (
853
- * <input type="text" bind={name}/>
854
- * );
847
+ * <input type="text" bind={name} />
855
848
  * ```
856
849
  *
857
850
  * Is the equivalent of this:
858
851
  *
859
- *```
860
- * const MyComponent = ({name}, {event}) => (
861
- * <input type="text" onChange={name = event.target.value} value={name}/>
862
- * );
863
852
  * ```
864
- *
865
- * In the case of a checkbox it uses `checked` instead of `value`, so is the equivalent of this:
853
+ * <input type="text" value={name} onChange={name = event.target.value} />
854
+ * ```
855
+ * By default it watches the `change` event, but you can specify a different one using
856
+ * the `event` directive:
866
857
  *
867
858
  * ```
868
- * const MyComponent = ({done}, {event}) => (
869
- * <input type="checkbox" onChange={done = event.target.checked} checked={done}/>
870
- * );
859
+ * <input type="text" bind={name} event:keyup />
871
860
  * ```
872
861
  *
873
- * By defaults it listens to the `change` event, but you can specify a different one:
862
+ * By default it binds to `value` but you can set a different property:
874
863
  *
875
864
  *```
876
- * const MyComponent = ({name}) => (
877
- * <input type="text" bind:KeyUp={name} />
878
- * );
865
+ * <input type="number" bind:valueAsNumber={name} />
879
866
  * ```
880
- *
881
- * Note that destructured props are converted to member expressions, so these examples
882
- * work even though it looks like you're setting a local variable.
883
867
  */
884
868
  bind?: MustBeExpression;
885
869
 
@@ -922,6 +906,19 @@ interface DirectiveAttributes extends AllDomEvents {
922
906
  */
923
907
  ctrl?: any;
924
908
 
909
+ /**
910
+ * ## Wallace directive: event
911
+ *
912
+ *
913
+ * Must be used with the `bind` directive, and causes it do watch a different event
914
+ * (the default is `change`)
915
+ *
916
+ * ```
917
+ * <input type="text" bind={name} event:keyup />
918
+ * ```
919
+ */
920
+ event?: string;
921
+
925
922
  /**
926
923
  * ## Wallace directive: fixed
927
924
  *
@@ -1085,6 +1082,7 @@ declare namespace JSX {
1085
1082
  * - `class:xyz` defines a set of classes to be toggled.
1086
1083
  * - `css` shorthand for `fixed:class`.
1087
1084
  * - `ctrl` specifies ctrl for nested/repeated components.
1085
+ * - `event` changes the event which `bind` reacts to.
1088
1086
  * - `fixed:xyz` sets a attribute from an expression at definition.
1089
1087
  * - `hide` sets an element or component's hidden property.
1090
1088
  * - `html` Set the element's `innnerHTML` property.
package/lib/watch.js CHANGED
@@ -9,12 +9,13 @@ export function watch(target, callback) {
9
9
  const handler = {
10
10
  get(target, key) {
11
11
  if (key == "isProxy") return true;
12
- const prop = target[key];
13
- if (typeof prop == "undefined") return;
14
- if (typeof prop === "object") return new Proxy(prop, handler);
12
+ const prop = target[key],
13
+ propType = typeof prop;
14
+ if (propType == "undefined") return;
15
+ if (propType === "object") return new Proxy(prop, handler);
15
16
  if (
16
- Array.isArray(target) &&
17
17
  typeof target[key] === "function" &&
18
+ Array.isArray(target) &&
18
19
  MUTATING_METHODS.includes(key)
19
20
  ) {
20
21
  return (...args) => {
@@ -23,6 +24,9 @@ export function watch(target, callback) {
23
24
  return result;
24
25
  };
25
26
  }
27
+ if (target instanceof Date && propType === "function") {
28
+ return prop.bind(target);
29
+ }
26
30
  return prop;
27
31
  },
28
32
  set(target, key, value) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wallace",
3
- "version": "0.13.0",
3
+ "version": "0.14.1",
4
4
  "author": "Andrew Buchan",
5
5
  "description": "An insanely small, fast, intuitive and extendable front-end framework",
6
6
  "homepage": "https://wallace.js.org",
@@ -15,8 +15,8 @@
15
15
  "test": "jest --clearCache && jest"
16
16
  },
17
17
  "dependencies": {
18
- "babel-plugin-wallace": "^0.13.0",
18
+ "babel-plugin-wallace": "^0.14.1",
19
19
  "browserify": "^17.0.1"
20
20
  },
21
- "gitHead": "4ee1dce381dcd46dd057f88c198dd5d6f3d257d9"
21
+ "gitHead": "c60384d682e38095780dd260004299e9c4038583"
22
22
  }