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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
const _domImpl_1 = require("./_domImpl");
|
|
3
|
+
exports.noTestId = exports.makeTestId = exports.getData = exports.data = exports.dataElem = exports.clsPrefix = exports.cls = exports.clsElem = exports.hide = exports.hideElem = exports.show = exports.showElem = exports.prop = exports.propElem = exports.style = exports.styleElem = exports.text = exports.textElem = exports.boolAttr = exports.boolAttrElem = exports.attr = exports.attrElem = exports.attrs = exports.attrsElem = void 0;
|
|
5
4
|
const binding_1 = require("./binding");
|
|
5
|
+
const domDispose_1 = require("./domDispose");
|
|
6
6
|
// Use the browser globals in a way that allows replacing them with mocks in tests.
|
|
7
7
|
const browserGlobals_1 = require("./browserGlobals");
|
|
8
8
|
/**
|
|
@@ -10,13 +10,6 @@ const browserGlobals_1 = require("./browserGlobals");
|
|
|
10
10
|
* values from being garbage collected when the owning DOM elements are no longer used.
|
|
11
11
|
*/
|
|
12
12
|
const _dataMap = new WeakMap();
|
|
13
|
-
/**
|
|
14
|
-
* Internal helper that binds the callback to valueObs, which may be a value, observble, or
|
|
15
|
-
* function, and attaches a disposal callback to the passed-in element.
|
|
16
|
-
*/
|
|
17
|
-
function _subscribe(elem, valueObs, callback) {
|
|
18
|
-
_domDispose_1.autoDisposeElem(elem, binding_1.subscribe(valueObs, callback));
|
|
19
|
-
}
|
|
20
13
|
/**
|
|
21
14
|
* Sets multiple attributes of a DOM element. The `attrs()` variant takes no `elem` argument.
|
|
22
15
|
* Null and undefined values are omitted, and booleans are either omitted or set to empty string.
|
|
@@ -53,7 +46,7 @@ function attrElem(elem, attrName, attrValue) {
|
|
|
53
46
|
}
|
|
54
47
|
exports.attrElem = attrElem;
|
|
55
48
|
function attr(attrName, attrValueObs) {
|
|
56
|
-
return (elem) =>
|
|
49
|
+
return (elem) => binding_1.subscribeElem(elem, attrValueObs, (val) => attrElem(elem, attrName, val));
|
|
57
50
|
}
|
|
58
51
|
exports.attr = attr;
|
|
59
52
|
/**
|
|
@@ -69,7 +62,7 @@ function boolAttrElem(elem, attrName, boolValue) {
|
|
|
69
62
|
}
|
|
70
63
|
exports.boolAttrElem = boolAttrElem;
|
|
71
64
|
function boolAttr(attrName, boolValueObs) {
|
|
72
|
-
return (elem) =>
|
|
65
|
+
return (elem) => binding_1.subscribeElem(elem, boolValueObs, (val) => boolAttrElem(elem, attrName, val));
|
|
73
66
|
}
|
|
74
67
|
exports.boolAttr = boolAttr;
|
|
75
68
|
/**
|
|
@@ -85,7 +78,7 @@ exports.textElem = textElem;
|
|
|
85
78
|
function text(valueObs) {
|
|
86
79
|
return (elem) => {
|
|
87
80
|
const textNode = browserGlobals_1.G.document.createTextNode('');
|
|
88
|
-
|
|
81
|
+
binding_1.subscribeElem(elem, valueObs, (val) => { textNode.nodeValue = val; });
|
|
89
82
|
elem.appendChild(textNode);
|
|
90
83
|
};
|
|
91
84
|
}
|
|
@@ -102,7 +95,7 @@ function styleElem(elem, property, value) {
|
|
|
102
95
|
}
|
|
103
96
|
exports.styleElem = styleElem;
|
|
104
97
|
function style(property, valueObs) {
|
|
105
|
-
return (elem) =>
|
|
98
|
+
return (elem) => binding_1.subscribeElem(elem, valueObs, (val) => styleElem(elem, property, val));
|
|
106
99
|
}
|
|
107
100
|
exports.style = style;
|
|
108
101
|
/**
|
|
@@ -117,7 +110,7 @@ function propElem(elem, property, value) {
|
|
|
117
110
|
}
|
|
118
111
|
exports.propElem = propElem;
|
|
119
112
|
function prop(property, valueObs) {
|
|
120
|
-
return (elem) =>
|
|
113
|
+
return (elem) => binding_1.subscribeElem(elem, valueObs, (val) => propElem(elem, property, val));
|
|
121
114
|
}
|
|
122
115
|
exports.prop = prop;
|
|
123
116
|
/**
|
|
@@ -132,7 +125,7 @@ function showElem(elem, boolValue) {
|
|
|
132
125
|
}
|
|
133
126
|
exports.showElem = showElem;
|
|
134
127
|
function show(boolValueObs) {
|
|
135
|
-
return (elem) =>
|
|
128
|
+
return (elem) => binding_1.subscribeElem(elem, boolValueObs, (val) => showElem(elem, val));
|
|
136
129
|
}
|
|
137
130
|
exports.show = show;
|
|
138
131
|
/**
|
|
@@ -146,7 +139,7 @@ function hideElem(elem, boolValue) {
|
|
|
146
139
|
}
|
|
147
140
|
exports.hideElem = hideElem;
|
|
148
141
|
function hide(boolValueObs) {
|
|
149
|
-
return (elem) =>
|
|
142
|
+
return (elem) => binding_1.subscribeElem(elem, boolValueObs, (val) => hideElem(elem, val));
|
|
150
143
|
}
|
|
151
144
|
exports.hide = hide;
|
|
152
145
|
/**
|
|
@@ -164,7 +157,7 @@ function cls(className, boolValue) {
|
|
|
164
157
|
return (elem) => clsElem(elem, className, boolValue);
|
|
165
158
|
}
|
|
166
159
|
else {
|
|
167
|
-
return (elem) =>
|
|
160
|
+
return (elem) => binding_1.subscribeElem(elem, boolValue, (val) => clsElem(elem, className, val));
|
|
168
161
|
}
|
|
169
162
|
}
|
|
170
163
|
exports.cls = cls;
|
|
@@ -180,7 +173,7 @@ exports.clsPrefix = clsPrefix;
|
|
|
180
173
|
function _clsDynamicPrefix(prefix, className) {
|
|
181
174
|
return (elem) => {
|
|
182
175
|
let prevClass = null;
|
|
183
|
-
|
|
176
|
+
binding_1.subscribeElem(elem, className, (name) => {
|
|
184
177
|
if (prevClass) {
|
|
185
178
|
elem.classList.remove(prevClass);
|
|
186
179
|
}
|
|
@@ -204,13 +197,13 @@ function dataElem(elem, key, value) {
|
|
|
204
197
|
obj[key] = value;
|
|
205
198
|
}
|
|
206
199
|
else {
|
|
207
|
-
|
|
200
|
+
domDispose_1.onDisposeElem(elem, () => _dataMap.delete(elem));
|
|
208
201
|
_dataMap.set(elem, { [key]: value });
|
|
209
202
|
}
|
|
210
203
|
}
|
|
211
204
|
exports.dataElem = dataElem;
|
|
212
205
|
function data(key, valueObs) {
|
|
213
|
-
return (elem) =>
|
|
206
|
+
return (elem) => binding_1.subscribeElem(elem, valueObs, (val) => dataElem(elem, key, val));
|
|
214
207
|
}
|
|
215
208
|
exports.data = data;
|
|
216
209
|
function getData(elem, key) {
|
|
@@ -219,63 +212,15 @@ function getData(elem, key) {
|
|
|
219
212
|
}
|
|
220
213
|
exports.getData = getData;
|
|
221
214
|
/**
|
|
222
|
-
*
|
|
223
|
-
* same parent node. New content may be anything allowed as an argument to dom(), including null
|
|
224
|
-
* to insert nothing. Runs disposers, if any, on all removed content.
|
|
215
|
+
* See documentation for TestId above.
|
|
225
216
|
*/
|
|
226
|
-
function
|
|
227
|
-
|
|
228
|
-
if (elem) {
|
|
229
|
-
let next;
|
|
230
|
-
for (let n = nodeBefore.nextSibling; n && n !== nodeAfter; n = next) {
|
|
231
|
-
next = n.nextSibling;
|
|
232
|
-
_domDispose_1.domDispose(n);
|
|
233
|
-
elem.removeChild(n);
|
|
234
|
-
}
|
|
235
|
-
if (content) {
|
|
236
|
-
elem.insertBefore(content instanceof browserGlobals_1.G.Node ? content : _domImpl_1.frag(content), nodeAfter);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
217
|
+
function makeTestId(prefix) {
|
|
218
|
+
return clsPrefix.bind(null, prefix);
|
|
239
219
|
}
|
|
240
|
-
exports.
|
|
241
|
-
function domComputed(valueObs, contentFunc) {
|
|
242
|
-
const _contentFunc = contentFunc || identity;
|
|
243
|
-
return (elem) => {
|
|
244
|
-
const markerPre = browserGlobals_1.G.document.createComment('a');
|
|
245
|
-
const markerPost = browserGlobals_1.G.document.createComment('b');
|
|
246
|
-
elem.appendChild(markerPre);
|
|
247
|
-
elem.appendChild(markerPost);
|
|
248
|
-
_subscribe(elem, valueObs, (value) => replaceContent(markerPre, markerPost, _contentFunc(value)));
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
exports.domComputed = domComputed;
|
|
252
|
-
function identity(arg) { return arg; }
|
|
220
|
+
exports.makeTestId = makeTestId;
|
|
253
221
|
/**
|
|
254
|
-
*
|
|
255
|
-
* a computed is created), whose value -- if truthy -- will be passed to `contentFunc` which
|
|
256
|
-
* should return DOM content. If the value is falsy, DOM content is removed.
|
|
257
|
-
*
|
|
258
|
-
* Note that if the observable changes between different truthy values, contentFunc gets called
|
|
259
|
-
* for each value, and previous content gets destroyed. To consider all truthy values the same,
|
|
260
|
-
* use an observable that returns a proper boolean, e.g.
|
|
261
|
-
*
|
|
262
|
-
* dom.maybe(use => Boolean(use(fooObs)), () => dom(...));
|
|
263
|
-
*
|
|
264
|
-
* As with domComputed(), dom.maybe() may but should not be used when the argument is not an
|
|
265
|
-
* observable or function. The following are equivalent:
|
|
266
|
-
*
|
|
267
|
-
* dom(..., dom.maybe(myValue, () => dom(...)));
|
|
268
|
-
* dom(..., myValue ? dom(...) : null);
|
|
269
|
-
*
|
|
270
|
-
* The latter is preferred for being simpler.
|
|
271
|
-
*
|
|
272
|
-
* @param {Element} elem: The element to which to append the DOM content.
|
|
273
|
-
* @param {Object} boolValueObs: Observable or function for a computed.
|
|
274
|
-
* @param [Function] contentFunc: Function called with the result of boolValueObs when it is
|
|
275
|
-
* truthy. Should returning DOM as output.
|
|
222
|
+
* See documentation for TestId above.
|
|
276
223
|
*/
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
exports.maybe = maybe;
|
|
281
|
-
//# sourceMappingURL=_domMethods.js.map
|
|
224
|
+
const noTestId = (name) => null;
|
|
225
|
+
exports.noTestId = noTestId;
|
|
226
|
+
//# sourceMappingURL=domMethods.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domMethods.js","sourceRoot":"","sources":["../../../lib/domMethods.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,9 +38,11 @@
|
|
|
38
38
|
* If you need to remove the callback on first call, here's a useful pattern:
|
|
39
39
|
* let lis = domevent.onElem(elem, 'mouseup', e => { lis.dispose(); other_work(); });
|
|
40
40
|
*/
|
|
41
|
-
import { DomElementMethod } from './_domImpl';
|
|
42
41
|
import { IDisposable } from './dispose';
|
|
43
|
-
|
|
42
|
+
import { DomElementMethod, DomMethod } from './domImpl';
|
|
43
|
+
export declare type EventName = keyof HTMLElementEventMap;
|
|
44
|
+
export declare type EventType<E extends EventName | string> = E extends EventName ? HTMLElementEventMap[E] : Event;
|
|
45
|
+
export declare type EventCB<E extends Event = Event, T extends EventTarget = EventTarget> = (this: void, event: E, elem: T) => void;
|
|
44
46
|
/**
|
|
45
47
|
* Listen to a DOM event. The `on()` variant takes no `elem` argument, and may be used as an
|
|
46
48
|
* argument to dom() function.
|
|
@@ -51,12 +53,12 @@ export declare type EventCB = (this: void, event: Event, elem: Element) => void;
|
|
|
51
53
|
* rarely be useful (e.g. JQuery doesn't even offer it as an option).
|
|
52
54
|
* @returns {Object} Listener object whose .dispose() method will remove the event listener.
|
|
53
55
|
*/
|
|
54
|
-
export declare function onElem(elem:
|
|
55
|
-
useCapture?: boolean;
|
|
56
|
+
export declare function onElem<E extends EventName | string, T extends EventTarget>(elem: T, eventType: E, callback: EventCB<EventType<E>, T>, { useCapture }?: {
|
|
57
|
+
useCapture?: boolean | undefined;
|
|
56
58
|
}): IDisposable;
|
|
57
|
-
export declare function on(eventType:
|
|
58
|
-
useCapture?: boolean;
|
|
59
|
-
}):
|
|
59
|
+
export declare function on<E extends EventName | string, T extends EventTarget>(eventType: E, callback: EventCB<EventType<E>, T>, { useCapture }?: {
|
|
60
|
+
useCapture?: boolean | undefined;
|
|
61
|
+
}): DomMethod<T>;
|
|
60
62
|
/**
|
|
61
63
|
* Listen to a DOM event on descendants of the given elem matching the given selector. The
|
|
62
64
|
* `onMatch()` variant takes no `elem` argument, and may be used as an argument to dom().
|
|
@@ -72,30 +74,39 @@ export declare function on(eventType: string, callback: EventCB, {useCapture}?:
|
|
|
72
74
|
* rarely be useful (e.g. JQuery doesn't even offer it as an option).
|
|
73
75
|
* @returns {Object} Listener object whose .dispose() method will remove the event listener.
|
|
74
76
|
*/
|
|
75
|
-
export declare function onMatchElem(elem: EventTarget, selector: string, eventType: string, callback: EventCB, {useCapture}?: {
|
|
76
|
-
useCapture?: boolean;
|
|
77
|
+
export declare function onMatchElem(elem: EventTarget, selector: string, eventType: string, callback: EventCB, { useCapture }?: {
|
|
78
|
+
useCapture?: boolean | undefined;
|
|
77
79
|
}): IDisposable;
|
|
78
|
-
export declare function onMatch(selector: string, eventType: string, callback: EventCB, {useCapture}?: {
|
|
79
|
-
useCapture?: boolean;
|
|
80
|
+
export declare function onMatch(selector: string, eventType: string, callback: EventCB, { useCapture }?: {
|
|
81
|
+
useCapture?: boolean | undefined;
|
|
80
82
|
}): DomElementMethod;
|
|
83
|
+
export declare type KeyEventType = 'keypress' | 'keyup' | 'keydown';
|
|
84
|
+
export interface IKeyHandlers<T extends HTMLElement = HTMLElement> {
|
|
85
|
+
[key: string]: (this: void, ev: KeyboardEvent, elem: T) => void;
|
|
86
|
+
}
|
|
81
87
|
/**
|
|
82
|
-
* Listen to key
|
|
83
|
-
* `elem` argument, and may be used as an argument to dom().
|
|
84
|
-
*
|
|
88
|
+
* Listen to key events (typically 'keydown' or 'keypress'), with specified per-key callbacks.
|
|
85
89
|
* Key names are listed at https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
|
|
86
90
|
*
|
|
91
|
+
* Methods onKeyPress() and onKeyDown() are intended to be used as arguments to dom().
|
|
92
|
+
*
|
|
93
|
+
* By default, handled events are stopped from bubbling with stopPropagation() and
|
|
94
|
+
* preventDefault(). If, however, you register a key with a "$" suffix (i.e. "Enter$" instead of
|
|
95
|
+
* "Enter"), then the event is allowed to bubble normally.
|
|
96
|
+
*
|
|
97
|
+
* When this handler is set on an element, we automatically ensure that tabindex attribute is set,
|
|
98
|
+
* to allow this element to receive keyboard events.
|
|
99
|
+
*
|
|
87
100
|
* For example:
|
|
88
101
|
*
|
|
89
102
|
* dom('input', ...
|
|
90
|
-
* dom.
|
|
103
|
+
* dom.onKeyDown({
|
|
91
104
|
* Enter: (e, elem) => console.log("Enter pressed"),
|
|
92
105
|
* Escape: (e, elem) => console.log("Escape pressed"),
|
|
106
|
+
* Delete$: (e, elem) => console.log("Delete pressed, will bubble"),
|
|
93
107
|
* })
|
|
94
108
|
* )
|
|
95
109
|
*/
|
|
96
|
-
export declare function
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
export declare function onKeyPress(callbacks: {
|
|
100
|
-
[key: string]: EventCB;
|
|
101
|
-
}): DomElementMethod;
|
|
110
|
+
export declare function onKeyElem<T extends HTMLElement>(elem: T, evType: KeyEventType, keyHandlers: IKeyHandlers<T>): IDisposable;
|
|
111
|
+
export declare function onKeyPress<T extends HTMLElement>(keyHandlers: IKeyHandlers<T>): DomMethod<T>;
|
|
112
|
+
export declare function onKeyDown<T extends HTMLElement>(keyHandlers: IKeyHandlers<T>): DomMethod<T>;
|
package/dist/cjs/lib/domevent.js
CHANGED
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
* let lis = domevent.onElem(elem, 'mouseup', e => { lis.dispose(); other_work(); });
|
|
41
41
|
*/
|
|
42
42
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.onKeyDown = exports.onKeyPress = exports.onKeyElem = exports.onMatch = exports.onMatchElem = exports.on = exports.onElem = void 0;
|
|
43
44
|
function _findMatch(inner, outer, selector) {
|
|
44
45
|
for (let el = inner; el && el !== outer; el = el.parentElement) {
|
|
45
46
|
if (el.matches(selector)) {
|
|
@@ -118,31 +119,51 @@ function onMatch(selector, eventType, callback, { useCapture = false } = {}) {
|
|
|
118
119
|
}
|
|
119
120
|
exports.onMatch = onMatch;
|
|
120
121
|
/**
|
|
121
|
-
* Listen to key
|
|
122
|
-
* `elem` argument, and may be used as an argument to dom().
|
|
123
|
-
*
|
|
122
|
+
* Listen to key events (typically 'keydown' or 'keypress'), with specified per-key callbacks.
|
|
124
123
|
* Key names are listed at https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
|
|
125
124
|
*
|
|
125
|
+
* Methods onKeyPress() and onKeyDown() are intended to be used as arguments to dom().
|
|
126
|
+
*
|
|
127
|
+
* By default, handled events are stopped from bubbling with stopPropagation() and
|
|
128
|
+
* preventDefault(). If, however, you register a key with a "$" suffix (i.e. "Enter$" instead of
|
|
129
|
+
* "Enter"), then the event is allowed to bubble normally.
|
|
130
|
+
*
|
|
131
|
+
* When this handler is set on an element, we automatically ensure that tabindex attribute is set,
|
|
132
|
+
* to allow this element to receive keyboard events.
|
|
133
|
+
*
|
|
126
134
|
* For example:
|
|
127
135
|
*
|
|
128
136
|
* dom('input', ...
|
|
129
|
-
* dom.
|
|
137
|
+
* dom.onKeyDown({
|
|
130
138
|
* Enter: (e, elem) => console.log("Enter pressed"),
|
|
131
139
|
* Escape: (e, elem) => console.log("Escape pressed"),
|
|
140
|
+
* Delete$: (e, elem) => console.log("Delete pressed, will bubble"),
|
|
132
141
|
* })
|
|
133
142
|
* )
|
|
134
143
|
*/
|
|
135
|
-
function
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
144
|
+
function onKeyElem(elem, evType, keyHandlers) {
|
|
145
|
+
if (!(elem.tabIndex >= 0)) { // If tabIndex property is undefined or -1,
|
|
146
|
+
elem.setAttribute('tabindex', '-1'); // Set tabIndex attribute to make the element focusable.
|
|
147
|
+
}
|
|
148
|
+
return onElem(elem, evType, (ev, _elem) => {
|
|
149
|
+
const plainHandler = keyHandlers[ev.key];
|
|
150
|
+
const handler = plainHandler || keyHandlers[ev.key + '$'];
|
|
151
|
+
if (handler) {
|
|
152
|
+
if (plainHandler) {
|
|
153
|
+
ev.stopPropagation();
|
|
154
|
+
ev.preventDefault();
|
|
155
|
+
}
|
|
156
|
+
handler(ev, _elem);
|
|
140
157
|
}
|
|
141
158
|
});
|
|
142
159
|
}
|
|
143
|
-
exports.
|
|
144
|
-
function onKeyPress(
|
|
145
|
-
return (elem) => {
|
|
160
|
+
exports.onKeyElem = onKeyElem;
|
|
161
|
+
function onKeyPress(keyHandlers) {
|
|
162
|
+
return (elem) => { onKeyElem(elem, 'keypress', keyHandlers); };
|
|
146
163
|
}
|
|
147
164
|
exports.onKeyPress = onKeyPress;
|
|
165
|
+
function onKeyDown(keyHandlers) {
|
|
166
|
+
return (elem) => { onKeyElem(elem, 'keydown', keyHandlers); };
|
|
167
|
+
}
|
|
168
|
+
exports.onKeyDown = onKeyDown;
|
|
148
169
|
//# 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/cjs/lib/emit.d.ts
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* emit.js implements an Emitter class which emits events to a list of listeners. Listeners are
|
|
3
|
+
* simply functions to call, and "emitting an event" just calls those functions.
|
|
4
|
+
*
|
|
5
|
+
* This is similar to Backbone events, with more focus on efficiency. Both inserting and removing
|
|
6
|
+
* listeners is constant time.
|
|
7
|
+
*
|
|
8
|
+
* To create an emitter:
|
|
9
|
+
* let emitter = new Emitter();
|
|
10
|
+
*
|
|
11
|
+
* To add a listener:
|
|
12
|
+
* let listener = fooEmitter.addListener(callback);
|
|
13
|
+
* To remove a listener:
|
|
14
|
+
* listener.dispose();
|
|
15
|
+
*
|
|
16
|
+
* The only way to remove a listener is to dispose the Listener object returned by addListener().
|
|
17
|
+
* You can often use autoDispose to do this automatically when subscribing in a constructor:
|
|
18
|
+
* this.autoDispose(fooEmitter.addListener(this.onFoo, this));
|
|
19
|
+
*
|
|
20
|
+
* To emit an event, call emit() with any number of arguments:
|
|
21
|
+
* emitter.emit("hello", "world");
|
|
22
|
+
*/
|
|
1
23
|
export declare type ListenerCB<T> = (this: T, ...args: any[]) => void;
|
|
2
24
|
export declare type ChangeCB = (hasListeners: boolean) => void;
|
|
3
25
|
/**
|
|
@@ -34,7 +56,8 @@ export declare class Emitter extends LLink {
|
|
|
34
56
|
* Sets the single callback that would get called when a listener is added or removed.
|
|
35
57
|
* @param {Function} changeCB(hasListeners): Function to call after a listener is added or
|
|
36
58
|
* removed. It's called with a boolean indicating whether this Emitter has any listeners.
|
|
37
|
-
* Pass in `null` to unset the callback.
|
|
59
|
+
* Pass in `null` to unset the callback. Note that it can be called multiple times in a row
|
|
60
|
+
* with hasListeners `true`.
|
|
38
61
|
*/
|
|
39
62
|
setChangeCB(changeCB: ChangeCB, optContext?: any): void;
|
|
40
63
|
/**
|
|
@@ -58,7 +81,7 @@ export declare class Emitter extends LLink {
|
|
|
58
81
|
export declare class Listener extends LLink {
|
|
59
82
|
private emitter;
|
|
60
83
|
private callback;
|
|
61
|
-
private context
|
|
84
|
+
private context?;
|
|
62
85
|
static callAll(begin: LLink, end: LLink, args: any[]): void;
|
|
63
86
|
constructor(emitter: Emitter, callback: ListenerCB<any>, context?: any);
|
|
64
87
|
dispose(): void;
|
package/dist/cjs/lib/emit.js
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
* emitter.emit("hello", "world");
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.Listener = exports.Emitter = exports.LLink = void 0;
|
|
25
26
|
// Note about a possible alternative implementation.
|
|
26
27
|
//
|
|
27
28
|
// We could implement the same interface using an array of listeners. Certain issues apply, in
|
|
@@ -104,7 +105,8 @@ class Emitter extends LLink {
|
|
|
104
105
|
* Sets the single callback that would get called when a listener is added or removed.
|
|
105
106
|
* @param {Function} changeCB(hasListeners): Function to call after a listener is added or
|
|
106
107
|
* removed. It's called with a boolean indicating whether this Emitter has any listeners.
|
|
107
|
-
* Pass in `null` to unset the callback.
|
|
108
|
+
* Pass in `null` to unset the callback. Note that it can be called multiple times in a row
|
|
109
|
+
* with hasListeners `true`.
|
|
108
110
|
*/
|
|
109
111
|
setChangeCB(changeCB, optContext) {
|
|
110
112
|
this._changeCB = changeCB || _noop;
|
package/dist/cjs/lib/emit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../../../lib/emit.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG
|
|
1
|
+
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../../../lib/emit.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/lib/kowrap.d.ts
CHANGED
|
@@ -19,22 +19,64 @@
|
|
|
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
25
|
import { Observable } from './observable';
|
|
25
|
-
export interface IKnockoutObservable<T> {
|
|
26
|
+
export interface IKnockoutObservable<T> extends IKnockoutReadObservable<T> {
|
|
26
27
|
(val: T): void;
|
|
28
|
+
}
|
|
29
|
+
export interface IKnockoutReadObservable<T> {
|
|
30
|
+
(): T;
|
|
27
31
|
peek(): T;
|
|
28
32
|
subscribe(callback: (newValue: T) => void, target?: any, event?: "change"): any;
|
|
33
|
+
getSubscriptionsCount(): number;
|
|
29
34
|
}
|
|
35
|
+
export declare type InferKoType<KObs extends IKnockoutReadObservable<any>> = KObs extends {
|
|
36
|
+
peek(): infer T;
|
|
37
|
+
} ? T : never;
|
|
30
38
|
/**
|
|
31
39
|
* Returns a Grain.js observable which mirrors a Knockout observable.
|
|
40
|
+
*
|
|
41
|
+
* Do not dispose this wrapper, as it is shared by all code using koObs, and its lifetime is tied
|
|
42
|
+
* to the lifetime of koObs. If unused, it consumes minimal resources, and should get garbage
|
|
43
|
+
* collected along with koObs.
|
|
44
|
+
*/
|
|
45
|
+
export declare function fromKo<KObs extends IKnockoutObservable<any>>(koObs: KObs): Observable<InferKoType<KObs>>;
|
|
46
|
+
/**
|
|
47
|
+
* An Observable that wraps a Knockout observable, created via fromKo(). It keeps minimal overhead
|
|
48
|
+
* when unused by only subscribing to the wrapped observable while it itself has subscriptions.
|
|
49
|
+
*
|
|
50
|
+
* This way, when unused, the only reference is from the wrapper to the wrapped object. KoWrapObs
|
|
51
|
+
* should not be disposed; its lifetime is tied to that of the wrapped object.
|
|
32
52
|
*/
|
|
33
|
-
export declare
|
|
53
|
+
export declare class KoWrapObs<T> extends Observable<T> {
|
|
54
|
+
private _koObs;
|
|
55
|
+
private _koSub;
|
|
56
|
+
constructor(_koObs: IKnockoutObservable<T>);
|
|
57
|
+
get(): T;
|
|
58
|
+
set(value: T): void;
|
|
59
|
+
dispose(): void;
|
|
60
|
+
}
|
|
34
61
|
export interface IKnockoutModule {
|
|
35
62
|
observable<T>(value: T): IKnockoutObservable<T>;
|
|
63
|
+
cleanNode(node: Node): void;
|
|
36
64
|
}
|
|
37
65
|
/**
|
|
38
66
|
* Returns a Knockout observable which mirrors a Grain.js observable.
|
|
39
67
|
*/
|
|
40
68
|
export declare function toKo<T>(knockout: IKnockoutModule, grainObs: Observable<T>): IKnockoutObservable<T>;
|
|
69
|
+
/**
|
|
70
|
+
* Set up integration between grainjs and knockout disposal. Knockout does cleanup using
|
|
71
|
+
* ko.removeNode / ko.cleanNode (it also takes care of JQuery cleanup if needed). GrainJS does
|
|
72
|
+
* cleanup using dom.domDispose(). By default these don't know about each other.
|
|
73
|
+
*
|
|
74
|
+
* If you mix the two libraries, however, disposing an element may need to trigger disposers
|
|
75
|
+
* registered by either library.
|
|
76
|
+
*
|
|
77
|
+
* This method ensures that this happens.
|
|
78
|
+
*
|
|
79
|
+
* Note: grainjs disposes text nodes too, but nothing relies on it. When disposal is triggered via
|
|
80
|
+
* knockout, we are forced to rely on knockout's node traversal which ignores text nodes.
|
|
81
|
+
*/
|
|
82
|
+
export declare function setupKoDisposal(ko: IKnockoutModule): void;
|
package/dist/cjs/lib/kowrap.js
CHANGED
|
@@ -20,26 +20,56 @@
|
|
|
20
20
|
* knockout as a dependency of grainjs.
|
|
21
21
|
*
|
|
22
22
|
* In both cases, calling fromKo/toKo twice on the same observable will return the same wrapper,
|
|
23
|
-
* and subscriptions and disposal are appropriately set up to make usage seamless.
|
|
23
|
+
* and subscriptions and disposal are appropriately set up to make usage seamless. In particular,
|
|
24
|
+
* the returned wrapper should not be disposed; it's tied to the lifetime of the wrapped object.
|
|
24
25
|
*/
|
|
25
26
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.setupKoDisposal = exports.toKo = exports.KoWrapObs = exports.fromKo = void 0;
|
|
28
|
+
const domDispose_1 = require("./domDispose");
|
|
26
29
|
const observable_1 = require("./observable");
|
|
27
30
|
const fromKoWrappers = new WeakMap();
|
|
28
31
|
const toKoWrappers = new WeakMap();
|
|
29
32
|
/**
|
|
30
33
|
* Returns a Grain.js observable which mirrors a Knockout observable.
|
|
34
|
+
*
|
|
35
|
+
* Do not dispose this wrapper, as it is shared by all code using koObs, and its lifetime is tied
|
|
36
|
+
* to the lifetime of koObs. If unused, it consumes minimal resources, and should get garbage
|
|
37
|
+
* collected along with koObs.
|
|
31
38
|
*/
|
|
32
|
-
function fromKo(
|
|
33
|
-
|
|
34
|
-
if (prevObs) {
|
|
35
|
-
return prevObs;
|
|
36
|
-
}
|
|
37
|
-
const newObs = observable_1.observable(koObservable.peek());
|
|
38
|
-
fromKoWrappers.set(koObservable, newObs);
|
|
39
|
-
koObservable.subscribe((val) => newObs.set(val));
|
|
40
|
-
return newObs;
|
|
39
|
+
function fromKo(koObs) {
|
|
40
|
+
return fromKoWrappers.get(koObs) || fromKoWrappers.set(koObs, new KoWrapObs(koObs)).get(koObs);
|
|
41
41
|
}
|
|
42
42
|
exports.fromKo = fromKo;
|
|
43
|
+
/**
|
|
44
|
+
* An Observable that wraps a Knockout observable, created via fromKo(). It keeps minimal overhead
|
|
45
|
+
* when unused by only subscribing to the wrapped observable while it itself has subscriptions.
|
|
46
|
+
*
|
|
47
|
+
* This way, when unused, the only reference is from the wrapper to the wrapped object. KoWrapObs
|
|
48
|
+
* should not be disposed; its lifetime is tied to that of the wrapped object.
|
|
49
|
+
*/
|
|
50
|
+
class KoWrapObs extends observable_1.Observable {
|
|
51
|
+
constructor(_koObs) {
|
|
52
|
+
super(_koObs.peek());
|
|
53
|
+
this._koObs = _koObs;
|
|
54
|
+
this._koSub = null;
|
|
55
|
+
this.setListenerChangeCB((hasListeners) => {
|
|
56
|
+
if (!hasListeners) {
|
|
57
|
+
this._koSub.dispose();
|
|
58
|
+
this._koSub = null;
|
|
59
|
+
}
|
|
60
|
+
else if (!this._koSub) {
|
|
61
|
+
// TODO this is a little hack, really, BaseObservable should expose a way to set the value
|
|
62
|
+
// directly by derived classes, i.e. a protected setter.
|
|
63
|
+
this._value = this._koObs.peek();
|
|
64
|
+
this._koSub = this._koObs.subscribe((val) => this.setAndTrigger(val));
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
get() { return this._koObs.peek(); }
|
|
69
|
+
set(value) { observable_1.bundleChanges(() => this._koObs(value)); }
|
|
70
|
+
dispose() { throw new Error("KoWrapObs should not be disposed"); }
|
|
71
|
+
}
|
|
72
|
+
exports.KoWrapObs = KoWrapObs;
|
|
43
73
|
/**
|
|
44
74
|
* Returns a Knockout observable which mirrors a Grain.js observable.
|
|
45
75
|
*/
|
|
@@ -54,4 +84,57 @@ function toKo(knockout, grainObs) {
|
|
|
54
84
|
return newKoObs;
|
|
55
85
|
}
|
|
56
86
|
exports.toKo = toKo;
|
|
87
|
+
// Marker for when knockout-disposal integration has already been setup.
|
|
88
|
+
let koDisposalIsSetup = false;
|
|
89
|
+
/**
|
|
90
|
+
* Set up integration between grainjs and knockout disposal. Knockout does cleanup using
|
|
91
|
+
* ko.removeNode / ko.cleanNode (it also takes care of JQuery cleanup if needed). GrainJS does
|
|
92
|
+
* cleanup using dom.domDispose(). By default these don't know about each other.
|
|
93
|
+
*
|
|
94
|
+
* If you mix the two libraries, however, disposing an element may need to trigger disposers
|
|
95
|
+
* registered by either library.
|
|
96
|
+
*
|
|
97
|
+
* This method ensures that this happens.
|
|
98
|
+
*
|
|
99
|
+
* Note: grainjs disposes text nodes too, but nothing relies on it. When disposal is triggered via
|
|
100
|
+
* knockout, we are forced to rely on knockout's node traversal which ignores text nodes.
|
|
101
|
+
*/
|
|
102
|
+
function setupKoDisposal(ko) {
|
|
103
|
+
// Ensure we don't do the setup more than once, or things will get called multiple times.
|
|
104
|
+
if (koDisposalIsSetup) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
koDisposalIsSetup = true;
|
|
108
|
+
const koDomNodeDisposal = ko.utils.domNodeDisposal;
|
|
109
|
+
// Knockout by default has an external-data-cleanup func set to cleanup JQuery. Whatever it is
|
|
110
|
+
// set to, we will continue calling it, and also will call grainjs domDisposeNode.
|
|
111
|
+
const origKoCleanExternalData = koDomNodeDisposal.cleanExternalData;
|
|
112
|
+
// The original function called by grainjs to clean nodes recursively. We'll override it.
|
|
113
|
+
const origGrainDisposeRecursive = domDispose_1.domDisposeHooks.disposeRecursive;
|
|
114
|
+
// New function called by knockout to do extra cleanup. Now calls grainjs single-node cleanup.
|
|
115
|
+
// (In knockout, we can only override single-node cleanup.)
|
|
116
|
+
function newKoCleanExternalData(node) {
|
|
117
|
+
origKoCleanExternalData(node);
|
|
118
|
+
domDispose_1.domDisposeHooks.disposeNode(node);
|
|
119
|
+
}
|
|
120
|
+
// Function called by grainjs to clean nodes recursively. We override the recursive cleanup
|
|
121
|
+
// function to call the recursive knockout cleanup (letting knockout do the dom traversal it
|
|
122
|
+
// normally does).
|
|
123
|
+
function newGrainDisposeRecursive(node) {
|
|
124
|
+
origGrainDisposeRecursive(node);
|
|
125
|
+
// While doing knockout cleanup, do NOT have it call grainjs cleanup too, as that would cause
|
|
126
|
+
// multiple unnecessary traversals of DOM.
|
|
127
|
+
koDomNodeDisposal.cleanExternalData = origKoCleanExternalData;
|
|
128
|
+
try {
|
|
129
|
+
ko.cleanNode(node);
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
koDomNodeDisposal.cleanExternalData = newKoCleanExternalData;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Use knockout and grainjs hooks to actually set the new cleanup functions.
|
|
136
|
+
koDomNodeDisposal.cleanExternalData = newKoCleanExternalData;
|
|
137
|
+
domDispose_1.domDisposeHooks.disposeRecursive = newGrainDisposeRecursive;
|
|
138
|
+
}
|
|
139
|
+
exports.setupKoDisposal = setupKoDisposal;
|
|
57
140
|
//# sourceMappingURL=kowrap.js.map
|