grainjs 0.1.0 → 1.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/README.md +54 -9
- package/dist/cjs/index.d.ts +6 -2
- package/dist/cjs/index.js +24 -17
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/PriorityQueue.d.ts +1 -1
- package/dist/cjs/lib/PriorityQueue.js +1 -0
- package/dist/cjs/lib/PriorityQueue.js.map +1 -1
- package/dist/cjs/lib/_computed_queue.d.ts +18 -0
- package/dist/cjs/lib/_computed_queue.js +6 -1
- package/dist/cjs/lib/_computed_queue.js.map +1 -1
- package/dist/cjs/lib/binding.d.ts +16 -10
- package/dist/cjs/lib/binding.js +22 -27
- package/dist/cjs/lib/binding.js.map +1 -1
- package/dist/cjs/lib/browserGlobals.d.ts +4 -1
- package/dist/cjs/lib/browserGlobals.js +2 -0
- package/dist/cjs/lib/browserGlobals.js.map +1 -1
- package/dist/cjs/lib/computed.d.ts +11 -7
- package/dist/cjs/lib/computed.js +16 -0
- package/dist/cjs/lib/computed.js.map +1 -1
- package/dist/cjs/lib/dispose.d.ts +106 -14
- package/dist/cjs/lib/dispose.js +76 -11
- package/dist/cjs/lib/dispose.js.map +1 -1
- package/dist/cjs/lib/dom.d.ts +21 -17
- package/dist/cjs/lib/dom.js +33 -26
- package/dist/cjs/lib/dom.js.map +1 -1
- package/dist/cjs/lib/domComponent.d.ts +71 -0
- package/dist/cjs/lib/domComponent.js +15 -0
- package/dist/cjs/lib/domComponent.js.map +1 -0
- package/dist/cjs/lib/domComputed.d.ts +89 -0
- package/dist/cjs/lib/domComputed.js +92 -0
- package/dist/cjs/lib/domComputed.js.map +1 -0
- package/dist/cjs/lib/{_domDispose.d.ts → domDispose.d.ts} +12 -2
- package/dist/cjs/lib/{_domDispose.js → domDispose.js} +21 -8
- package/dist/cjs/lib/domDispose.js.map +1 -0
- package/dist/cjs/lib/{_domForEach.d.ts → domForEach.d.ts} +2 -2
- package/dist/cjs/lib/domForEach.js +72 -0
- package/dist/cjs/lib/domForEach.js.map +1 -0
- package/dist/cjs/lib/{_domImpl.d.ts → domImpl.d.ts} +15 -12
- package/dist/cjs/lib/{_domImpl.js → domImpl.js} +23 -6
- package/dist/cjs/lib/domImpl.js.map +1 -0
- package/dist/cjs/lib/{_domMethods.d.ts → domMethods.d.ts} +27 -62
- package/dist/cjs/lib/{_domMethods.js → domMethods.js} +21 -76
- package/dist/cjs/lib/domMethods.js.map +1 -0
- package/dist/cjs/lib/domevent.d.ts +32 -21
- package/dist/cjs/lib/domevent.js +33 -12
- package/dist/cjs/lib/domevent.js.map +1 -1
- package/dist/cjs/lib/emit.d.ts +25 -2
- package/dist/cjs/lib/emit.js +3 -1
- package/dist/cjs/lib/emit.js.map +1 -1
- package/dist/cjs/lib/kowrap.d.ts +45 -3
- package/dist/cjs/lib/kowrap.js +93 -10
- package/dist/cjs/lib/kowrap.js.map +1 -1
- package/dist/cjs/lib/obsArray.d.ts +8 -8
- package/dist/cjs/lib/obsArray.js +1 -0
- package/dist/cjs/lib/obsArray.js.map +1 -1
- package/dist/cjs/lib/observable.d.ts +6 -1
- package/dist/cjs/lib/observable.js +11 -2
- package/dist/cjs/lib/observable.js.map +1 -1
- package/dist/cjs/lib/pureComputed.d.ts +3 -3
- package/dist/cjs/lib/pureComputed.js +2 -1
- package/dist/cjs/lib/pureComputed.js.map +1 -1
- package/dist/cjs/lib/styled.d.ts +76 -11
- package/dist/cjs/lib/styled.js +55 -23
- package/dist/cjs/lib/styled.js.map +1 -1
- package/dist/cjs/lib/subscribe.d.ts +15 -6
- package/dist/cjs/lib/subscribe.js +6 -2
- package/dist/cjs/lib/subscribe.js.map +1 -1
- package/dist/cjs/lib/util.js +1 -0
- package/dist/cjs/lib/util.js.map +1 -1
- package/dist/cjs/lib/widgets/input.d.ts +2 -2
- package/dist/cjs/lib/widgets/input.js +2 -2
- package/dist/cjs/lib/widgets/input.js.map +1 -1
- package/dist/cjs/lib/widgets/select.d.ts +1 -1
- package/dist/cjs/lib/widgets/select.js +1 -0
- package/dist/cjs/lib/widgets/select.js.map +1 -1
- package/dist/esm/index.js +6 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/PriorityQueue.js.map +1 -1
- package/dist/esm/lib/_computed_queue.js +5 -1
- package/dist/esm/lib/_computed_queue.js.map +1 -1
- package/dist/esm/lib/binding.js +20 -27
- package/dist/esm/lib/binding.js.map +1 -1
- package/dist/esm/lib/browserGlobals.js +1 -0
- package/dist/esm/lib/browserGlobals.js.map +1 -1
- package/dist/esm/lib/computed.js +15 -0
- package/dist/esm/lib/computed.js.map +1 -1
- package/dist/esm/lib/dispose.js +74 -11
- package/dist/esm/lib/dispose.js.map +1 -1
- package/dist/esm/lib/dom.js +21 -17
- package/dist/esm/lib/dom.js.map +1 -1
- package/dist/esm/lib/domComponent.js +11 -0
- package/dist/esm/lib/domComponent.js.map +1 -0
- package/dist/esm/lib/domComputed.js +84 -0
- package/dist/esm/lib/domComputed.js.map +1 -0
- package/dist/esm/lib/{_domDispose.js → domDispose.js} +19 -8
- package/dist/esm/lib/domDispose.js.map +1 -0
- package/dist/esm/lib/domForEach.js +68 -0
- package/dist/esm/lib/domForEach.js.map +1 -0
- package/dist/esm/lib/{_domImpl.js → domImpl.js} +20 -4
- package/dist/esm/lib/domImpl.js.map +1 -0
- package/dist/esm/lib/{_domMethods.js → domMethods.js} +8 -63
- package/dist/esm/lib/domMethods.js.map +1 -0
- package/dist/esm/lib/domevent.js +30 -11
- package/dist/esm/lib/domevent.js.map +1 -1
- package/dist/esm/lib/emit.js +2 -1
- package/dist/esm/lib/emit.js.map +1 -1
- package/dist/esm/lib/kowrap.js +90 -10
- package/dist/esm/lib/kowrap.js.map +1 -1
- package/dist/esm/lib/obsArray.js.map +1 -1
- package/dist/esm/lib/observable.js +9 -1
- package/dist/esm/lib/observable.js.map +1 -1
- package/dist/esm/lib/pureComputed.js +1 -1
- package/dist/esm/lib/pureComputed.js.map +1 -1
- package/dist/esm/lib/styled.js +52 -22
- package/dist/esm/lib/styled.js.map +1 -1
- package/dist/esm/lib/subscribe.js +5 -2
- package/dist/esm/lib/subscribe.js.map +1 -1
- package/dist/esm/lib/util.js.map +1 -1
- package/dist/esm/lib/widgets/input.js +1 -2
- package/dist/esm/lib/widgets/input.js.map +1 -1
- package/dist/esm/lib/widgets/select.js.map +1 -1
- package/dist/grain-full.debug.js +1627 -1222
- package/dist/grain-full.min.js +1 -1
- package/dist/grain-full.min.js.map +1 -1
- package/index.ts +6 -2
- package/lib/_computed_queue.ts +7 -1
- package/lib/binding.ts +33 -28
- package/lib/browserGlobals.ts +3 -1
- package/lib/computed.ts +37 -7
- package/lib/dispose.ts +81 -33
- package/lib/dom.ts +24 -18
- package/lib/domComponent.ts +89 -0
- package/lib/domComputed.ts +146 -0
- package/lib/{_domDispose.ts → domDispose.ts} +26 -8
- package/lib/{_domForEach.ts → domForEach.ts} +12 -11
- package/lib/{_domImpl.ts → domImpl.ts} +36 -30
- package/lib/{_domMethods.ts → domMethods.ts} +33 -103
- package/lib/domevent.ts +59 -22
- package/lib/emit.ts +2 -1
- package/lib/kowrap.ts +109 -11
- package/lib/obsArray.ts +2 -2
- package/lib/observable.ts +10 -2
- package/lib/pureComputed.ts +7 -6
- package/lib/styled.ts +65 -39
- package/lib/subscribe.ts +24 -8
- package/lib/widgets/input.ts +9 -7
- package/lib/widgets/select.ts +3 -3
- package/package.json +41 -42
- package/dist/cjs/lib/_domComponent.d.ts +0 -84
- package/dist/cjs/lib/_domComponent.js +0 -160
- package/dist/cjs/lib/_domComponent.js.map +0 -1
- package/dist/cjs/lib/_domDispose.js.map +0 -1
- package/dist/cjs/lib/_domForEach.js +0 -71
- package/dist/cjs/lib/_domForEach.js.map +0 -1
- package/dist/cjs/lib/_domImpl.js.map +0 -1
- package/dist/cjs/lib/_domMethods.js.map +0 -1
- package/dist/esm/lib/_domComponent.js +0 -155
- package/dist/esm/lib/_domComponent.js.map +0 -1
- package/dist/esm/lib/_domDispose.js.map +0 -1
- package/dist/esm/lib/_domForEach.js +0 -68
- package/dist/esm/lib/_domForEach.js.map +0 -1
- package/dist/esm/lib/_domImpl.js.map +0 -1
- package/dist/esm/lib/_domMethods.js.map +0 -1
- package/lib/_domComponent.ts +0 -167
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { subscribeElem } from './binding';
|
|
2
|
+
import { Holder, MultiHolder } from './dispose';
|
|
3
|
+
import { autoDisposeElem, domDispose } from './domDispose';
|
|
4
|
+
import { frag } from './domImpl';
|
|
5
|
+
// Use the browser globals in a way that allows replacing them with mocks in tests.
|
|
6
|
+
import { G } from './browserGlobals';
|
|
7
|
+
/**
|
|
8
|
+
* Replaces the content between nodeBefore and nodeAfter, which should be two siblings within the
|
|
9
|
+
* same parent node. New content may be anything allowed as an argument to dom(), including null
|
|
10
|
+
* to insert nothing. Runs disposers, if any, on all removed content.
|
|
11
|
+
*/
|
|
12
|
+
export function replaceContent(nodeBefore, nodeAfter, content) {
|
|
13
|
+
const elem = nodeBefore.parentNode;
|
|
14
|
+
if (elem) {
|
|
15
|
+
let next;
|
|
16
|
+
for (let n = nodeBefore.nextSibling; n && n !== nodeAfter; n = next) {
|
|
17
|
+
next = n.nextSibling;
|
|
18
|
+
domDispose(n);
|
|
19
|
+
elem.removeChild(n);
|
|
20
|
+
}
|
|
21
|
+
if (content) {
|
|
22
|
+
elem.insertBefore(content instanceof G.Node ? content : frag(content), nodeAfter);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function domComputed(valueObs, contentFunc = identity) {
|
|
27
|
+
const markerPre = G.document.createComment('a');
|
|
28
|
+
const markerPost = G.document.createComment('b');
|
|
29
|
+
// Function is added after markerPre and markerPost, so that it runs once they have already been
|
|
30
|
+
// attached to elem (the parent element).
|
|
31
|
+
return [markerPre, markerPost, (elem) => {
|
|
32
|
+
subscribeElem(markerPost, valueObs, (value) => replaceContent(markerPre, markerPost, contentFunc(value)));
|
|
33
|
+
}];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Like domComputed(), but the callback gets an additional first argument, owner, which may be
|
|
37
|
+
* used to take ownership of objects created by the callback. These will be disposed before each
|
|
38
|
+
* new call to the callback, and when the containing DOM is disposed.
|
|
39
|
+
*
|
|
40
|
+
* domComputedOwned(valueObs, (owner, value) => Editor.create(owner, value).renderSomething());
|
|
41
|
+
*/
|
|
42
|
+
export function domComputedOwned(valueObs, contentFunc) {
|
|
43
|
+
const holder = Holder.create(null);
|
|
44
|
+
const [markerPre, markerPost, func] = domComputed(valueObs, (val) => contentFunc(MultiHolder.create(holder), val));
|
|
45
|
+
autoDisposeElem(markerPost, holder);
|
|
46
|
+
return [markerPre, markerPost, func];
|
|
47
|
+
}
|
|
48
|
+
function identity(arg) { return arg; }
|
|
49
|
+
/**
|
|
50
|
+
* Conditionally appends DOM to an element. The value may be an observable or function (from which
|
|
51
|
+
* a computed is created), whose value -- if truthy -- will be passed to `contentFunc` which
|
|
52
|
+
* should return DOM content. If the value is falsy, DOM content is removed.
|
|
53
|
+
*
|
|
54
|
+
* Note that if the observable changes between different truthy values, contentFunc gets called
|
|
55
|
+
* for each value, and previous content gets destroyed. To consider all truthy values the same,
|
|
56
|
+
* use an observable that returns a proper boolean, e.g.
|
|
57
|
+
*
|
|
58
|
+
* dom.maybe(use => Boolean(use(fooObs)), () => dom(...));
|
|
59
|
+
*
|
|
60
|
+
* As with domComputed(), dom.maybe() may but should not be used when the argument is not an
|
|
61
|
+
* observable or function. The following are equivalent:
|
|
62
|
+
*
|
|
63
|
+
* dom(..., dom.maybe(myValue, () => dom(...)));
|
|
64
|
+
* dom(..., myValue ? dom(...) : null);
|
|
65
|
+
*
|
|
66
|
+
* The latter is preferred for being simpler.
|
|
67
|
+
*
|
|
68
|
+
* @param boolValueObs: Observable or function for a computed.
|
|
69
|
+
* @param contentFunc: Called with the result of boolValueObs when it is truthy. Should return DOM.
|
|
70
|
+
*/
|
|
71
|
+
export function maybe(boolValueObs, contentFunc) {
|
|
72
|
+
return domComputed(boolValueObs, (value) => value ? contentFunc(value) : null);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Like maybe(), but the callback gets an additional first argument, owner, which may be used to
|
|
76
|
+
* take ownership of objects created by the callback. These will be disposed before each new call
|
|
77
|
+
* to the callback, and when the condition becomes false or the containing DOM gets disposed.
|
|
78
|
+
*
|
|
79
|
+
* maybeOwned(showEditor, (owner) => Editor.create(owner).renderSomething());
|
|
80
|
+
*/
|
|
81
|
+
export function maybeOwned(boolValueObs, contentFunc) {
|
|
82
|
+
return domComputedOwned(boolValueObs, (owner, value) => value ? contentFunc(owner, value) : null);
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=domComputed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domComputed.js","sourceRoot":"","sources":["../../../lib/domComputed.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,19 +23,30 @@ function _walkDom(elem, visitFunc) {
|
|
|
23
23
|
visitFunc(elem);
|
|
24
24
|
}
|
|
25
25
|
// Internal helper to run all disposers for a single element.
|
|
26
|
-
function
|
|
27
|
-
let disposer = _disposeMap.get(
|
|
26
|
+
export function _disposeNode(node) {
|
|
27
|
+
let disposer = _disposeMap.get(node);
|
|
28
28
|
if (disposer) {
|
|
29
|
-
let key =
|
|
29
|
+
let key = node;
|
|
30
30
|
do {
|
|
31
31
|
_disposeMap.delete(key);
|
|
32
|
-
disposer(
|
|
32
|
+
disposer(node);
|
|
33
33
|
// Find the next disposer; these are chained when there are multiple.
|
|
34
34
|
key = disposer;
|
|
35
35
|
disposer = _disposeMap.get(key);
|
|
36
36
|
} while (disposer);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
+
function _disposeNodeRecursive(node) {
|
|
40
|
+
_walkDom(node, domDisposeHooks.disposeNode);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Support for extending dom disposal. This is very low-level, and needs utmost care. Any
|
|
44
|
+
* disposers set should take care of calling the original versions of the disposers.
|
|
45
|
+
*/
|
|
46
|
+
export const domDisposeHooks = {
|
|
47
|
+
disposeNode: _disposeNode,
|
|
48
|
+
disposeRecursive: _disposeNodeRecursive,
|
|
49
|
+
};
|
|
39
50
|
/**
|
|
40
51
|
* Run disposers associated with any descendant of elem or with elem itself. Disposers get
|
|
41
52
|
* associated with elements using dom.onDispose(). Descendants are processed first.
|
|
@@ -43,10 +54,10 @@ function _disposeElem(elem) {
|
|
|
43
54
|
* It is automatically called if one of the function arguments to dom() throws an exception during
|
|
44
55
|
* element creation. This way any onDispose() handlers set on the unfinished element get called.
|
|
45
56
|
*
|
|
46
|
-
* @param {
|
|
57
|
+
* @param {Node} node: The element to run disposers on.
|
|
47
58
|
*/
|
|
48
|
-
export function domDispose(
|
|
49
|
-
|
|
59
|
+
export function domDispose(node) {
|
|
60
|
+
domDisposeHooks.disposeRecursive(node);
|
|
50
61
|
}
|
|
51
62
|
/**
|
|
52
63
|
* Associate a disposerFunc with a DOM element. It will be called when the element is disposed
|
|
@@ -84,4 +95,4 @@ export function autoDispose(disposable) {
|
|
|
84
95
|
return (elem) => autoDisposeElem(elem, disposable);
|
|
85
96
|
}
|
|
86
97
|
}
|
|
87
|
-
//# sourceMappingURL=
|
|
98
|
+
//# sourceMappingURL=domDispose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domDispose.js","sourceRoot":"","sources":["../../../lib/domDispose.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,GAAuC,IAAI,OAAO,EAAE,CAAC;AAItE,4FAA4F;AAC5F,mCAAmC;AACnC,SAAS,QAAQ,CAAC,IAAU,EAAE,SAAoB;IAChD,IAAI,CAAC,GAAc,IAAI,CAAC,UAAU,CAAC;IACnC,OAAO,CAAC,EAAE;QACR,4FAA4F;QAC5F,gCAAgC;QAChC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QACvB,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC;KACnB;IACD,SAAS,CAAC,IAAI,CAAC,CAAC;AAClB,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,YAAY,CAAC,IAAU;IACrC,IAAI,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,QAAQ,EAAE;QACZ,IAAI,GAAG,GAAmB,IAAI,CAAC;QAC/B,GAAG;YACD,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACxB,QAAQ,CAAC,IAAI,CAAC,CAAC;YACf,qEAAqE;YACrE,GAAG,GAAG,QAAQ,CAAC;YACf,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;SACjC,QAAQ,QAAQ,EAAE;KACpB;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAU;IACvC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC;AAC9C,CAAC;AAOD;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAqB;IAC/C,WAAW,EAAE,YAAY;IACzB,gBAAgB,EAAE,qBAAqB;CACxC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,IAAU;IACnC,eAAe,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,IAAU,EAAE,YAAuB;IAC/D,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC3C,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACpC,IAAI,YAAY,EAAE;QAChB,WAAW,CAAC,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;KAC7C;AACH,CAAC;AACD,MAAM,UAAU,SAAS,CAAC,YAAuB;IAC/C,OAAO,CAAC,IAAU,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,IAAU,EAAE,UAA4B;IACtE,IAAI,UAAU,EAAE;QACd,aAAa,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;KACjD;AACH,CAAC;AACD,MAAM,UAAU,WAAW,CAAC,UAA4B;IACtD,IAAI,UAAU,EAAE;QACd,OAAO,CAAC,IAAU,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;KAC1D;AACH,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { replaceContent } from './domComputed';
|
|
2
|
+
import { autoDisposeElem, domDispose } from './domDispose';
|
|
3
|
+
import { frag } from './domImpl';
|
|
4
|
+
import { computedArray } from './obsArray';
|
|
5
|
+
// Use the browser globals in a way that allows replacing them with mocks in tests.
|
|
6
|
+
import { G } from './browserGlobals';
|
|
7
|
+
/**
|
|
8
|
+
* Creates DOM elements for each element of an observable array. As the array is changed, children
|
|
9
|
+
* are added or removed. This works for any array-valued observable, and for obsArray() and
|
|
10
|
+
* computedArray() it works more efficiently for simple changes.
|
|
11
|
+
*
|
|
12
|
+
* The given itemCreateFunc() should return a single DOM node for each item, or null to skip that
|
|
13
|
+
* item. It is called for new items whenever they are spliced in, or the array replaced. The
|
|
14
|
+
* forEach() owns the created nodes, and runs domDispose() on them when they are spliced out.
|
|
15
|
+
*
|
|
16
|
+
* If the created nodes are removed from their parent externally, forEach() will cope with it, but
|
|
17
|
+
* will consider these elements as no longer owned, and will not run domDispose() on them.
|
|
18
|
+
*
|
|
19
|
+
* Note that itemCreateFunc() does not receive an index: an index would only be correct at the
|
|
20
|
+
* time the item is created, and would not reflect further changes to the array.
|
|
21
|
+
*
|
|
22
|
+
* If you'd like to map the DOM node back to its source item, use dom.data() and dom.getData() in
|
|
23
|
+
* itemCreateFunc().
|
|
24
|
+
*/
|
|
25
|
+
export function forEach(obsArray, itemCreateFunc) {
|
|
26
|
+
const markerPre = G.document.createComment('a');
|
|
27
|
+
const markerPost = G.document.createComment('b');
|
|
28
|
+
return [markerPre, markerPost, (elem) => {
|
|
29
|
+
if (Array.isArray(obsArray)) {
|
|
30
|
+
replaceContent(markerPre, markerPost, obsArray.map(itemCreateFunc));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const nodes = computedArray(obsArray, itemCreateFunc);
|
|
34
|
+
// Be sure to dispose the newly-created array when the DOM it's associated with is gone.
|
|
35
|
+
autoDisposeElem(markerPost, nodes);
|
|
36
|
+
nodes.addListener((newArr, oldArr, splice) => {
|
|
37
|
+
if (splice) {
|
|
38
|
+
// Remove the elements that are gone.
|
|
39
|
+
for (const node of splice.deleted) {
|
|
40
|
+
if (node && node.parentNode === elem) {
|
|
41
|
+
domDispose(node);
|
|
42
|
+
elem.removeChild(node);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (splice.numAdded > 0) {
|
|
46
|
+
// Find a valid child immediately following the spliced out portion, for DOM insertion.
|
|
47
|
+
const endIndex = splice.start + splice.numAdded;
|
|
48
|
+
let nextElem = markerPost;
|
|
49
|
+
for (let i = endIndex; i < newArr.length; i++) {
|
|
50
|
+
const node = newArr[i];
|
|
51
|
+
if (node && node.parentNode === elem) {
|
|
52
|
+
nextElem = node;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Insert the new elements.
|
|
57
|
+
const content = frag(newArr.slice(splice.start, endIndex));
|
|
58
|
+
elem.insertBefore(content, nextElem);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
replaceContent(markerPre, markerPost, newArr);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
replaceContent(markerPre, markerPost, nodes.get());
|
|
66
|
+
}];
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=domForEach.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domForEach.js","sourceRoot":"","sources":["../../../lib/domForEach.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,cAAc,EAAC,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAC,eAAe,EAAE,UAAU,EAAC,MAAM,cAAc,CAAC;AACzD,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AAC/B,OAAO,EAAC,aAAa,EAA0B,MAAM,YAAY,CAAC;AAElE,mFAAmF;AACnF,OAAO,EAAC,CAAC,EAAC,MAAM,kBAAkB,CAAC;AAEnC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,OAAO,CAAI,QAA0B,EAAE,cAAsC;IAC3F,MAAM,SAAS,GAAG,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACjD,OAAO,CAAC,SAAS,EAAE,UAAU,EAAE,CAAC,IAAU,EAAE,EAAE;YAC5C,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAC3B,cAAc,CAAC,SAAS,EAAE,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;gBACpE,OAAO;aACR;YAED,MAAM,KAAK,GAAwB,aAAa,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;YAE3E,wFAAwF;YACxF,eAAe,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YAEnC,KAAK,CAAC,WAAW,CAAC,CAAC,MAAwB,EAAE,MAAwB,EAAE,MAAO,EAAE,EAAE;gBAChF,IAAI,MAAM,EAAE;oBACV,qCAAqC;oBACrC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE;wBACjC,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;4BACpC,UAAU,CAAC,IAAI,CAAC,CAAC;4BACjB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;yBACxB;qBACF;oBAED,IAAI,MAAM,CAAC,QAAQ,GAAG,CAAC,EAAE;wBACvB,uFAAuF;wBACvF,MAAM,QAAQ,GAAW,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC;wBACxD,IAAI,QAAQ,GAAS,UAAU,CAAC;wBAChC,KAAK,IAAI,CAAC,GAAG,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;4BAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;4BACvB,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;gCACpC,QAAQ,GAAG,IAAI,CAAC;gCAChB,MAAM;6BACP;yBACF;wBAED,2BAA2B;wBAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;wBAC3D,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;qBACtC;iBACF;qBAAM;oBACL,cAAc,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;iBAC/C;YACH,CAAC,CAAC,CAAC;YACH,cAAc,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { domDispose } from './
|
|
2
|
-
import { attrsElem } from './
|
|
1
|
+
import { domDispose } from './domDispose';
|
|
2
|
+
import { attrsElem } from './domMethods';
|
|
3
3
|
// Use the browser globals in a way that allows replacing them with mocks in tests.
|
|
4
4
|
import { G } from './browserGlobals';
|
|
5
5
|
// The goal of the above declarations is to get help from TypeScript in detecting incorrect usage:
|
|
6
|
-
//
|
|
6
|
+
// (See test/types/dom.ts for a test of this.)
|
|
7
|
+
// import {text, hide} from './domMethods';
|
|
7
8
|
// dom('div', text('hello')); // OK
|
|
8
9
|
// dom('div', hide(true)); // OK
|
|
9
10
|
// dom('div', {title: 'hello'}); // OK
|
|
@@ -15,6 +16,10 @@ import { G } from './browserGlobals';
|
|
|
15
16
|
* The first argument is a string consisting of a tag name, with optional #foo suffix
|
|
16
17
|
* to add the ID 'foo', and zero or more .bar suffixes to add a CSS class 'bar'.
|
|
17
18
|
*
|
|
19
|
+
* NOTE that better typings are available when a tag is used directly, e.g.
|
|
20
|
+
* dom('input', {id: 'foo'}, (elem) => ...) --> elem has type HTMLInputElement
|
|
21
|
+
* dom('input#foo', (elem) => ...) --> elem has type HTMLElement
|
|
22
|
+
*
|
|
18
23
|
* The rest of the arguments are optional and may be:
|
|
19
24
|
*
|
|
20
25
|
* Nodes - which become children of the created element;
|
|
@@ -86,15 +91,26 @@ function _createFromTagString(createFunc, tagString) {
|
|
|
86
91
|
}
|
|
87
92
|
return elem;
|
|
88
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Update an element with any number of arguments, as documented in dom().
|
|
96
|
+
*/
|
|
89
97
|
export function update(elem, ...args) {
|
|
90
98
|
return _updateWithArgs(elem, args);
|
|
91
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Update an element with an array of arguments.
|
|
102
|
+
*/
|
|
92
103
|
function _updateWithArgs(elem, args) {
|
|
93
104
|
for (const arg of args) {
|
|
94
105
|
_updateWithArg(elem, arg);
|
|
95
106
|
}
|
|
96
107
|
return elem;
|
|
97
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Update an element with an array of arguments, calling disposers in case of an exception. It is
|
|
111
|
+
* an internal helper to be used whenever elem is a newly-created element. If elem is an existing
|
|
112
|
+
* element which the user already knows about, then _updateWithArgs should be called.
|
|
113
|
+
*/
|
|
98
114
|
function _updateWithArgsOrDispose(elem, args) {
|
|
99
115
|
try {
|
|
100
116
|
return _updateWithArgs(elem, args);
|
|
@@ -143,4 +159,4 @@ export function find(selector) { return G.document.querySelector(selector); }
|
|
|
143
159
|
* Find all elements matching a selector; just an abbreviation for document.querySelectorAll().
|
|
144
160
|
*/
|
|
145
161
|
export function findAll(selector) { return G.document.querySelectorAll(selector); }
|
|
146
|
-
//# sourceMappingURL=
|
|
162
|
+
//# sourceMappingURL=domImpl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domImpl.js","sourceRoot":"","sources":["../../../lib/domImpl.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { subscribe as subscribeBinding } from './binding';
|
|
1
|
+
import { subscribeElem as _subscribe } from './binding';
|
|
2
|
+
import { onDisposeElem } from './domDispose';
|
|
4
3
|
// Use the browser globals in a way that allows replacing them with mocks in tests.
|
|
5
4
|
import { G } from './browserGlobals';
|
|
6
5
|
/**
|
|
@@ -8,13 +7,6 @@ import { G } from './browserGlobals';
|
|
|
8
7
|
* values from being garbage collected when the owning DOM elements are no longer used.
|
|
9
8
|
*/
|
|
10
9
|
const _dataMap = new WeakMap();
|
|
11
|
-
/**
|
|
12
|
-
* Internal helper that binds the callback to valueObs, which may be a value, observble, or
|
|
13
|
-
* function, and attaches a disposal callback to the passed-in element.
|
|
14
|
-
*/
|
|
15
|
-
function _subscribe(elem, valueObs, callback) {
|
|
16
|
-
autoDisposeElem(elem, subscribeBinding(valueObs, callback));
|
|
17
|
-
}
|
|
18
10
|
/**
|
|
19
11
|
* Sets multiple attributes of a DOM element. The `attrs()` variant takes no `elem` argument.
|
|
20
12
|
* Null and undefined values are omitted, and booleans are either omitted or set to empty string.
|
|
@@ -195,60 +187,13 @@ export function getData(elem, key) {
|
|
|
195
187
|
return obj && obj[key];
|
|
196
188
|
}
|
|
197
189
|
/**
|
|
198
|
-
*
|
|
199
|
-
* same parent node. New content may be anything allowed as an argument to dom(), including null
|
|
200
|
-
* to insert nothing. Runs disposers, if any, on all removed content.
|
|
190
|
+
* See documentation for TestId above.
|
|
201
191
|
*/
|
|
202
|
-
export function
|
|
203
|
-
|
|
204
|
-
if (elem) {
|
|
205
|
-
let next;
|
|
206
|
-
for (let n = nodeBefore.nextSibling; n && n !== nodeAfter; n = next) {
|
|
207
|
-
next = n.nextSibling;
|
|
208
|
-
domDispose(n);
|
|
209
|
-
elem.removeChild(n);
|
|
210
|
-
}
|
|
211
|
-
if (content) {
|
|
212
|
-
elem.insertBefore(content instanceof G.Node ? content : frag(content), nodeAfter);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
192
|
+
export function makeTestId(prefix) {
|
|
193
|
+
return clsPrefix.bind(null, prefix);
|
|
215
194
|
}
|
|
216
|
-
export function domComputed(valueObs, contentFunc) {
|
|
217
|
-
const _contentFunc = contentFunc || identity;
|
|
218
|
-
return (elem) => {
|
|
219
|
-
const markerPre = G.document.createComment('a');
|
|
220
|
-
const markerPost = G.document.createComment('b');
|
|
221
|
-
elem.appendChild(markerPre);
|
|
222
|
-
elem.appendChild(markerPost);
|
|
223
|
-
_subscribe(elem, valueObs, (value) => replaceContent(markerPre, markerPost, _contentFunc(value)));
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
function identity(arg) { return arg; }
|
|
227
195
|
/**
|
|
228
|
-
*
|
|
229
|
-
* a computed is created), whose value -- if truthy -- will be passed to `contentFunc` which
|
|
230
|
-
* should return DOM content. If the value is falsy, DOM content is removed.
|
|
231
|
-
*
|
|
232
|
-
* Note that if the observable changes between different truthy values, contentFunc gets called
|
|
233
|
-
* for each value, and previous content gets destroyed. To consider all truthy values the same,
|
|
234
|
-
* use an observable that returns a proper boolean, e.g.
|
|
235
|
-
*
|
|
236
|
-
* dom.maybe(use => Boolean(use(fooObs)), () => dom(...));
|
|
237
|
-
*
|
|
238
|
-
* As with domComputed(), dom.maybe() may but should not be used when the argument is not an
|
|
239
|
-
* observable or function. The following are equivalent:
|
|
240
|
-
*
|
|
241
|
-
* dom(..., dom.maybe(myValue, () => dom(...)));
|
|
242
|
-
* dom(..., myValue ? dom(...) : null);
|
|
243
|
-
*
|
|
244
|
-
* The latter is preferred for being simpler.
|
|
245
|
-
*
|
|
246
|
-
* @param {Element} elem: The element to which to append the DOM content.
|
|
247
|
-
* @param {Object} boolValueObs: Observable or function for a computed.
|
|
248
|
-
* @param [Function] contentFunc: Function called with the result of boolValueObs when it is
|
|
249
|
-
* truthy. Should returning DOM as output.
|
|
196
|
+
* See documentation for TestId above.
|
|
250
197
|
*/
|
|
251
|
-
export
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
//# sourceMappingURL=_domMethods.js.map
|
|
198
|
+
export const noTestId = (name) => null;
|
|
199
|
+
//# sourceMappingURL=domMethods.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domMethods.js","sourceRoot":"","sources":["../../../lib/domMethods.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/lib/domevent.js
CHANGED
|
@@ -112,29 +112,48 @@ export function onMatch(selector, eventType, callback, { useCapture = false } =
|
|
|
112
112
|
return (elem) => { new DomEventMatchListener(elem, eventType, callback, useCapture, selector); };
|
|
113
113
|
}
|
|
114
114
|
/**
|
|
115
|
-
* Listen to key
|
|
116
|
-
* `elem` argument, and may be used as an argument to dom().
|
|
117
|
-
*
|
|
115
|
+
* Listen to key events (typically 'keydown' or 'keypress'), with specified per-key callbacks.
|
|
118
116
|
* Key names are listed at https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
|
|
119
117
|
*
|
|
118
|
+
* Methods onKeyPress() and onKeyDown() are intended to be used as arguments to dom().
|
|
119
|
+
*
|
|
120
|
+
* By default, handled events are stopped from bubbling with stopPropagation() and
|
|
121
|
+
* preventDefault(). If, however, you register a key with a "$" suffix (i.e. "Enter$" instead of
|
|
122
|
+
* "Enter"), then the event is allowed to bubble normally.
|
|
123
|
+
*
|
|
124
|
+
* When this handler is set on an element, we automatically ensure that tabindex attribute is set,
|
|
125
|
+
* to allow this element to receive keyboard events.
|
|
126
|
+
*
|
|
120
127
|
* For example:
|
|
121
128
|
*
|
|
122
129
|
* dom('input', ...
|
|
123
|
-
* dom.
|
|
130
|
+
* dom.onKeyDown({
|
|
124
131
|
* Enter: (e, elem) => console.log("Enter pressed"),
|
|
125
132
|
* Escape: (e, elem) => console.log("Escape pressed"),
|
|
133
|
+
* Delete$: (e, elem) => console.log("Delete pressed, will bubble"),
|
|
126
134
|
* })
|
|
127
135
|
* )
|
|
128
136
|
*/
|
|
129
|
-
export function
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
137
|
+
export function onKeyElem(elem, evType, keyHandlers) {
|
|
138
|
+
if (!(elem.tabIndex >= 0)) { // If tabIndex property is undefined or -1,
|
|
139
|
+
elem.setAttribute('tabindex', '-1'); // Set tabIndex attribute to make the element focusable.
|
|
140
|
+
}
|
|
141
|
+
return onElem(elem, evType, (ev, _elem) => {
|
|
142
|
+
const plainHandler = keyHandlers[ev.key];
|
|
143
|
+
const handler = plainHandler || keyHandlers[ev.key + '$'];
|
|
144
|
+
if (handler) {
|
|
145
|
+
if (plainHandler) {
|
|
146
|
+
ev.stopPropagation();
|
|
147
|
+
ev.preventDefault();
|
|
148
|
+
}
|
|
149
|
+
handler(ev, _elem);
|
|
134
150
|
}
|
|
135
151
|
});
|
|
136
152
|
}
|
|
137
|
-
export function onKeyPress(
|
|
138
|
-
return (elem) => {
|
|
153
|
+
export function onKeyPress(keyHandlers) {
|
|
154
|
+
return (elem) => { onKeyElem(elem, 'keypress', keyHandlers); };
|
|
155
|
+
}
|
|
156
|
+
export function onKeyDown(keyHandlers) {
|
|
157
|
+
return (elem) => { onKeyElem(elem, 'keydown', keyHandlers); };
|
|
139
158
|
}
|
|
140
159
|
//# sourceMappingURL=domevent.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domevent.js","sourceRoot":"","sources":["../../../lib/domevent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;
|
|
1
|
+
{"version":3,"file":"domevent.js","sourceRoot":"","sources":["../../../lib/domevent.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/lib/emit.js
CHANGED
|
@@ -101,7 +101,8 @@ export class Emitter extends LLink {
|
|
|
101
101
|
* Sets the single callback that would get called when a listener is added or removed.
|
|
102
102
|
* @param {Function} changeCB(hasListeners): Function to call after a listener is added or
|
|
103
103
|
* removed. It's called with a boolean indicating whether this Emitter has any listeners.
|
|
104
|
-
* Pass in `null` to unset the callback.
|
|
104
|
+
* Pass in `null` to unset the callback. Note that it can be called multiple times in a row
|
|
105
|
+
* with hasListeners `true`.
|
|
105
106
|
*/
|
|
106
107
|
setChangeCB(changeCB, optContext) {
|
|
107
108
|
this._changeCB = changeCB || _noop;
|
package/dist/esm/lib/emit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../../../lib/emit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,oDAAoD;AACpD,EAAE;AACF,8FAA8F;AAC9F,2FAA2F;AAC3F,+FAA+F;AAC/F,+FAA+F;AAC/F,8FAA8F;AAC9F,EAAE;AACF,kGAAkG;AAClG,gGAAgG;AAChG,4FAA4F;AAC5F,8BAA8B;AAE9B,wDAAwD;AAExD,
|
|
1
|
+
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../../../lib/emit.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/lib/kowrap.js
CHANGED
|
@@ -19,23 +19,51 @@
|
|
|
19
19
|
* knockout as a dependency of grainjs.
|
|
20
20
|
*
|
|
21
21
|
* In both cases, calling fromKo/toKo twice on the same observable will return the same wrapper,
|
|
22
|
-
* and subscriptions and disposal are appropriately set up to make usage seamless.
|
|
22
|
+
* and subscriptions and disposal are appropriately set up to make usage seamless. In particular,
|
|
23
|
+
* the returned wrapper should not be disposed; it's tied to the lifetime of the wrapped object.
|
|
23
24
|
*/
|
|
24
|
-
import {
|
|
25
|
+
import { domDisposeHooks } from './domDispose';
|
|
26
|
+
import { bundleChanges, Observable } from './observable';
|
|
25
27
|
const fromKoWrappers = new WeakMap();
|
|
26
28
|
const toKoWrappers = new WeakMap();
|
|
27
29
|
/**
|
|
28
30
|
* Returns a Grain.js observable which mirrors a Knockout observable.
|
|
31
|
+
*
|
|
32
|
+
* Do not dispose this wrapper, as it is shared by all code using koObs, and its lifetime is tied
|
|
33
|
+
* to the lifetime of koObs. If unused, it consumes minimal resources, and should get garbage
|
|
34
|
+
* collected along with koObs.
|
|
29
35
|
*/
|
|
30
|
-
export function fromKo(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
export function fromKo(koObs) {
|
|
37
|
+
return fromKoWrappers.get(koObs) || fromKoWrappers.set(koObs, new KoWrapObs(koObs)).get(koObs);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* An Observable that wraps a Knockout observable, created via fromKo(). It keeps minimal overhead
|
|
41
|
+
* when unused by only subscribing to the wrapped observable while it itself has subscriptions.
|
|
42
|
+
*
|
|
43
|
+
* This way, when unused, the only reference is from the wrapper to the wrapped object. KoWrapObs
|
|
44
|
+
* should not be disposed; its lifetime is tied to that of the wrapped object.
|
|
45
|
+
*/
|
|
46
|
+
export class KoWrapObs extends Observable {
|
|
47
|
+
constructor(_koObs) {
|
|
48
|
+
super(_koObs.peek());
|
|
49
|
+
this._koObs = _koObs;
|
|
50
|
+
this._koSub = null;
|
|
51
|
+
this.setListenerChangeCB((hasListeners) => {
|
|
52
|
+
if (!hasListeners) {
|
|
53
|
+
this._koSub.dispose();
|
|
54
|
+
this._koSub = null;
|
|
55
|
+
}
|
|
56
|
+
else if (!this._koSub) {
|
|
57
|
+
// TODO this is a little hack, really, BaseObservable should expose a way to set the value
|
|
58
|
+
// directly by derived classes, i.e. a protected setter.
|
|
59
|
+
this._value = this._koObs.peek();
|
|
60
|
+
this._koSub = this._koObs.subscribe((val) => this.setAndTrigger(val));
|
|
61
|
+
}
|
|
62
|
+
});
|
|
34
63
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return newObs;
|
|
64
|
+
get() { return this._koObs.peek(); }
|
|
65
|
+
set(value) { bundleChanges(() => this._koObs(value)); }
|
|
66
|
+
dispose() { throw new Error("KoWrapObs should not be disposed"); }
|
|
39
67
|
}
|
|
40
68
|
/**
|
|
41
69
|
* Returns a Knockout observable which mirrors a Grain.js observable.
|
|
@@ -50,4 +78,56 @@ export function toKo(knockout, grainObs) {
|
|
|
50
78
|
grainObs.addListener((val) => newKoObs(val));
|
|
51
79
|
return newKoObs;
|
|
52
80
|
}
|
|
81
|
+
// Marker for when knockout-disposal integration has already been setup.
|
|
82
|
+
let koDisposalIsSetup = false;
|
|
83
|
+
/**
|
|
84
|
+
* Set up integration between grainjs and knockout disposal. Knockout does cleanup using
|
|
85
|
+
* ko.removeNode / ko.cleanNode (it also takes care of JQuery cleanup if needed). GrainJS does
|
|
86
|
+
* cleanup using dom.domDispose(). By default these don't know about each other.
|
|
87
|
+
*
|
|
88
|
+
* If you mix the two libraries, however, disposing an element may need to trigger disposers
|
|
89
|
+
* registered by either library.
|
|
90
|
+
*
|
|
91
|
+
* This method ensures that this happens.
|
|
92
|
+
*
|
|
93
|
+
* Note: grainjs disposes text nodes too, but nothing relies on it. When disposal is triggered via
|
|
94
|
+
* knockout, we are forced to rely on knockout's node traversal which ignores text nodes.
|
|
95
|
+
*/
|
|
96
|
+
export function setupKoDisposal(ko) {
|
|
97
|
+
// Ensure we don't do the setup more than once, or things will get called multiple times.
|
|
98
|
+
if (koDisposalIsSetup) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
koDisposalIsSetup = true;
|
|
102
|
+
const koDomNodeDisposal = ko.utils.domNodeDisposal;
|
|
103
|
+
// Knockout by default has an external-data-cleanup func set to cleanup JQuery. Whatever it is
|
|
104
|
+
// set to, we will continue calling it, and also will call grainjs domDisposeNode.
|
|
105
|
+
const origKoCleanExternalData = koDomNodeDisposal.cleanExternalData;
|
|
106
|
+
// The original function called by grainjs to clean nodes recursively. We'll override it.
|
|
107
|
+
const origGrainDisposeRecursive = domDisposeHooks.disposeRecursive;
|
|
108
|
+
// New function called by knockout to do extra cleanup. Now calls grainjs single-node cleanup.
|
|
109
|
+
// (In knockout, we can only override single-node cleanup.)
|
|
110
|
+
function newKoCleanExternalData(node) {
|
|
111
|
+
origKoCleanExternalData(node);
|
|
112
|
+
domDisposeHooks.disposeNode(node);
|
|
113
|
+
}
|
|
114
|
+
// Function called by grainjs to clean nodes recursively. We override the recursive cleanup
|
|
115
|
+
// function to call the recursive knockout cleanup (letting knockout do the dom traversal it
|
|
116
|
+
// normally does).
|
|
117
|
+
function newGrainDisposeRecursive(node) {
|
|
118
|
+
origGrainDisposeRecursive(node);
|
|
119
|
+
// While doing knockout cleanup, do NOT have it call grainjs cleanup too, as that would cause
|
|
120
|
+
// multiple unnecessary traversals of DOM.
|
|
121
|
+
koDomNodeDisposal.cleanExternalData = origKoCleanExternalData;
|
|
122
|
+
try {
|
|
123
|
+
ko.cleanNode(node);
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
koDomNodeDisposal.cleanExternalData = newKoCleanExternalData;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Use knockout and grainjs hooks to actually set the new cleanup functions.
|
|
130
|
+
koDomNodeDisposal.cleanExternalData = newKoCleanExternalData;
|
|
131
|
+
domDisposeHooks.disposeRecursive = newGrainDisposeRecursive;
|
|
132
|
+
}
|
|
53
133
|
//# sourceMappingURL=kowrap.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kowrap.js","sourceRoot":"","sources":["../../../lib/kowrap.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"kowrap.js","sourceRoot":"","sources":["../../../lib/kowrap.ts"],"names":[],"mappings":"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"}
|