@gogocat/data-bind 1.11.0 → 2.0.0
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/.editorconfig +14 -14
- package/.vscode/launch.json +12 -12
- package/CONFIGURATION.md +294 -0
- package/REACTIVE_MODE.md +553 -0
- package/README.md +266 -829
- package/babel.config.json +30 -0
- package/dist/js/_escape.d.ts +14 -0
- package/dist/js/_escape.d.ts.map +1 -0
- package/dist/js/applyBinding.d.ts +11 -0
- package/dist/js/applyBinding.d.ts.map +1 -0
- package/dist/js/attrBinding.d.ts +12 -0
- package/dist/js/attrBinding.d.ts.map +1 -0
- package/dist/js/binder.d.ts +67 -0
- package/dist/js/binder.d.ts.map +1 -0
- package/dist/js/changeBinding.d.ts +19 -0
- package/dist/js/changeBinding.d.ts.map +1 -0
- package/dist/js/commentWrapper.d.ts +39 -0
- package/dist/js/commentWrapper.d.ts.map +1 -0
- package/dist/js/config.d.ts +55 -0
- package/dist/js/config.d.ts.map +1 -0
- package/dist/js/createBindingOption.d.ts +32 -0
- package/dist/js/createBindingOption.d.ts.map +1 -0
- package/dist/js/createEventBinding.d.ts +10 -0
- package/dist/js/createEventBinding.d.ts.map +1 -0
- package/dist/js/cssBinding.d.ts +15 -0
- package/dist/js/cssBinding.d.ts.map +1 -0
- package/dist/js/dataBind.js +2772 -2519
- package/dist/js/dataBind.min.js +8 -1
- package/dist/js/dataBind.min.js.map +1 -1
- package/dist/js/domWalker.d.ts +9 -0
- package/dist/js/domWalker.d.ts.map +1 -0
- package/dist/js/forOfBinding.d.ts +12 -0
- package/dist/js/forOfBinding.d.ts.map +1 -0
- package/dist/js/hoverBinding.d.ts +13 -0
- package/dist/js/hoverBinding.d.ts.map +1 -0
- package/dist/js/ifBinding.d.ts +12 -0
- package/dist/js/ifBinding.d.ts.map +1 -0
- package/dist/js/index.d.ts +10 -0
- package/dist/js/index.d.ts.map +1 -0
- package/dist/js/modelBinding.d.ts +12 -0
- package/dist/js/modelBinding.d.ts.map +1 -0
- package/dist/js/postProcess.d.ts +3 -0
- package/dist/js/postProcess.d.ts.map +1 -0
- package/dist/js/pubSub.d.ts +11 -0
- package/dist/js/pubSub.d.ts.map +1 -0
- package/dist/js/reactiveProxy.d.ts +28 -0
- package/dist/js/reactiveProxy.d.ts.map +1 -0
- package/dist/js/renderForOfBinding.d.ts +8 -0
- package/dist/js/renderForOfBinding.d.ts.map +1 -0
- package/dist/js/renderIfBinding.d.ts +22 -0
- package/dist/js/renderIfBinding.d.ts.map +1 -0
- package/dist/js/renderIteration.d.ts +16 -0
- package/dist/js/renderIteration.d.ts.map +1 -0
- package/dist/js/renderTemplate.d.ts +14 -0
- package/dist/js/renderTemplate.d.ts.map +1 -0
- package/dist/js/renderTemplatesBinding.d.ts +19 -0
- package/dist/js/renderTemplatesBinding.d.ts.map +1 -0
- package/dist/js/showBinding.d.ts +13 -0
- package/dist/js/showBinding.d.ts.map +1 -0
- package/dist/js/switchBinding.d.ts +13 -0
- package/dist/js/switchBinding.d.ts.map +1 -0
- package/dist/js/textBinding.d.ts +13 -0
- package/dist/js/textBinding.d.ts.map +1 -0
- package/dist/js/types/_escape.d.ts +14 -0
- package/dist/js/types/_escape.d.ts.map +1 -0
- package/dist/js/types/applyBinding.d.ts +11 -0
- package/dist/js/types/applyBinding.d.ts.map +1 -0
- package/dist/js/types/attrBinding.d.ts +12 -0
- package/dist/js/types/attrBinding.d.ts.map +1 -0
- package/dist/js/types/binder.d.ts +67 -0
- package/dist/js/types/binder.d.ts.map +1 -0
- package/dist/js/types/changeBinding.d.ts +19 -0
- package/dist/js/types/changeBinding.d.ts.map +1 -0
- package/dist/js/types/commentWrapper.d.ts +39 -0
- package/dist/js/types/commentWrapper.d.ts.map +1 -0
- package/dist/js/types/config.d.ts +55 -0
- package/dist/js/types/config.d.ts.map +1 -0
- package/dist/js/types/createBindingOption.d.ts +32 -0
- package/dist/js/types/createBindingOption.d.ts.map +1 -0
- package/dist/js/types/createEventBinding.d.ts +10 -0
- package/dist/js/types/createEventBinding.d.ts.map +1 -0
- package/dist/js/types/cssBinding.d.ts +15 -0
- package/dist/js/types/cssBinding.d.ts.map +1 -0
- package/dist/js/types/domWalker.d.ts +9 -0
- package/dist/js/types/domWalker.d.ts.map +1 -0
- package/dist/js/types/forOfBinding.d.ts +12 -0
- package/dist/js/types/forOfBinding.d.ts.map +1 -0
- package/dist/js/types/hoverBinding.d.ts +13 -0
- package/dist/js/types/hoverBinding.d.ts.map +1 -0
- package/dist/js/types/ifBinding.d.ts +12 -0
- package/dist/js/types/ifBinding.d.ts.map +1 -0
- package/dist/js/types/index.d.ts +10 -0
- package/dist/js/types/index.d.ts.map +1 -0
- package/dist/js/types/modelBinding.d.ts +12 -0
- package/dist/js/types/modelBinding.d.ts.map +1 -0
- package/dist/js/types/postProcess.d.ts +3 -0
- package/dist/js/types/postProcess.d.ts.map +1 -0
- package/dist/js/types/pubSub.d.ts +11 -0
- package/dist/js/types/pubSub.d.ts.map +1 -0
- package/dist/js/types/reactiveProxy.d.ts +28 -0
- package/dist/js/types/reactiveProxy.d.ts.map +1 -0
- package/dist/js/types/renderForOfBinding.d.ts +8 -0
- package/dist/js/types/renderForOfBinding.d.ts.map +1 -0
- package/dist/js/types/renderIfBinding.d.ts +22 -0
- package/dist/js/types/renderIfBinding.d.ts.map +1 -0
- package/dist/js/types/renderIteration.d.ts +16 -0
- package/dist/js/types/renderIteration.d.ts.map +1 -0
- package/dist/js/types/renderTemplate.d.ts +14 -0
- package/dist/js/types/renderTemplate.d.ts.map +1 -0
- package/dist/js/types/renderTemplatesBinding.d.ts +19 -0
- package/dist/js/types/renderTemplatesBinding.d.ts.map +1 -0
- package/dist/js/types/showBinding.d.ts +13 -0
- package/dist/js/types/showBinding.d.ts.map +1 -0
- package/dist/js/types/switchBinding.d.ts +13 -0
- package/dist/js/types/switchBinding.d.ts.map +1 -0
- package/dist/js/types/textBinding.d.ts +13 -0
- package/dist/js/types/textBinding.d.ts.map +1 -0
- package/dist/js/types/types.d.ts +111 -0
- package/dist/js/types/types.d.ts.map +1 -0
- package/dist/js/types/util.d.ts +119 -0
- package/dist/js/types/util.d.ts.map +1 -0
- package/dist/js/types.d.ts +111 -0
- package/dist/js/types.d.ts.map +1 -0
- package/dist/js/util.d.ts +119 -0
- package/dist/js/util.d.ts.map +1 -0
- package/eslint.config.js +124 -0
- package/examples/DBMONSTER_COMPARISON.md +123 -0
- package/examples/afterRenderDemo.html +119 -0
- package/examples/bootstrap/css/animate.css +1579 -1579
- package/examples/bootstrap/css/bootstrap.min.css +6 -6
- package/examples/bootstrap/css/homeservices.css +378 -390
- package/examples/bootstrap/css/open-iconic.css +511 -511
- package/examples/bootstrap/fonts/open-iconic.svg +543 -543
- package/examples/bootstrap/js/compMessageDialog.js +20 -19
- package/examples/bootstrap/js/compSearchBar.js +12 -19
- package/examples/bootstrap/js/compSearchResults.js +50 -46
- package/examples/bootstrap/js/featureAdsResult.json +65 -65
- package/examples/bootstrap/js/searchResult.json +57 -57
- package/examples/bootstrap.html +343 -332
- package/examples/css/baseTodo.css +141 -141
- package/examples/css/dbMonsterStyles.css +27 -27
- package/examples/css/indexTodo.css +374 -374
- package/examples/dbmonsterForOfReactive.html +40 -0
- package/examples/dbmonsterReact.html +19 -0
- package/examples/forOfBindingSimpleDebug.html +45 -0
- package/examples/form.html +20 -4
- package/examples/globalConfig.html +131 -0
- package/examples/js/afterRenderDemo.js +190 -0
- package/examples/js/appTodo.js +46 -46
- package/examples/js/attrBindingDemo.js +2 -2
- package/examples/js/dbMonApp.js +24 -26
- package/examples/js/dbMonAppReact.jsx +79 -0
- package/examples/js/dbMonAppReactive.js +28 -0
- package/examples/js/fiberDemo.js +4 -4
- package/examples/js/filtersDemo.js +8 -8
- package/examples/js/forOfDemo.js +7 -9
- package/examples/js/forOfDemoComplex.js +44 -17
- package/examples/js/form.js +44 -12
- package/examples/js/globalConfig.js +117 -0
- package/examples/js/ifBindingDemo.js +16 -16
- package/examples/js/reactiveDemo.js +119 -0
- package/examples/js/switchBindingDemo.js +8 -8
- package/examples/react-dbmonster/dist/bundle.js +43 -0
- package/examples/react-dbmonster/package-lock.json +537 -0
- package/examples/react-dbmonster/package.json +16 -0
- package/examples/react-dbmonster/src/index.jsx +80 -0
- package/examples/reactiveDemo.html +127 -0
- package/examples/refreshRateTest.html +75 -75
- package/index.html +841 -0
- package/package.json +31 -34
- package/rollup.config.js +79 -36
- package/src/{_escape.js → _escape.ts} +19 -17
- package/src/applyBinding.ts +179 -0
- package/src/{attrBinding.js → attrBinding.ts} +14 -13
- package/src/binder.ts +289 -0
- package/src/changeBinding.ts +93 -0
- package/src/{commentWrapper.js → commentWrapper.ts} +33 -30
- package/src/config.ts +107 -0
- package/src/createBindingOption.ts +91 -0
- package/src/createEventBinding.ts +88 -0
- package/src/{cssBinding.js → cssBinding.ts} +13 -11
- package/src/{domWalker.js → domWalker.ts} +44 -30
- package/src/{forOfBinding.js → forOfBinding.ts} +4 -3
- package/src/hoverBinding.ts +84 -0
- package/src/{ifBinding.js → ifBinding.ts} +14 -12
- package/src/index.ts +53 -0
- package/src/{modelBinding.js → modelBinding.ts} +11 -9
- package/src/postProcess.ts +22 -0
- package/src/{pubSub.js → pubSub.ts} +24 -15
- package/src/reactiveProxy.ts +285 -0
- package/src/{renderForOfBinding.js → renderForOfBinding.ts} +55 -33
- package/src/{renderIfBinding.js → renderIfBinding.ts} +45 -20
- package/src/renderIteration.ts +53 -0
- package/src/renderTemplate.ts +165 -0
- package/src/renderTemplatesBinding.ts +73 -0
- package/src/{showBinding.js → showBinding.ts} +4 -3
- package/src/{switchBinding.js → switchBinding.ts} +18 -15
- package/src/{textBinding.js → textBinding.ts} +5 -4
- package/src/types.ts +124 -0
- package/src/util.ts +810 -0
- package/test/css/reporter.css +9 -9
- package/test/fixtures/dataBindBootstrap.html +2 -2
- package/test/fixtures/formBindings.html +9 -1
- package/test/globals.d.ts +19 -0
- package/test/helpers/testHelper.js +46 -11
- package/test/mocks/featureAdsResult.json +65 -65
- package/test/mocks/searchResult.json +57 -57
- package/test/specs/{attrBinding.spec.js → attrBinding.spec.ts} +103 -106
- package/test/specs/{binder.spec.js → binder.spec.ts} +29 -27
- package/test/specs/blurBinding.spec.ts +60 -0
- package/test/specs/chainableUse.spec.ts +125 -0
- package/test/specs/clickBinding.spec.ts +194 -0
- package/test/specs/{cssBinding.spec.js → cssBinding.spec.ts} +72 -79
- package/test/specs/{dataBindBootstrap.spec.js → dataBindBootstrap.spec.ts} +332 -313
- package/test/specs/{filter.spec.js → filter.spec.ts} +75 -76
- package/test/specs/{forOfBinding.spec.js → forOfBinding.spec.ts} +208 -219
- package/test/specs/formBinding.spec.ts +272 -0
- package/test/specs/ifBinding.spec.ts +165 -0
- package/test/specs/{nestedComponent.spec.js → nestedComponent.spec.ts} +88 -88
- package/test/specs/reactiveProxy.spec.ts +465 -0
- package/test/specs/{showBinding.spec.js → showBinding.spec.ts} +148 -149
- package/test/specs/{switchBinding.spec.js → switchBinding.spec.ts} +172 -173
- package/test/specs/templateBinding.spec.ts +273 -0
- package/test/specs/{textBinding.spec.js → textBinding.spec.ts} +47 -48
- package/test/tsconfig.json +31 -0
- package/test-output.txt +200 -0
- package/test-reactive.html +224 -0
- package/tsconfig.json +28 -0
- package/vendors/lodash.custom.js +4577 -4577
- package/vendors/lodash.custom.min.js +45 -45
- package/vitest.config.js +27 -0
- package/.eslintrc.js +0 -1
- package/.grunt/grunt-contrib-jasmine/boot.js +0 -161
- package/.grunt/grunt-contrib-jasmine/dist/js/dataBind.js +0 -9
- package/.grunt/grunt-contrib-jasmine/grunt-template-jasmine-istanbul/reporter.js +0 -23
- package/.grunt/grunt-contrib-jasmine/jasmine-html.js +0 -853
- package/.grunt/grunt-contrib-jasmine/jasmine.css +0 -271
- package/.grunt/grunt-contrib-jasmine/jasmine.js +0 -9761
- package/.grunt/grunt-contrib-jasmine/jasmine_favicon.png +0 -0
- package/.grunt/grunt-contrib-jasmine/json2.js +0 -489
- package/.grunt/grunt-contrib-jasmine/reporter.js +0 -107
- package/coverage/coverage.json +0 -1
- package/coverage/lcov/lcov-report/base.css +0 -213
- package/coverage/lcov/lcov-report/index.html +0 -93
- package/coverage/lcov/lcov-report/js/dataBind.js.html +0 -6596
- package/coverage/lcov/lcov-report/js/index.html +0 -93
- package/coverage/lcov/lcov-report/prettify.css +0 -1
- package/coverage/lcov/lcov-report/prettify.js +0 -1
- package/coverage/lcov/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov/lcov-report/sorter.js +0 -158
- package/coverage/lcov/lcov.info +0 -1991
- package/eslintrc.json +0 -40
- package/examples/bootstrap/js/bootstrap.min.js +0 -6
- package/examples/bootstrap/js/popper.min.js +0 -5
- package/examples/bootstrap/js/searchSuggestion.js +0 -58
- package/examples/bootstrap/js/typeahead.jquery.js +0 -1538
- package/gruntfile.js +0 -92
- package/gulpfile.js +0 -32
- package/src/binder.js +0 -422
- package/src/changeBinding.js +0 -57
- package/src/config.js +0 -65
- package/src/createBindingOption.js +0 -66
- package/src/createEventBinding.js +0 -46
- package/src/eventSystem.js +0 -46
- package/src/hoverBinding.js +0 -57
- package/src/index.js +0 -26
- package/src/renderTemplate.js +0 -128
- package/src/util.js +0 -648
- package/test/specs/blurBinding.spec.js +0 -57
- package/test/specs/formBinding.spec.js +0 -292
- package/test/specs/ifBinding.spec.js +0 -169
- package/test/specs/templateBinding.spec.js +0 -117
- package/vendors/jasmine-jquery.js +0 -841
- package/vendors/jquery-3.2.1.min.js +0 -4
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import {isEmptyObject} from './util';
|
|
2
|
-
import
|
|
2
|
+
import renderIteration from './renderIteration';
|
|
3
3
|
import createBindingCache from './domWalker';
|
|
4
4
|
import {commentSuffix} from './config';
|
|
5
5
|
import {removeElemnetsByCommentWrap, insertRenderedElements} from './commentWrapper';
|
|
6
|
+
import type {BindingCache, ViewModel, BindingAttrs, ElementCache} from './types';
|
|
7
|
+
|
|
8
|
+
interface RenderIfBindingParams {
|
|
9
|
+
bindingData: BindingCache;
|
|
10
|
+
viewModel: ViewModel;
|
|
11
|
+
bindingAttrs: BindingAttrs;
|
|
12
|
+
}
|
|
6
13
|
|
|
7
14
|
/**
|
|
8
15
|
* isTargetDomRemoved
|
|
@@ -10,13 +17,13 @@ import {removeElemnetsByCommentWrap, insertRenderedElements} from './commentWrap
|
|
|
10
17
|
* @param {object} bindingData
|
|
11
18
|
* @return {boolean}
|
|
12
19
|
*/
|
|
13
|
-
const isTargetDomRemoved = (bindingData) => {
|
|
20
|
+
const isTargetDomRemoved = (bindingData: BindingCache): boolean => {
|
|
14
21
|
let ret = false;
|
|
15
22
|
if (bindingData && bindingData.previousNonTemplateElement) {
|
|
16
23
|
const commentStartTextContent = bindingData.previousNonTemplateElement.textContent;
|
|
17
24
|
const endCommentTag = bindingData.previousNonTemplateElement.nextSibling;
|
|
18
25
|
|
|
19
|
-
if (endCommentTag.nodeType === 8) {
|
|
26
|
+
if (endCommentTag && endCommentTag.nodeType === 8) {
|
|
20
27
|
if (endCommentTag.textContent === commentStartTextContent + commentSuffix) {
|
|
21
28
|
ret = true;
|
|
22
29
|
}
|
|
@@ -25,27 +32,51 @@ const isTargetDomRemoved = (bindingData) => {
|
|
|
25
32
|
return ret;
|
|
26
33
|
};
|
|
27
34
|
|
|
28
|
-
|
|
35
|
+
/**
|
|
36
|
+
* removeIfBinding
|
|
37
|
+
* @description remove if binding DOM and clean up cache
|
|
38
|
+
* @param {object} bindingData
|
|
39
|
+
*/
|
|
40
|
+
const removeIfBinding = (bindingData: BindingCache): void => {
|
|
41
|
+
removeElemnetsByCommentWrap(bindingData);
|
|
42
|
+
// remove cache.IterationBindingCache to prevent memory leak
|
|
43
|
+
if (bindingData.hasIterationBindingCache) {
|
|
44
|
+
delete bindingData.iterationBindingCache;
|
|
45
|
+
delete bindingData.hasIterationBindingCache;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* renderIfBinding
|
|
51
|
+
* @description render if binding DOM
|
|
52
|
+
* @param {object} bindingData
|
|
53
|
+
* @param {object} viewModel
|
|
54
|
+
* @param {object} bindingAttrs
|
|
55
|
+
*/
|
|
56
|
+
const renderIfBinding = ({bindingData, viewModel, bindingAttrs}: RenderIfBindingParams): void => {
|
|
29
57
|
if (!bindingData.fragment) {
|
|
30
58
|
return;
|
|
31
59
|
}
|
|
32
60
|
|
|
33
61
|
const isDomRemoved = isTargetDomRemoved(bindingData);
|
|
34
|
-
let rootElement = bindingData.el;
|
|
62
|
+
let rootElement: Node = bindingData.el;
|
|
35
63
|
|
|
36
64
|
// remove current old DOM.
|
|
37
65
|
// TODO: try preserve DOM
|
|
38
66
|
if (!isDomRemoved && !bindingData.isOnce) {
|
|
39
67
|
removeIfBinding(bindingData);
|
|
40
68
|
// use fragment for create iterationBindingCache
|
|
41
|
-
|
|
69
|
+
const firstChild = bindingData.fragment.firstChild;
|
|
70
|
+
if (firstChild) {
|
|
71
|
+
rootElement = firstChild.cloneNode(true);
|
|
72
|
+
}
|
|
42
73
|
}
|
|
43
74
|
|
|
44
75
|
// walk clonedElement to create iterationBindingCache once
|
|
45
76
|
if (!bindingData.iterationBindingCache || !bindingData.hasIterationBindingCache) {
|
|
46
77
|
bindingData.iterationBindingCache = createBindingCache({
|
|
47
|
-
rootNode: rootElement,
|
|
48
|
-
bindingAttrs
|
|
78
|
+
rootNode: rootElement as HTMLElement,
|
|
79
|
+
bindingAttrs,
|
|
49
80
|
});
|
|
50
81
|
}
|
|
51
82
|
|
|
@@ -54,25 +85,19 @@ const renderIfBinding = ({bindingData, viewModel, bindingAttrs}) => {
|
|
|
54
85
|
if (!isEmptyObject(bindingData.iterationBindingCache)) {
|
|
55
86
|
bindingData.hasIterationBindingCache = true;
|
|
56
87
|
renderIteration({
|
|
57
|
-
elementCache: bindingData.iterationBindingCache,
|
|
88
|
+
elementCache: bindingData.iterationBindingCache as ElementCache,
|
|
58
89
|
iterationVm: viewModel,
|
|
59
|
-
bindingAttrs
|
|
90
|
+
bindingAttrs,
|
|
60
91
|
isRegenerate: true,
|
|
61
92
|
});
|
|
62
93
|
}
|
|
63
94
|
|
|
64
95
|
// insert to new rendered DOM
|
|
65
96
|
// TODO: check unnecessary insertion when DOM is preserved
|
|
66
|
-
insertRenderedElements(bindingData, rootElement);
|
|
97
|
+
insertRenderedElements(bindingData, rootElement as DocumentFragment);
|
|
67
98
|
};
|
|
68
99
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (bindingData.hasIterationBindingCache) {
|
|
73
|
-
delete bindingData.iterationBindingCache;
|
|
74
|
-
delete bindingData.hasIterationBindingCache;
|
|
75
|
-
}
|
|
100
|
+
export {
|
|
101
|
+
renderIfBinding,
|
|
102
|
+
removeIfBinding,
|
|
76
103
|
};
|
|
77
|
-
|
|
78
|
-
export {renderIfBinding, removeIfBinding};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {bindingUpdateConditions} from './config';
|
|
2
|
+
import createBindingOption from './createBindingOption';
|
|
3
|
+
import renderTemplatesBinding from './renderTemplatesBinding';
|
|
4
|
+
import * as applyBindingModule from './applyBinding';
|
|
5
|
+
import type {ElementCache, ViewModel, BindingAttrs} from './types';
|
|
6
|
+
import type Binder from './binder';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* renderIteration
|
|
10
|
+
* @param {object} opt
|
|
11
|
+
* @description
|
|
12
|
+
* render element's binding by supplied elementCache
|
|
13
|
+
* This function is desidned for FoOf, If, switch bindings
|
|
14
|
+
*/
|
|
15
|
+
const renderIteration = ({
|
|
16
|
+
elementCache,
|
|
17
|
+
iterationVm,
|
|
18
|
+
bindingAttrs,
|
|
19
|
+
isRegenerate,
|
|
20
|
+
}: {
|
|
21
|
+
elementCache: ElementCache;
|
|
22
|
+
iterationVm: ViewModel;
|
|
23
|
+
bindingAttrs: BindingAttrs;
|
|
24
|
+
isRegenerate: boolean;
|
|
25
|
+
}): void => {
|
|
26
|
+
const bindingUpdateOption = isRegenerate ? createBindingOption(bindingUpdateConditions.init) : createBindingOption();
|
|
27
|
+
|
|
28
|
+
// enforce render even element is not in DOM tree
|
|
29
|
+
bindingUpdateOption.forceRender = true;
|
|
30
|
+
|
|
31
|
+
// render and apply binding to template(s)
|
|
32
|
+
// this is an share function therefore passing current APP 'this' context
|
|
33
|
+
// viewModel is a dynamic generated iterationVm
|
|
34
|
+
renderTemplatesBinding({
|
|
35
|
+
ctx: (iterationVm.$root ? iterationVm.$root.APP : iterationVm.APP) as Binder,
|
|
36
|
+
elementCache,
|
|
37
|
+
updateOption: bindingUpdateOption,
|
|
38
|
+
bindingAttrs,
|
|
39
|
+
viewModel: iterationVm,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Use namespace import to access the function at runtime,
|
|
43
|
+
// which breaks the circular dependency during module initialization
|
|
44
|
+
applyBindingModule.default({
|
|
45
|
+
ctx: (iterationVm.$root ? iterationVm.$root.APP : iterationVm.APP) as Binder,
|
|
46
|
+
elementCache,
|
|
47
|
+
updateOption: bindingUpdateOption,
|
|
48
|
+
bindingAttrs,
|
|
49
|
+
viewModel: iterationVm,
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export default renderIteration;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import {dataIndexAttr} from './config';
|
|
2
|
+
import {
|
|
3
|
+
createHtmlFragment,
|
|
4
|
+
emptyElement,
|
|
5
|
+
getViewModelPropValue,
|
|
6
|
+
parseStringToJson,
|
|
7
|
+
updateDomWithMinimalChanges,
|
|
8
|
+
} from './util';
|
|
9
|
+
import type {BindingCache, ViewModel, BindingAttrs, ElementCache, PlainObject} from './types';
|
|
10
|
+
|
|
11
|
+
let $domFragment: DocumentFragment | null = null;
|
|
12
|
+
let $templateRoot: HTMLElement | null = null;
|
|
13
|
+
let $templateRootPrepend = false;
|
|
14
|
+
let $templateRootAppend = false;
|
|
15
|
+
let nestTemplatesCount = 0;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* getTemplateString
|
|
19
|
+
* @description get Template tag innerHTML string
|
|
20
|
+
* @param {string} id
|
|
21
|
+
* @return {string} rendered html string
|
|
22
|
+
*/
|
|
23
|
+
const getTemplateString = (id: string): string => {
|
|
24
|
+
const templateElement = document.getElementById(id);
|
|
25
|
+
|
|
26
|
+
return templateElement ? templateElement.innerHTML : '';
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* renderTemplate
|
|
31
|
+
* @description
|
|
32
|
+
* get template setting from DOM attribute then call compileTemplate
|
|
33
|
+
* to render and append to target DOM
|
|
34
|
+
* @param {object} cache
|
|
35
|
+
* @param {object} viewModel
|
|
36
|
+
* @param {object} bindingAttrs
|
|
37
|
+
* @param {object} elementCache
|
|
38
|
+
*/
|
|
39
|
+
const renderTemplate = (cache: BindingCache, viewModel: ViewModel, bindingAttrs: BindingAttrs, elementCache: ElementCache): void => {
|
|
40
|
+
const settings = typeof cache.dataKey === 'string' ? parseStringToJson(cache.dataKey) : cache.dataKey as PlainObject;
|
|
41
|
+
let viewData: unknown = (settings as PlainObject).data;
|
|
42
|
+
const isAppend = (settings as PlainObject).append;
|
|
43
|
+
const isPrepend = (settings as PlainObject).prepend;
|
|
44
|
+
let $currentElement: DocumentFragment | HTMLElement;
|
|
45
|
+
|
|
46
|
+
cache.dataKey = settings as unknown as string;
|
|
47
|
+
|
|
48
|
+
viewData = (typeof viewData === 'undefined' || viewData === '$root') ?
|
|
49
|
+
viewModel :
|
|
50
|
+
getViewModelPropValue(viewModel, {
|
|
51
|
+
dataKey: (settings as PlainObject).data,
|
|
52
|
+
parameters: cache.parameters,
|
|
53
|
+
} as BindingCache);
|
|
54
|
+
|
|
55
|
+
if (!viewData) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const $element = cache.el;
|
|
60
|
+
const $indexAttr = $element.getAttribute(dataIndexAttr);
|
|
61
|
+
const $index = typeof viewModel.$index !== 'undefined' ? viewModel.$index : ($indexAttr ? parseInt($indexAttr, 10) : undefined);
|
|
62
|
+
|
|
63
|
+
if (typeof $index !== 'undefined' && viewData && typeof viewData === 'object') {
|
|
64
|
+
(viewData as ViewModel).$index = $index;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
$domFragment = $domFragment || document.createDocumentFragment();
|
|
68
|
+
|
|
69
|
+
if (!$templateRoot) {
|
|
70
|
+
$templateRoot = $element;
|
|
71
|
+
// Store the prepend/append flags from the root template only
|
|
72
|
+
$templateRootPrepend = Boolean(isPrepend);
|
|
73
|
+
$templateRootAppend = Boolean(isAppend);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const htmlString = getTemplateString((settings as PlainObject).id as string);
|
|
77
|
+
|
|
78
|
+
const htmlFragment = createHtmlFragment(htmlString);
|
|
79
|
+
|
|
80
|
+
// Return early if htmlFragment is null (invalid template)
|
|
81
|
+
if (!htmlFragment) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// append rendered html
|
|
86
|
+
if (!$domFragment.childNodes.length) {
|
|
87
|
+
// domFragment should be empty in first run
|
|
88
|
+
$currentElement = $domFragment; // copy of $domFragment for later find nested template check
|
|
89
|
+
$domFragment.appendChild(htmlFragment);
|
|
90
|
+
} else {
|
|
91
|
+
// during recursive run keep append to current fragment
|
|
92
|
+
// For nested templates, use the original behavior (clear and append)
|
|
93
|
+
// because they may contain forOf bindings or other dynamic content
|
|
94
|
+
// that manages its own DOM structure
|
|
95
|
+
$currentElement = $element; // reset to current nested template element
|
|
96
|
+
if (!isAppend && !isPrepend) {
|
|
97
|
+
$currentElement = emptyElement($currentElement);
|
|
98
|
+
}
|
|
99
|
+
if (isPrepend) {
|
|
100
|
+
$currentElement.insertBefore(htmlFragment, $currentElement.firstChild);
|
|
101
|
+
} else {
|
|
102
|
+
$currentElement.appendChild(htmlFragment);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// check if there are nested template then recurisive render them
|
|
107
|
+
const $nestedTemplates = $currentElement.querySelectorAll(`[${ bindingAttrs.tmp }]`);
|
|
108
|
+
|
|
109
|
+
const nestedTemplatesLength = $nestedTemplates.length;
|
|
110
|
+
|
|
111
|
+
if (nestedTemplatesLength) {
|
|
112
|
+
nestTemplatesCount += nestedTemplatesLength;
|
|
113
|
+
|
|
114
|
+
for (let i=0; i < nestedTemplatesLength; i+=1) {
|
|
115
|
+
const thisTemplateCache = {
|
|
116
|
+
el: $nestedTemplates[i] as HTMLElement,
|
|
117
|
+
dataKey: $nestedTemplates[i].getAttribute(bindingAttrs.tmp),
|
|
118
|
+
} as BindingCache;
|
|
119
|
+
elementCache[bindingAttrs.tmp].push(thisTemplateCache);
|
|
120
|
+
// recursive template render
|
|
121
|
+
renderTemplate(thisTemplateCache, viewModel, bindingAttrs, elementCache);
|
|
122
|
+
nestTemplatesCount -= 1;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// no more nested tempalted to render, start to append $domFragment into $templateRoot
|
|
127
|
+
if (nestTemplatesCount === 0) {
|
|
128
|
+
// append to DOM once
|
|
129
|
+
// Use the prepend/append flags from the root template, not the current nested template
|
|
130
|
+
if (!$templateRootAppend && !$templateRootPrepend) {
|
|
131
|
+
// Check if this is a re-render by looking for a marker attribute
|
|
132
|
+
// This is more reliable than checking childNodes.length because templates
|
|
133
|
+
// may have placeholder content
|
|
134
|
+
const isRerender = $templateRoot.hasAttribute('data-template-rendered');
|
|
135
|
+
|
|
136
|
+
if (isRerender) {
|
|
137
|
+
// Re-render: Use minimal DOM updates to preserve unchanged elements
|
|
138
|
+
// This is faster and preserves DOM state (focus, scroll, animations)
|
|
139
|
+
updateDomWithMinimalChanges($templateRoot, $domFragment);
|
|
140
|
+
} else {
|
|
141
|
+
// Initial render: Clear any placeholder content and render fresh
|
|
142
|
+
$templateRoot = emptyElement($templateRoot);
|
|
143
|
+
$templateRoot.appendChild($domFragment);
|
|
144
|
+
// Mark this template as rendered for future re-renders
|
|
145
|
+
$templateRoot.setAttribute('data-template-rendered', 'true');
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
// For prepend/append modes, use the original behavior
|
|
149
|
+
if ($templateRootPrepend) {
|
|
150
|
+
$templateRoot.insertBefore($domFragment, $templateRoot.firstChild);
|
|
151
|
+
} else {
|
|
152
|
+
$templateRoot.appendChild($domFragment);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// clear cached fragment and flags
|
|
156
|
+
$domFragment = $templateRoot = null;
|
|
157
|
+
$templateRootPrepend = $templateRootAppend = false;
|
|
158
|
+
// trigger callback if provided
|
|
159
|
+
if (viewModel.afterTemplateRender && typeof viewModel.afterTemplateRender === 'function') {
|
|
160
|
+
(viewModel.afterTemplateRender as Function)(viewData);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
export default renderTemplate;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {bindingUpdateConditions} from './config';
|
|
2
|
+
import * as applyBindingModule from './applyBinding';
|
|
3
|
+
import createBindingOption from './createBindingOption';
|
|
4
|
+
import renderTemplate from './renderTemplate';
|
|
5
|
+
import type {ElementCache, ViewModel, BindingAttrs, BindingCache} from './types';
|
|
6
|
+
import type {BindingOption} from './createBindingOption';
|
|
7
|
+
|
|
8
|
+
interface BinderContext {
|
|
9
|
+
updateElementCache: (opt: {
|
|
10
|
+
allCache?: boolean;
|
|
11
|
+
templateCache?: boolean;
|
|
12
|
+
elementCache?: ElementCache;
|
|
13
|
+
isRenderedTemplates?: boolean;
|
|
14
|
+
}) => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const renderTemplatesBinding = ({
|
|
18
|
+
ctx,
|
|
19
|
+
elementCache,
|
|
20
|
+
updateOption,
|
|
21
|
+
bindingAttrs,
|
|
22
|
+
viewModel,
|
|
23
|
+
}: {
|
|
24
|
+
ctx: BinderContext;
|
|
25
|
+
elementCache: ElementCache;
|
|
26
|
+
updateOption: BindingOption;
|
|
27
|
+
bindingAttrs: BindingAttrs;
|
|
28
|
+
viewModel: ViewModel;
|
|
29
|
+
}): boolean => {
|
|
30
|
+
if (!elementCache || !bindingAttrs) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
// render and apply binding to template(s) and forOf DOM
|
|
34
|
+
if (elementCache[bindingAttrs.tmp] && elementCache[bindingAttrs.tmp].length) {
|
|
35
|
+
// when re-render call with {templateBinding: true}
|
|
36
|
+
// template and nested templates
|
|
37
|
+
if (updateOption.templateBinding) {
|
|
38
|
+
// overwrite updateOption with 'init' bindingUpdateConditions
|
|
39
|
+
updateOption = createBindingOption(bindingUpdateConditions.init);
|
|
40
|
+
|
|
41
|
+
// forEach is correct here - nested templates are added to array but rendered recursively
|
|
42
|
+
// We don't want the loop to re-render templates that were already rendered via recursion
|
|
43
|
+
elementCache[bindingAttrs.tmp].forEach(($element: unknown) => {
|
|
44
|
+
renderTemplate($element as BindingCache, viewModel, bindingAttrs, elementCache);
|
|
45
|
+
});
|
|
46
|
+
// update cache after all template(s) rendered
|
|
47
|
+
ctx.updateElementCache({
|
|
48
|
+
templateCache: true,
|
|
49
|
+
elementCache,
|
|
50
|
+
isRenderedTemplates: true,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
// enforce render even element is not in DOM tree
|
|
54
|
+
updateOption.forceRender = true;
|
|
55
|
+
|
|
56
|
+
// apply bindings to rendered templates element
|
|
57
|
+
// Use namespace import to access the function at runtime,
|
|
58
|
+
// which breaks the circular dependency during module initialization
|
|
59
|
+
// Use for loop to handle templates added during rendering
|
|
60
|
+
for (let i = 0; i < elementCache[bindingAttrs.tmp].length; i++) {
|
|
61
|
+
applyBindingModule.default({
|
|
62
|
+
ctx,
|
|
63
|
+
elementCache: elementCache[bindingAttrs.tmp][i].bindingCache as ElementCache,
|
|
64
|
+
updateOption,
|
|
65
|
+
bindingAttrs,
|
|
66
|
+
viewModel,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default renderTemplatesBinding;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {getViewModelPropValue} from './util';
|
|
2
|
+
import type {BindingCache, ViewModel, BindingAttrs} from './types';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* showBinding
|
|
@@ -9,9 +10,9 @@ import {getViewModelPropValue} from './util';
|
|
|
9
10
|
* @param {object} viewModel
|
|
10
11
|
* @param {object} bindingAttrs
|
|
11
12
|
*/
|
|
12
|
-
const showBinding = (cache, viewModel,
|
|
13
|
+
const showBinding = (cache: BindingCache, viewModel: ViewModel, _bindingAttrs: BindingAttrs, _forceRender?: boolean): void => {
|
|
13
14
|
const dataKey = cache.dataKey;
|
|
14
|
-
let currentInlineSytle = {};
|
|
15
|
+
let currentInlineSytle: CSSStyleDeclaration | Record<string, never> = {};
|
|
15
16
|
let currentInlineDisplaySytle = '';
|
|
16
17
|
let shouldShow = true;
|
|
17
18
|
|
|
@@ -42,7 +43,7 @@ const showBinding = (cache, viewModel, bindingAttrs) => {
|
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
shouldShow = getViewModelPropValue(viewModel, cache);
|
|
46
|
+
shouldShow = getViewModelPropValue(viewModel, cache) as boolean;
|
|
46
47
|
|
|
47
48
|
// treat undefined || null as false.
|
|
48
49
|
// eg if property doesn't exsits in viewModel, it will treat as false to hide element
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {getViewModelPropValue} from './util';
|
|
2
2
|
import {createClonedElementCache, wrapCommentAround} from './commentWrapper';
|
|
3
3
|
import {renderIfBinding, removeIfBinding} from './renderIfBinding';
|
|
4
|
+
import type {BindingCache, ViewModel, BindingAttrs, CaseData} from './types';
|
|
5
|
+
|
|
4
6
|
/**
|
|
5
7
|
* switch-Binding
|
|
6
8
|
* @description
|
|
@@ -10,7 +12,7 @@ import {renderIfBinding, removeIfBinding} from './renderIfBinding';
|
|
|
10
12
|
* @param {object} viewModel
|
|
11
13
|
* @param {object} bindingAttrs
|
|
12
14
|
*/
|
|
13
|
-
const switchBinding = (cache, viewModel, bindingAttrs) => {
|
|
15
|
+
const switchBinding = (cache: BindingCache, viewModel: ViewModel, bindingAttrs: BindingAttrs, _forceRender?: boolean): void => {
|
|
14
16
|
const dataKey = cache.dataKey;
|
|
15
17
|
|
|
16
18
|
if (!dataKey) {
|
|
@@ -35,11 +37,12 @@ const switchBinding = (cache, viewModel, bindingAttrs) => {
|
|
|
35
37
|
}
|
|
36
38
|
cache.cases = [];
|
|
37
39
|
for (let i = 0, elementLength = childrenElements.length; i < elementLength; i += 1) {
|
|
38
|
-
let caseData = null;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
let caseData: CaseData | null = null;
|
|
41
|
+
const childElement = childrenElements[i] as HTMLElement;
|
|
42
|
+
if (childElement.hasAttribute(bindingAttrs.case)) {
|
|
43
|
+
caseData = createCaseData(childElement, bindingAttrs.case);
|
|
44
|
+
} else if (childElement.hasAttribute(bindingAttrs.default)) {
|
|
45
|
+
caseData = createCaseData(childElement, bindingAttrs.default);
|
|
43
46
|
caseData.isDefault = true;
|
|
44
47
|
}
|
|
45
48
|
// create fragment by clone node
|
|
@@ -62,7 +65,7 @@ const switchBinding = (cache, viewModel, bindingAttrs) => {
|
|
|
62
65
|
let hasMatch = false;
|
|
63
66
|
// do switch operation - reuse if binding logic
|
|
64
67
|
for (let j = 0, casesLength = cache.cases.length; j < casesLength; j += 1) {
|
|
65
|
-
let newCaseValue;
|
|
68
|
+
let newCaseValue: unknown;
|
|
66
69
|
if (cache.cases[j].dataKey) {
|
|
67
70
|
// set back to dataKey if nothing found in viewModel
|
|
68
71
|
newCaseValue = getViewModelPropValue(viewModel, cache.cases[j]) || cache.cases[j].dataKey;
|
|
@@ -73,8 +76,8 @@ const switchBinding = (cache, viewModel, bindingAttrs) => {
|
|
|
73
76
|
// render element
|
|
74
77
|
renderIfBinding({
|
|
75
78
|
bindingData: cache.cases[j],
|
|
76
|
-
viewModel
|
|
77
|
-
bindingAttrs
|
|
79
|
+
viewModel,
|
|
80
|
+
bindingAttrs,
|
|
78
81
|
});
|
|
79
82
|
|
|
80
83
|
// remove other elements
|
|
@@ -89,8 +92,8 @@ const switchBinding = (cache, viewModel, bindingAttrs) => {
|
|
|
89
92
|
}
|
|
90
93
|
};
|
|
91
94
|
|
|
92
|
-
|
|
93
|
-
cases.forEach((caseData, index) => {
|
|
95
|
+
const removeUnmatchCases = (cases: CaseData[], matchedIndex?: number): void => {
|
|
96
|
+
cases.forEach((caseData: CaseData, index: number) => {
|
|
94
97
|
if (index !== matchedIndex || typeof matchedIndex === 'undefined') {
|
|
95
98
|
removeIfBinding(caseData);
|
|
96
99
|
// remove cache.IterationBindingCache to prevent memory leak
|
|
@@ -100,15 +103,15 @@ function removeUnmatchCases(cases, matchedIndex) {
|
|
|
100
103
|
}
|
|
101
104
|
}
|
|
102
105
|
});
|
|
103
|
-
}
|
|
106
|
+
};
|
|
104
107
|
|
|
105
|
-
|
|
106
|
-
const caseData = {
|
|
108
|
+
const createCaseData = (node: HTMLElement, attrName: string): CaseData => {
|
|
109
|
+
const caseData: CaseData = {
|
|
107
110
|
el: node,
|
|
108
111
|
dataKey: node.getAttribute(attrName),
|
|
109
112
|
type: attrName,
|
|
110
113
|
};
|
|
111
114
|
return caseData;
|
|
112
|
-
}
|
|
115
|
+
};
|
|
113
116
|
|
|
114
117
|
export default switchBinding;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {getViewModelPropValue} from './util';
|
|
2
|
+
import type {BindingCache, ViewModel, BindingAttrs} from './types';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* textBinding
|
|
@@ -9,12 +10,12 @@ import {getViewModelPropValue} from './util';
|
|
|
9
10
|
* @param {object} bindingAttrs
|
|
10
11
|
* @param {boolean} forceRender
|
|
11
12
|
*/
|
|
12
|
-
const textBinding = (cache, viewModel, bindingAttrs, forceRender) => {
|
|
13
|
+
const textBinding = (cache: BindingCache, viewModel: ViewModel, bindingAttrs: BindingAttrs, forceRender: boolean): void => {
|
|
13
14
|
const dataKey = cache.dataKey;
|
|
14
|
-
const APP = viewModel.APP || viewModel.$root
|
|
15
|
+
const APP = viewModel.APP || viewModel.$root?.APP;
|
|
15
16
|
|
|
16
17
|
// NOTE: this doesn't work for for-of, if and switch bindings because element was not in DOM
|
|
17
|
-
if (!dataKey || (!forceRender && !APP
|
|
18
|
+
if (!dataKey || (!forceRender && !(APP?.$rootElement as HTMLElement)?.contains(cache.el))) {
|
|
18
19
|
return;
|
|
19
20
|
}
|
|
20
21
|
|
|
@@ -23,7 +24,7 @@ const textBinding = (cache, viewModel, bindingAttrs, forceRender) => {
|
|
|
23
24
|
|
|
24
25
|
if (typeof newValue !== 'undefined' && typeof newValue !== 'object' && newValue !== null) {
|
|
25
26
|
if (newValue !== oldValue) {
|
|
26
|
-
cache.el.textContent = newValue;
|
|
27
|
+
cache.el.textContent = String(newValue);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
};
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// Common types used across the application
|
|
2
|
+
|
|
3
|
+
// Generic unknown value type - safer than any
|
|
4
|
+
export type UnknownValue = unknown;
|
|
5
|
+
|
|
6
|
+
export interface PlainObject {
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ViewModel {
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
APP?: {
|
|
13
|
+
render?: (opt?: UpdateOption) => void | Promise<void>;
|
|
14
|
+
postProcessQueue?: Array<() => void>;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
};
|
|
17
|
+
$root?: ViewModel;
|
|
18
|
+
$data?: unknown;
|
|
19
|
+
$index?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ElementData {
|
|
23
|
+
viewModelPropValue?: unknown;
|
|
24
|
+
displayStyle?: string | null;
|
|
25
|
+
computedStyle?: string | null;
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface BindingCache {
|
|
30
|
+
el: HTMLElement;
|
|
31
|
+
dataKey?: string;
|
|
32
|
+
parameters?: unknown[];
|
|
33
|
+
filters?: string[];
|
|
34
|
+
isOnce?: boolean;
|
|
35
|
+
elementData?: ElementData;
|
|
36
|
+
bindingCache?: unknown;
|
|
37
|
+
type?: string;
|
|
38
|
+
fragment?: DocumentFragment;
|
|
39
|
+
hasIterationBindingCache?: boolean;
|
|
40
|
+
iterationBindingCache?: unknown;
|
|
41
|
+
parentElement?: HTMLElement | null;
|
|
42
|
+
previousNonTemplateElement?: Node | null;
|
|
43
|
+
nextNonTemplateElement?: Node | null;
|
|
44
|
+
iterator?: {
|
|
45
|
+
alias?: string;
|
|
46
|
+
dataKey?: string;
|
|
47
|
+
};
|
|
48
|
+
cases?: CaseData[];
|
|
49
|
+
[key: string]: unknown;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface CaseData {
|
|
53
|
+
el: HTMLElement;
|
|
54
|
+
dataKey?: string;
|
|
55
|
+
type: string;
|
|
56
|
+
isDefault?: boolean;
|
|
57
|
+
fragment?: DocumentFragment;
|
|
58
|
+
hasIterationBindingCache?: boolean;
|
|
59
|
+
iterationBindingCache?: unknown;
|
|
60
|
+
[key: string]: unknown;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface ElementCache {
|
|
64
|
+
[key: string]: BindingCache[];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface UpdateOption {
|
|
68
|
+
forceRender?: boolean;
|
|
69
|
+
attrBinding?: boolean;
|
|
70
|
+
cssBinding?: boolean;
|
|
71
|
+
textBinding?: boolean;
|
|
72
|
+
modelBinding?: boolean;
|
|
73
|
+
showBinding?: boolean;
|
|
74
|
+
ifBinding?: boolean;
|
|
75
|
+
switchBinding?: boolean;
|
|
76
|
+
forOfBinding?: boolean;
|
|
77
|
+
changeBinding?: boolean;
|
|
78
|
+
submitBinding?: boolean;
|
|
79
|
+
clickBinding?: boolean;
|
|
80
|
+
dblclickBinding?: boolean;
|
|
81
|
+
blurBinding?: boolean;
|
|
82
|
+
focusBinding?: boolean;
|
|
83
|
+
hoverBinding?: boolean;
|
|
84
|
+
inputBinding?: boolean;
|
|
85
|
+
[key: string]: unknown;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface DeferredObj<T = unknown> {
|
|
89
|
+
promise: Promise<T>;
|
|
90
|
+
resolve: (value?: T) => void;
|
|
91
|
+
reject: (reason?: unknown) => void;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface WrapMap {
|
|
95
|
+
[key: string]: [string, string, string];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export interface BindingAttrs {
|
|
99
|
+
[key: string]: string;
|
|
100
|
+
attr: string;
|
|
101
|
+
css: string;
|
|
102
|
+
text: string;
|
|
103
|
+
model: string;
|
|
104
|
+
show: string;
|
|
105
|
+
if: string;
|
|
106
|
+
switch: string;
|
|
107
|
+
case: string;
|
|
108
|
+
default: string;
|
|
109
|
+
forOf: string;
|
|
110
|
+
change: string;
|
|
111
|
+
submit: string;
|
|
112
|
+
click: string;
|
|
113
|
+
dblclick: string;
|
|
114
|
+
blur: string;
|
|
115
|
+
focus: string;
|
|
116
|
+
hover: string;
|
|
117
|
+
input: string;
|
|
118
|
+
tmp: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface BinderOptions {
|
|
122
|
+
reactive?: boolean;
|
|
123
|
+
trackChanges?: boolean;
|
|
124
|
+
}
|