@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
@@ -0,0 +1,40 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta name="description" content="DBMON WITH REACTIVE MODE" />
5
+ <link href="css/dbMonsterStyles.css" rel="stylesheet" type="text/css" />
6
+ <title>dbmon test dataBind.js (Reactive Mode)</title>
7
+ </head>
8
+
9
+ <body>
10
+ <div id="app">
11
+ <table class="table table-striped latest-data">
12
+ <tbody>
13
+ <tr data-bind-for="database in databases">
14
+ <td class="dbname" data-bind-text="database.dbname"></td>
15
+ <td class="query-count">
16
+ <span
17
+ data-bind-css="database.lastSample.countClassName"
18
+ data-bind-text="database.lastSample.nbQueries"
19
+ ></span>
20
+ </td>
21
+ <td data-bind-css="q.elapsedClassName" data-bind-for="q in $data.lastSample.topFiveQueries">
22
+ <span data-bind-text="q.formatElapsed"></span>
23
+ <div class="popover left">
24
+ <div class="popover-content" data-bind-text="q.query"></div>
25
+ <div class="arrow"></div>
26
+ </div>
27
+ </td>
28
+ </tr>
29
+ </tbody>
30
+ </table>
31
+ </div>
32
+
33
+ <script src="https://mathieuancelin.github.io/js-repaint-perfs/ENV.js"></script>
34
+ <script src="https://mathieuancelin.github.io/js-repaint-perfs/lib/memory-stats.js"></script>
35
+ <script src="https://mathieuancelin.github.io/js-repaint-perfs/lib/monitor.js"></script>
36
+
37
+ <script src="../dist/js/dataBind.min.js"></script>
38
+ <script src="js/dbMonAppReactive.js"></script>
39
+ </body>
40
+ </html>
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta name="description" content="DBMON REACT" />
5
+ <link href="css/dbMonsterStyles.css" rel="stylesheet" type="text/css" />
6
+ <title>dbmon test React</title>
7
+ </head>
8
+
9
+ <body>
10
+ <div id="app"></div>
11
+
12
+ <script src="https://mathieuancelin.github.io/js-repaint-perfs/ENV.js"></script>
13
+ <script src="https://mathieuancelin.github.io/js-repaint-perfs/lib/memory-stats.js"></script>
14
+ <script src="https://mathieuancelin.github.io/js-repaint-perfs/lib/monitor.js"></script>
15
+
16
+ <!-- Compiled React bundle -->
17
+ <script src="react-dbmonster/dist/bundle.js"></script>
18
+ </body>
19
+ </html>
@@ -0,0 +1,45 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>ForOf Debug</title>
6
+ </head>
7
+ <body>
8
+ <h1>ForOf Binding Debug</h1>
9
+
10
+ <div data-bind-comp="test-component">
11
+ <h3>Title: <span data-bind-text="title"></span></h3>
12
+ <p>Item count: <span data-bind-text="items.length"></span></p>
13
+
14
+ <div id="results" data-bind-tmp="{id: 'itemsTemplate', data: 'items'}"></div>
15
+ </div>
16
+
17
+ <template id="itemsTemplate">
18
+ <div data-bind-for="item in $root.items" style="border: 1px solid black; padding: 10px; margin: 5px;">
19
+ <strong data-bind-text="item.name"></strong>:
20
+ <span data-bind-text="item.value"></span>
21
+ </div>
22
+ </template>
23
+
24
+ <script src="../dist/js/dataBind.min.js"></script>
25
+ <script>
26
+ const viewModel = {
27
+ title: 'Test Items',
28
+ items: [
29
+ { name: 'Item 1', value: 'Value 1' },
30
+ { name: 'Item 2', value: 'Value 2' },
31
+ { name: 'Item 3', value: 'Value 3' },
32
+ { name: 'Item 4', value: 'Value 4' },
33
+ { name: 'Item 5', value: 'Value 5' }
34
+ ]
35
+ };
36
+
37
+ const component = dataBind.init(document.querySelector('[data-bind-comp="test-component"]'), viewModel);
38
+ component.render().then(() => {
39
+ console.log('Rendered!', component);
40
+ console.log('Results div:', document.getElementById('results'));
41
+ console.log('Results div children:', document.getElementById('results').children);
42
+ });
43
+ </script>
44
+ </body>
45
+ </html>
@@ -0,0 +1,131 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>dataBind - Global Configuration Demo</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ max-width: 1200px;
11
+ margin: 0 auto;
12
+ padding: 20px;
13
+ }
14
+ .section {
15
+ border: 2px solid #ddd;
16
+ padding: 20px;
17
+ margin: 20px 0;
18
+ border-radius: 8px;
19
+ }
20
+ .section h3 {
21
+ margin-top: 0;
22
+ color: #333;
23
+ }
24
+ button {
25
+ padding: 8px 16px;
26
+ margin: 5px;
27
+ cursor: pointer;
28
+ border: 1px solid #007bff;
29
+ background: #007bff;
30
+ color: white;
31
+ border-radius: 4px;
32
+ }
33
+ button:hover {
34
+ background: #0056b3;
35
+ }
36
+ .output {
37
+ background: #f5f5f5;
38
+ padding: 10px;
39
+ margin: 10px 0;
40
+ border-radius: 4px;
41
+ font-family: monospace;
42
+ }
43
+ .mode-badge {
44
+ display: inline-block;
45
+ padding: 4px 8px;
46
+ border-radius: 4px;
47
+ font-size: 12px;
48
+ font-weight: bold;
49
+ }
50
+ .reactive {
51
+ background: #28a745;
52
+ color: white;
53
+ }
54
+ .manual {
55
+ background: #ffc107;
56
+ color: #333;
57
+ }
58
+ </style>
59
+ </head>
60
+
61
+ <body>
62
+ <h1>dataBind.js - Global Configuration Demo</h1>
63
+ <p>This demo shows how to use <code>dataBind.use()</code> to configure global defaults.</p>
64
+
65
+ <!-- Example 1: Default Reactive Mode -->
66
+ <div class="section">
67
+ <h3>Example 1: Default Configuration <span class="mode-badge reactive">REACTIVE</span></h3>
68
+ <p>No configuration - uses built-in default (reactive: true)</p>
69
+ <div data-bind-comp="default-example">
70
+ <div class="output">
71
+ <div>Counter: <span data-bind-text="counter"></span></div>
72
+ </div>
73
+ <button data-bind-click="increment">Increment</button>
74
+ <button data-bind-click="reset">Reset</button>
75
+ </div>
76
+ </div>
77
+
78
+ <!-- Example 2: Global Manual Mode -->
79
+ <div class="section">
80
+ <h3>Example 2: After dataBind.use({reactive: false}) <span class="mode-badge manual">MANUAL</span></h3>
81
+ <p>This component uses manual mode because we called dataBind.use({reactive: false})</p>
82
+ <div data-bind-comp="global-manual">
83
+ <div class="output">
84
+ <div>Counter: <span data-bind-text="counter"></span></div>
85
+ </div>
86
+ <button data-bind-click="increment">Increment (Manual Mode)</button>
87
+ <button data-bind-click="reset">Reset (Manual Mode)</button>
88
+ </div>
89
+ </div>
90
+
91
+ <!-- Example 3: Chainable API -->
92
+ <div class="section">
93
+ <h3>Example 3: Chainable API <span class="mode-badge manual">MANUAL</span></h3>
94
+ <p>This component uses <code>dataBind.use({reactive: false}).init(...)</code> chaining</p>
95
+ <div data-bind-comp="chainable">
96
+ <div class="output">
97
+ <div>Counter: <span data-bind-text="counter"></span></div>
98
+ </div>
99
+ <button data-bind-click="increment">Increment (Chained)</button>
100
+ <button data-bind-click="reset">Reset (Chained)</button>
101
+ </div>
102
+ </div>
103
+
104
+ <!-- Example 4: Instance Override -->
105
+ <div class="section">
106
+ <h3>Example 4: Instance Override <span class="mode-badge reactive">REACTIVE</span></h3>
107
+ <p>This component overrides global setting with {reactive: true}</p>
108
+ <div data-bind-comp="instance-override">
109
+ <div class="output">
110
+ <div>Counter: <span data-bind-text="counter"></span></div>
111
+ </div>
112
+ <button data-bind-click="increment">Increment (Override to Reactive)</button>
113
+ <button data-bind-click="reset">Reset (Override to Reactive)</button>
114
+ </div>
115
+ </div>
116
+
117
+ <!-- Configuration Status -->
118
+ <div class="section">
119
+ <h3>Current Configuration</h3>
120
+ <div class="output">
121
+ <div>Example 1 Mode: <span id="mode1"></span></div>
122
+ <div>Example 2 Mode: <span id="mode2"></span></div>
123
+ <div>Example 3 Mode: <span id="mode3"></span></div>
124
+ <div>Example 4 Mode: <span id="mode4"></span></div>
125
+ </div>
126
+ </div>
127
+
128
+ <script src="../dist/js/dataBind.min.js"></script>
129
+ <script src="js/globalConfig.js"></script>
130
+ </body>
131
+ </html>
@@ -0,0 +1,190 @@
1
+ (function () {
2
+ // Helper function to log messages
3
+ function log(logId, message, type = 'info') {
4
+ const logEl = document.getElementById(logId);
5
+ const entry = document.createElement('div');
6
+ entry.className = 'log-entry';
7
+ entry.textContent = `[${new Date().toLocaleTimeString()}] ${message}`;
8
+ logEl.appendChild(entry);
9
+ logEl.scrollTop = logEl.scrollHeight;
10
+ }
11
+
12
+ // Example 1: Basic Usage
13
+ const basicViewModel = {
14
+ counter: 0,
15
+ increment() {
16
+ this.counter++;
17
+ // Reactive mode - automatic render!
18
+ },
19
+ reset() {
20
+ this.counter = 0;
21
+ // Reactive mode - automatic render!
22
+ },
23
+ };
24
+
25
+ const basicComponent = dataBind.init(
26
+ document.querySelector('[data-bind-comp="basic-demo"]'),
27
+ basicViewModel,
28
+ );
29
+
30
+ // Register afterRender callback
31
+ basicComponent.afterRender(() => {
32
+ log('basic-log', `Counter updated to: ${basicComponent.viewModel.counter}`);
33
+ });
34
+
35
+ basicComponent.render().then(() => {
36
+ log('basic-log', 'Component initialized');
37
+ });
38
+
39
+ // Example 2: Performance Monitoring
40
+ const perfViewModel = {
41
+ items: [],
42
+ addItems() {
43
+ for (let i = 0; i < 10; i++) {
44
+ this.items.push({
45
+ text: `Item ${this.items.length + 1}`,
46
+ id: Date.now() + i,
47
+ });
48
+ }
49
+ // Reactive mode - automatic render!
50
+ },
51
+ clearItems() {
52
+ this.items = [];
53
+ // Reactive mode - automatic render!
54
+ },
55
+ };
56
+
57
+ const perfComponent = dataBind.init(
58
+ document.querySelector('[data-bind-comp="perf-demo"]'),
59
+ perfViewModel,
60
+ );
61
+
62
+ // Track render performance
63
+ let renderStartTime;
64
+ perfComponent.afterRender(() => {
65
+ if (renderStartTime) {
66
+ const renderTime = performance.now() - renderStartTime;
67
+ log('perf-log', `Render completed in ${renderTime.toFixed(2)}ms (${perfComponent.viewModel.items.length} items)`);
68
+ renderStartTime = null;
69
+ }
70
+ });
71
+
72
+ // Hook into viewModel changes to track start time
73
+ const originalAddItems = perfViewModel.addItems;
74
+ perfViewModel.addItems = function () {
75
+ renderStartTime = performance.now();
76
+ originalAddItems.call(this);
77
+ };
78
+
79
+ const originalClearItems = perfViewModel.clearItems;
80
+ perfViewModel.clearItems = function () {
81
+ renderStartTime = performance.now();
82
+ originalClearItems.call(this);
83
+ };
84
+
85
+ perfComponent.render().then(() => {
86
+ log('perf-log', 'Performance monitor ready');
87
+ });
88
+
89
+ // Example 3: DOM Manipulation
90
+ const domViewModel = {
91
+ items: [
92
+ {text: 'Item 1', active: true},
93
+ {text: 'Item 2', active: false},
94
+ ],
95
+ get activeCount() {
96
+ return this.items.filter(item => item.active).length;
97
+ },
98
+ addItem() {
99
+ this.items.push({
100
+ text: `Item ${this.items.length + 1}`,
101
+ active: false,
102
+ });
103
+ // Reactive mode - automatic render!
104
+ },
105
+ toggleFirst() {
106
+ if (this.items.length > 0) {
107
+ this.items[0].active = !this.items[0].active;
108
+ // Reactive mode - automatic render!
109
+ }
110
+ },
111
+ };
112
+
113
+ const domComponent = dataBind.init(
114
+ document.querySelector('[data-bind-comp="dom-demo"]'),
115
+ domViewModel,
116
+ );
117
+
118
+ // DOM manipulation after render
119
+ domComponent.afterRender(() => {
120
+ const list = document.getElementById('dom-list');
121
+ const activeItems = list.querySelectorAll('.highlight');
122
+ log('dom-log', `Render complete: ${activeItems.length} active items highlighted`);
123
+
124
+ // Example: Scroll to first active item
125
+ if (activeItems.length > 0) {
126
+ activeItems[0].scrollIntoView({behavior: 'smooth', block: 'nearest'});
127
+ }
128
+ });
129
+
130
+ domComponent.render().then(() => {
131
+ log('dom-log', 'DOM manipulation demo ready');
132
+ });
133
+
134
+ // Example 4: Add/Remove Callbacks
135
+ const toggleViewModel = {
136
+ value: 0,
137
+ increment() {
138
+ this.value++;
139
+ // Reactive mode - automatic render!
140
+ },
141
+ };
142
+
143
+ const toggleComponent = dataBind.init(
144
+ document.querySelector('[data-bind-comp="toggle-demo"]'),
145
+ toggleViewModel,
146
+ );
147
+
148
+ // Callback reference for add/remove
149
+ let loggerCallback = null;
150
+
151
+ document.getElementById('addCallback').addEventListener('click', () => {
152
+ if (!loggerCallback) {
153
+ loggerCallback = () => {
154
+ log('toggle-log', `Value changed to: ${toggleComponent.viewModel.value}`);
155
+ };
156
+ toggleComponent.afterRender(loggerCallback);
157
+ log('toggle-log', '✅ Logger callback added', 'success');
158
+ } else {
159
+ log('toggle-log', '⚠️ Logger already added', 'warning');
160
+ }
161
+ });
162
+
163
+ document.getElementById('removeCallback').addEventListener('click', () => {
164
+ if (loggerCallback) {
165
+ toggleComponent.removeAfterRender(loggerCallback);
166
+ log('toggle-log', '❌ Logger callback removed', 'info');
167
+ loggerCallback = null;
168
+ } else {
169
+ log('toggle-log', '⚠️ No logger to remove', 'warning');
170
+ }
171
+ });
172
+
173
+ document.getElementById('clearCallbacks').addEventListener('click', () => {
174
+ toggleComponent.clearAfterRender();
175
+ log('toggle-log', '🗑️ All callbacks cleared', 'info');
176
+ loggerCallback = null;
177
+ });
178
+
179
+ toggleComponent.render().then(() => {
180
+ log('toggle-log', 'Toggle demo ready');
181
+ });
182
+
183
+ // Debug access
184
+ window.afterRenderDemos = {
185
+ basic: basicComponent,
186
+ perf: perfComponent,
187
+ dom: domComponent,
188
+ toggle: toggleComponent,
189
+ };
190
+ })();
@@ -12,7 +12,7 @@
12
12
  showAllCss: {selected: true},
