@gogocat/data-bind 1.12.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.
Files changed (271) hide show
  1. package/.editorconfig +14 -14
  2. package/.vscode/launch.json +12 -12
  3. package/CONFIGURATION.md +294 -0
  4. package/REACTIVE_MODE.md +553 -0
  5. package/README.md +266 -829
  6. package/babel.config.json +30 -0
  7. package/dist/js/_escape.d.ts +14 -0
  8. package/dist/js/_escape.d.ts.map +1 -0
  9. package/dist/js/applyBinding.d.ts +11 -0
  10. package/dist/js/applyBinding.d.ts.map +1 -0
  11. package/dist/js/attrBinding.d.ts +12 -0
  12. package/dist/js/attrBinding.d.ts.map +1 -0
  13. package/dist/js/binder.d.ts +67 -0
  14. package/dist/js/binder.d.ts.map +1 -0
  15. package/dist/js/changeBinding.d.ts +19 -0
  16. package/dist/js/changeBinding.d.ts.map +1 -0
  17. package/dist/js/commentWrapper.d.ts +39 -0
  18. package/dist/js/commentWrapper.d.ts.map +1 -0
  19. package/dist/js/config.d.ts +55 -0
  20. package/dist/js/config.d.ts.map +1 -0
  21. package/dist/js/createBindingOption.d.ts +32 -0
  22. package/dist/js/createBindingOption.d.ts.map +1 -0
  23. package/dist/js/createEventBinding.d.ts +10 -0
  24. package/dist/js/createEventBinding.d.ts.map +1 -0
  25. package/dist/js/cssBinding.d.ts +15 -0
  26. package/dist/js/cssBinding.d.ts.map +1 -0
  27. package/dist/js/dataBind.js +2756 -2530
  28. package/dist/js/dataBind.min.js +8 -1
  29. package/dist/js/dataBind.min.js.map +1 -1
  30. package/dist/js/domWalker.d.ts +9 -0
  31. package/dist/js/domWalker.d.ts.map +1 -0
  32. package/dist/js/forOfBinding.d.ts +12 -0
  33. package/dist/js/forOfBinding.d.ts.map +1 -0
  34. package/dist/js/hoverBinding.d.ts +13 -0
  35. package/dist/js/hoverBinding.d.ts.map +1 -0
  36. package/dist/js/ifBinding.d.ts +12 -0
  37. package/dist/js/ifBinding.d.ts.map +1 -0
  38. package/dist/js/index.d.ts +10 -0
  39. package/dist/js/index.d.ts.map +1 -0
  40. package/dist/js/modelBinding.d.ts +12 -0
  41. package/dist/js/modelBinding.d.ts.map +1 -0
  42. package/dist/js/postProcess.d.ts +3 -0
  43. package/dist/js/postProcess.d.ts.map +1 -0
  44. package/dist/js/pubSub.d.ts +11 -0
  45. package/dist/js/pubSub.d.ts.map +1 -0
  46. package/dist/js/reactiveProxy.d.ts +28 -0
  47. package/dist/js/reactiveProxy.d.ts.map +1 -0
  48. package/dist/js/renderForOfBinding.d.ts +8 -0
  49. package/dist/js/renderForOfBinding.d.ts.map +1 -0
  50. package/dist/js/renderIfBinding.d.ts +22 -0
  51. package/dist/js/renderIfBinding.d.ts.map +1 -0
  52. package/dist/js/renderIteration.d.ts +16 -0
  53. package/dist/js/renderIteration.d.ts.map +1 -0
  54. package/dist/js/renderTemplate.d.ts +14 -0
  55. package/dist/js/renderTemplate.d.ts.map +1 -0
  56. package/dist/js/renderTemplatesBinding.d.ts +19 -0
  57. package/dist/js/renderTemplatesBinding.d.ts.map +1 -0
  58. package/dist/js/showBinding.d.ts +13 -0
  59. package/dist/js/showBinding.d.ts.map +1 -0
  60. package/dist/js/switchBinding.d.ts +13 -0
  61. package/dist/js/switchBinding.d.ts.map +1 -0
  62. package/dist/js/textBinding.d.ts +13 -0
  63. package/dist/js/textBinding.d.ts.map +1 -0
  64. package/dist/js/types/_escape.d.ts +14 -0
  65. package/dist/js/types/_escape.d.ts.map +1 -0
  66. package/dist/js/types/applyBinding.d.ts +11 -0
  67. package/dist/js/types/applyBinding.d.ts.map +1 -0
  68. package/dist/js/types/attrBinding.d.ts +12 -0
  69. package/dist/js/types/attrBinding.d.ts.map +1 -0
  70. package/dist/js/types/binder.d.ts +67 -0
  71. package/dist/js/types/binder.d.ts.map +1 -0
  72. package/dist/js/types/changeBinding.d.ts +19 -0
  73. package/dist/js/types/changeBinding.d.ts.map +1 -0
  74. package/dist/js/types/commentWrapper.d.ts +39 -0
  75. package/dist/js/types/commentWrapper.d.ts.map +1 -0
  76. package/dist/js/types/config.d.ts +55 -0
  77. package/dist/js/types/config.d.ts.map +1 -0
  78. package/dist/js/types/createBindingOption.d.ts +32 -0
  79. package/dist/js/types/createBindingOption.d.ts.map +1 -0
  80. package/dist/js/types/createEventBinding.d.ts +10 -0
  81. package/dist/js/types/createEventBinding.d.ts.map +1 -0
  82. package/dist/js/types/cssBinding.d.ts +15 -0
  83. package/dist/js/types/cssBinding.d.ts.map +1 -0
  84. package/dist/js/types/domWalker.d.ts +9 -0
  85. package/dist/js/types/domWalker.d.ts.map +1 -0
  86. package/dist/js/types/forOfBinding.d.ts +12 -0
  87. package/dist/js/types/forOfBinding.d.ts.map +1 -0
  88. package/dist/js/types/hoverBinding.d.ts +13 -0
  89. package/dist/js/types/hoverBinding.d.ts.map +1 -0
  90. package/dist/js/types/ifBinding.d.ts +12 -0
  91. package/dist/js/types/ifBinding.d.ts.map +1 -0
  92. package/dist/js/types/index.d.ts +10 -0
  93. package/dist/js/types/index.d.ts.map +1 -0
  94. package/dist/js/types/modelBinding.d.ts +12 -0
  95. package/dist/js/types/modelBinding.d.ts.map +1 -0
  96. package/dist/js/types/postProcess.d.ts +3 -0
  97. package/dist/js/types/postProcess.d.ts.map +1 -0
  98. package/dist/js/types/pubSub.d.ts +11 -0
  99. package/dist/js/types/pubSub.d.ts.map +1 -0
  100. package/dist/js/types/reactiveProxy.d.ts +28 -0
  101. package/dist/js/types/reactiveProxy.d.ts.map +1 -0
  102. package/dist/js/types/renderForOfBinding.d.ts +8 -0
  103. package/dist/js/types/renderForOfBinding.d.ts.map +1 -0
  104. package/dist/js/types/renderIfBinding.d.ts +22 -0
  105. package/dist/js/types/renderIfBinding.d.ts.map +1 -0
  106. package/dist/js/types/renderIteration.d.ts +16 -0
  107. package/dist/js/types/renderIteration.d.ts.map +1 -0
  108. package/dist/js/types/renderTemplate.d.ts +14 -0
  109. package/dist/js/types/renderTemplate.d.ts.map +1 -0
  110. package/dist/js/types/renderTemplatesBinding.d.ts +19 -0
  111. package/dist/js/types/renderTemplatesBinding.d.ts.map +1 -0
  112. package/dist/js/types/showBinding.d.ts +13 -0
  113. package/dist/js/types/showBinding.d.ts.map +1 -0
  114. package/dist/js/types/switchBinding.d.ts +13 -0
  115. package/dist/js/types/switchBinding.d.ts.map +1 -0
  116. package/dist/js/types/textBinding.d.ts +13 -0
  117. package/dist/js/types/textBinding.d.ts.map +1 -0
  118. package/dist/js/types/types.d.ts +111 -0
  119. package/dist/js/types/types.d.ts.map +1 -0
  120. package/dist/js/types/util.d.ts +119 -0
  121. package/dist/js/types/util.d.ts.map +1 -0
  122. package/dist/js/types.d.ts +111 -0
  123. package/dist/js/types.d.ts.map +1 -0
  124. package/dist/js/util.d.ts +119 -0
  125. package/dist/js/util.d.ts.map +1 -0
  126. package/eslint.config.js +124 -0
  127. package/examples/DBMONSTER_COMPARISON.md +123 -0
  128. package/examples/afterRenderDemo.html +119 -0
  129. package/examples/bootstrap/css/animate.css +1579 -1579
  130. package/examples/bootstrap/css/bootstrap.min.css +6 -6
  131. package/examples/bootstrap/css/homeservices.css +378 -390
  132. package/examples/bootstrap/css/open-iconic.css +511 -511
  133. package/examples/bootstrap/fonts/open-iconic.svg +543 -543
  134. package/examples/bootstrap/js/compMessageDialog.js +20 -19
  135. package/examples/bootstrap/js/compSearchBar.js +12 -19
  136. package/examples/bootstrap/js/compSearchResults.js +50 -46
  137. package/examples/bootstrap/js/featureAdsResult.json +65 -65
  138. package/examples/bootstrap/js/searchResult.json +57 -57
  139. package/examples/bootstrap.html +343 -332
  140. package/examples/css/baseTodo.css +141 -141
  141. package/examples/css/dbMonsterStyles.css +27 -27
  142. package/examples/css/indexTodo.css +374 -374
  143. package/examples/dbmonsterForOfReactive.html +40 -0
  144. package/examples/dbmonsterReact.html +19 -0
  145. package/examples/forOfBindingSimpleDebug.html +45 -0
  146. package/examples/globalConfig.html +131 -0
  147. package/examples/js/afterRenderDemo.js +190 -0
  148. package/examples/js/appTodo.js +46 -46
  149. package/examples/js/attrBindingDemo.js +2 -2
  150. package/examples/js/dbMonApp.js +24 -26
  151. package/examples/js/dbMonAppReact.jsx +79 -0
  152. package/examples/js/dbMonAppReactive.js +28 -0
  153. package/examples/js/fiberDemo.js +4 -4
  154. package/examples/js/filtersDemo.js +8 -8
  155. package/examples/js/forOfDemo.js +7 -9
  156. package/examples/js/forOfDemoComplex.js +44 -17
  157. package/examples/js/form.js +14 -14
  158. package/examples/js/globalConfig.js +117 -0
  159. package/examples/js/ifBindingDemo.js +16 -16
  160. package/examples/js/reactiveDemo.js +119 -0
  161. package/examples/js/switchBindingDemo.js +8 -8
  162. package/examples/react-dbmonster/dist/bundle.js +43 -0
  163. package/examples/react-dbmonster/package-lock.json +537 -0
  164. package/examples/react-dbmonster/package.json +16 -0
  165. package/examples/react-dbmonster/src/index.jsx +80 -0
  166. package/examples/reactiveDemo.html +127 -0
  167. package/examples/refreshRateTest.html +75 -75
  168. package/index.html +841 -0
  169. package/package.json +31 -34
  170. package/rollup.config.js +79 -36
  171. package/src/{_escape.js → _escape.ts} +19 -17
  172. package/src/{applyBinding.js → applyBinding.ts} +27 -18
  173. package/src/{attrBinding.js → attrBinding.ts} +14 -13
  174. package/src/{binder.js → binder.ts} +289 -181
  175. package/src/changeBinding.ts +93 -0
  176. package/src/{commentWrapper.js → commentWrapper.ts} +33 -30
  177. package/src/config.ts +107 -0
  178. package/src/{createBindingOption.js → createBindingOption.ts} +39 -15
  179. package/src/createEventBinding.ts +88 -0
  180. package/src/{cssBinding.js → cssBinding.ts} +13 -11
  181. package/src/{domWalker.js → domWalker.ts} +44 -30
  182. package/src/{forOfBinding.js → forOfBinding.ts} +4 -3
  183. package/src/hoverBinding.ts +84 -0
  184. package/src/{ifBinding.js → ifBinding.ts} +14 -12
  185. package/src/index.ts +53 -0
  186. package/src/{modelBinding.js → modelBinding.ts} +11 -9
  187. package/src/{postProcess.js → postProcess.ts} +6 -4
  188. package/src/{pubSub.js → pubSub.ts} +24 -21
  189. package/src/reactiveProxy.ts +285 -0
  190. package/src/{renderForOfBinding.js → renderForOfBinding.ts} +54 -32
  191. package/src/{renderIfBinding.js → renderIfBinding.ts} +41 -19
  192. package/src/{renderIteration.js → renderIteration.ts} +24 -8
  193. package/src/renderTemplate.ts +165 -0
  194. package/src/renderTemplatesBinding.ts +73 -0
  195. package/src/{showBinding.js → showBinding.ts} +4 -3
  196. package/src/{switchBinding.js → switchBinding.ts} +18 -15
  197. package/src/{textBinding.js → textBinding.ts} +5 -4
  198. package/src/types.ts +124 -0
  199. package/src/util.ts +810 -0
  200. package/test/css/reporter.css +9 -9
  201. package/test/globals.d.ts +19 -0
  202. package/test/helpers/testHelper.js +46 -11
  203. package/test/mocks/featureAdsResult.json +65 -65
  204. package/test/mocks/searchResult.json +57 -57
  205. package/test/specs/{attrBinding.spec.js → attrBinding.spec.ts} +103 -106
  206. package/test/specs/{binder.spec.js → binder.spec.ts} +29 -27
  207. package/test/specs/blurBinding.spec.ts +60 -0
  208. package/test/specs/chainableUse.spec.ts +125 -0
  209. package/test/specs/clickBinding.spec.ts +194 -0
  210. package/test/specs/{cssBinding.spec.js → cssBinding.spec.ts} +72 -79
  211. package/test/specs/{dataBindBootstrap.spec.js → dataBindBootstrap.spec.ts} +332 -313
  212. package/test/specs/{filter.spec.js → filter.spec.ts} +75 -76
  213. package/test/specs/{forOfBinding.spec.js → forOfBinding.spec.ts} +208 -219
  214. package/test/specs/formBinding.spec.ts +272 -0
  215. package/test/specs/ifBinding.spec.ts +165 -0
  216. package/test/specs/{nestedComponent.spec.js → nestedComponent.spec.ts} +88 -88
  217. package/test/specs/reactiveProxy.spec.ts +465 -0
  218. package/test/specs/{showBinding.spec.js → showBinding.spec.ts} +148 -149
  219. package/test/specs/{switchBinding.spec.js → switchBinding.spec.ts} +172 -173
  220. package/test/specs/templateBinding.spec.ts +273 -0
  221. package/test/specs/{textBinding.spec.js → textBinding.spec.ts} +47 -48
  222. package/test/tsconfig.json +31 -0
  223. package/test-output.txt +200 -0
  224. package/test-reactive.html +224 -0
  225. package/tsconfig.json +28 -0
  226. package/vendors/lodash.custom.js +4577 -4577
  227. package/vendors/lodash.custom.min.js +45 -45
  228. package/vitest.config.js +27 -0
  229. package/.eslintrc.js +0 -1
  230. package/.grunt/grunt-contrib-jasmine/boot.js +0 -161
  231. package/.grunt/grunt-contrib-jasmine/dist/js/dataBind.js +0 -9
  232. package/.grunt/grunt-contrib-jasmine/grunt-template-jasmine-istanbul/reporter.js +0 -23
  233. package/.grunt/grunt-contrib-jasmine/jasmine-html.js +0 -853
  234. package/.grunt/grunt-contrib-jasmine/jasmine.css +0 -271
  235. package/.grunt/grunt-contrib-jasmine/jasmine.js +0 -9761
  236. package/.grunt/grunt-contrib-jasmine/jasmine_favicon.png +0 -0
  237. package/.grunt/grunt-contrib-jasmine/json2.js +0 -489
  238. package/.grunt/grunt-contrib-jasmine/reporter.js +0 -107
  239. package/coverage/coverage.json +0 -1
  240. package/coverage/lcov/lcov-report/base.css +0 -213
  241. package/coverage/lcov/lcov-report/index.html +0 -93
  242. package/coverage/lcov/lcov-report/js/dataBind.js.html +0 -6596
  243. package/coverage/lcov/lcov-report/js/index.html +0 -93
  244. package/coverage/lcov/lcov-report/prettify.css +0 -1
  245. package/coverage/lcov/lcov-report/prettify.js +0 -1
  246. package/coverage/lcov/lcov-report/sort-arrow-sprite.png +0 -0
  247. package/coverage/lcov/lcov-report/sorter.js +0 -158
  248. package/coverage/lcov/lcov.info +0 -1991
  249. package/eslintrc.json +0 -40
  250. package/examples/bootstrap/js/bootstrap.min.js +0 -6
  251. package/examples/bootstrap/js/popper.min.js +0 -5
  252. package/examples/bootstrap/js/searchSuggestion.js +0 -58
  253. package/examples/bootstrap/js/typeahead.jquery.js +0 -1538
  254. package/gruntfile.js +0 -92
  255. package/gulpfile.js +0 -32
  256. package/src/applyBindingExport.js +0 -5
  257. package/src/changeBinding.js +0 -63
  258. package/src/config.js +0 -66
  259. package/src/createEventBinding.js +0 -46
  260. package/src/eventSystem.js +0 -46
  261. package/src/hoverBinding.js +0 -57
  262. package/src/index.js +0 -26
  263. package/src/renderTemplate.js +0 -128
  264. package/src/renderTemplatesBinding.js +0 -44
  265. package/src/util.js +0 -648
  266. package/test/specs/blurBinding.spec.js +0 -57
  267. package/test/specs/formBinding.spec.js +0 -316
  268. package/test/specs/ifBinding.spec.js +0 -169
  269. package/test/specs/templateBinding.spec.js +0 -117
  270. package/vendors/jasmine-jquery.js +0 -841
  271. package/vendors/jquery-3.2.1.min.js +0 -4