13
13
  showActiveCss: {selected: false},
14
14
  showCompletedCss: {selected: false},
15
- onAddTask: function(e, $el, newValue, oldValue) {
15
+ onAddTask(e, $el, newValue) {
16
16
  this.tasks.push({
17
17
  taskTitle: String(newValue).trim(),
18
18
  completed: false,
@@ -23,32 +23,32 @@
23
23
  this.updateViewData();
24
24
  $el.value = '';
25
25
  },
26
- onMarkAllCompleted: function(e, $el, newValue, oldValue) {
27
- this.tasks.forEach(function(task, index) {
26
+ onMarkAllCompleted(e, $el, newValue) {
27
+ this.tasks.forEach((task) => {
28
28
  task.completed = newValue;
29
29
  });
30
30
  this.updateViewData();
31
31
  },
32
- onClearAllCompleted: function(e, $el) {
33
- const newTasks = this.tasks.filter(function(task, index) {
32
+ onClearAllCompleted() {
33
+ const newTasks = this.tasks.filter((task) => {
34
34
  return task.completed !== true;
35
35
  });
36
36
  this.tasks = newTasks;
37
37
  this.updateViewData();
38
38
  },
39
- onTaskCompleted: function(e, $el, newValue, oldValue, index) {
39
+ onTaskCompleted(e, $el, newValue, oldValue, index) {
40
40
  this.tasks[index].completed = newValue;
41
41
  this.updateViewData({templateBinding: true});
42
42
  },
43
- onTaskRemove: function(e, $el, index) {
43
+ onTaskRemove(e, $el, index) {
44
44
  this.tasks.splice(index, 1);
45
45
  this.updateViewData();
46
46
  },
47
- onEditTask: function(e, $el, index) {
47
+ onEditTask(e, $el, index) {
48
48
  this.tasks[index].editing = true;
49
49
  this.updateViewData({templateBinding: false});
50
50
  },
51
- onBlurEditTask: function(e, $el, index) {
51
+ onBlurEditTask(e, $el, index) {
52
52
  const oldValue = this.tasks[index].taskTitle;
53
53
  const newValue = $el.value.trim();
54
54
  let isChanged = false;
@@ -60,58 +60,58 @@
60
60
  this.tasks[index].editing = false;
61
61
  this.updateViewData({templateBinding: isChanged});
62
62
  },
63
- onShowAllTasks: function(e) {
63
+ onShowAllTasks() {
64
64
  this.displayFilter = 'all';
65
65
  this.updateViewData();
66
66
  },
67
- onShowAactiveTasks: function(e) {
67
+ onShowAactiveTasks() {
68
68
  this.displayFilter = 'active';
69
69
  this.updateViewData();
70
70
  },
71
- onShowCompletedTasks: function(e) {
71
+ onShowCompletedTasks() {
72
72
  this.displayFilter = 'completed';
73
73
  this.updateViewData();
74
74
  },
75
- getCompletedTasks: function() {
76
- return this.tasks.filter(function(task, index) {
75
+ getCompletedTasks() {
76
+ return this.tasks.filter((task) => {
77
77
  return task.completed === true;
78
78
  });
79
79
  },
80
- getDisplayTasks: function() {
80
+ getDisplayTasks() {
81
81
  let displayTasks = [];
82
82
  switch (this.displayFilter) {
83
- case 'all':
84
- displayTasks = this.tasks;
85
- this.showAllCss = {selected: true};
86
- this.showActiveCss = {selected: false};
87
- this.showCompletedCss = {selected: false};
88
- break;
89
- case 'active':
90
- displayTasks = this.tasks.filter(function(task, index) {
91
- return task.completed !== true;
92
- });
93
- this.showAllCss = {selected: false};
94
- this.showActiveCss = {selected: true};
95
- this.showCompletedCss = {selected: false};
96
- break;
97
- case 'completed':
98
- displayTasks = displayTasks = this.tasks.filter(function(task, index) {
99
- return task.completed === true;
100
- });
101
- this.showAllCss = {selected: false};
102
- this.showActiveCss = {selected: false};
103
- this.showCompletedCss = {selected: true};
104
- break;
83
+ case 'all':
84
+ displayTasks = this.tasks;
85
+ this.showAllCss = {selected: true};
86
+ this.showActiveCss = {selected: false};
87
+ this.showCompletedCss = {selected: false};
88
+ break;
89
+ case 'active':
90
+ displayTasks = this.tasks.filter((task) => {
91
+ return task.completed !== true;
92
+ });
93
+ this.showAllCss = {selected: false};
94
+ this.showActiveCss = {selected: true};
95
+ this.showCompletedCss = {selected: false};
96
+ break;
97
+ case 'completed':
98
+ displayTasks = displayTasks = this.tasks.filter((task) => {
99
+ return task.completed === true;
100
+ });
101
+ this.showAllCss = {selected: false};
102
+ this.showActiveCss = {selected: false};
103
+ this.showCompletedCss = {selected: true};
104
+ break;
105
105
  }
106
106
  return displayTasks;
107
107
  },
108
- setTaskLabelAttr: function(index) {
108
+ setTaskLabelAttr(index) {
109
109
  return {for: `taskEdit-${index}`};
110
110
  },
111
- setTaskInputAttr: function(index) {
111
+ setTaskInputAttr(index) {
112
112
  return {id: `taskEdit-${index}`};
113
113
  },
114
- updateViewData: function(renderOption) {
114
+ updateViewData(renderOption) {
115
115
  const compltedTasks = this.getCompletedTasks();
116
116
  const compltedTasksLength = compltedTasks.length;
117
117
  const currentTaskLength = this.tasks.length;
@@ -122,25 +122,25 @@
122
122
  this.remainingCount = currentTaskLength - compltedTasksLength;
123
123
  this.remainingCountLabel = this.remainingCount > 1 ? ' tasks' : ' task';
124
124
  this.displayTasks = this.getDisplayTasks();
125
- todoApp.render(renderOption);
125
+ // Reactive mode - automatic render!
126
126
  // update db
127
127
  db.set('todos', this.tasks);
128
128
  },
129
- afterTemplateRender: function() {
129
+ afterTemplateRender() {
130
130
  console.log('template rendered');
131
131
  },
132
132
  };
133
133
 
134
134
  const db = {
135
- set: function(storeKey, data) {
135
+ set(storeKey, data) {
136
136
  if (storeKey && data) {
137
137
  localStorage.setItem(storeKey, JSON.stringify(data));
138
138
  }
139
139
  },
140
- get: function(storeKey) {
140
+ get(storeKey) {
141
141
  return JSON.parse(localStorage.getItem(storeKey));
142
142
  },
143
- clear: function(storeKey) {
143
+ clear(storeKey) {
144
144
  if (storeKey) {
145
145
  localStorage.removeItem(storeKey);
146
146
  }
@@ -150,7 +150,7 @@
150
150
  viewModel.displayTasks = db.get('todos') || [];
151
151
 
152
152
  const todoApp = dataBind.init(document.getElementById('todoapp'), viewModel);
153
- todoApp.render().then(function() {
153
+ todoApp.render().then(() => {
154
154
  // retrive data from storage
155
155
  viewModel.tasks = db.get('todos') || [];
156
156
  // update viewModel data and trigger todoApp.render
@@ -5,13 +5,13 @@ const viewModel = {
5
5
  style: 'width:300px',
6
6
  ref: 'newRef',
7
7
  },
8
- attrFn: function($data) {
8
+ attrFn() {
9
9
  return {
10
10
  id: 'newId',
11
11
  ref: 'newRef2',
12
12
  };
13
13
  },
14
- updateView: function(opt) {
14
+ updateView(opt) {
15
15
  this.APP.render(opt);
16
16
  },
17
17
  };
@@ -1,26 +1,24 @@
1
- const viewModel = {
2
- databases: ENV.generateData().toArray(),
3
- };
4
- let oldDbLength = viewModel.databases.length;
5
- let newDbLength = 0;
6
-
7
- function refreshApp() {
8
- let shouldUpdateTemplate = true;
9
-
10
- viewModel.databases = ENV.generateData().toArray();
11
- newDbLength = viewModel.databases.length;
12
- shouldUpdateTemplate = oldDbLength !== newDbLength;
13
- // only re-render template binding if database size different
14
- dbMonApp.render({templateBinding: shouldUpdateTemplate});
15
- oldDbLength = newDbLength;
16
-
17
- Monitoring.renderRate.ping();
18
- setTimeout(refreshApp, ENV.timeout);
19
- }
20
-
21
-
22
- const dbMonApp = dataBind.init(document.getElementById('app'), viewModel);
23
- dbMonApp.render().then(function() {
24
- console.log('dbMonApp inited');
25
- refreshApp();
26
- });
1
+ const performanceEnv = window.ENV;
2
+ const performanceMonitoring = window.Monitoring;
3
+
4
+ const viewModel = {
5
+ databases: performanceEnv.generateData().toArray(),
6
+ };
7
+
8
+ // Manual mode for performance benchmark
9
+ const dbMonApp = dataBind.init(document.getElementById('app'), viewModel, {reactive: false});
10
+
11
+ function refreshApp() {
12
+ viewModel.databases = performanceEnv.generateData().toArray();
13
+ dbMonApp.render();
14
+
15
+ performanceMonitoring.renderRate.ping();
16
+ setTimeout(refreshApp, performanceEnv.timeout);
17
+ }
18
+
19
+ // render().then() works with both reactive and manual modes
20
+ // The callback runs after the initial render completes
21
+ dbMonApp.render().then(() => {
22
+ console.log('dbMonApp (Manual) inited');
23
+ refreshApp();
24
+ });