@@ -1,6 +1,7 @@
1
1
  import {maxDatakeyLength} from './config';
2
2
  import {REGEX} from './util';
3
3
  import renderForOfBinding from './renderForOfBinding';
4
+ import type {BindingCache, ViewModel, BindingAttrs} from './types';
4
5
 
5
6
  /**
6
7
  * forOfBinding
@@ -10,7 +11,7 @@ import renderForOfBinding from './renderForOfBinding';
10
11
  * @param {object} viewModel
11
12
  * @param {object} bindingAttrs
12
13
  */
13
- const forOfBinding = (cache, viewModel, bindingAttrs) => {
14
+ const forOfBinding = (cache: BindingCache, viewModel: ViewModel, bindingAttrs: BindingAttrs, _forceRender?: boolean): void => {
14
15
  const dataKey = cache.dataKey;
15
16
 
16
17
  if (!dataKey || dataKey.length > maxDatakeyLength) {
@@ -42,8 +43,8 @@ const forOfBinding = (cache, viewModel, bindingAttrs) => {
42
43
 
43
44
  renderForOfBinding({
44
45
  bindingData: cache,
45
- viewModel: viewModel,
46
- bindingAttrs: bindingAttrs,
46
+ viewModel,
47
+ bindingAttrs,
47
48
  });
48
49
  };
49
50
 
@@ -0,0 +1,84 @@
1
+
2
+ import {bindingDataReference} from './config';
3
+ import {
4
+ getViewModelValue,
5
+ resolveViewModelContext,
6
+ resolveParamList,
7
+ } from './util';
8
+ import type {BindingCache, ViewModel, BindingAttrs, PlainObject} from './types';
9
+
10
+ /**
11
+ * Create mouse enter handler
12
+ */
13
+ const createMouseEnterHandler = (
14
+ cache: BindingCache,
15
+ handlers: PlainObject,
16
+ inHandlerName: string,
17
+ viewModelContext: ViewModel,
18
+ paramList: unknown[],
19
+ ): (e: MouseEvent) => void => {
20
+ return function onMouseEnterHandler(e: MouseEvent) {
21
+ const args = [e, cache.el, ...paramList];
22
+ (handlers[inHandlerName] as Function).apply(viewModelContext, args);
23
+ };
24
+ };
25
+
26
+ /**
27
+ * Create mouse leave handler
28
+ */
29
+ const createMouseLeaveHandler = (
30
+ cache: BindingCache,
31
+ handlers: PlainObject,
32
+ outHandlerName: string,
33
+ viewModelContext: ViewModel,
34
+ paramList: unknown[],
35
+ ): (e: MouseEvent) => void => {
36
+ return function onMouseLeaveHandler(e: MouseEvent) {
37
+ const args = [e, cache.el, ...paramList];
38
+ (handlers[outHandlerName] as Function).apply(viewModelContext, args);
39
+ };
40
+ };
41
+
42
+ /**
43
+ * hoverBinding
44
+ * DOM decleartive on hover event binding
45
+ * event handler bind to viewModel method according to the DOM attribute
46
+ * @param {object} cache
47
+ * @param {object} viewModel
48
+ * @param {object} bindingAttrs
49
+ * @param {boolean} forceRender
50
+ */
51
+ const hoverBinding = (cache: BindingCache, viewModel: ViewModel, bindingAttrs: BindingAttrs, forceRender: boolean): void => {
52
+ const handlerName = cache.dataKey;
53
+ let paramList = cache.parameters;
54
+ const inHandlerName = bindingDataReference.mouseEnterHandlerName;
55
+ const outHandlerName = bindingDataReference.mouseLeaveHandlerName;
56
+ let viewModelContext: ViewModel;
57
+ const APP = viewModel.APP || viewModel.$root?.APP;
58
+
59
+ cache.elementData = cache.elementData || {};
60
+
61
+ // TODO: check what is APP.$rootElement.contains(cache.el)
62
+ const rootElement = APP?.$rootElement as HTMLElement | undefined;
63
+ if (!handlerName || (!forceRender && rootElement && !rootElement.contains(cache.el))) {
64
+ return;
65
+ }
66
+
67
+ const handlers = getViewModelValue(viewModel, handlerName) as PlainObject;
68
+
69
+ if (handlers && typeof handlers[inHandlerName] === 'function' && typeof handlers[outHandlerName] === 'function') {
70
+ viewModelContext = resolveViewModelContext(viewModel, handlerName);
71
+ paramList = paramList ? resolveParamList(viewModel, paramList) : [];
72
+
73
+ const onMouseEnterHandler = createMouseEnterHandler(cache, handlers as PlainObject, inHandlerName, viewModelContext, paramList);
74
+ const onMouseLeaveHandler = createMouseLeaveHandler(cache, handlers as PlainObject, outHandlerName, viewModelContext, paramList);
75
+
76
+ cache.el.removeEventListener('mouseenter', onMouseEnterHandler, false);
77
+ cache.el.removeEventListener('mouseleave', onMouseLeaveHandler, false);
78
+
79
+ cache.el.addEventListener('mouseenter', onMouseEnterHandler, false);
80
+ cache.el.addEventListener('mouseleave', onMouseLeaveHandler, false);
81
+ }
82
+ };
83
+
84
+ export default hoverBinding;
@@ -2,6 +2,7 @@ import {bindingAttrs as configBindingAttrs, constants} from './config';
2
2
  import {getViewModelPropValue, removeElement} from './util';
3
3
  import {createClonedElementCache, wrapCommentAround} from './commentWrapper';
4
4
  import {renderIfBinding, removeIfBinding} from './renderIfBinding';
5
+ import type {BindingCache, ViewModel, BindingAttrs} from './types';
5
6
 
6
7
  /**
7
8
  * if-Binding
@@ -11,7 +12,7 @@ import {renderIfBinding, removeIfBinding} from './renderIfBinding';
11
12
  * @param {object} viewModel
12
13
  * @param {object} bindingAttrs
13
14
  */
14
- const ifBinding = (cache, viewModel, bindingAttrs) => {
15
+ const ifBinding = (cache: BindingCache, viewModel: ViewModel, bindingAttrs: BindingAttrs, _forceRender?: boolean): void => {
15
16
  const dataKey = cache.dataKey;
16
17
 
17
18
  // isOnce only return if there is no child bindings
@@ -38,8 +39,8 @@ const ifBinding = (cache, viewModel, bindingAttrs) => {
38
39
  removeElement(cache.el);
39
40
  // delete cache.fragment;
40
41
  removeBindingInQueue({
41
- viewModel: viewModel,
42
- cache: cache,
42
+ viewModel,
43
+ cache,
43
44
  });
44
45
  return;
45
46
  }
@@ -63,8 +64,8 @@ const ifBinding = (cache, viewModel, bindingAttrs) => {
63
64
  // render element
64
65
  renderIfBinding({
65
66
  bindingData: cache,
66
- viewModel: viewModel,
67
- bindingAttrs: bindingAttrs,
67
+ viewModel,
68
+ bindingAttrs,
68
69
  });
69
70
 
70
71
  // if render once
@@ -72,20 +73,21 @@ const ifBinding = (cache, viewModel, bindingAttrs) => {
72
73
  if (cache.isOnce && !cache.hasIterationBindingCache) {
73
74
  // delete cache.fragment;
74
75
  removeBindingInQueue({
75
- viewModel: viewModel,
76
- cache: cache,
76
+ viewModel,
77
+ cache,
77
78
  });
78
79
  }
79
80
  }
80
81
  };
81
82
 
82
- const removeBindingInQueue = ({viewModel, cache}) => {
83
+ const removeBindingInQueue = ({viewModel, cache}: {viewModel: ViewModel; cache: BindingCache}): boolean => {
83
84
  let ret = false;
84
- if (viewModel.APP.postProcessQueue) {
85
+ if (viewModel.APP?.postProcessQueue) {
86
+ const parentRef = cache[constants.PARENT_REF] as BindingCache[];
85
87
  viewModel.APP.postProcessQueue.push(
86
- ((cache, index) => () => {
87
- cache[constants.PARENT_REF].splice(index, 1);
88
- })(cache, cache[constants.PARENT_REF].indexOf(cache)),
88
+ ((cache: BindingCache, index: number) => () => {
89
+ parentRef.splice(index, 1);
90
+ })(cache, parentRef.indexOf(cache)),
89
91
  );
90
92
  ret = true;
91
93
  }
package/src/index.ts ADDED
@@ -0,0 +1,53 @@
1
+ import * as config from './config';
2
+ import {extend} from './util';
3
+ import Binder from './binder';
4
+ import type {PlainObject, ViewModel, BindingAttrs, BinderOptions} from './types';
5
+
6
+ const isSupportPromise = typeof window['Promise'] === 'function';
7
+
8
+ let bindingAttrs = config.bindingAttrs;
9
+
10
+ // Global default options for all Binder instances
11
+ const defaultOptions: BinderOptions = {
12
+ reactive: true, // Enable reactive mode by default
13
+ };
14
+
15
+ interface DataBindAPI {
16
+ use: (settings: PlainObject) => DataBindAPI;
17
+ init: ($rootElement: HTMLElement, viewModel: ViewModel | null, options?: BinderOptions) => Binder | void;
18
+ version: string;
19
+ }
20
+
21
+ const use = (settings: PlainObject = {}): DataBindAPI => {
22
+ if (settings.bindingAttrs) {
23
+ bindingAttrs = extend(false, {}, settings.bindingAttrs as PlainObject) as unknown as typeof config.bindingAttrs;
24
+ }
25
+ // Allow setting global reactive option
26
+ if (typeof settings.reactive === 'boolean') {
27
+ defaultOptions.reactive = settings.reactive;
28
+ }
29
+ // Allow setting global trackChanges option
30
+ if (typeof settings.trackChanges === 'boolean') {
31
+ defaultOptions.trackChanges = settings.trackChanges;
32
+ }
33
+ // Return API for chaining
34
+ return api;
35
+ };
36
+
37
+ const init = ($rootElement: HTMLElement, viewModel: ViewModel | null = null, options?: BinderOptions): Binder | void => {
38
+ if (!isSupportPromise) {
39
+ return console.warn('Browser not support Promise');
40
+ }
41
+ // Merge global defaults with instance-specific options
42
+ // Instance options take precedence over global defaults
43
+ const mergedOptions = {...defaultOptions, ...options};
44
+ return new Binder($rootElement, viewModel, bindingAttrs as unknown as BindingAttrs, mergedOptions);
45
+ };
46
+
47
+ const api: DataBindAPI = {
48
+ use,
49
+ init,
50
+ version: '@version@',
51
+ };
52
+
53
+ export default api;
@@ -1,4 +1,5 @@
1
1
  import {getViewModelValue} from './util';
2
+ import type {BindingCache, ViewModel, BindingAttrs} from './types';
2
3
 
3
4
  /**
4
5
  * modelBinding
@@ -8,23 +9,23 @@ import {getViewModelValue} from './util';
8
9
  * @param {object} bindingAttrs
9
10
  * @param {boolean} forceRender
10
11
  */
11
- const modelBinding = (cache, viewModel, bindingAttrs, forceRender) => {
12
+ const modelBinding = (cache: BindingCache, viewModel: ViewModel, bindingAttrs: BindingAttrs, forceRender: boolean): void => {
12
13
  const dataKey = cache.dataKey;
13
- let newValue = '';
14
- const APP = viewModel.APP || viewModel.$root.APP;
14
+ let newValue: unknown = '';
15
+ const APP = viewModel.APP || viewModel.$root?.APP;
15
16
 
16
- if (!dataKey || (!forceRender && !APP.$rootElement.contains(cache.el))) {
17
+ if (!dataKey || (!forceRender && !(APP?.$rootElement as HTMLElement)?.contains(cache.el))) {
17
18
  return;
18
19
  }
19
20
 
20
21
  newValue = getViewModelValue(viewModel, dataKey);
21
22
 
22
23
  if (typeof newValue !== 'undefined' && newValue !== null) {
23
- const $element = cache.el;
24
+ const $element = cache.el as HTMLInputElement;
24
25
  const isCheckbox = $element.type === 'checkbox';
25
26
  const isRadio = $element.type === 'radio';
26
27
  const inputName = $element.name;
27
- const $radioGroup = isRadio ? APP.$rootElement.querySelectorAll(`input[name="${inputName}"]`) : [];
28
+ const $radioGroup = isRadio ? (APP?.$rootElement as HTMLElement).querySelectorAll(`input[name="${inputName}"]`) : [];
28
29
  const oldValue = isCheckbox ? $element.checked : $element.value;
29
30
 
30
31
  // update element value
@@ -36,13 +37,14 @@ const modelBinding = (cache, viewModel, bindingAttrs, forceRender) => {
36
37
  const radioGroupLength = $radioGroup.length;
37
38
 
38
39
  for (i = 0; i < radioGroupLength; i += 1) {
39
- if ($radioGroup[i].value === newValue) {
40
- $radioGroup[i].checked = true;
40
+ const radioInput = $radioGroup[i] as HTMLInputElement;
41
+ if (radioInput.value === newValue) {
42
+ radioInput.checked = true;
41
43
  break;
42
44
  }
43
45
  }
44
46
  } else {
45
- $element.value = newValue;
47
+ $element.value = String(newValue);
46
48
  }
47
49
  }
48
50
  }
@@ -3,18 +3,20 @@ import {
3
3
  throwErrorMessage,
4
4
  } from './util';
5
5
 
6
- export default function postProcess(tasks) {
6
+ const postProcess = (tasks: Function[]): void => {
7
7
  if (!tasks || !tasks.length) {
8
8
  return;
9
9
  }
10
10
 
11
- each(tasks, (index, task) => {
11
+ each(tasks, (index: number, task: Function) => {
12
12
  if (typeof task === 'function') {
13
13
  try {
14
14
  task();
15
15
  } catch (err) {
16
- throwErrorMessage(err, 'Error postProcess: ' + String(task));
16
+ throwErrorMessage(err, `Error postProcess: ${ String(task)}`);
17
17
  }
18
18
  }
19
19
  });
20
- }
20
+ };
21
+
22
+ export default postProcess;
@@ -10,47 +10,58 @@ import * as util from './util';
10
10
  };
11
11
  */
12
12
 
13
- const EVENTS = {};
13
+ interface Subscriber {
14
+ [compId: string]: Function | boolean | undefined;
15
+ isOnce?: boolean;
16
+ }
14
17
 
15
- const subscribeEvent = (instance = null, eventName = '', fn, isOnce = false) => {
16
- if (!instance || !instance.compId || !eventName || typeof fn !== 'function') {
18
+ interface Events {
19
+ [eventName: string]: Subscriber[];
20
+ }
21
+
22
+ const EVENTS: Events = {};
23
+
24
+ export const subscribeEvent = (instance: unknown = null, eventName: string = '', fn: Function, isOnce: boolean = false): void => {
25
+ if (!instance || typeof instance !== 'object' || !('compId' in instance) || !instance.compId || !eventName || typeof fn !== 'function') {
17
26
  return;
18
27
  }
19
28
 
20
- let subscriber;
29
+ let subscriber: Subscriber;
21
30
  let isSubscribed = false;
22
31
 
23
32
  eventName = eventName.replace(util.REGEX.WHITE_SPACES, '');
24
33
  EVENTS[eventName] = EVENTS[eventName] || [];
25
34
  // check if already subscribed and update callback fn
35
+ const instanceWithViewModel = instance as { compId: string | number; viewModel: unknown };
26
36
  isSubscribed = EVENTS[eventName].some((subscriber) => {
27
- if (subscriber[instance.compId]) {
28
- subscriber[instance.compId] = fn.bind(instance.viewModel);
37
+ if (subscriber[instanceWithViewModel.compId]) {
38
+ subscriber[instanceWithViewModel.compId] = fn.bind(instanceWithViewModel.viewModel);
29
39
  subscriber.isOnce = isOnce;
30
40
  return true;
31
41
  }
42
+ return false;
32
43
  });
33
44
  // push if not yet subscribe
34
45
  if (!isSubscribed) {
35
46
  subscriber = {};
36
- subscriber[instance.compId] = fn.bind(instance.viewModel);
47
+ subscriber[instanceWithViewModel.compId] = fn.bind(instanceWithViewModel.viewModel);
37
48
  subscriber.isOnce = isOnce;
38
49
  EVENTS[eventName].push(subscriber);
39
50
  }
40
51
  };
41
52
 
42
- const subscribeEventOnce = (instance = null, eventName = '', fn) => {
53
+ export const subscribeEventOnce = (instance: unknown = null, eventName: string = '', fn: Function): void => {
43
54
  subscribeEvent(instance, eventName, fn, true);
44
55
  };
45
56
 
46
- const unsubscribeEvent = (compId = '', eventName = '') => {
57
+ export const unsubscribeEvent = (compId: string | number = '', eventName: string = ''): void => {
47
58
  if (!compId || !eventName) {
48
59
  return;
49
60
  }
50
61
 
51
62
  let i = 0;
52
63
  let subscribersLength = 0;
53
- let subscriber;
64
+ let subscriber: Subscriber;
54
65
 
55
66
  eventName = eventName.replace(util.REGEX.WHITE_SPACES, '');
56
67
 
@@ -65,7 +76,7 @@ const unsubscribeEvent = (compId = '', eventName = '') => {
65
76
  }
66
77
  }
67
78
  // delete the event if no more subscriber
68
- if (!EVENTS[eventName].length) {
79
+ if (EVENTS[eventName] && !EVENTS[eventName].length) {
69
80
  delete EVENTS[eventName];
70
81
  }
71
82
  };
@@ -75,7 +86,7 @@ const unsubscribeEvent = (compId = '', eventName = '') => {
75
86
  * @description unsubscribe all event by compId. eg when a component removed
76
87
  * @param {string} compId
77
88
  */
78
- const unsubscribeAllEvent = (compId = '') => {
89
+ export const unsubscribeAllEvent = (compId: string | number = ''): void => {
79
90
  if (!compId) {
80
91
  return;
81
92
  }
@@ -84,7 +95,7 @@ const unsubscribeAllEvent = (compId = '') => {
84
95
  });
85
96
  };
86
97
 
87
- const publishEvent = (eventName = '', ...args) => {
98
+ export const publishEvent = (eventName: string = '', ...args: unknown[]): void => {
88
99
  if (!eventName || !EVENTS[eventName]) {
89
100
  return;
90
101
  }
@@ -103,11 +114,3 @@ const publishEvent = (eventName = '', ...args) => {
103
114
  });
104
115
  });
105
116
  };
106
-
107
- export {
108
- subscribeEvent,
109
- subscribeEventOnce,
110
- unsubscribeEvent,
111
- unsubscribeAllEvent,
112
- publishEvent,
113
- };