@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.
- 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 +2756 -2530
- 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/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 +14 -14
- 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.js → applyBinding.ts} +27 -18
- package/src/{attrBinding.js → attrBinding.ts} +14 -13
- package/src/{binder.js → binder.ts} +289 -181
- package/src/changeBinding.ts +93 -0
- package/src/{commentWrapper.js → commentWrapper.ts} +33 -30
- package/src/config.ts +107 -0
- package/src/{createBindingOption.js → createBindingOption.ts} +39 -15
- 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.js → postProcess.ts} +6 -4
- package/src/{pubSub.js → pubSub.ts} +24 -21
- package/src/reactiveProxy.ts +285 -0
- package/src/{renderForOfBinding.js → renderForOfBinding.ts} +54 -32
- package/src/{renderIfBinding.js → renderIfBinding.ts} +41 -19
- package/src/{renderIteration.js → renderIteration.ts} +24 -8
- 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/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/applyBindingExport.js +0 -5
- package/src/changeBinding.js +0 -63
- package/src/config.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/renderTemplatesBinding.js +0 -44
- package/src/util.js +0 -648
- package/test/specs/blurBinding.spec.js +0 -57
- package/test/specs/formBinding.spec.js +0 -316
- 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 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["dataBind.min.js"],"names":["global","factory","exports","module","define","amd","globalThis","self","dataBind","this","bindingAttrs$1","comp","tmp","text","click","dblclick","blur","focus","hover","input","change","submit","model","show","css","attr","forOf","if","switch","case","default","serverRenderedAttr","commentPrefix","commentSuffix","bindingDataReference","bindingUpdateConditions","maxDatakeyLength","constants","ONCE","hasIsArray","Array","isArray","REGEX","BAD_TAGS","FOR_OF","FUNCTION_PARAM","HTML_TAG","OBJECT_LITERAL","PIPE","WHITE_SPACES","LINE_BREAKS_TABS","IS_SUPPORT_TEMPLATE","document","createElement","WRAP_MAP","div","thead","col","tr","td","caption","colgroup","tbody","tfoot","th","obj","Object","prototype","toString","call","isJsObject","isPlainObject","ctor","constructor","prot","hasOwnProperty","isEmptyObject","getOwnPropertyNames","length","createHtmlFragment","htmlString","template","innerHTML","replace","removeBadTags","content","fragment","createDocumentFragment","queryContainer","firstTag","match","getFirstHtmlStringTag","wrap","createRange","createContextualFragment","insertAdjacentHTML","query","querySelector","firstChild","appendChild","getViewModelValue","viewModel","prop","split","filter","Boolean","every","step","undefined","def","setViewModelValue","value","path","slice","reduce","a","c","i","Math","abs","_set","getViewModelPropValue","bindingCache","dataKey","paramList","parameters","isInvertBoolean","charAt","substring","ret","viewModelContext","resolveViewModelContext","oldViewModelProValue","elementData","viewModelPropValue","resolveParamList","args","concat","el","apply","filtersViewModelPropValue","filters","each","index","filterFn","err","throwErrorMessage","createDeferredObj","dfObj","promise","Promise","resolve","reject","extend","isDeepMerge","target","sources","source","shift","isMergebleObject","keys","forEach","key","assign","fn","keysLength","isArrayObj","TypeError","item","insertAfter","parentNode","newNode","referenceNode","refNextElement","nextSibling","insertBefore","datakey","bindingDataContext","map","param","trim","emptyElement","node","removeChild","errorMessage","message","console","error","log","bindingAttrsMap","walkDOM","func","parseChildNode","firstElementChild","nextElementSibling","rootSkipCheck","tagName","defaultSkipCheck","bindingAttrs","hasAttribute","populateBindingCache","attrObj","type","attrValue","cacheData","filterList","isOnceIndex","v","isOnce","splice","extractFilterList","str","paramlist","getFunctionParameterList","push","createBindingCache","rootNode","skipCheck","isRenderedTemplate","window","Node","sourceObj","parseNode","skipNodeCheckFn","isSkipForOfChild","nodeType","hasAttributes","attributes","name","getAttributesObject","hasSkipChildParseBindings","checkSkipChildParseBindings","iterateList","createBindingOption","condition","opt","visualBindingOptions","templateBinding","textBinding","cssBinding","ifBinding","showBinding","modelBinding","attrBinding","forOfBinding","switchBinding","eventsBindingOptions","changeBinding","clickBinding","dblclickBinding","blurBinding","focusBinding","hoverBinding","inputBinding","submitBinding","serverRenderedOptions","updateOption","reUnescapedHtml","reHasUnescapedHtml","RegExp","htmlEscapes","escapeHtmlChar","chr","cache","forceRender","handlerName","modelDataKey","getAttribute","newValue","oldValue","APP","$root","$rootElement","contains","handlerFn","changeHandler","e","$this","isCheckbox","string","checked","test","currentTarget","removeEventListener","addEventListener","isObjLiteralStr","isObjectLiteralString","vmAttrObj","objectLiteralString","keyVal","parseBindingObjectString","JSON","stringify","oldAttrObj","setAttribute","removeAttribute","$domFragment","$templateRoot","nestTemplatesCount","renderTemplate","elementCache","settings","parse","parseStringToJson","viewData","data","isAppend","append","isPrepend","prepend","$currentElement","$element","$index","htmlFragment","id","templateElement","getElementById","getTemplateString","childNodes","$nestedTemplates","querySelectorAll","nestedTemplatesLength","thisTemplateCache","afterTemplateRender","renderTemplatesBinding","ctx","updateElementCache","templateCache","isRenderedTemplates","applyBinding","renderIteration","iterationVm","isRegenerate","bindingUpdateOption","createClonedElementCache","bindingData","clonedElement","cloneNode","setCommentPrefix","commentPrefix$1","dataKeyMarker","setDocRangeEndAfter","endTextContent","textContent","docRange","setEndBefore","wrapCommentAround","prefix","commentBegin","createComment","commentEnd","previousNonTemplateElement","previousSibling","nextNonTemplateElement","parentElement","removeElemnetsByCommentWrap","setStartBefore","deleteContents","insertRenderedElements","createIterationViewModel","iterationData","iterator","alias","generateForOfElements","iterationDataLength","iterationSize","clonedItem","iterationBindingCache","forExpMatch","renderForOfBinding","renderIfBinding","isDomRemoved","commentStartTextContent","endCommentTag","isTargetDomRemoved","rootElement","removeIfBinding","hasIterationBindingCache","removeBindingInQueue","postProcessQueue","indexOf","removeUnmatchCases","cases","matchedIndex","caseData","createCaseData","attrName","createEventBinding","handlerWrap","formData","$form","HTMLFormElement","FormData","getFormData","shouldRender","currentInlineSytle","currentInlineDisplaySytle","shouldShow","oldShowStatus","displayStyle","computedStyle","style","display","computeStyle","getComputedStyle","getPropertyValue","setProperty","removeProperty","newExpression","childrenElements","children","elementLength","isDefault","hasMatch","j","casesLength","newCaseValue","oldCssList","newCssList","vmCssListObj","vmCssListArray","isViewDataObject","isViewDataString","cssList","domCssList","classList","domCssListLength","frommArray","k","join","isRadio","inputName","$radioGroup","radioGroupLength","inHandlerName","outHandlerName","handlers","onMouseEnterHandler","onMouseLeaveHandler","EVENTS","subscribeEvent","instance","eventName","compId","subscriber","isSubscribed","some","bind","unsubscribeEvent","subscribersLength","compIdIndex","Binder","initRendered","render","rafId","from","arguments","cancelAnimationFrame","requestAnimationFrame","debounceRaf","isServerRendered","parseView","allCache","skipForOfParseFn","renderBindingOption","tasks","task","String","subscribe","subscribeOnce","subscribeEventOnce","unsubscribe","unsubscribeAll","unsubscribeAllEvent","publish","publishEvent","isSupportPromise","use","init","warn","version"],"mappings":"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","file":"dataBind.min.js","sourcesContent":["/**\n * @gogocat/data-bind\n * version 1.12.0\n * By Adam Chow\n * link https://gogocat.github.io/dataBind/\n * license MIT\n * \n */\n\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.dataBind = factory());\n}(this, (function () { 'use strict';\n\n const bindingAttrs$1 = {\n comp: 'data-bind-comp',\n tmp: 'data-bind-tmp',\n text: 'data-bind-text',\n click: 'data-bind-click',\n dblclick: 'data-bind-dblclick',\n blur: 'data-bind-blur',\n focus: 'data-bind-focus',\n hover: 'data-bind-hover',\n input: 'data-bind-input',\n change: 'data-bind-change',\n submit: 'data-bind-submit',\n model: 'data-bind-model',\n show: 'data-bind-show',\n css: 'data-bind-css',\n attr: 'data-bind-attr',\n forOf: 'data-bind-for',\n if: 'data-bind-if',\n switch: 'data-bind-switch',\n case: 'data-bind-case',\n default: 'data-bind-default'\n };\n const serverRenderedAttr = 'data-server-rendered';\n const dataIndexAttr = 'data-index';\n const commentPrefix = {\n forOf: 'data-forOf_',\n if: 'data-if_',\n case: 'data-case_',\n default: 'data-default_'\n };\n const commentSuffix = '_end';\n const bindingDataReference = {\n rootDataKey: '$root',\n currentData: '$data',\n currentIndex: '$index',\n mouseEnterHandlerName: 'in',\n mouseLeaveHandlerName: 'out'\n };\n const bindingUpdateConditions = {\n serverRendered: 'SERVER-RENDERED',\n init: 'INIT'\n }; // maximum string length before running regex\n\n const maxDatakeyLength = 250;\n const constants = {\n filters: {\n ONCE: 'once'\n },\n PARENT_REF: '_parent'\n };\n\n const hasIsArray = Array.isArray;\n const REGEX = {\n BAD_TAGS: /<(script|del)(?=[\\s>])[\\w\\W]*?<\\/\\1\\s*>/ig,\n FOR_OF: /(.*?)\\s+(?:in|of)\\s+(.*)/,\n FUNCTION_PARAM: /\\((.*?)\\)/,\n HTML_TAG: /^[\\s]*<([a-z][^\\/\\s>]+)/i,\n OBJECT_LITERAL: /^\\{.+\\}$/,\n PIPE: /\\|/,\n WHITE_SPACES: /\\s+/g,\n LINE_BREAKS_TABS: /(\\r\\n|\\n|\\r|\\t)/gm\n };\n const IS_SUPPORT_TEMPLATE = ('content' in document.createElement('template'));\n const WRAP_MAP = {\n div: ['div', '<div>', '</div>'],\n thead: ['table', '<table>', '</table>'],\n col: ['colgroup', '<table><colgroup>', '</colgroup></table>'],\n tr: ['tbody', '<table><tbody>', '</tbody></table>'],\n td: ['tr', '<table><tr>', '</tr></table>']\n };\n WRAP_MAP.caption = WRAP_MAP.colgroup = WRAP_MAP.tbody = WRAP_MAP.tfoot = WRAP_MAP.thead;\n WRAP_MAP.th = WRAP_MAP.td;\n\n const isArray = obj => {\n return hasIsArray ? Array.isArray(obj) : Object.prototype.toString.call(obj) === '[object Array]';\n };\n\n const isJsObject = obj => {\n return obj !== null && typeof obj === 'object' && Object.prototype.toString.call(obj) === '[object Object]';\n };\n\n const isPlainObject = obj => {\n if (!isJsObject(obj)) {\n return false;\n } // If has modified constructor\n\n\n const ctor = obj.constructor;\n if (typeof ctor !== 'function') return false; // If has modified prototype\n\n const prot = ctor.prototype;\n if (isJsObject(prot) === false) return false; // If constructor does not have an Object-specific method\n\n if (prot.hasOwnProperty('isPrototypeOf') === false) {\n return false;\n } // Most likely a plain Object\n\n\n return true;\n }; // test if string contains '{...}'. string must not contains tab, line breaks\n\n\n const isObjectLiteralString = (str = '') => {\n return REGEX.OBJECT_LITERAL.test(str);\n };\n\n const isEmptyObject = obj => {\n if (isJsObject(obj)) {\n return Object.getOwnPropertyNames(obj).length === 0;\n }\n\n return false;\n };\n\n function getFirstHtmlStringTag(htmlString) {\n const match = htmlString.match(REGEX.HTML_TAG);\n\n if (match) {\n return match[1];\n }\n\n return null;\n }\n\n function removeBadTags(htmlString = '') {\n return htmlString.replace(REGEX.BAD_TAGS, '');\n }\n\n function createHtmlFragment(htmlString) {\n if (typeof htmlString !== 'string') {\n return null;\n } // use template element\n\n\n if (IS_SUPPORT_TEMPLATE) {\n const template = document.createElement('template');\n template.innerHTML = removeBadTags(htmlString);\n return template.content;\n } // use document fragment with wrap html tag for tr, td etc.\n\n\n const fragment = document.createDocumentFragment();\n const queryContainer = document.createElement('div');\n const firstTag = getFirstHtmlStringTag(htmlString);\n const wrap = WRAP_MAP[firstTag || 'div'];\n\n if (wrap[0] === 'div') {\n return document.createRange().createContextualFragment(htmlString);\n }\n\n queryContainer.insertAdjacentHTML('beforeend', `${wrap[1]}${htmlString}${wrap[2]}`);\n const query = queryContainer.querySelector(wrap[0]);\n\n while (query.firstChild) {\n fragment.appendChild(query.firstChild);\n }\n\n return fragment;\n }\n\n\n const _get = function get(obj, path, def) {\n function everyFunc(step) {\n return !(step && (obj = obj[step]) === undefined);\n }\n\n const fullPath = path.replace(/\\[/g, '.').replace(/]/g, '').split('.').filter(Boolean);\n return fullPath.every(everyFunc) ? obj : def;\n };\n /**\r\n * getViewModelValue\r\n * @description walk a object by provided string path. eg 'a.b.c'\r\n * @param {object} viewModel\r\n * @param {string} prop\r\n * @return {object}\r\n */\n\n\n const getViewModelValue = (viewModel, prop) => {\n return _get(viewModel, prop);\n }; // simplified version of Lodash _.set\n // https://stackoverflow.com/questions/54733539/javascript-implementation-of-lodash-set-method\n\n\n const _set = (obj, path, value) => {\n if (Object(obj) !== obj) return obj; // When obj is not an object\n // If not yet an array, get the keys from the string-path\n\n if (!Array.isArray(path)) path = path.toString().match(/[^.[\\]]+/g) || []; // Iterate all of them except the last one\n\n path.slice(0, -1).reduce((a, c, i) => Object(a[c]) === a[c] ? // Does the key exist and is its value an object?\n // Yes: then follow that path\n a[c] : // No: create the key. Is the next key a potential array-index?\n a[c] = Math.abs(path[i + 1]) >> 0 === +path[i + 1] ? [] : // Yes: assign a new array object\n {}, // No: assign a new plain object\n obj)[path[path.length - 1]] = value; // Finally assign the value to the last key\n // Return the top-level object to allow chaining\n\n return obj;\n };\n /**\r\n * setViewModelValue\r\n * @description populate viewModel object by path string\r\n * @param {object} obj\r\n * @param {string} prop\r\n * @param {string} value\r\n * @return {call} underscore set\r\n */\n\n\n const setViewModelValue = (obj, prop, value) => {\n return _set(obj, prop, value);\n };\n\n const getViewModelPropValue = (viewModel, bindingCache) => {\n let dataKey = bindingCache.dataKey;\n let paramList = bindingCache.parameters;\n const isInvertBoolean = dataKey.charAt(0) === '!';\n\n if (isInvertBoolean) {\n dataKey = isInvertBoolean ? dataKey.substring(1) : dataKey;\n }\n\n let ret = getViewModelValue(viewModel, dataKey);\n\n if (typeof ret === 'function') {\n const viewModelContext = resolveViewModelContext(viewModel, dataKey);\n const oldViewModelProValue = bindingCache.elementData ? bindingCache.elementData.viewModelPropValue : null;\n paramList = paramList ? resolveParamList(viewModel, paramList) : []; // let args = [oldViewModelProValue, bindingCache.el].concat(paramList);\n\n const args = paramList.concat([oldViewModelProValue, bindingCache.el]);\n ret = ret.apply(viewModelContext, args);\n }\n\n ret = isInvertBoolean ? !Boolean(ret) : ret; // call through fitlers to get final value\n\n ret = filtersViewModelPropValue({\n value: ret,\n viewModel: viewModel,\n bindingCache: bindingCache\n });\n return ret;\n };\n\n const filtersViewModelPropValue = ({\n value,\n viewModel,\n bindingCache\n }) => {\n let ret = value;\n\n if (bindingCache.filters) {\n each(bindingCache.filters, (index, filter) => {\n const viewModelContext = resolveViewModelContext(viewModel, filter);\n const filterFn = getViewModelValue.call(viewModelContext, viewModelContext, filter);\n\n try {\n ret = filterFn.call(viewModelContext, ret);\n } catch (err) {\n throwErrorMessage(err, `Invalid filter: ${filter}`);\n }\n });\n }\n\n return ret;\n };\n\n const parseStringToJson = str => {\n // fix unquote or single quote keys and replace single quote to double quote\n const ret = str.replace(/(\\s*?{\\s*?|\\s*?,\\s*?)(['\"])?([a-zA-Z0-9]+)(['\"])?:/g, '$1\"$3\":').replace(/'/g, '\"');\n return JSON.parse(ret);\n };\n /**\r\n * arrayRemoveMatch\r\n * @description remove match items in fromArray out of toArray\r\n * @param {array} toArray\r\n * @param {array} frommArray\r\n * @return {boolean}\r\n */\n\n\n const arrayRemoveMatch = (toArray, frommArray) => {\n return toArray.filter((value, index) => {\n return frommArray.indexOf(value) < 0;\n });\n };\n\n const getFormData = $form => {\n const data = {};\n\n if (!$form instanceof HTMLFormElement) {\n return data;\n }\n\n const formData = new FormData($form);\n formData.forEach((value, key) => {\n if (!Object.prototype.hasOwnProperty.call(Object, key)) {\n data[key] = value;\n return;\n }\n\n if (!Array.isArray(data[key])) {\n data[key] = [data[key]];\n }\n\n data[key].push(value);\n });\n return data;\n };\n /**\r\n * getFunctionParameterList\r\n * @description convert parameter string to arrary\r\n * eg. '(\"a\",\"b\",\"c\")' > [\"a\",\"b\",\"c\"]\r\n * @param {string} str\r\n * @return {array} paramlist\r\n */\n\n\n const getFunctionParameterList = str => {\n if (!str || str.length > maxDatakeyLength) {\n return;\n }\n\n let paramlist = str.match(REGEX.FUNCTION_PARAM);\n\n if (paramlist && paramlist[1]) {\n paramlist = paramlist[1].split(',');\n paramlist.forEach(function (v, i) {\n paramlist[i] = v.trim();\n });\n }\n\n return paramlist;\n };\n\n const extractFilterList = cacheData => {\n if (!cacheData || !cacheData.dataKey || cacheData.dataKey.length > maxDatakeyLength) {\n return cacheData;\n }\n\n const filterList = cacheData.dataKey.split(REGEX.PIPE);\n let isOnceIndex;\n cacheData.dataKey = filterList[0].trim();\n\n if (filterList.length > 1) {\n filterList.shift(0);\n filterList.forEach(function (v, i) {\n filterList[i] = v.trim();\n\n if (filterList[i] === constants.filters.ONCE) {\n cacheData.isOnce = true;\n isOnceIndex = i;\n }\n }); // don't store filter 'once' - because it is internal logic not a property from viewModel\n\n if (isOnceIndex >= 0) {\n filterList.splice(isOnceIndex, 1);\n }\n\n cacheData.filters = filterList;\n }\n\n return cacheData;\n };\n\n const invertObj = sourceObj => {\n return Object.keys(sourceObj).reduce(function (obj, key) {\n obj[sourceObj[key]] = key;\n return obj;\n }, {});\n };\n\n const createDeferredObj = () => {\n const dfObj = {};\n dfObj.promise = new Promise((resolve, reject) => {\n dfObj.resolve = resolve;\n dfObj.reject = reject;\n });\n return dfObj;\n };\n /**\r\n * debounce\r\n * @description decorate a function to be debounce using requestAnimationFrame\r\n * @param {function} fn\r\n * @param {context} ctx\r\n * @return {function}\r\n */\n\n\n const debounceRaf = (fn, ctx = null) => {\n return function (fn, ctx) {\n let dfObj = createDeferredObj();\n let rafId = 0; // return decorated fn\n\n return function () {\n /* eslint-disable prefer-rest-params */\n const args = Array.from ? Array.from(arguments) : Array.prototype.slice.call(arguments);\n window.cancelAnimationFrame(rafId);\n rafId = window.requestAnimationFrame(() => {\n try {\n // fn is Binder.render function\n fn.apply(ctx, args); // dfObj.resolve is function provided in .then promise chain\n // ctx is the current component\n\n dfObj.resolve(ctx);\n } catch (err) {\n console.error('error in rendering: ', err);\n dfObj.reject(err);\n } // reset dfObj - otherwise then callbacks will not be in execution order\n // example:\n // myApp.render().then(function(){console.log('ok1')});\n // myApp.render().then(function(){console.log('ok2')});\n // myApp.render().then(function(){console.log('ok3')});\n // >> ok1, ok2, ok3\n\n\n dfObj = createDeferredObj();\n window.cancelAnimationFrame(rafId);\n });\n return dfObj.promise;\n };\n }(fn, ctx);\n };\n /**\r\n * extend\r\n * @param {boolean} isDeepMerge\r\n * @param {object} target\r\n * @param {object} sources\r\n * @return {object} merged object\r\n */\n\n\n const extend = (isDeepMerge = false, target, ...sources) => {\n if (!sources.length) {\n return target;\n }\n\n const source = sources.shift();\n\n if (source === undefined) {\n return target;\n }\n\n if (!isDeepMerge) {\n return Object.assign(target, ...sources);\n }\n\n if (isMergebleObject(target) && isMergebleObject(source)) {\n Object.keys(source).forEach(key => {\n if (isMergebleObject(source[key])) {\n if (!target[key]) {\n target[key] = {};\n }\n\n extend(target[key], source[key]);\n } else {\n target[key] = source[key];\n }\n });\n }\n\n return extend(true, target, ...sources);\n };\n\n const each = (obj, fn) => {\n if (typeof obj !== 'object' || typeof fn !== 'function') {\n return;\n }\n\n let keys = [];\n let keysLength = 0;\n const isArrayObj = isArray(obj);\n let key;\n let value;\n let i = 0;\n\n if (isArrayObj) {\n keysLength = obj.length;\n } else if (isJsObject(obj)) {\n keys = Object.keys(obj);\n keysLength = keys.length;\n } else {\n throw new TypeError('Object is not an array or object');\n }\n\n for (i = 0; i < keysLength; i += 1) {\n if (isArrayObj) {\n key = i;\n value = obj[i];\n } else {\n key = keys[i];\n value = obj[key];\n }\n\n fn(key, value);\n }\n };\n\n const isMergebleObject = item => {\n return isJsObject(item) && !isArray(item);\n };\n /**\r\n * cloneDomNode\r\n * @param {object} element\r\n * @return {object} cloned element\r\n * @description helper function to clone node\r\n */\n\n\n const cloneDomNode = element => {\n return element.cloneNode(true);\n };\n /**\r\n * insertAfter\r\n * @param {object} parentNode\r\n * @param {object} newNode\r\n * @param {object} referenceNode\r\n * @return {object} node\r\n * @description helper function to insert new node before the reference node\r\n */\n\n\n const insertAfter = (parentNode, newNode, referenceNode) => {\n const refNextElement = referenceNode && referenceNode.nextSibling ? referenceNode.nextSibling : null;\n return parentNode.insertBefore(newNode, refNextElement);\n };\n\n const resolveViewModelContext = (viewModel, datakey) => {\n let ret = viewModel;\n\n if (typeof datakey !== 'string') {\n return ret;\n }\n\n const bindingDataContext = datakey.split('.');\n\n if (bindingDataContext.length > 1) {\n if (bindingDataContext[0] === bindingDataReference.rootDataKey) {\n ret = viewModel[bindingDataReference.rootDataKey] || viewModel;\n } else if (bindingDataContext[0] === bindingDataReference.currentData) {\n ret = viewModel[bindingDataReference.currentData] || viewModel;\n }\n }\n\n return ret;\n };\n\n const resolveParamList = (viewModel, paramList) => {\n if (!viewModel || !isArray(paramList)) {\n return;\n }\n\n return paramList.map(param => {\n param = param.trim();\n\n if (param === bindingDataReference.currentIndex) {\n // convert '$index' to value\n param = viewModel[bindingDataReference.currentIndex];\n } else if (param === bindingDataReference.currentData) {\n // convert '$data' to value or current viewModel\n param = viewModel[bindingDataReference.currentData] || viewModel;\n } else if (param === bindingDataReference.rootDataKey) {\n // convert '$root' to root viewModel\n param = viewModel[bindingDataReference.rootDataKey] || viewModel;\n }\n\n return param;\n });\n };\n\n const removeElement = el => {\n if (el && el.parentNode) {\n el.parentNode.removeChild(el);\n }\n };\n\n const emptyElement = node => {\n if (node && node.firstChild) {\n while (node.firstChild) {\n node.removeChild(node.firstChild);\n }\n }\n\n return node;\n };\n\n const throwErrorMessage = (err = null, errorMessage = '') => {\n const message = err && err.message ? err.message : errorMessage;\n\n if (typeof console.error === 'function') {\n return console.error(message);\n }\n\n return console.log(message);\n };\n /**\r\n * parseBindingObjectString\r\n * @description parse bining object string to object with value always stringify\r\n * @param {string} str - eg '{ id: $data.id, name: $data.name }'\r\n * @return {object} - eg { id: '$data.id', name: '$data.name'}\r\n */\n\n\n const parseBindingObjectString = (str = '') => {\n let objectLiteralString = str.trim();\n const ret = {};\n\n if (!REGEX.OBJECT_LITERAL.test(str)) {\n return null;\n } // clearn up line breaks and remove first { character\n\n\n objectLiteralString = objectLiteralString.replace(REGEX.LINE_BREAKS_TABS, '').substring(1); // remove last } character\n\n objectLiteralString = objectLiteralString.substring(0, objectLiteralString.length - 1);\n objectLiteralString.split(',').forEach(item => {\n const keyVal = item.trim(); // ignore if last empty item - eg split last comma in object literal\n\n if (keyVal) {\n const prop = keyVal.split(':');\n const key = prop[0].trim();\n ret[key] = `${prop[1]}`.trim();\n }\n });\n return ret;\n };\n\n let bindingAttrsMap;\n /**\n * walkDOM\n * @description by Douglas Crockford - walk each DOM node and calls provided callback function\n * start walk from firstChild\n * @param {object} node\n * @param {function} func\n */\n\n const walkDOM = (node, func) => {\n let parseChildNode = true;\n node = node.firstElementChild;\n\n while (node) {\n parseChildNode = func(node);\n\n if (parseChildNode) {\n walkDOM(node, func);\n }\n\n node = node.nextElementSibling;\n }\n };\n\n const getAttributesObject = node => {\n const ret = {};\n Array.prototype.slice.call(node.attributes).forEach(item => {\n ret[item.name] = item.value;\n });\n return ret;\n };\n\n const checkSkipChildParseBindings = (attrObj = {}, bindingAttrs) => {\n return [bindingAttrs.forOf, bindingAttrs.if, bindingAttrs.case, bindingAttrs.default].filter(type => {\n return typeof attrObj[type] !== 'undefined';\n });\n };\n\n const rootSkipCheck = node => {\n return node.tagName === 'SVG';\n };\n\n const defaultSkipCheck = (node, bindingAttrs) => {\n return node.tagName === 'SVG' || node.hasAttribute(bindingAttrs.comp);\n };\n\n const populateBindingCache = ({\n node,\n attrObj,\n bindingCache,\n type\n }) => {\n let attrValue;\n let cacheData;\n\n if (bindingAttrsMap && bindingAttrsMap[type] && typeof attrObj[type] !== 'undefined') {\n bindingCache[type] = bindingCache[type] || [];\n attrValue = attrObj[type] || '';\n\n if (attrValue) {\n attrValue = attrValue.replace(REGEX.LINE_BREAKS_TABS, '').replace(REGEX.WHITE_SPACES, ' ').trim();\n }\n\n cacheData = {\n el: node,\n dataKey: attrValue\n }; // populate cacheData.filters. update filterList first item as dataKey\n\n cacheData = extractFilterList(cacheData); // populate cacheData.parameters\n // for store function call parameters eg. '$index', '$root'\n // useful with DOM for-loop template as reference to binding data\n\n const paramList = getFunctionParameterList(cacheData.dataKey);\n\n if (paramList) {\n cacheData.parameters = paramList;\n cacheData.dataKey = cacheData.dataKey.replace(REGEX.FUNCTION_PARAM, '').trim();\n } // store parent array reference to cacheData\n\n\n cacheData[constants.PARENT_REF] = bindingCache[type];\n bindingCache[type].push(cacheData);\n }\n\n return bindingCache;\n };\n\n const createBindingCache = ({\n rootNode = null,\n bindingAttrs = {},\n skipCheck,\n isRenderedTemplate = false\n }) => {\n let bindingCache = {};\n\n if (!rootNode instanceof window.Node) {\n throw new TypeError('walkDOM: Expected a DOM node');\n }\n\n bindingAttrsMap = bindingAttrsMap || invertObj(bindingAttrs);\n\n const parseNode = (node, skipNodeCheckFn = defaultSkipCheck) => {\n let isSkipForOfChild = false;\n\n if (node.nodeType !== 1 || !node.hasAttributes()) {\n return true;\n }\n\n if (skipNodeCheckFn(node, bindingAttrs) || typeof skipCheck === 'function' && skipCheck(node)) {\n return false;\n } // when creating sub bindingCache if is for tmp binding\n // skip same element that has forOf binding the forOf is alredy parsed\n\n\n const attrObj = getAttributesObject(node);\n const hasSkipChildParseBindings = checkSkipChildParseBindings(attrObj, bindingAttrs);\n let iterateList = [];\n\n if (hasSkipChildParseBindings.length) {\n isSkipForOfChild = true;\n iterateList = hasSkipChildParseBindings;\n } else if (isRenderedTemplate && attrObj[bindingAttrs.tmp]) {\n // skip current node parse if was called by node has template binding and already rendered\n return true;\n } else {\n iterateList = Object.keys(attrObj);\n }\n\n iterateList.forEach(key => {\n // skip for switch case and default bining\n if (key !== bindingAttrs.case && key !== bindingAttrs.default) {\n bindingCache = populateBindingCache({\n node: node,\n attrObj: attrObj,\n bindingCache: bindingCache,\n type: key\n });\n }\n }); // after cache forOf skip parse child nodes\n\n if (isSkipForOfChild) {\n return false;\n }\n\n return true;\n };\n\n if (parseNode(rootNode, rootSkipCheck)) {\n walkDOM(rootNode, parseNode);\n }\n\n return bindingCache;\n };\n\n /**\n * createBindingOption\n * @param {string} condition\n * @param {object} opt\n * @description\n * generate binding update option object by condition\n * @return {object} updateOption\n */\n\n function createBindingOption(condition = '', opt = {}) {\n const visualBindingOptions = {\n templateBinding: false,\n textBinding: true,\n cssBinding: true,\n ifBinding: true,\n showBinding: true,\n modelBinding: true,\n attrBinding: true,\n forOfBinding: true,\n switchBinding: true\n };\n const eventsBindingOptions = {\n changeBinding: true,\n clickBinding: true,\n dblclickBinding: true,\n blurBinding: true,\n focusBinding: true,\n hoverBinding: true,\n inputBinding: true,\n submitBinding: true\n }; // this is visualBindingOptions but everything false\n // concrete declear for performance purpose\n\n const serverRenderedOptions = {\n templateBinding: false,\n textBinding: false,\n cssBinding: false,\n ifBinding: false,\n showBinding: false,\n modelBinding: false,\n attrBinding: false,\n forOfBinding: false,\n switchBinding: false\n };\n let updateOption = {};\n\n switch (condition) {\n case bindingUpdateConditions.serverRendered:\n updateOption = extend({}, eventsBindingOptions, serverRenderedOptions, opt);\n break;\n\n case bindingUpdateConditions.init:\n // flag templateBinding to true to render tempalte(s)\n opt.templateBinding = true;\n updateOption = extend({}, visualBindingOptions, eventsBindingOptions, opt);\n break;\n\n default:\n // when called again only update visualBinding options\n updateOption = extend({}, visualBindingOptions, opt);\n }\n\n return updateOption;\n }\n\n /* eslint-disable no-invalid-this */\n /**\n * blurBinding\n * DOM decleartive on blur event binding\n * event handler bind to viewModel method according to the DOM attribute\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n * @param {boolean} forceRender\n */\n\n const hoverBinding = (cache, viewModel, bindingAttrs, forceRender) => {\n const handlerName = cache.dataKey;\n let paramList = cache.parameters;\n const inHandlerName = bindingDataReference.mouseEnterHandlerName;\n const outHandlerName = bindingDataReference.mouseLeaveHandlerName;\n let viewModelContext;\n const APP = viewModel.APP || viewModel.$root.APP;\n cache.elementData = cache.elementData || {}; // TODO: check what is APP.$rootElement.contains(cache.el)\n\n if (!handlerName || !forceRender && !APP.$rootElement.contains(cache.el)) {\n return;\n }\n\n const handlers = getViewModelValue(viewModel, handlerName);\n\n if (handlers && typeof handlers[inHandlerName] === 'function' && typeof handlers[outHandlerName] === 'function') {\n viewModelContext = resolveViewModelContext(viewModel, handlerName);\n paramList = paramList ? resolveParamList(viewModel, paramList) : [];\n\n function onMouseEnterHandler(e) {\n const args = [e, cache.el].concat(paramList);\n handlers[inHandlerName].apply(viewModelContext, args);\n }\n\n function onMouseLeaveHandler(e) {\n const args = [e, cache.el].concat(paramList);\n handlers[outHandlerName].apply(viewModelContext, args);\n }\n\n cache.el.removeEventListener('mouseenter', onMouseEnterHandler, false);\n cache.el.removeEventListener('mouseleave', onMouseLeaveHandler, false);\n cache.el.addEventListener('mouseenter', onMouseEnterHandler, false);\n cache.el.addEventListener('mouseleave', onMouseLeaveHandler, false);\n }\n };\n\n /**\n * _escape\n * @description\n * https://github.com/lodash/lodash/blob/master/escape.js\n */\n function baseToString(value) {\n if (typeof value == 'string') {\n return value;\n }\n\n return value == null ? '' : `${value}`;\n }\n /** Used to match HTML entities and HTML characters. */\n\n\n const reUnescapedHtml = /[&<>\"'`]/g;\n const reHasUnescapedHtml = RegExp(reUnescapedHtml.source);\n /** Used to map characters to HTML entities. */\n\n const htmlEscapes = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n '\\'': ''',\n '`': '`'\n };\n /**\n * escapeHtmlChar\n * @description convert characters to HTML entities.\n * @private\n * @param {string} chr The matched character to escape.\n * @return {string} Returns the escaped character.\n */\n\n function escapeHtmlChar(chr) {\n return htmlEscapes[chr];\n }\n /**\n * Converts the characters \"&\", \"<\", \">\", '\"', \"'\", and \"\\`\", in `string` to\n * their corresponding HTML entities.\n * @param {string} string\n * @return {string} string\n */\n\n\n function escape(string) {\n // Reset `lastIndex` because in IE < 9 `String#replace` does not.\n string = baseToString(string);\n return string && reHasUnescapedHtml.test(string) ? string.replace(reUnescapedHtml, escapeHtmlChar) : string;\n }\n\n /* eslint-disable no-invalid-this */\n /**\n * changeBinding\n * @description input element on change event binding. DOM -> viewModel update\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n * @param {boolean} forceRender\n */\n\n const changeBinding = ({\n cache,\n viewModel,\n bindingAttrs,\n forceRender,\n type = 'change'\n }) => {\n const handlerName = cache.dataKey;\n let paramList = cache.parameters;\n const modelDataKey = cache.el.getAttribute(bindingAttrs.model);\n let newValue = '';\n let oldValue = '';\n let viewModelContext;\n const APP = viewModel.APP || viewModel.$root.APP;\n\n if (!handlerName || !forceRender && !APP.$rootElement.contains(cache.el)) {\n return;\n }\n\n const handlerFn = getViewModelValue(viewModel, handlerName);\n\n if (typeof handlerFn === 'function') {\n viewModelContext = resolveViewModelContext(viewModel, handlerName);\n paramList = paramList ? resolveParamList(viewModel, paramList) : [];\n\n function changeHandler(e) {\n const $this = this;\n const isCheckbox = $this.type === 'checkbox';\n newValue = isCheckbox ? $this.checked : escape($this.value); // set data to viewModel\n\n if (modelDataKey) {\n oldValue = getViewModelValue(viewModel, modelDataKey);\n setViewModelValue(viewModel, modelDataKey, newValue);\n }\n\n const args = [e, e.currentTarget, newValue, oldValue].concat(paramList);\n handlerFn.apply(viewModelContext, args);\n oldValue = newValue;\n } // assing on change event\n\n\n cache.el.removeEventListener(type, changeHandler, false);\n cache.el.addEventListener(type, changeHandler, false);\n }\n };\n\n /**\n * modelBinding\n * @description input element data binding. viewModel -> DOM update\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n * @param {boolean} forceRender\n */\n\n const modelBinding = (cache, viewModel, bindingAttrs, forceRender) => {\n const dataKey = cache.dataKey;\n let newValue = '';\n const APP = viewModel.APP || viewModel.$root.APP;\n\n if (!dataKey || !forceRender && !APP.$rootElement.contains(cache.el)) {\n return;\n }\n\n newValue = getViewModelValue(viewModel, dataKey);\n\n if (typeof newValue !== 'undefined' && newValue !== null) {\n const $element = cache.el;\n const isCheckbox = $element.type === 'checkbox';\n const isRadio = $element.type === 'radio';\n const inputName = $element.name;\n const $radioGroup = isRadio ? APP.$rootElement.querySelectorAll(`input[name=\"${inputName}\"]`) : [];\n const oldValue = isCheckbox ? $element.checked : $element.value; // update element value\n\n if (newValue !== oldValue) {\n if (isCheckbox) {\n $element.checked = Boolean(newValue);\n } else if (isRadio) {\n let i = 0;\n const radioGroupLength = $radioGroup.length;\n\n for (i = 0; i < radioGroupLength; i += 1) {\n if ($radioGroup[i].value === newValue) {\n $radioGroup[i].checked = true;\n break;\n }\n }\n } else {\n $element.value = newValue;\n }\n }\n }\n };\n\n /**\n * textBinding\n * * @description\n * DOM decleartive text binding update dom textnode with viewModel data\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n * @param {boolean} forceRender\n */\n\n const textBinding = (cache, viewModel, bindingAttrs, forceRender) => {\n const dataKey = cache.dataKey;\n const APP = viewModel.APP || viewModel.$root.APP; // NOTE: this doesn't work for for-of, if and switch bindings because element was not in DOM\n\n if (!dataKey || !forceRender && !APP.$rootElement.contains(cache.el)) {\n return;\n }\n\n const newValue = getViewModelPropValue(viewModel, cache);\n const oldValue = cache.el.textContent;\n\n if (typeof newValue !== 'undefined' && typeof newValue !== 'object' && newValue !== null) {\n if (newValue !== oldValue) {\n cache.el.textContent = newValue;\n }\n }\n };\n\n /**\n * showBinding\n * @description\n * DOM decleartive show binding. Make binding show/hide according to viewModel data (boolean)\n * viewModel data can function but must return boolean\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n */\n\n const showBinding = (cache, viewModel, bindingAttrs) => {\n const dataKey = cache.dataKey;\n let currentInlineSytle = {};\n let currentInlineDisplaySytle = '';\n let shouldShow = true;\n\n if (!dataKey) {\n return;\n }\n\n cache.elementData = cache.elementData || {};\n const oldShowStatus = cache.elementData.viewModelPropValue; // store current element display default style once only\n\n if (typeof cache.elementData.displayStyle === 'undefined' || typeof cache.elementData.computedStyle === 'undefined') {\n currentInlineSytle = cache.el.style;\n currentInlineDisplaySytle = currentInlineSytle.display; // use current inline style if defined\n\n if (currentInlineDisplaySytle) {\n // set to 'block' if is 'none'\n cache.elementData.displayStyle = currentInlineDisplaySytle === 'none' ? 'block' : currentInlineDisplaySytle;\n cache.elementData.computedStyle = null;\n } else {\n const computeStyle = window.getComputedStyle(cache.el, null).getPropertyValue('display');\n cache.elementData.displayStyle = null;\n cache.elementData.computedStyle = computeStyle;\n }\n }\n\n shouldShow = getViewModelPropValue(viewModel, cache); // treat undefined || null as false.\n // eg if property doesn't exsits in viewModel, it will treat as false to hide element\n\n shouldShow = Boolean(shouldShow); // reject if nothing changed\n\n if (oldShowStatus === shouldShow) {\n return;\n }\n\n if (!shouldShow) {\n if (cache.el.style.display !== 'none') {\n cache.el.style.setProperty('display', 'none');\n }\n } else {\n if (cache.elementData.computedStyle || cache.el.style.display === 'none') {\n if (cache.elementData.computedStyle === 'none') {\n // default display is none in css rule, so use display 'block'\n cache.el.style.setProperty('display', 'block');\n } else {\n // has default displayable type so just remove inline display 'none'\n if (currentInlineSytle.length > 1) {\n cache.el.style.removeProperty('display');\n } else {\n cache.el.removeAttribute('style');\n }\n }\n } else {\n // element default display was inline style, so restore it\n cache.el.style.setProperty('display', cache.elementData.displayStyle);\n }\n } // store new show status\n\n\n cache.elementData.viewModelPropValue = shouldShow;\n };\n\n /**\n * cssBinding\n * @description\n * DOM decleartive css binding. update classlist.\n * viewModel data can function but must return JSOL.\n * added css class if value is true\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n * @param {boolean} forceRender\n */\n\n const cssBinding = (cache, viewModel, bindingAttrs, forceRender) => {\n const dataKey = cache.dataKey;\n const APP = viewModel.APP || viewModel.$root.APP;\n\n if (!dataKey || !forceRender && !APP.$rootElement.contains(cache.el)) {\n return;\n }\n\n cache.elementData = cache.elementData || {};\n cache.elementData.viewModelPropValue = cache.elementData.viewModelPropValue || '';\n const oldCssList = cache.elementData.viewModelPropValue;\n let newCssList = '';\n const vmCssListObj = getViewModelPropValue(viewModel, cache);\n let vmCssListArray = [];\n let isViewDataObject = false;\n let isViewDataString = false;\n let cssList = [];\n\n if (typeof vmCssListObj === 'string') {\n isViewDataString = true;\n } else if (isPlainObject(vmCssListObj)) {\n isViewDataObject = true;\n } else {\n // reject if vmCssListObj is not an object or string\n return;\n }\n\n if (isViewDataObject) {\n newCssList = JSON.stringify(vmCssListObj);\n } else {\n newCssList = vmCssListObj.replace(/\\s\\s+/g, ' ').trim();\n vmCssListArray = newCssList.split(' ');\n } // reject if nothing changed\n\n\n if (oldCssList === newCssList) {\n return;\n } // get current css classes from element\n\n\n const domCssList = cache.el.classList; // clone domCssList as new array\n\n const domCssListLength = domCssList.length;\n\n for (let i = 0; i < domCssListLength; i += 1) {\n cssList.push(domCssList[i]);\n }\n\n if (isViewDataObject) {\n each(vmCssListObj, function (k, v) {\n const i = cssList.indexOf(k);\n\n if (v === true) {\n cssList.push(k);\n } else if (i !== -1) {\n cssList.splice(i, 1);\n }\n });\n } else if (isViewDataString) {\n // remove oldCssList items from cssList\n cssList = arrayRemoveMatch(cssList, oldCssList);\n cssList = cssList.concat(vmCssListArray);\n } // unique cssList array\n\n\n cssList = cssList.filter((v, i, a) => {\n return a.indexOf(v) === i;\n });\n cssList = cssList.join(' '); // update element data\n\n cache.elementData.viewModelPropValue = newCssList; // replace all css classes\n\n cache.el.setAttribute('class', cssList);\n };\n\n /**\n * attrBinding\n * @description\n * DOM decleartive attr binding. update elenment attributes\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n */\n\n const attrBinding = (cache = {}, viewModel) => {\n if (!cache.dataKey) {\n return;\n } // check if Object Literal String style dataKey\n\n\n const isObjLiteralStr = isObjectLiteralString(cache.dataKey); // resolve vmAttrObj, when Object Literal String style if will be object without resolve each value\n // otherwise, resolve value from viewModel\n\n const vmAttrObj = isObjLiteralStr ? parseBindingObjectString(cache.dataKey) : getViewModelPropValue(viewModel, cache); // vmAttrObj must be a plain object\n\n if (!isPlainObject(vmAttrObj)) {\n return;\n } // populate cache.elementData if not exits\n // check and set default cache.elementData.viewModelPropValue\n\n\n cache.elementData = cache.elementData || {};\n cache.elementData.viewModelPropValue = cache.elementData.viewModelPropValue || {}; // start diff comparison\n // reject if nothing changed by comparing\n // cache.elementData.viewModelPropValue (previous render) vs vmAttrObj(current render)\n\n if (JSON.stringify(cache.elementData.viewModelPropValue) === JSON.stringify(vmAttrObj)) {\n return;\n }\n\n if (isObjLiteralStr) {\n // resolve each value in vmAttrObj\n each(vmAttrObj, (key, value) => {\n // resolve value from viewModel including $data and $root\n // from viewModel.$data or viewModel.$root\n vmAttrObj[key] = getViewModelPropValue(viewModel, {\n dataKey: value\n });\n });\n } // shortcut for reading cache.elementData.viewModelPropValue\n\n\n const oldAttrObj = cache.elementData.viewModelPropValue; // start set element attribute - oldAttrObj is empty meaning no previous render\n\n if (isEmptyObject(oldAttrObj)) {\n each(vmAttrObj, (key, value) => {\n if (typeof value !== 'undefined') {\n cache.el.setAttribute(key, value); // populate cache.elementData.viewModelPropValue for future comparison\n\n if (!isObjLiteralStr) {\n cache.elementData.viewModelPropValue[key] = value;\n }\n }\n });\n } else {\n // loop oldAttrObj, remove attribute not present in current vmAttrObj\n each(oldAttrObj, (key, value) => {\n if (typeof vmAttrObj[key] === 'undefined') {\n cache.el.removeAttribute(key);\n }\n }); // loop vmAttrObj, set attribute not present in oldAttrObj\n\n each(vmAttrObj, (key, value) => {\n if (typeof value !== 'undefined') {\n if (oldAttrObj[key] !== vmAttrObj[key]) {\n cache.el.setAttribute(key, vmAttrObj[key]); // populate cache.elementData.viewModelPropValue for future comparison\n\n if (!isObjLiteralStr) {\n cache.elementData.viewModelPropValue[key] = value;\n }\n }\n }\n });\n } // for object literal style binding\n // set viewModelPropValue for future diff comaprison\n // note: vmAttrObj is a not fully resolve object, each value is still string unresloved\n\n\n if (isObjLiteralStr) {\n cache.elementData.viewModelPropValue = extend({}, vmAttrObj);\n }\n };\n\n let $domFragment = null;\n let $templateRoot = null;\n let nestTemplatesCount = 0;\n /**\n * getTemplateString\n * @description get Template tag innerHTML string\n * @param {string} id\n * @return {string} rendered html string\n */\n\n const getTemplateString = id => {\n const templateElement = document.getElementById(id);\n return templateElement ? templateElement.innerHTML : '';\n };\n /**\n * renderTemplate\n * @description\n * get template setting from DOM attribute then call compileTemplate\n * to render and append to target DOM\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n * @param {object} elementCache\n */\n\n\n const renderTemplate = (cache, viewModel, bindingAttrs, elementCache) => {\n const settings = typeof cache.dataKey === 'string' ? parseStringToJson(cache.dataKey) : cache.dataKey;\n let viewData = settings.data;\n const isAppend = settings.append;\n const isPrepend = settings.prepend;\n let $currentElement;\n cache.dataKey = settings;\n viewData = typeof viewData === 'undefined' || viewData === '$root' ? viewModel : getViewModelPropValue(viewModel, {\n dataKey: settings.data,\n parameters: cache.parameters\n });\n\n if (!viewData) {\n return;\n }\n\n const $element = cache.el;\n const $index = typeof viewModel.$index !== 'undefined' ? viewModel.$index : $element.getAttribute(dataIndexAttr);\n\n if (typeof $index !== 'undefined') {\n viewData.$index = $index;\n }\n\n $domFragment = $domFragment || document.createDocumentFragment();\n $templateRoot = $templateRoot || $element;\n const htmlString = getTemplateString(settings.id);\n const htmlFragment = createHtmlFragment(htmlString); // append rendered html\n\n if (!$domFragment.childNodes.length) {\n // domFragment should be empty in first run\n $currentElement = $domFragment; // copy of $domFragment for later find nested template check\n\n $domFragment.appendChild(htmlFragment);\n } else {\n // during recursive run keep append to current fragment\n $currentElement = $element; // reset to current nested template element\n\n if (!isAppend && !isPrepend) {\n $currentElement = emptyElement($currentElement);\n }\n\n if (isPrepend) {\n $currentElement.insertBefore(htmlFragment, $currentElement.firstChild);\n } else {\n $currentElement.appendChild(htmlFragment);\n }\n } // check if there are nested template then recurisive render them\n\n\n const $nestedTemplates = $currentElement.querySelectorAll('[' + bindingAttrs.tmp + ']');\n const nestedTemplatesLength = $nestedTemplates.length;\n\n if (nestedTemplatesLength) {\n nestTemplatesCount += nestedTemplatesLength;\n\n for (let i = 0; i < nestedTemplatesLength; i += 1) {\n const thisTemplateCache = {\n el: $nestedTemplates[i],\n dataKey: $nestedTemplates[i].getAttribute(bindingAttrs.tmp)\n };\n elementCache[bindingAttrs.tmp].push(thisTemplateCache); // recursive template render\n\n renderTemplate(thisTemplateCache, viewModel, bindingAttrs, elementCache);\n nestTemplatesCount -= 1;\n }\n } // no more nested tempalted to render, start to append $domFragment into $templateRoot\n\n\n if (nestTemplatesCount === 0) {\n // append to DOM once\n if (!isAppend && !isPrepend) {\n $templateRoot = emptyElement($templateRoot);\n }\n\n if (isPrepend) {\n $templateRoot.insertBefore($domFragment, $templateRoot.firstChild);\n } else {\n $templateRoot.appendChild($domFragment);\n } // clear cached fragment\n\n\n $domFragment = $templateRoot = null; // trigger callback if provided\n\n if (typeof viewModel.afterTemplateRender === 'function') {\n viewModel.afterTemplateRender(viewData);\n }\n }\n };\n\n const renderTemplatesBinding = ({\n ctx,\n elementCache,\n updateOption,\n bindingAttrs,\n viewModel\n }) => {\n if (!elementCache || !bindingAttrs) {\n return false;\n } // render and apply binding to template(s) and forOf DOM\n\n\n if (elementCache[bindingAttrs.tmp] && elementCache[bindingAttrs.tmp].length) {\n // when re-render call with {templateBinding: true}\n // template and nested templates\n if (updateOption.templateBinding) {\n // overwrite updateOption with 'init' bindingUpdateConditions\n updateOption = createBindingOption(bindingUpdateConditions.init);\n elementCache[bindingAttrs.tmp].forEach($element => {\n renderTemplate($element, viewModel, bindingAttrs, elementCache);\n }); // update cache after all template(s) rendered\n\n ctx.updateElementCache({\n templateCache: true,\n elementCache: elementCache,\n isRenderedTemplates: true\n });\n } // enforce render even element is not in DOM tree\n\n\n updateOption.forceRender = true; // apply bindings to rendered templates element\n\n elementCache[bindingAttrs.tmp].forEach(cache => {\n applyBinding({\n elementCache: cache.bindingCache,\n updateOption: updateOption,\n bindingAttrs: bindingAttrs,\n viewModel: viewModel\n });\n });\n }\n\n return true;\n };\n\n /**\n * renderIteration\n * @param {object} opt\n * @description\n * render element's binding by supplied elementCache\n * This function is desidned for FoOf, If, switch bindings\n */\n\n const renderIteration = ({\n elementCache,\n iterationVm,\n bindingAttrs,\n isRegenerate\n }) => {\n const bindingUpdateOption = isRegenerate ? createBindingOption(bindingUpdateConditions.init) : createBindingOption(); // enforce render even element is not in DOM tree\n\n bindingUpdateOption.forceRender = true; // render and apply binding to template(s)\n // this is an share function therefore passing current APP 'this' context\n // viewModel is a dynamic generated iterationVm\n\n renderTemplatesBinding({\n ctx: iterationVm.$root ? iterationVm.$root.APP : iterationVm.APP,\n elementCache: elementCache,\n updateOption: bindingUpdateOption,\n bindingAttrs: bindingAttrs,\n viewModel: iterationVm\n });\n applyBinding({\n elementCache: elementCache,\n updateOption: bindingUpdateOption,\n bindingAttrs: bindingAttrs,\n viewModel: iterationVm\n });\n };\n\n /* eslint-disable no-invalid-this */\n\n const createClonedElementCache = bindingData => {\n const clonedElement = bindingData.el.cloneNode(true);\n bindingData.fragment = document.createDocumentFragment();\n bindingData.fragment.appendChild(clonedElement);\n return bindingData;\n };\n\n const setCommentPrefix = bindingData => {\n if (!bindingData || !bindingData.type) {\n return bindingData;\n }\n\n let commentPrefix$1 = '';\n const dataKeyMarker = bindingData.dataKey ? bindingData.dataKey.replace(REGEX.WHITE_SPACES, '_') : '';\n\n switch (bindingData.type) {\n case bindingAttrs$1.forOf:\n commentPrefix$1 = commentPrefix.forOf;\n break;\n\n case bindingAttrs$1.if:\n commentPrefix$1 = commentPrefix.if;\n break;\n\n case bindingAttrs$1.case:\n commentPrefix$1 = commentPrefix.case;\n break;\n\n case bindingAttrs$1.default:\n commentPrefix$1 = commentPrefix.default;\n break;\n }\n\n bindingData.commentPrefix = commentPrefix$1 + dataKeyMarker;\n return bindingData;\n };\n /**\n * setDocRangeEndAfter\n * @param {object} node\n * @param {object} bindingData\n * @description\n * recursive execution to find last wrapping comment node\n * and set as bindingData.docRange.setEndAfter\n * if not found deleteContents will has no operation\n * @return {undefined}\n */\n\n\n const setDocRangeEndAfter = (node, bindingData) => {\n if (!bindingData.commentPrefix) {\n setCommentPrefix(bindingData);\n }\n\n const startTextContent = bindingData.commentPrefix;\n const endTextContent = startTextContent + commentSuffix;\n node = node.nextSibling; // check last wrap comment node\n\n if (node) {\n if (node.nodeType === 8 && node.textContent === endTextContent) {\n return bindingData.docRange.setEndBefore(node);\n }\n\n setDocRangeEndAfter(node, bindingData);\n }\n };\n /**\n * wrapCommentAround\n * @param {object} bindingData\n * @param {Node} node\n * @return {object} DOM fragment\n * @description\n * wrap frament with comment node\n */\n\n\n const wrapCommentAround = (bindingData, node) => {\n let prefix = '';\n\n if (!bindingData.commentPrefix) {\n setCommentPrefix(bindingData);\n }\n\n prefix = bindingData.commentPrefix;\n const commentBegin = document.createComment(prefix);\n const commentEnd = document.createComment(prefix + commentSuffix); // document fragment - logic for ForOf binding\n // check node.parentNode because node could be from cache and no longer in DOM\n\n if (node.nodeType === 11) {\n node.insertBefore(commentBegin, node.firstChild);\n node.appendChild(commentEnd);\n } else if (node.parentNode) {\n node.parentNode.insertBefore(commentBegin, node);\n insertAfter(node.parentNode, commentEnd, node); // update bindingData details\n\n bindingData.previousNonTemplateElement = node.previousSibling;\n bindingData.nextNonTemplateElement = node.nextSibling;\n bindingData.parentElement = node.previousSibling.parentElement;\n }\n\n return node;\n };\n /**\n * removeElemnetsByCommentWrap\n * @param {object} bindingData\n * @return {undefined}\n * @description remove elments by range\n */\n\n\n const removeElemnetsByCommentWrap = bindingData => {\n if (!bindingData.docRange) {\n bindingData.docRange = document.createRange();\n }\n\n try {\n if (bindingData.previousNonTemplateElement) {\n // update docRange start and end match the wrapped comment node\n bindingData.docRange.setStartBefore(bindingData.previousNonTemplateElement.nextSibling);\n setDocRangeEndAfter(bindingData.previousNonTemplateElement.nextSibling, bindingData);\n } else {\n // insert before next non template element\n bindingData.docRange.setStartBefore(bindingData.parentElement.firstChild);\n setDocRangeEndAfter(bindingData.parentElement.firstChild, bindingData);\n }\n } catch (err) {\n console.log('error removeElemnetsByCommentWrap: ', err.message);\n }\n\n return bindingData.docRange.deleteContents();\n };\n\n const insertRenderedElements = (bindingData, fragment) => {\n // insert rendered fragment after the previousNonTemplateElement\n if (bindingData.previousNonTemplateElement) {\n insertAfter(bindingData.parentElement, fragment, bindingData.previousNonTemplateElement);\n } else {\n // insert before next non template element\n if (bindingData.nextNonTemplateElement) {\n bindingData.parentElement.insertBefore(fragment, bindingData.nextNonTemplateElement);\n } else if (bindingData.parentElement) {\n // insert from parent\n bindingData.parentElement.appendChild(fragment);\n }\n }\n };\n\n /* eslint-disable no-invalid-this */\n\n const renderForOfBinding = ({\n bindingData,\n viewModel,\n bindingAttrs\n }) => {\n if (!bindingData || !viewModel || !bindingAttrs) {\n return;\n }\n\n let keys;\n let iterationDataLength;\n const iterationData = getViewModelPropValue(viewModel, bindingData.iterator);\n let isRegenerate = false; // check iterationData and set iterationDataLength\n\n if (isArray(iterationData)) {\n iterationDataLength = iterationData.length;\n } else if (isPlainObject(iterationData)) {\n keys = Object.keys(iterationData);\n iterationDataLength = keys.length;\n } else {\n // throw error but let script contince to run\n return throwErrorMessage(null, 'iterationData is not an plain object or array');\n } // flag as pared for-of logic with bindingData.type\n\n\n if (!bindingData.type) {\n bindingData.type = bindingAttrs$1.forOf;\n wrapCommentAround(bindingData, bindingData.el);\n } // assign forOf internal id to bindingData once\n\n\n if (typeof bindingData.iterationSize === 'undefined') {\n // store iterationDataLength\n bindingData.iterationSize = iterationDataLength; // remove orignal node for-of attributes\n\n bindingData.el.removeAttribute(bindingAttrs.forOf);\n isRegenerate = true;\n } else {\n // only regenerate cache if iterationDataLength changed\n isRegenerate = bindingData.iterationSize !== iterationDataLength; // update iterationSize\n\n bindingData.iterationSize = iterationDataLength;\n }\n\n if (!isRegenerate) {\n bindingData.iterationBindingCache.forEach(function (elementCache, i) {\n if (!isEmptyObject(elementCache)) {\n const iterationVm = createIterationViewModel({\n bindingData: bindingData,\n viewModel: viewModel,\n iterationData: iterationData,\n keys: keys,\n index: i\n });\n renderIteration({\n elementCache: elementCache,\n iterationVm: iterationVm,\n bindingAttrs: bindingAttrs,\n isRegenerate: false\n });\n }\n });\n return;\n } // generate forOfBinding elements into fragment\n\n\n const fragment = generateForOfElements(bindingData, viewModel, bindingAttrs, iterationData, keys);\n removeElemnetsByCommentWrap(bindingData); // insert fragment content into DOM\n\n return insertRenderedElements(bindingData, fragment);\n };\n /**\n * createIterationViewModel\n * @description\n * create an virtual viewModel for render binding while in loop iteration\n * $data is the current data in the loop eg. data in array\n * $root is point to top level viewModel\n * $index is the current loop index\n * @param {*} param0\n * @return {object} virtual viewModel\n */\n\n\n const createIterationViewModel = ({\n bindingData,\n viewModel,\n iterationData,\n keys,\n index\n }) => {\n const iterationVm = {};\n iterationVm[bindingData.iterator.alias] = keys ? iterationData[keys[index]] : iterationData[index]; // populate common binding data reference\n\n iterationVm[bindingDataReference.rootDataKey] = viewModel.$root || viewModel;\n iterationVm[bindingDataReference.currentData] = iterationVm[bindingData.iterator.alias];\n iterationVm[bindingDataReference.currentIndex] = index;\n return iterationVm;\n };\n\n const generateForOfElements = (bindingData, viewModel, bindingAttrs, iterationData, keys) => {\n const fragment = document.createDocumentFragment();\n const iterationDataLength = bindingData.iterationSize;\n let clonedItem;\n let iterationVm;\n let iterationBindingCache;\n let i = 0; // create or clear exisitng iterationBindingCache\n\n if (isArray(bindingData.iterationBindingCache)) {\n bindingData.iterationBindingCache.length = 0;\n } else {\n bindingData.iterationBindingCache = [];\n } // generate forOf and append to DOM\n\n\n for (i = 0; i < iterationDataLength; i += 1) {\n clonedItem = cloneDomNode(bindingData.el); // create bindingCache per iteration\n\n iterationBindingCache = createBindingCache({\n rootNode: clonedItem,\n bindingAttrs: bindingAttrs\n });\n bindingData.iterationBindingCache.push(iterationBindingCache);\n\n if (!isEmptyObject(iterationBindingCache)) {\n // create an iterationVm match iterator alias\n iterationVm = createIterationViewModel({\n bindingData: bindingData,\n viewModel: viewModel,\n iterationData: iterationData,\n keys: keys,\n index: i\n });\n renderIteration({\n elementCache: bindingData.iterationBindingCache[i],\n iterationVm: iterationVm,\n bindingAttrs: bindingAttrs,\n isRegenerate: true\n });\n }\n\n fragment.appendChild(clonedItem);\n }\n\n return fragment;\n };\n\n /**\n * forOfBinding\n * @description\n * DOM decleartive for binding.\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n */\n\n const forOfBinding = (cache, viewModel, bindingAttrs) => {\n const dataKey = cache.dataKey;\n\n if (!dataKey || dataKey.length > maxDatakeyLength) {\n return;\n }\n\n if (!cache.iterator) {\n if (dataKey.length > maxDatakeyLength) {\n return;\n } // replace mess spaces with single space\n\n\n cache.dataKey = cache.dataKey.replace(REGEX.WHITE_SPACES, ' ');\n const forExpMatch = dataKey.match(REGEX.FOR_OF);\n\n if (!forExpMatch) {\n return;\n }\n\n cache.iterator = {};\n cache.iterator.alias = forExpMatch[1].trim();\n\n if (forExpMatch[2]) {\n cache.iterator.dataKey = forExpMatch[2].trim();\n cache.parentElement = cache.el.parentElement;\n cache.previousNonTemplateElement = cache.el.previousSibling;\n cache.nextNonTemplateElement = cache.el.nextSibling;\n }\n }\n\n renderForOfBinding({\n bindingData: cache,\n viewModel: viewModel,\n bindingAttrs: bindingAttrs\n });\n };\n\n /**\n * isTargetDomRemoved\n * @description check if DOM between 'start' and 'end' comment tag has been removed\n * @param {object} bindingData\n * @return {boolean}\n */\n\n const isTargetDomRemoved = bindingData => {\n let ret = false;\n\n if (bindingData && bindingData.previousNonTemplateElement) {\n const commentStartTextContent = bindingData.previousNonTemplateElement.textContent;\n const endCommentTag = bindingData.previousNonTemplateElement.nextSibling;\n\n if (endCommentTag.nodeType === 8) {\n if (endCommentTag.textContent === commentStartTextContent + commentSuffix) {\n ret = true;\n }\n }\n }\n\n return ret;\n };\n\n const renderIfBinding = ({\n bindingData,\n viewModel,\n bindingAttrs\n }) => {\n if (!bindingData.fragment) {\n return;\n }\n\n const isDomRemoved = isTargetDomRemoved(bindingData);\n let rootElement = bindingData.el; // remove current old DOM.\n // TODO: try preserve DOM\n\n if (!isDomRemoved && !bindingData.isOnce) {\n removeIfBinding(bindingData); // use fragment for create iterationBindingCache\n\n rootElement = bindingData.fragment.firstChild.cloneNode(true);\n } // walk clonedElement to create iterationBindingCache once\n\n\n if (!bindingData.iterationBindingCache || !bindingData.hasIterationBindingCache) {\n bindingData.iterationBindingCache = createBindingCache({\n rootNode: rootElement,\n bindingAttrs: bindingAttrs\n });\n } // only render if has iterationBindingCache\n // means has other dataBindings to be render\n\n\n if (!isEmptyObject(bindingData.iterationBindingCache)) {\n bindingData.hasIterationBindingCache = true;\n renderIteration({\n elementCache: bindingData.iterationBindingCache,\n iterationVm: viewModel,\n bindingAttrs: bindingAttrs,\n isRegenerate: true\n });\n } // insert to new rendered DOM\n // TODO: check unnecessary insertion when DOM is preserved\n\n\n insertRenderedElements(bindingData, rootElement);\n };\n\n const removeIfBinding = bindingData => {\n removeElemnetsByCommentWrap(bindingData); // remove cache.IterationBindingCache to prevent memory leak\n\n if (bindingData.hasIterationBindingCache) {\n delete bindingData.iterationBindingCache;\n delete bindingData.hasIterationBindingCache;\n }\n };\n\n /**\n * if-Binding\n * @description\n * DOM decleartive for binding.\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n */\n\n const ifBinding = (cache, viewModel, bindingAttrs) => {\n const dataKey = cache.dataKey; // isOnce only return if there is no child bindings\n\n if (!dataKey || cache.isOnce && cache.hasIterationBindingCache === false) {\n return;\n }\n\n cache.elementData = cache.elementData || {};\n cache.type = cache.type || bindingAttrs$1.if;\n const oldViewModelProValue = cache.elementData.viewModelPropValue; // getViewModelPropValue could be return undefined or null\n\n const viewModelPropValue = getViewModelPropValue(viewModel, cache) || false; // do nothing if viewModel value not changed and no child bindings\n\n if (oldViewModelProValue === viewModelPropValue && !cache.hasIterationBindingCache) {\n return;\n }\n\n const shouldRender = Boolean(viewModelPropValue); // remove this cache from parent array\n\n if (!shouldRender && cache.isOnce && cache.el.parentNode) {\n removeElement(cache.el); // delete cache.fragment;\n\n removeBindingInQueue({\n viewModel: viewModel,\n cache: cache\n });\n return;\n } // store new show status\n\n\n cache.elementData.viewModelPropValue = viewModelPropValue; // only create fragment once\n // wrap comment tag around\n // remove if attribute from original element to allow later dataBind parsing\n\n if (!cache.fragment) {\n wrapCommentAround(cache, cache.el);\n cache.el.removeAttribute(bindingAttrs.if);\n createClonedElementCache(cache);\n }\n\n if (!shouldRender) {\n // remove element\n removeIfBinding(cache);\n } else {\n // render element\n renderIfBinding({\n bindingData: cache,\n viewModel: viewModel,\n bindingAttrs: bindingAttrs\n }); // if render once\n // remove this cache from parent array if no child caches\n\n if (cache.isOnce && !cache.hasIterationBindingCache) {\n // delete cache.fragment;\n removeBindingInQueue({\n viewModel: viewModel,\n cache: cache\n });\n }\n }\n };\n\n const removeBindingInQueue = ({\n viewModel,\n cache\n }) => {\n let ret = false;\n\n if (viewModel.APP.postProcessQueue) {\n viewModel.APP.postProcessQueue.push(((cache, index) => () => {\n cache[constants.PARENT_REF].splice(index, 1);\n })(cache, cache[constants.PARENT_REF].indexOf(cache)));\n ret = true;\n }\n\n return ret;\n };\n\n /**\n * switch-Binding\n * @description\n * DOM decleartive switch binding.\n * switch parent element wrap direct child with case bindings\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n */\n\n const switchBinding = (cache, viewModel, bindingAttrs) => {\n const dataKey = cache.dataKey;\n\n if (!dataKey) {\n return;\n }\n\n cache.elementData = cache.elementData || {};\n const newExpression = getViewModelPropValue(viewModel, cache);\n\n if (newExpression === cache.elementData.viewModelPropValue) {\n return;\n }\n\n cache.elementData.viewModelPropValue = newExpression; // build switch cases if not yet defined\n\n if (!cache.cases) {\n const childrenElements = cache.el.children;\n\n if (!childrenElements.length) {\n return;\n }\n\n cache.cases = [];\n\n for (let i = 0, elementLength = childrenElements.length; i < elementLength; i += 1) {\n let caseData = null;\n\n if (childrenElements[i].hasAttribute(bindingAttrs.case)) {\n caseData = createCaseData(childrenElements[i], bindingAttrs.case);\n } else if (childrenElements[i].hasAttribute(bindingAttrs.default)) {\n caseData = createCaseData(childrenElements[i], bindingAttrs.default);\n caseData.isDefault = true;\n } // create fragment by clone node\n // wrap with comment tag\n\n\n if (caseData) {\n wrapCommentAround(caseData, caseData.el); // remove binding attribute for later dataBind parse\n\n if (caseData.isDefault) {\n caseData.el.removeAttribute(bindingAttrs.default);\n } else {\n caseData.el.removeAttribute(bindingAttrs.case);\n }\n\n createClonedElementCache(caseData);\n cache.cases.push(caseData);\n }\n }\n }\n\n if (cache.cases.length) {\n let hasMatch = false; // do switch operation - reuse if binding logic\n\n for (let j = 0, casesLength = cache.cases.length; j < casesLength; j += 1) {\n let newCaseValue;\n\n if (cache.cases[j].dataKey) {\n // set back to dataKey if nothing found in viewModel\n newCaseValue = getViewModelPropValue(viewModel, cache.cases[j]) || cache.cases[j].dataKey;\n }\n\n if (newCaseValue === cache.elementData.viewModelPropValue || cache.cases[j].isDefault) {\n hasMatch = true; // render element\n\n renderIfBinding({\n bindingData: cache.cases[j],\n viewModel: viewModel,\n bindingAttrs: bindingAttrs\n }); // remove other elements\n\n removeUnmatchCases(cache.cases, j);\n break;\n }\n } // no match remove all cases\n\n\n if (!hasMatch) {\n removeUnmatchCases(cache.cases);\n }\n }\n };\n\n function removeUnmatchCases(cases, matchedIndex) {\n cases.forEach((caseData, index) => {\n if (index !== matchedIndex || typeof matchedIndex === 'undefined') {\n removeIfBinding(caseData); // remove cache.IterationBindingCache to prevent memory leak\n\n if (caseData.hasIterationBindingCache) {\n caseData.iterationBindingCache = null;\n caseData.hasIterationBindingCache = false;\n }\n }\n });\n }\n\n function createCaseData(node, attrName) {\n const caseData = {\n el: node,\n dataKey: node.getAttribute(attrName),\n type: attrName\n };\n return caseData;\n }\n\n const createEventBinding = ({\n cache = {},\n forceRender = false,\n type = '',\n viewModel = {}\n }) => {\n const handlerName = cache.dataKey;\n let paramList = cache.parameters;\n let viewModelContext;\n const APP = viewModel.APP || viewModel.$root.APP;\n\n if (!type || !handlerName || !forceRender && !APP.$rootElement.contains(cache.el)) {\n return;\n }\n\n const handlerFn = getViewModelValue(viewModel, handlerName);\n\n if (typeof handlerFn === 'function') {\n viewModelContext = resolveViewModelContext(viewModel, handlerName);\n paramList = paramList ? resolveParamList(viewModel, paramList) : [];\n\n const handlerWrap = e => {\n let formData;\n let args = [];\n\n if (type === 'submit') {\n formData = getFormData(e.currentTarget);\n args = [e, e.currentTarget, formData].concat(paramList);\n } else {\n args = [e, e.currentTarget].concat(paramList);\n }\n\n handlerFn.apply(viewModelContext, args);\n };\n\n cache.el.removeEventListener(type, handlerWrap, false);\n cache.el.addEventListener(type, handlerWrap, false);\n }\n };\n\n function applyBinding({\n ctx,\n elementCache,\n updateOption,\n bindingAttrs,\n viewModel\n }) {\n if (!elementCache || !updateOption) {\n return;\n } // the follow binding should be in order for better efficiency\n // apply forOf Binding\n\n\n if (updateOption.forOfBinding && elementCache[bindingAttrs.forOf] && elementCache[bindingAttrs.forOf].length) {\n elementCache[bindingAttrs.forOf].forEach(cache => {\n forOfBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n } // apply attr Binding\n\n\n if (updateOption.attrBinding && elementCache[bindingAttrs.attr] && elementCache[bindingAttrs.attr].length) {\n elementCache[bindingAttrs.attr].forEach(cache => {\n attrBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n } // apply if Binding\n\n\n if (updateOption.ifBinding && elementCache[bindingAttrs.if] && elementCache[bindingAttrs.if].length) {\n elementCache[bindingAttrs.if].forEach(cache => {\n ifBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n } // apply show Binding\n\n\n if (updateOption.showBinding && elementCache[bindingAttrs.show] && elementCache[bindingAttrs.show].length) {\n elementCache[bindingAttrs.show].forEach(cache => {\n showBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n } // apply switch Binding\n\n\n if (updateOption.switchBinding && elementCache[bindingAttrs.switch] && elementCache[bindingAttrs.switch].length) {\n elementCache[bindingAttrs.switch].forEach(cache => {\n switchBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n } // apply text binding\n\n\n if (updateOption.textBinding && elementCache[bindingAttrs.text] && elementCache[bindingAttrs.text].length) {\n elementCache[bindingAttrs.text].forEach(cache => {\n textBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n } // apply cssBinding\n\n\n if (updateOption.cssBinding && elementCache[bindingAttrs.css] && elementCache[bindingAttrs.css].length) {\n elementCache[bindingAttrs.css].forEach(cache => {\n cssBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n } // apply model binding\n\n\n if (updateOption.modelBinding && elementCache[bindingAttrs.model] && elementCache[bindingAttrs.model].length) {\n elementCache[bindingAttrs.model].forEach(cache => {\n modelBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n } // apply change binding\n\n\n if (updateOption.changeBinding && elementCache[bindingAttrs.change] && elementCache[bindingAttrs.change].length) {\n elementCache[bindingAttrs.change].forEach(cache => {\n changeBinding({\n bindingAttrs,\n cache,\n forceRender: updateOption.forceRender,\n type: 'change',\n viewModel\n });\n });\n } // apply submit binding\n\n\n if (updateOption.submitBinding && elementCache[bindingAttrs.submit] && elementCache[bindingAttrs.submit].length) {\n elementCache[bindingAttrs.submit].forEach(cache => {\n createEventBinding({\n cache,\n forceRender: updateOption.forceRender,\n type: 'submit',\n viewModel\n });\n });\n } // apply click binding\n\n\n if (updateOption.clickBinding && elementCache[bindingAttrs.click] && elementCache[bindingAttrs.click].length) {\n elementCache[bindingAttrs.click].forEach(cache => {\n createEventBinding({\n cache,\n forceRender: updateOption.forceRender,\n type: 'click',\n viewModel\n });\n });\n } // apply double click binding\n\n\n if (updateOption.dblclickBinding && elementCache[bindingAttrs.dblclick] && elementCache[bindingAttrs.dblclick].length) {\n elementCache[bindingAttrs.dblclick].forEach(cache => {\n createEventBinding({\n cache,\n forceRender: updateOption.forceRender,\n type: 'dblclick',\n viewModel\n });\n });\n } // apply blur binding\n\n\n if (updateOption.blurBinding && elementCache[bindingAttrs.blur] && elementCache[bindingAttrs.blur].length) {\n elementCache[bindingAttrs.blur].forEach(cache => {\n createEventBinding({\n cache,\n forceRender: updateOption.forceRender,\n type: 'blur',\n viewModel\n });\n });\n } // apply focus binding\n\n\n if (updateOption.focusBinding && elementCache[bindingAttrs.focus] && elementCache[bindingAttrs.focus].length) {\n elementCache[bindingAttrs.focus].forEach(cache => {\n createEventBinding({\n cache,\n forceRender: updateOption.forceRender,\n type: 'focus',\n viewModel\n });\n });\n } // apply hover binding\n\n\n if (updateOption.hoverBinding && elementCache[bindingAttrs.hover] && elementCache[bindingAttrs.hover].length) {\n elementCache[bindingAttrs.hover].forEach(cache => {\n hoverBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n } // apply input binding - eg html range input\n\n\n if (updateOption.inputBinding && elementCache[bindingAttrs.input] && elementCache[bindingAttrs.input].length) {\n elementCache[bindingAttrs.input].forEach(cache => {\n changeBinding({\n bindingAttrs,\n cache,\n forceRender: updateOption.forceRender,\n type: 'input',\n viewModel\n });\n });\n }\n }\n\n function postProcess(tasks) {\n if (!tasks || !tasks.length) {\n return;\n }\n\n each(tasks, (index, task) => {\n if (typeof task === 'function') {\n try {\n task();\n } catch (err) {\n throwErrorMessage(err, 'Error postProcess: ' + String(task));\n }\n }\n });\n }\n\n /**\n * pubSub\n * @description use jQuery object as pubSub\n * @example EVENTS object strucure:\n * EVENTS = {\n 'EVENT-NAME': [{ 'comp-id': fn }],\n 'EVENT-NAME2': [{ 'comp-id': fn }]\n };\n */\n\n const EVENTS = {};\n\n const subscribeEvent = (instance = null, eventName = '', fn, isOnce = false) => {\n if (!instance || !instance.compId || !eventName || typeof fn !== 'function') {\n return;\n }\n\n let subscriber;\n let isSubscribed = false;\n eventName = eventName.replace(REGEX.WHITE_SPACES, '');\n EVENTS[eventName] = EVENTS[eventName] || []; // check if already subscribed and update callback fn\n\n isSubscribed = EVENTS[eventName].some(subscriber => {\n if (subscriber[instance.compId]) {\n subscriber[instance.compId] = fn.bind(instance.viewModel);\n subscriber.isOnce = isOnce;\n return true;\n }\n }); // push if not yet subscribe\n\n if (!isSubscribed) {\n subscriber = {};\n subscriber[instance.compId] = fn.bind(instance.viewModel);\n subscriber.isOnce = isOnce;\n EVENTS[eventName].push(subscriber);\n }\n };\n\n const subscribeEventOnce = (instance = null, eventName = '', fn) => {\n subscribeEvent(instance, eventName, fn, true);\n };\n\n const unsubscribeEvent = (compId = '', eventName = '') => {\n if (!compId || !eventName) {\n return;\n }\n\n let i = 0;\n let subscribersLength = 0;\n let subscriber;\n eventName = eventName.replace(REGEX.WHITE_SPACES, '');\n\n if (EVENTS[eventName]) {\n subscribersLength = EVENTS[eventName].length;\n\n for (i = 0; i < subscribersLength; i += 1) {\n subscriber = EVENTS[eventName][i];\n\n if (subscriber[compId]) {\n EVENTS[eventName].splice(i, 1);\n break;\n }\n }\n } // delete the event if no more subscriber\n\n\n if (!EVENTS[eventName].length) {\n delete EVENTS[eventName];\n }\n };\n /**\n * unsubscribeAllEvent\n * @description unsubscribe all event by compId. eg when a component removed\n * @param {string} compId\n */\n\n\n const unsubscribeAllEvent = (compId = '') => {\n if (!compId) {\n return;\n }\n\n Object.keys(EVENTS).forEach(eventName => {\n unsubscribeEvent(compId, eventName);\n });\n };\n\n const publishEvent = (eventName = '', ...args) => {\n if (!eventName || !EVENTS[eventName]) {\n return;\n }\n\n eventName = eventName.replace(REGEX.WHITE_SPACES, '');\n EVENTS[eventName].forEach(subscriber => {\n Object.keys(subscriber).forEach(compId => {\n if (typeof subscriber[compId] === 'function') {\n const ret = subscriber[compId](...args);\n\n if (subscriber.isOnce) {\n unsubscribeEvent(compId, eventName);\n }\n\n return ret;\n }\n });\n });\n };\n\n let compIdIndex = 0;\n\n class Binder {\n constructor($rootElement, viewModel, bindingAttrs) {\n if (!$rootElement || $rootElement.nodeType !== 1 || viewModel === null || typeof viewModel !== 'object') {\n throw new TypeError('$rootElement or viewModel is invalid');\n }\n\n this.initRendered = false;\n this.compId = compIdIndex += 1;\n this.$rootElement = $rootElement;\n this.viewModel = viewModel;\n this.bindingAttrs = bindingAttrs;\n this.render = debounceRaf(this.render, this);\n this.isServerRendered = this.$rootElement.getAttribute(serverRenderedAttr) !== null; // inject instance into viewModel\n\n this.viewModel.APP = this; // add $root pointer to viewModel so binding can be refer as $root.something\n\n this.viewModel.$root = this.viewModel; // 1st step\n // parsView walk the DOM and create binding cache that holds each element's binding details\n // this binding cache is like AST for render and update\n\n this.parseView(); // for jquery user set viewModel referece to $rootElement for easy debug\n // otherwise use Expando to attach viewModel to $rootElement\n\n this.$rootElement[bindingDataReference.rootDataKey] = this.viewModel;\n return this;\n }\n /**\r\n * parseView\r\n * @description\r\n * @return {this}\r\n * traver from $rootElement to find each data-bind-* element\r\n * then apply data binding\r\n */\n\n\n parseView() {\n this.elementCache = createBindingCache({\n rootNode: this.$rootElement,\n bindingAttrs: this.bindingAttrs\n }); // updateElementCache if server rendered on init\n\n if (this.isServerRendered && !this.initRendered) {\n this.updateElementCache({\n templateCache: true\n });\n }\n\n return this;\n }\n /**\r\n * updateElementCache\r\n * @param {object} opt\r\n * @description call createBindingCache to parse view and generate bindingCache\r\n */\n\n\n updateElementCache(opt = {}) {\n const elementCache = opt.elementCache || this.elementCache;\n\n if (opt.allCache) {\n // walk dom from root element to regenerate elementCache\n this.elementCache = createBindingCache({\n rootNode: this.$rootElement,\n bindingAttrs: this.bindingAttrs\n });\n } // walk from first rendered template node to create/update child bindingCache\n\n\n if (opt.allCache || opt.templateCache) {\n if (elementCache[this.bindingAttrs.tmp] && elementCache[this.bindingAttrs.tmp].length) {\n elementCache[this.bindingAttrs.tmp].forEach(cache => {\n // set skipCheck as skipForOfParseFn whenever an node has\n // both template and forOf bindings\n // then the template bindingCache should be an empty object\n let skipForOfParseFn = null;\n\n if (cache.el.hasAttribute(this.bindingAttrs.forOf)) {\n skipForOfParseFn = () => {\n return true;\n };\n }\n\n cache.bindingCache = createBindingCache({\n rootNode: cache.el,\n bindingAttrs: this.bindingAttrs,\n skipCheck: skipForOfParseFn,\n isRenderedTemplate: opt.isRenderedTemplates\n });\n });\n }\n }\n }\n\n render(opt = {}) {\n let updateOption = {};\n\n if (!this.initRendered) {\n // only update eventsBinding if server rendered\n if (this.isServerRendered) {\n this.$rootElement.removeAttribute(serverRenderedAttr);\n updateOption = createBindingOption(bindingUpdateConditions.serverRendered, opt);\n } else {\n updateOption = createBindingOption(bindingUpdateConditions.init, opt);\n }\n } else {\n // when called again only update visualBinding options\n updateOption = createBindingOption('', opt);\n } // create postProcessQueue before start rendering\n\n\n this.postProcessQueue = [];\n const renderBindingOption = {\n ctx: this,\n elementCache: this.elementCache,\n updateOption: updateOption,\n bindingAttrs: this.bindingAttrs,\n viewModel: this.viewModel\n }; // always render template binding first\n // render and apply binding to template(s)\n // this is an share function therefore passing 'this' context\n\n renderTemplatesBinding(renderBindingOption); // apply bindings to rest of the DOM\n\n applyBinding(renderBindingOption); // trigger postProcess\n\n postProcess(this.postProcessQueue); // clear postProcessQueue\n\n this.postProcessQueue.length = 0;\n delete this.postProcessQueue;\n this.initRendered = true;\n }\n\n subscribe(eventName = '', fn) {\n subscribeEvent(this, eventName, fn);\n return this;\n }\n\n subscribeOnce(eventName = '', fn) {\n subscribeEventOnce(this, eventName, fn);\n return this;\n }\n\n unsubscribe(eventName = '') {\n unsubscribeEvent(this.compId, eventName);\n return this;\n }\n\n unsubscribeAll() {\n unsubscribeAllEvent(this.compId);\n return this;\n }\n\n publish(eventName = '', ...args) {\n publishEvent(eventName, ...args);\n return this;\n }\n\n }\n\n const isSupportPromise = typeof window['Promise'] === 'function';\n let bindingAttrs = bindingAttrs$1;\n\n const use = (settings = {}) => {\n if (settings.bindingAttrs) {\n bindingAttrs = extend({}, settings.bindingAttrs);\n }\n };\n\n const init = ($rootElement, viewModel = null) => {\n if (!isSupportPromise) {\n return console.warn('Browser not support Promise');\n }\n\n return new Binder($rootElement, viewModel, bindingAttrs);\n };\n\n var index = {\n use: use,\n init: init,\n version: '1.12.0'\n };\n\n return index;\n\n})));\n"]}
|
|
1
|
+
{"version":3,"file":"dataBind.min.js","sources":["../../../src/config.ts","../../../src/util.ts","../../../src/domWalker.ts","../../../src/createBindingOption.ts","../../../src/_escape.ts","../../../src/changeBinding.ts","../../../src/attrBinding.ts","../../../src/renderTemplate.ts","../../../src/renderTemplatesBinding.ts","../../../src/renderIteration.ts","../../../src/commentWrapper.ts","../../../src/renderForOfBinding.ts","../../../src/forOfBinding.ts","../../../src/renderIfBinding.ts","../../../src/ifBinding.ts","../../../src/switchBinding.ts","../../../src/createEventBinding.ts","../../../src/applyBinding.ts","../../../src/showBinding.ts","../../../src/textBinding.ts","../../../src/cssBinding.ts","../../../src/modelBinding.ts","../../../src/hoverBinding.ts","../../../src/pubSub.ts","../../../src/reactiveProxy.ts","../../../src/binder.ts","../../../src/postProcess.ts","../../../src/index.ts"],"sourcesContent":["export interface BindingAttrs {\n comp: string;\n tmp: string;\n text: string;\n click: string;\n dblclick: string;\n blur: string;\n focus: string;\n hover: string;\n input: string;\n change: string;\n submit: string;\n model: string;\n show: string;\n css: string;\n attr: string;\n forOf: string;\n if: string;\n switch: string;\n case: string;\n default: string;\n}\n\nexport const bindingAttrs: BindingAttrs = {\n comp: 'data-bind-comp',\n tmp: 'data-bind-tmp',\n text: 'data-bind-text',\n click: 'data-bind-click',\n dblclick: 'data-bind-dblclick',\n blur: 'data-bind-blur',\n focus: 'data-bind-focus',\n hover: 'data-bind-hover',\n input: 'data-bind-input',\n change: 'data-bind-change',\n submit: 'data-bind-submit',\n model: 'data-bind-model',\n show: 'data-bind-show',\n css: 'data-bind-css',\n attr: 'data-bind-attr',\n forOf: 'data-bind-for',\n if: 'data-bind-if',\n switch: 'data-bind-switch',\n case: 'data-bind-case',\n default: 'data-bind-default',\n};\n\nexport const serverRenderedAttr = 'data-server-rendered';\nexport const dataIndexAttr = 'data-index';\n\nexport interface CommentPrefix {\n forOf: string;\n if: string;\n case: string;\n default: string;\n}\n\nexport const commentPrefix: CommentPrefix = {\n forOf: 'data-forOf_',\n if: 'data-if_',\n case: 'data-case_',\n default: 'data-default_',\n};\n\nexport const commentSuffix = '_end';\n\nexport interface BindingDataReference {\n rootDataKey: string;\n currentData: string;\n currentIndex: string;\n mouseEnterHandlerName: string;\n mouseLeaveHandlerName: string;\n}\n\nexport const bindingDataReference: BindingDataReference = {\n rootDataKey: '$root',\n currentData: '$data',\n currentIndex: '$index',\n mouseEnterHandlerName: 'in',\n mouseLeaveHandlerName: 'out',\n};\n\nexport interface BindingUpdateConditions {\n serverRendered: string;\n init: string;\n}\n\nexport const bindingUpdateConditions: BindingUpdateConditions = {\n serverRendered: 'SERVER-RENDERED',\n init: 'INIT',\n};\n\n// maximum string length before running regex\nexport const maxDatakeyLength = 250;\n\nexport interface Constants {\n filters: {\n ONCE: string;\n };\n PARENT_REF: string;\n}\n\nexport const constants: Constants = {\n filters: {\n ONCE: 'once',\n },\n PARENT_REF: '_parent',\n};\n","import * as config from './config';\nimport type {ViewModel, BindingCache, ElementCache, DeferredObj, WrapMap, PlainObject} from './types';\n\nconst hasIsArray = Array.isArray;\n\nexport const REGEX = {\n BAD_TAGS: /<(script|del)(?=[\\s>])[\\w\\W]*?<\\/\\1\\s*>/ig,\n FOR_OF: /(.*?)\\s+(?:in|of)\\s+(.*)/,\n FUNCTION_PARAM: /\\((.*?)\\)/,\n HTML_TAG: /^[\\s]*<([a-z][^\\/\\s>]+)/i,\n OBJECT_LITERAL: /^\\{.+\\}$/,\n PIPE: /\\|/,\n WHITE_SPACES: /\\s+/g,\n LINE_BREAKS_TABS: /(\\r\\n|\\n|\\r|\\t)/gm,\n};\n\nconst IS_SUPPORT_TEMPLATE = 'content' in document.createElement('template');\n\nconst WRAP_MAP: WrapMap = {\n div: ['div', '<div>', '</div>'],\n thead: ['table', '<table>', '</table>'],\n col: ['colgroup', '<table><colgroup>', '</colgroup></table>'],\n tr: ['tbody', '<table><tbody>', '</tbody></table>'],\n td: ['tr', '<table><tr>', '</tr></table>'],\n};\nWRAP_MAP.caption = WRAP_MAP.colgroup = WRAP_MAP.tbody = WRAP_MAP.tfoot = WRAP_MAP.thead;\nWRAP_MAP.th = WRAP_MAP.td;\n\nexport const isArray = (obj: unknown): obj is unknown[] => {\n return hasIsArray ? Array.isArray(obj) : Object.prototype.toString.call(obj) === '[object Array]';\n};\n\nexport const isJsObject = (obj: unknown): obj is object => {\n return obj !== null && typeof obj === 'object' && Object.prototype.toString.call(obj) === '[object Object]';\n};\n\nexport const isPlainObject = (obj: unknown): obj is PlainObject => {\n if (!isJsObject(obj)) {\n return false;\n }\n\n // If has modified constructor\n const ctor = (obj as PlainObject).constructor;\n if (typeof ctor !== 'function') return false;\n\n // If has modified prototype\n const prot = ctor.prototype;\n if (isJsObject(prot) === false) return false;\n\n // If constructor does not have an Object-specific method\n if (prot.hasOwnProperty('isPrototypeOf') === false) {\n return false;\n }\n\n // Most likely a plain Object\n return true;\n};\n\n// test if string contains '{...}'. string must not contains tab, line breaks\nexport const isObjectLiteralString = (str: string = ''): boolean => {\n return REGEX.OBJECT_LITERAL.test(str);\n};\n\nexport const isEmptyObject = (obj: unknown): boolean => {\n if (isJsObject(obj)) {\n return Object.getOwnPropertyNames(obj).length === 0;\n }\n return false;\n};\n\nconst getFirstHtmlStringTag = (htmlString: string): string | null => {\n const match = htmlString.match(REGEX.HTML_TAG);\n if (match) {\n return match[1];\n }\n return null;\n};\n\nconst removeBadTags = (htmlString: string = ''): string => {\n return htmlString.replace(REGEX.BAD_TAGS, '');\n};\n\nexport const createHtmlFragment = (htmlString: unknown): DocumentFragment | null => {\n if (typeof htmlString !== 'string') {\n return null;\n }\n // use template element\n if (IS_SUPPORT_TEMPLATE) {\n const template = document.createElement('template');\n template.innerHTML = removeBadTags(htmlString);\n return template.content;\n }\n // use document fragment with wrap html tag for tr, td etc.\n const fragment = document.createDocumentFragment();\n const queryContainer = document.createElement('div');\n const firstTag = getFirstHtmlStringTag(htmlString);\n const wrap = WRAP_MAP[firstTag || 'div'];\n\n if (wrap[0] === 'div') {\n return document.createRange().createContextualFragment(htmlString);\n }\n\n queryContainer.insertAdjacentHTML('beforeend', `${wrap[1]}${htmlString}${wrap[2]}`);\n\n const query = queryContainer.querySelector(wrap[0]);\n\n while (query && query.firstChild) {\n fragment.appendChild(query.firstChild);\n }\n\n return fragment;\n};\n\nexport const generateElementCache = (bindingAttrs: PlainObject | unknown[]): ElementCache => {\n const elementCache: ElementCache = {};\n\n for (const i in bindingAttrs) {\n if (bindingAttrs.hasOwnProperty(i)) {\n if (isArray(bindingAttrs)) {\n elementCache[bindingAttrs[i] as string] = [];\n } else {\n elementCache[i] = [];\n }\n }\n }\n\n return elementCache;\n};\n\n\n/**\n * List of dangerous property names that should not be accessed\n * to prevent prototype pollution attacks\n */\nconst DANGEROUS_PROPS = ['__proto__', 'constructor', 'prototype'];\n\n/**\n * Check if a property name is safe to access\n */\nconst isSafeProperty = (prop: string): boolean => {\n return !DANGEROUS_PROPS.includes(prop);\n};\n\n// simplified version of Lodash _.get with prototype pollution protection\nconst _get = (obj: unknown, path: string, def?: unknown): unknown => {\n const fullPath = path\n .replace(/\\[/g, '.')\n .replace(/]/g, '')\n .split('.')\n .filter(Boolean);\n\n let current: unknown = obj;\n for (const step of fullPath) {\n // Prevent access to dangerous properties\n if (!step || !isSafeProperty(step)) {\n return def;\n }\n\n if (current == null) {\n return def;\n }\n\n current = (current as PlainObject)[step];\n\n if (current === undefined) {\n return def;\n }\n }\n\n return current;\n};\n\n/**\n * getViewModelValue\n * @description walk a object by provided string path. eg 'a.b.c'\n * @param {object} viewModel\n * @param {string} prop\n * @return {object}\n */\nexport const getViewModelValue = (viewModel: ViewModel, prop: string): unknown => {\n return _get(viewModel, prop);\n};\n\n// simplified version of Lodash _.set with prototype pollution protection\n// https://stackoverflow.com/questions/54733539/javascript-implementation-of-lodash-set-method\nconst _set = (obj: PlainObject, path: string | string[], value: unknown): PlainObject => {\n if (Object(obj) !== obj) return obj; // When obj is not an object\n\n // If not yet an array, get the keys from the string-path\n let pathArray: string[];\n if (!Array.isArray(path)) {\n pathArray = path.toString().match(/[^.[\\]]+/g) || [];\n } else {\n pathArray = path;\n }\n\n // Check all keys in path for dangerous properties\n for (const key of pathArray) {\n if (!isSafeProperty(key)) {\n console.warn(`Blocked attempt to set dangerous property: ${key}`);\n return obj;\n }\n }\n\n // Iterate all of them except the last one\n const lastKey = pathArray[pathArray.length - 1];\n const target = pathArray.slice(0, -1).reduce((a: PlainObject, c: string, i: number) => {\n // Prevent setting dangerous properties\n if (!isSafeProperty(c)) {\n return a;\n }\n\n if (Object(a[c]) === a[c]) {\n // Key exists and is an object, follow that path\n return a[c] as PlainObject;\n }\n\n // Create the key. Is the next key a potential array-index?\n const nextKey = pathArray[i + 1];\n a[c] = Math.abs(Number(nextKey)) >> 0 === +nextKey ? [] : {};\n return a[c] as PlainObject;\n }, obj);\n\n // Set the final value only if the key is safe\n if (isSafeProperty(lastKey)) {\n target[lastKey] = value;\n }\n\n // Return the top-level object to allow chaining\n return obj;\n};\n\n/**\n * setViewModelValue\n * @description populate viewModel object by path string\n * @param {object} obj\n * @param {string} prop\n * @param {string} value\n * @return {call} underscore set\n */\nexport const setViewModelValue = (obj: PlainObject, prop: string, value: unknown): PlainObject => {\n return _set(obj, prop, value);\n};\n\nexport const getViewModelPropValue = (viewModel: ViewModel, bindingCache: BindingCache): unknown => {\n let dataKey = bindingCache.dataKey;\n let paramList = bindingCache.parameters;\n const isInvertBoolean = dataKey && dataKey.charAt(0) === '!';\n\n if (isInvertBoolean && dataKey) {\n dataKey = isInvertBoolean ? dataKey.substring(1) : dataKey;\n }\n\n let ret = dataKey ? getViewModelValue(viewModel, dataKey) : undefined;\n\n if (typeof ret === 'function') {\n const viewModelContext = resolveViewModelContext(viewModel, dataKey || '');\n const oldViewModelProValue = bindingCache.elementData ? bindingCache.elementData.viewModelPropValue : null;\n paramList = paramList ? resolveParamList(viewModel, paramList) : [];\n // let args = [oldViewModelProValue, bindingCache.el].concat(paramList);\n const args = paramList.concat([oldViewModelProValue, bindingCache.el]);\n ret = (ret as Function).apply(viewModelContext, args);\n }\n\n ret = isInvertBoolean ? !ret : ret;\n\n // call through fitlers to get final value\n ret = filtersViewModelPropValue({\n value: ret,\n viewModel,\n bindingCache,\n });\n\n return ret;\n};\n\nconst filtersViewModelPropValue = ({value, viewModel, bindingCache}: {value: unknown, viewModel: ViewModel, bindingCache: BindingCache}): unknown => {\n let ret = value;\n if (bindingCache.filters) {\n each(bindingCache.filters, (index: string | number, filter: string) => {\n const viewModelContext = resolveViewModelContext(viewModel, filter);\n const filterFn = getViewModelValue.call(viewModelContext, viewModelContext, filter);\n try {\n ret = (filterFn as Function).call(viewModelContext, ret);\n } catch (err) {\n throwErrorMessage(err, `Invalid filter: ${filter}`);\n }\n });\n }\n return ret;\n};\n\nexport const parseStringToJson = (str: string): PlainObject => {\n // fix unquote or single quote keys and replace single quote to double quote\n const ret = str.replace(/(\\s*?{\\s*?|\\s*?,\\s*?)(['\"])?([a-zA-Z0-9]+)(['\"])?:/g, '$1\"$3\":').replace(/'/g, '\"');\n return JSON.parse(ret) as PlainObject;\n};\n\n/**\n * arrayRemoveMatch\n * @description remove match items in fromArray out of toArray\n * @param {array} toArray\n * @param {array} frommArray\n * @return {boolean}\n */\nexport const arrayRemoveMatch = (toArray: unknown[], frommArray: unknown[]): unknown[] => {\n return toArray.filter((value, _index) => {\n return frommArray.indexOf(value) < 0;\n });\n};\n\nexport const getFormData = ($form: HTMLFormElement): PlainObject => {\n const data: PlainObject = {};\n\n if (!($form instanceof HTMLFormElement)) {\n return data;\n }\n\n const formData = new FormData($form);\n\n formData.forEach((value, key) => {\n if (!Object.prototype.hasOwnProperty.call(Object, key)) {\n data[key] = value;\n return;\n }\n if (!Array.isArray(data[key])) {\n data[key] = [data[key]];\n }\n (data[key] as unknown[]).push(value);\n });\n\n return data;\n};\n\n/**\n * getFunctionParameterList\n * @description convert parameter string to arrary\n * eg. '(\"a\",\"b\",\"c\")' > [\"a\",\"b\",\"c\"]\n * @param {string} str\n * @return {array} paramlist\n */\nexport const getFunctionParameterList = (str: string): string[] | undefined => {\n if (!str || str.length > config.maxDatakeyLength) {\n return;\n }\n const paramlist = str.match(REGEX.FUNCTION_PARAM);\n\n if (paramlist && paramlist[1]) {\n const params = paramlist[1].split(',');\n params.forEach((v, i) => {\n params[i] = v.trim();\n });\n return params;\n }\n return undefined;\n};\n\nexport const extractFilterList = (cacheData: Partial<BindingCache>): Partial<BindingCache> => {\n if (!cacheData || !cacheData.dataKey || cacheData.dataKey.length > config.maxDatakeyLength) {\n return cacheData;\n }\n const filterList = cacheData.dataKey.split(REGEX.PIPE);\n let isOnceIndex: number | undefined;\n cacheData.dataKey = filterList[0].trim();\n if (filterList.length > 1) {\n filterList.shift();\n filterList.forEach((v, i) => {\n filterList[i] = v.trim();\n if (filterList[i] === config.constants.filters.ONCE) {\n cacheData.isOnce = true;\n isOnceIndex = i;\n }\n });\n // don't store filter 'once' - because it is internal logic not a property from viewModel\n if (isOnceIndex !== undefined && isOnceIndex >= 0) {\n filterList.splice(isOnceIndex, 1);\n }\n cacheData.filters = filterList;\n }\n return cacheData;\n};\n\nexport const invertObj = (sourceObj: PlainObject): PlainObject => {\n return Object.keys(sourceObj).reduce((obj: PlainObject, key: string) => {\n const invertedKey = sourceObj[key];\n // Prevent prototype pollution by checking if the inverted key is safe\n if (typeof invertedKey === 'string' && isSafeProperty(invertedKey)) {\n obj[invertedKey] = key;\n }\n return obj;\n }, {});\n};\n\nexport const createDeferredObj = (): DeferredObj => {\n const dfObj = {} as DeferredObj;\n\n dfObj.promise = new Promise((resolve, reject) => {\n dfObj.resolve = resolve;\n dfObj.reject = reject;\n });\n\n return dfObj;\n};\n\n/**\n * debounce\n * @description decorate a function to be debounce using requestAnimationFrame\n * @param {function} fn\n * @param {context} ctx\n * @return {function}\n */\nexport const debounceRaf = (fn: Function, ctx: unknown = null): Function => {\n return (function (fn: Function, ctx: unknown) {\n let dfObj = createDeferredObj();\n let rafId = 0;\n\n // return decorated fn\n return function () {\n\n const args = Array.from ? Array.from(arguments) : Array.prototype.slice.call(arguments);\n\n window.cancelAnimationFrame(rafId);\n rafId = window.requestAnimationFrame(() => {\n try {\n // fn is Binder.render function\n fn.apply(ctx, args);\n // dfObj.resolve is function provided in .then promise chain\n // ctx is the current component\n dfObj.resolve(ctx);\n } catch (err) {\n console.error('error in rendering: ', err);\n dfObj.reject(err);\n }\n\n // reset dfObj - otherwise then callbacks will not be in execution order\n // example:\n // myApp.render().then(function(){console.log('ok1')});\n // myApp.render().then(function(){console.log('ok2')});\n // myApp.render().then(function(){console.log('ok3')});\n // >> ok1, ok2, ok3\n dfObj = createDeferredObj();\n\n window.cancelAnimationFrame(rafId);\n });\n\n return dfObj.promise;\n };\n })(fn, ctx);\n};\n\n/**\n * getNodeAttrObj\n * @description convert Node attributes object to a json object\n * @param {object} node\n * @param {array} skipList\n * @return {object}\n */\nexport const getNodeAttrObj = (node: HTMLElement, skipList?: string | string[]): Record<string, string> | undefined => {\n let attributesLength = 0;\n let skipArray: string[] | undefined;\n\n if (!node || node.nodeType !== 1 || !node.hasAttributes()) {\n return;\n }\n if (skipList) {\n skipArray = [];\n skipArray = typeof skipList === 'string' ? [skipList] : skipList;\n }\n const attrObj: Record<string, string> = {};\n attributesLength = node.attributes.length;\n\n if (attributesLength) {\n for (let i = 0; i < attributesLength; i += 1) {\n const attribute = node.attributes.item(i);\n if (attribute) {\n attrObj[attribute.nodeName] = attribute.nodeValue || '';\n }\n }\n }\n\n if (isArray(skipArray)) {\n skipArray.forEach((item) => {\n if (attrObj[item]) {\n delete attrObj[item];\n }\n });\n }\n return attrObj;\n};\n\n/**\n * extend\n * @param {boolean} isDeepMerge\n * @param {object} target\n * @param {object} sources\n * @return {object} merged object\n */\nexport const extend = (isDeepMerge: boolean = false, target?: PlainObject, ...sources: PlainObject[]): PlainObject => {\n if (!sources.length) {\n return target || {};\n }\n const source = sources.shift();\n if (source === undefined) {\n return target || {};\n }\n\n if (!isDeepMerge) {\n return Object.assign(target || {}, source, ...sources);\n }\n\n if (isMergebleObject(target) && isMergebleObject(source)) {\n Object.keys(source).forEach((key) => {\n if (isMergebleObject(source[key])) {\n if (!target[key]) {\n target[key] = {};\n }\n extend(true, target[key] as PlainObject, source[key] as PlainObject);\n } else {\n target[key] = source[key];\n }\n });\n }\n\n return extend(true, target, ...sources);\n};\n\nexport const each = (obj: unknown[] | PlainObject, fn: Function): void => {\n if (typeof obj !== 'object' || typeof fn !== 'function') {\n return;\n }\n let keys: string[] = [];\n let keysLength = 0;\n const isArrayObj = isArray(obj);\n let key: string | number;\n let value: unknown;\n let i = 0;\n\n if (isArrayObj) {\n keysLength = obj.length;\n } else if (isJsObject(obj)) {\n keys = Object.keys(obj);\n keysLength = keys.length;\n } else {\n throw new TypeError('Object is not an array or object');\n }\n\n for (i = 0; i < keysLength; i += 1) {\n if (isArrayObj) {\n key = i;\n value = (obj as unknown[])[i];\n } else {\n key = keys[i];\n value = (obj as PlainObject)[key];\n }\n fn(key, value);\n }\n};\n\nconst isMergebleObject = (item: unknown): item is PlainObject => {\n return isJsObject(item) && !isArray(item);\n};\n\n/**\n * cloneDomNode\n * @param {object} element\n * @return {object} cloned element\n * @description helper function to clone node\n */\nexport const cloneDomNode = (element: HTMLElement): HTMLElement => {\n return element.cloneNode(true) as HTMLElement;\n};\n\n/**\n * insertAfter\n * @param {object} parentNode\n * @param {object} newNode\n * @param {object} referenceNode\n * @return {object} node\n * @description helper function to insert new node before the reference node\n */\nexport const insertAfter = (parentNode: Node, newNode: Node, referenceNode: Node | null): Node => {\n const refNextElement = referenceNode && referenceNode.nextSibling ? referenceNode.nextSibling : null;\n return parentNode.insertBefore(newNode, refNextElement);\n};\n\nexport const resolveViewModelContext = (viewModel: ViewModel, datakey: string): ViewModel => {\n let ret = viewModel;\n if (typeof datakey !== 'string') {\n return ret;\n }\n const bindingDataContext = datakey.split('.');\n if (bindingDataContext.length > 1) {\n if (bindingDataContext[0] === config.bindingDataReference.rootDataKey) {\n ret = (viewModel[config.bindingDataReference.rootDataKey] as ViewModel) || viewModel;\n } else if (bindingDataContext[0] === config.bindingDataReference.currentData) {\n ret = (viewModel[config.bindingDataReference.currentData] as ViewModel) || viewModel;\n }\n }\n return ret;\n};\n\nexport const resolveParamList = (viewModel: ViewModel, paramList: unknown[]): unknown[] | undefined => {\n if (!viewModel || !isArray(paramList)) {\n return;\n }\n return paramList.map((param) => {\n let resolvedParam: unknown = param;\n if (typeof param === 'string') {\n resolvedParam = param.trim();\n\n if (resolvedParam === config.bindingDataReference.currentIndex) {\n // convert '$index' to value\n resolvedParam = viewModel[config.bindingDataReference.currentIndex];\n } else if (resolvedParam === config.bindingDataReference.currentData) {\n // convert '$data' to value or current viewModel\n resolvedParam = viewModel[config.bindingDataReference.currentData] || viewModel;\n } else if (resolvedParam === config.bindingDataReference.rootDataKey) {\n // convert '$root' to root viewModel\n resolvedParam = viewModel[config.bindingDataReference.rootDataKey] || viewModel;\n }\n }\n return resolvedParam;\n });\n};\n\nexport const removeElement = (el: HTMLElement): void => {\n if (el && el.parentNode) {\n el.parentNode.removeChild(el);\n }\n};\n\nexport const emptyElement = (node: HTMLElement): HTMLElement => {\n if (node && node.firstChild) {\n while (node.firstChild) {\n node.removeChild(node.firstChild);\n }\n }\n return node;\n};\n\n/**\n * areNodesEqual\n * @description Compare two nodes to determine if they are structurally equal\n * @param {Node} node1\n * @param {Node} node2\n * @return {boolean}\n */\nconst areNodesEqual = (node1: Node, node2: Node): boolean => {\n // Different node types\n if (node1.nodeType !== node2.nodeType) {\n return false;\n }\n\n // Text nodes - compare content\n if (node1.nodeType === 3) {\n return node1.nodeValue === node2.nodeValue;\n }\n\n // Element nodes - compare tag names\n if (node1.nodeType === 1) {\n const el1 = node1 as HTMLElement;\n const el2 = node2 as HTMLElement;\n return el1.tagName === el2.tagName;\n }\n\n // Other node types (comments, etc.)\n return node1.nodeValue === node2.nodeValue;\n};\n\n/**\n * updateElementAttributes\n * @description Update element attributes to match new element\n * Only updates attributes that are in the new element.\n * Does NOT remove attributes that exist only in the existing element,\n * as these might be runtime-added by the binding system.\n * @param {HTMLElement} existingElement\n * @param {HTMLElement} newElement\n */\nconst updateElementAttributes = (existingElement: HTMLElement, newElement: HTMLElement): void => {\n // Get all attributes from new element\n const newAttrs = newElement.attributes;\n const attrsLength = newAttrs.length;\n\n // Update or add attributes from new element\n for (let i = 0; i < attrsLength; i += 1) {\n const attr = newAttrs[i];\n if (attr && attr.name) {\n const existingValue = existingElement.getAttribute(attr.name);\n if (existingValue !== attr.value) {\n existingElement.setAttribute(attr.name, attr.value || '');\n }\n }\n }\n\n // NOTE: We deliberately do NOT remove attributes that exist in the existing element\n // but not in the new element. This preserves runtime-added attributes from the binding\n // system (like data-bind-*, data-index, event handlers, etc.)\n};\n\n/**\n * createFragmentFromChildren\n * @description Create a DocumentFragment from a node's children\n * @param {Node} node\n * @return {DocumentFragment}\n */\nconst createFragmentFromChildren = (node: Node): DocumentFragment => {\n const fragment = document.createDocumentFragment();\n const children = Array.from(node.childNodes);\n children.forEach(child => {\n fragment.appendChild(child.cloneNode(true));\n });\n return fragment;\n};\n\n/**\n * updateDomWithMinimalChanges\n * @description Updates DOM by comparing existing nodes with new fragment\n * Only modifies what changed - performs minimal DOM manipulation\n * @param {HTMLElement} targetElement - The existing DOM element to update\n * @param {DocumentFragment} newFragment - The new content to apply\n */\nexport const updateDomWithMinimalChanges = (\n targetElement: HTMLElement,\n newFragment: DocumentFragment,\n): void => {\n const newNodes = Array.from(newFragment.childNodes);\n const existingNodes = Array.from(targetElement.childNodes);\n const newNodesLength = newNodes.length;\n const existingNodesLength = existingNodes.length;\n\n // Loop through new nodes and compare with existing\n for (let i = 0; i < newNodesLength; i += 1) {\n const newNode = newNodes[i];\n const existingNode = existingNodes[i];\n\n if (!existingNode) {\n // New node doesn't have a corresponding existing node - append it\n targetElement.appendChild(newNode);\n } else if (!areNodesEqual(existingNode, newNode)) {\n // Nodes are different types or tags - replace entire node\n targetElement.replaceChild(newNode, existingNode);\n } else {\n // Nodes are structurally equal - update content/attributes\n if (newNode.nodeType === 1 && existingNode.nodeType === 1) {\n // Element nodes - update attributes and recurse into children\n updateElementAttributes(existingNode as HTMLElement, newNode as HTMLElement);\n updateDomWithMinimalChanges(\n existingNode as HTMLElement,\n createFragmentFromChildren(newNode),\n );\n } else if (newNode.nodeType === 3) {\n // Text nodes - update text content if different\n if (existingNode.nodeValue !== newNode.nodeValue) {\n existingNode.nodeValue = newNode.nodeValue;\n }\n }\n }\n }\n\n // Remove extra existing nodes that don't have corresponding new nodes\n for (let i = existingNodesLength - 1; i >= newNodesLength; i -= 1) {\n if (existingNodes[i] && existingNodes[i].parentNode) {\n targetElement.removeChild(existingNodes[i]);\n }\n }\n};\n\nexport const throwErrorMessage = (err: unknown = null, errorMessage: string = ''): void => {\n const message = err && typeof err === 'object' && 'message' in err ? (err as Error).message : errorMessage;\n if (typeof console.error === 'function') {\n console.error(message);\n return;\n }\n console.log(message);\n};\n\n/**\n * parseBindingObjectString\n * @description parse bining object string to object with value always stringify\n * @param {string} str - eg '{ id: $data.id, name: $data.name }'\n * @return {object} - eg { id: '$data.id', name: '$data.name'}\n */\nexport const parseBindingObjectString = (str: string = ''): Record<string, string> | null => {\n let objectLiteralString = str.trim();\n const ret: Record<string, string> = {};\n\n if (!REGEX.OBJECT_LITERAL.test(str)) {\n return null;\n }\n\n // clearn up line breaks and remove first { character\n objectLiteralString = objectLiteralString\n .replace(REGEX.LINE_BREAKS_TABS, '')\n .substring(1);\n\n // remove last } character\n objectLiteralString = objectLiteralString.substring(0, objectLiteralString.length - 1);\n\n objectLiteralString.split(',').forEach((item) => {\n const keyVal = item.trim();\n // ignore if last empty item - eg split last comma in object literal\n if (keyVal) {\n const prop = keyVal.split(':');\n const key = prop[0].trim();\n ret[key] = `${prop[1]}`.trim();\n }\n });\n\n return ret;\n};\n","import {invertObj, extractFilterList, getFunctionParameterList, REGEX} from './util';\nimport {constants} from './config';\nimport type {PlainObject, BindingAttrs, ElementCache, BindingCache} from './types';\n\nlet bindingAttrsMap: PlainObject | undefined;\n\n/**\n * walkDOM\n * @description by Douglas Crockford - walk each DOM node and calls provided callback function\n * start walk from firstChild\n * @param {object} node\n * @param {function} func\n */\nconst walkDOM = (node: HTMLElement, func: (node: HTMLElement) => boolean): void => {\n let parseChildNode = true;\n let currentNode = node.firstElementChild as HTMLElement | null;\n while (currentNode) {\n parseChildNode = func(currentNode);\n if (parseChildNode) {\n walkDOM(currentNode, func);\n }\n currentNode = currentNode.nextElementSibling as HTMLElement | null;\n }\n};\n\nconst getAttributesObject = (node: HTMLElement): PlainObject => {\n const ret: PlainObject = {};\n Array.prototype.slice.call(node.attributes).forEach((item: Attr) => {\n ret[item.name] = item.value;\n });\n return ret;\n};\n\nconst checkSkipChildParseBindings = (attrObj: PlainObject = {}, bindingAttrs: BindingAttrs): string[] => {\n return [bindingAttrs.forOf, bindingAttrs.if, bindingAttrs.case, bindingAttrs.default].filter((type: string) => {\n return typeof attrObj[type] !== 'undefined';\n });\n};\n\nconst rootSkipCheck = (node: HTMLElement): boolean => {\n return node.tagName === 'SVG';\n};\n\nconst defaultSkipCheck = (node: HTMLElement, bindingAttrs: BindingAttrs): boolean => {\n return node.tagName === 'SVG' || node.hasAttribute(bindingAttrs.comp);\n};\n\nconst populateBindingCache = ({node, attrObj, bindingCache, type}: {\n node: HTMLElement;\n attrObj: PlainObject;\n bindingCache: ElementCache;\n type: string;\n}): ElementCache => {\n let attrValue: string;\n let cacheData: Partial<BindingCache>;\n\n if (bindingAttrsMap && bindingAttrsMap[type] && typeof attrObj[type] !== 'undefined') {\n bindingCache[type] = bindingCache[type] || [];\n attrValue = (attrObj[type] as string) || '';\n\n if (attrValue) {\n attrValue = attrValue.replace(REGEX.LINE_BREAKS_TABS, '').replace(REGEX.WHITE_SPACES, ' ').trim();\n }\n\n cacheData = {\n el: node,\n dataKey: attrValue,\n };\n\n // populate cacheData.filters. update filterList first item as dataKey\n cacheData = extractFilterList(cacheData);\n\n // populate cacheData.parameters\n // for store function call parameters eg. '$index', '$root'\n // useful with DOM for-loop template as reference to binding data\n const paramList = getFunctionParameterList(cacheData.dataKey || '');\n if (paramList) {\n cacheData.parameters = paramList;\n cacheData.dataKey = (cacheData.dataKey || '').replace(REGEX.FUNCTION_PARAM, '').trim();\n }\n // store parent array reference to cacheData\n cacheData[constants.PARENT_REF] = bindingCache[type];\n bindingCache[type].push(cacheData as BindingCache);\n }\n return bindingCache;\n};\n\nconst createBindingCache = ({rootNode = null, bindingAttrs = {} as BindingAttrs, skipCheck, isRenderedTemplate = false}: {\n rootNode?: HTMLElement | null;\n bindingAttrs?: BindingAttrs;\n skipCheck?: (node: HTMLElement) => boolean;\n isRenderedTemplate?: boolean;\n}): ElementCache => {\n let bindingCache: ElementCache = {};\n\n if (!(rootNode instanceof window.Node)) {\n throw new TypeError('walkDOM: Expected a DOM node');\n }\n\n bindingAttrsMap = bindingAttrsMap || invertObj(bindingAttrs);\n\n const parseNode = (\n node: HTMLElement,\n skipNodeCheckFn: (node: HTMLElement, bindingAttrs: BindingAttrs) => boolean = defaultSkipCheck,\n ): boolean => {\n let isSkipForOfChild = false;\n\n if (node.nodeType !== 1 || !node.hasAttributes()) {\n return true;\n }\n if (skipNodeCheckFn(node, bindingAttrs) || (typeof skipCheck === 'function' && skipCheck(node))) {\n return false;\n }\n\n // when creating sub bindingCache if is for tmp binding\n // skip same element that has forOf binding the forOf is alredy parsed\n const attrObj = getAttributesObject(node);\n const hasSkipChildParseBindings = checkSkipChildParseBindings(attrObj, bindingAttrs);\n let iterateList: string[] = [];\n\n if (hasSkipChildParseBindings.length) {\n isSkipForOfChild = true;\n iterateList = hasSkipChildParseBindings;\n } else if (isRenderedTemplate && attrObj[bindingAttrs.tmp]) {\n // skip current node parse if was called by node has template binding and already rendered\n return true;\n } else {\n iterateList = Object.keys(attrObj);\n }\n\n iterateList.forEach((key: string) => {\n // skip for switch case and default bining\n if (key !== bindingAttrs.case && key !== bindingAttrs.default) {\n bindingCache = populateBindingCache({\n node,\n attrObj,\n bindingCache,\n type: key,\n });\n }\n });\n\n // after cache forOf skip parse child nodes\n if (isSkipForOfChild) {\n return false;\n }\n\n return true;\n };\n\n if (parseNode(rootNode, rootSkipCheck)) {\n walkDOM(rootNode, parseNode);\n }\n return bindingCache;\n};\n\nexport default createBindingCache;\n","import {\n bindingUpdateConditions,\n} from './config';\nimport {extend} from './util';\n\nexport interface BindingOption {\n templateBinding?: boolean;\n textBinding?: boolean;\n cssBinding?: boolean;\n ifBinding?: boolean;\n showBinding?: boolean;\n modelBinding?: boolean;\n attrBinding?: boolean;\n forOfBinding?: boolean;\n switchBinding?: boolean;\n changeBinding?: boolean;\n clickBinding?: boolean;\n dblclickBinding?: boolean;\n blurBinding?: boolean;\n focusBinding?: boolean;\n hoverBinding?: boolean;\n inputBinding?: boolean;\n submitBinding?: boolean;\n forceRender?: boolean;\n [key: string]: unknown;\n}\n\n/**\n * createBindingOption\n * @param {string} condition\n * @param {object} opt\n * @description\n * generate binding update option object by condition\n * @return {object} updateOption\n */\nconst createBindingOption = (condition: string = '', opt: BindingOption = {}): BindingOption => {\n const visualBindingOptions: BindingOption = {\n templateBinding: false,\n textBinding: true,\n cssBinding: true,\n ifBinding: true,\n showBinding: true,\n modelBinding: true,\n attrBinding: true,\n forOfBinding: true,\n switchBinding: true,\n };\n const eventsBindingOptions: BindingOption = {\n changeBinding: true,\n clickBinding: true,\n dblclickBinding: true,\n blurBinding: true,\n focusBinding: true,\n hoverBinding: true,\n inputBinding: true,\n submitBinding: true,\n };\n // this is visualBindingOptions but everything false\n // concrete declear for performance purpose\n const serverRenderedOptions: BindingOption = {\n templateBinding: false,\n textBinding: false,\n cssBinding: false,\n ifBinding: false,\n showBinding: false,\n modelBinding: false,\n attrBinding: false,\n forOfBinding: false,\n switchBinding: false,\n };\n let updateOption: BindingOption = {};\n\n switch (condition) {\n case bindingUpdateConditions.serverRendered:\n updateOption = extend(false, {}, eventsBindingOptions, serverRenderedOptions, opt);\n break;\n case bindingUpdateConditions.init:\n // flag templateBinding to true to render tempalte(s)\n opt.templateBinding = true;\n opt.forceRender = true;\n updateOption = extend(false, {}, visualBindingOptions, eventsBindingOptions, opt);\n break;\n default:\n // when called again only update visualBinding options\n updateOption = extend(false, {}, visualBindingOptions, opt);\n }\n\n return updateOption;\n};\n\nexport default createBindingOption;\n","/**\n * _escape\n * @description\n * https://github.com/lodash/lodash/blob/master/escape.js\n */\n\nconst baseToString = (value: unknown): string => {\n if (typeof value == 'string') {\n return value;\n }\n return value == null ? '' : `${value}`;\n};\n\n/** Used to match HTML entities and HTML characters. */\nconst reUnescapedHtml = /[&<>\"'`]/g;\nconst reHasUnescapedHtml = RegExp(reUnescapedHtml.source);\n\n/** Used to map characters to HTML entities. */\nconst htmlEscapes: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n '\\'': ''',\n '`': '`',\n};\n\n/**\n * escapeHtmlChar\n * @description convert characters to HTML entities.\n * @private\n * @param {string} chr The matched character to escape.\n * @return {string} Returns the escaped character.\n */\nconst escapeHtmlChar = (chr: string): string => {\n return htmlEscapes[chr];\n};\n\n/**\n * Converts the characters \"&\", \"<\", \">\", '\"', \"'\", and \"\\`\", in `string` to\n * their corresponding HTML entities.\n * @param {string} string\n * @return {string} string\n */\nconst escape = (string: unknown): string => {\n // Reset `lastIndex` because in IE < 9 `String#replace` does not.\n const strValue = baseToString(string);\n return (strValue && reHasUnescapedHtml.test(strValue)) ?\n strValue.replace(reUnescapedHtml, escapeHtmlChar) :\n strValue;\n};\n\nexport default escape;\n","\nimport {\n getViewModelValue,\n setViewModelValue,\n resolveViewModelContext,\n resolveParamList,\n} from './util';\nimport _escape from './_escape';\nimport type {BindingCache, ViewModel, BindingAttrs} from './types';\n\n/**\n * Create change handler\n */\nconst createChangeHandler = (\n viewModel: ViewModel,\n modelDataKey: string | null,\n paramList: unknown[],\n handlerFn: Function,\n viewModelContext: ViewModel,\n): EventListener => {\n let oldValue: unknown = '';\n let newValue: unknown = '';\n\n return function changeHandler(this: HTMLInputElement, e: Event) {\n const $this = this;\n const isCheckbox = $this.type === 'checkbox';\n newValue = isCheckbox ? $this.checked : _escape($this.value);\n // set data to viewModel\n if (modelDataKey) {\n oldValue = getViewModelValue(viewModel, modelDataKey);\n setViewModelValue(viewModel, modelDataKey, newValue);\n }\n const args = [e, e.currentTarget, newValue, oldValue, ...paramList];\n handlerFn.apply(viewModelContext, args);\n oldValue = newValue;\n };\n};\n\ninterface ChangeBindingParams {\n cache: BindingCache;\n viewModel: ViewModel;\n bindingAttrs: BindingAttrs;\n forceRender: boolean;\n type?: string;\n}\n\n/**\n * changeBinding\n * @description input element on change event binding. DOM -> viewModel update\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n * @param {boolean} forceRender\n */\nconst changeBinding = ({\n cache,\n viewModel,\n bindingAttrs,\n forceRender,\n type = 'change',\n}: ChangeBindingParams): void => {\n const handlerName = cache.dataKey;\n let paramList = cache.parameters;\n const modelDataKey = cache.el.getAttribute(bindingAttrs.model);\n let viewModelContext: ViewModel;\n const APP = viewModel.APP || viewModel.$root?.APP;\n const rootElement = APP?.$rootElement as HTMLElement | undefined;\n\n if (!handlerName || (!forceRender && rootElement && !rootElement.contains(cache.el))) {\n return;\n }\n\n const handlerFn = getViewModelValue(viewModel, handlerName);\n\n if (typeof handlerFn === 'function') {\n viewModelContext = resolveViewModelContext(viewModel, handlerName);\n paramList = paramList ? resolveParamList(viewModel, paramList) : [];\n\n const changeHandler = createChangeHandler(\n viewModel,\n modelDataKey,\n paramList,\n handlerFn,\n viewModelContext,\n );\n\n // assign on change event\n cache.el.removeEventListener(type, changeHandler, false);\n cache.el.addEventListener(type, changeHandler, false);\n }\n};\n\nexport default changeBinding;\n","import {\n extend,\n getViewModelPropValue,\n isPlainObject,\n isEmptyObject,\n isObjectLiteralString,\n parseBindingObjectString,\n each,\n} from './util';\nimport type {BindingCache, ViewModel, PlainObject} from './types';\n\n/**\n * attrBinding\n * @description\n * DOM decleartive attr binding. update elenment attributes\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n */\nconst attrBinding = (cache: BindingCache = {} as BindingCache, viewModel: ViewModel, _bindingAttrs?: unknown, _forceRender?: unknown): void => {\n if (!cache.dataKey) {\n return;\n }\n // check if Object Literal String style dataKey\n const isObjLiteralStr = isObjectLiteralString(cache.dataKey);\n\n // resolve vmAttrObj, when Object Literal String style if will be object without resolve each value\n // otherwise, resolve value from viewModel\n const vmAttrObj = isObjLiteralStr ? parseBindingObjectString(cache.dataKey) : getViewModelPropValue(viewModel, cache);\n\n // vmAttrObj must be a plain object\n if (!isPlainObject(vmAttrObj)) {\n return;\n }\n\n // populate cache.elementData if not exits\n // check and set default cache.elementData.viewModelPropValue\n cache.elementData = cache.elementData || {};\n cache.elementData.viewModelPropValue = cache.elementData.viewModelPropValue || {};\n\n // start diff comparison\n // reject if nothing changed by comparing\n // cache.elementData.viewModelPropValue (previous render) vs vmAttrObj(current render)\n if (JSON.stringify(cache.elementData.viewModelPropValue) === JSON.stringify(vmAttrObj)) {\n return;\n }\n\n if (isObjLiteralStr) {\n // resolve each value in vmAttrObj\n each(vmAttrObj, (key: string, value: unknown) => {\n // resolve value from viewModel including $data and $root\n // from viewModel.$data or viewModel.$root\n (vmAttrObj as PlainObject)[key] = getViewModelPropValue(viewModel, {dataKey: value, el: cache.el} as BindingCache);\n });\n }\n\n // shortcut for reading cache.elementData.viewModelPropValue\n const oldAttrObj = cache.elementData.viewModelPropValue;\n\n // start set element attribute - oldAttrObj is empty meaning no previous render\n if (isEmptyObject(oldAttrObj)) {\n each(vmAttrObj, (key: string, value: unknown) => {\n if (typeof value !== 'undefined') {\n cache.el.setAttribute(key, String(value));\n // populate cache.elementData.viewModelPropValue for future comparison\n if (!isObjLiteralStr && cache.elementData) {\n cache.elementData.viewModelPropValue[key] = value;\n }\n }\n });\n } else {\n // loop oldAttrObj, remove attribute not present in current vmAttrObj\n each(oldAttrObj as PlainObject, (key: string, _value: unknown) => {\n if (typeof (vmAttrObj as PlainObject)[key] === 'undefined') {\n cache.el.removeAttribute(key);\n }\n });\n\n // loop vmAttrObj, set attribute not present in oldAttrObj\n each(vmAttrObj, (key: string, value: unknown) => {\n if (typeof value !== 'undefined') {\n if ((oldAttrObj as PlainObject)[key] !== (vmAttrObj as PlainObject)[key]) {\n cache.el.setAttribute(key, String((vmAttrObj as PlainObject)[key]));\n // populate cache.elementData.viewModelPropValue for future comparison\n if (!isObjLiteralStr && cache.elementData) {\n cache.elementData.viewModelPropValue[key] = value;\n }\n }\n }\n });\n }\n\n // for object literal style binding\n // set viewModelPropValue for future diff comaprison\n // note: vmAttrObj is a not fully resolve object, each value is still string unresloved\n if (isObjLiteralStr) {\n cache.elementData.viewModelPropValue = extend(false, {}, vmAttrObj);\n }\n};\n\nexport default attrBinding;\n","import {dataIndexAttr} from './config';\nimport {\n createHtmlFragment,\n emptyElement,\n getViewModelPropValue,\n parseStringToJson,\n updateDomWithMinimalChanges,\n} from './util';\nimport type {BindingCache, ViewModel, BindingAttrs, ElementCache, PlainObject} from './types';\n\nlet $domFragment: DocumentFragment | null = null;\nlet $templateRoot: HTMLElement | null = null;\nlet $templateRootPrepend = false;\nlet $templateRootAppend = false;\nlet nestTemplatesCount = 0;\n\n/**\n * getTemplateString\n * @description get Template tag innerHTML string\n * @param {string} id\n * @return {string} rendered html string\n */\nconst getTemplateString = (id: string): string => {\n const templateElement = document.getElementById(id);\n\n return templateElement ? templateElement.innerHTML : '';\n};\n\n/**\n * renderTemplate\n * @description\n * get template setting from DOM attribute then call compileTemplate\n * to render and append to target DOM\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n * @param {object} elementCache\n */\nconst renderTemplate = (cache: BindingCache, viewModel: ViewModel, bindingAttrs: BindingAttrs, elementCache: ElementCache): void => {\n const settings = typeof cache.dataKey === 'string' ? parseStringToJson(cache.dataKey) : cache.dataKey as PlainObject;\n let viewData: unknown = (settings as PlainObject).data;\n const isAppend = (settings as PlainObject).append;\n const isPrepend = (settings as PlainObject).prepend;\n let $currentElement: DocumentFragment | HTMLElement;\n\n cache.dataKey = settings as unknown as string;\n\n viewData = (typeof viewData === 'undefined' || viewData === '$root') ?\n viewModel :\n getViewModelPropValue(viewModel, {\n dataKey: (settings as PlainObject).data,\n parameters: cache.parameters,\n } as BindingCache);\n\n if (!viewData) {\n return;\n }\n\n const $element = cache.el;\n const $indexAttr = $element.getAttribute(dataIndexAttr);\n const $index = typeof viewModel.$index !== 'undefined' ? viewModel.$index : ($indexAttr ? parseInt($indexAttr, 10) : undefined);\n\n if (typeof $index !== 'undefined' && viewData && typeof viewData === 'object') {\n (viewData as ViewModel).$index = $index;\n }\n\n $domFragment = $domFragment || document.createDocumentFragment();\n\n if (!$templateRoot) {\n $templateRoot = $element;\n // Store the prepend/append flags from the root template only\n $templateRootPrepend = Boolean(isPrepend);\n $templateRootAppend = Boolean(isAppend);\n }\n\n const htmlString = getTemplateString((settings as PlainObject).id as string);\n\n const htmlFragment = createHtmlFragment(htmlString);\n\n // Return early if htmlFragment is null (invalid template)\n if (!htmlFragment) {\n return;\n }\n\n // append rendered html\n if (!$domFragment.childNodes.length) {\n // domFragment should be empty in first run\n $currentElement = $domFragment; // copy of $domFragment for later find nested template check\n $domFragment.appendChild(htmlFragment);\n } else {\n // during recursive run keep append to current fragment\n // For nested templates, use the original behavior (clear and append)\n // because they may contain forOf bindings or other dynamic content\n // that manages its own DOM structure\n $currentElement = $element; // reset to current nested template element\n if (!isAppend && !isPrepend) {\n $currentElement = emptyElement($currentElement);\n }\n if (isPrepend) {\n $currentElement.insertBefore(htmlFragment, $currentElement.firstChild);\n } else {\n $currentElement.appendChild(htmlFragment);\n }\n }\n\n // check if there are nested template then recurisive render them\n const $nestedTemplates = $currentElement.querySelectorAll(`[${ bindingAttrs.tmp }]`);\n\n const nestedTemplatesLength = $nestedTemplates.length;\n\n if (nestedTemplatesLength) {\n nestTemplatesCount += nestedTemplatesLength;\n\n for (let i=0; i < nestedTemplatesLength; i+=1) {\n const thisTemplateCache = {\n el: $nestedTemplates[i] as HTMLElement,\n dataKey: $nestedTemplates[i].getAttribute(bindingAttrs.tmp),\n } as BindingCache;\n elementCache[bindingAttrs.tmp].push(thisTemplateCache);\n // recursive template render\n renderTemplate(thisTemplateCache, viewModel, bindingAttrs, elementCache);\n nestTemplatesCount -= 1;\n }\n }\n\n // no more nested tempalted to render, start to append $domFragment into $templateRoot\n if (nestTemplatesCount === 0) {\n // append to DOM once\n // Use the prepend/append flags from the root template, not the current nested template\n if (!$templateRootAppend && !$templateRootPrepend) {\n // Check if this is a re-render by looking for a marker attribute\n // This is more reliable than checking childNodes.length because templates\n // may have placeholder content\n const isRerender = $templateRoot.hasAttribute('data-template-rendered');\n\n if (isRerender) {\n // Re-render: Use minimal DOM updates to preserve unchanged elements\n // This is faster and preserves DOM state (focus, scroll, animations)\n updateDomWithMinimalChanges($templateRoot, $domFragment);\n } else {\n // Initial render: Clear any placeholder content and render fresh\n $templateRoot = emptyElement($templateRoot);\n $templateRoot.appendChild($domFragment);\n // Mark this template as rendered for future re-renders\n $templateRoot.setAttribute('data-template-rendered', 'true');\n }\n } else {\n // For prepend/append modes, use the original behavior\n if ($templateRootPrepend) {\n $templateRoot.insertBefore($domFragment, $templateRoot.firstChild);\n } else {\n $templateRoot.appendChild($domFragment);\n }\n }\n // clear cached fragment and flags\n $domFragment = $templateRoot = null;\n $templateRootPrepend = $templateRootAppend = false;\n // trigger callback if provided\n if (viewModel.afterTemplateRender && typeof viewModel.afterTemplateRender === 'function') {\n (viewModel.afterTemplateRender as Function)(viewData);\n }\n }\n};\n\nexport default renderTemplate;\n","import {bindingUpdateConditions} from './config';\nimport * as applyBindingModule from './applyBinding';\nimport createBindingOption from './createBindingOption';\nimport renderTemplate from './renderTemplate';\nimport type {ElementCache, ViewModel, BindingAttrs, BindingCache} from './types';\nimport type {BindingOption} from './createBindingOption';\n\ninterface BinderContext {\n updateElementCache: (opt: {\n allCache?: boolean;\n templateCache?: boolean;\n elementCache?: ElementCache;\n isRenderedTemplates?: boolean;\n }) => void;\n}\n\nconst renderTemplatesBinding = ({\n ctx,\n elementCache,\n updateOption,\n bindingAttrs,\n viewModel,\n}: {\n ctx: BinderContext;\n elementCache: ElementCache;\n updateOption: BindingOption;\n bindingAttrs: BindingAttrs;\n viewModel: ViewModel;\n}): boolean => {\n if (!elementCache || !bindingAttrs) {\n return false;\n }\n // render and apply binding to template(s) and forOf DOM\n if (elementCache[bindingAttrs.tmp] && elementCache[bindingAttrs.tmp].length) {\n // when re-render call with {templateBinding: true}\n // template and nested templates\n if (updateOption.templateBinding) {\n // overwrite updateOption with 'init' bindingUpdateConditions\n updateOption = createBindingOption(bindingUpdateConditions.init);\n\n // forEach is correct here - nested templates are added to array but rendered recursively\n // We don't want the loop to re-render templates that were already rendered via recursion\n elementCache[bindingAttrs.tmp].forEach(($element: unknown) => {\n renderTemplate($element as BindingCache, viewModel, bindingAttrs, elementCache);\n });\n // update cache after all template(s) rendered\n ctx.updateElementCache({\n templateCache: true,\n elementCache,\n isRenderedTemplates: true,\n });\n }\n // enforce render even element is not in DOM tree\n updateOption.forceRender = true;\n\n // apply bindings to rendered templates element\n // Use namespace import to access the function at runtime,\n // which breaks the circular dependency during module initialization\n // Use for loop to handle templates added during rendering\n for (let i = 0; i < elementCache[bindingAttrs.tmp].length; i++) {\n applyBindingModule.default({\n ctx,\n elementCache: elementCache[bindingAttrs.tmp][i].bindingCache as ElementCache,\n updateOption,\n bindingAttrs,\n viewModel,\n });\n }\n }\n return true;\n};\n\nexport default renderTemplatesBinding;\n","import {bindingUpdateConditions} from './config';\nimport createBindingOption from './createBindingOption';\nimport renderTemplatesBinding from './renderTemplatesBinding';\nimport * as applyBindingModule from './applyBinding';\nimport type {ElementCache, ViewModel, BindingAttrs} from './types';\nimport type Binder from './binder';\n\n/**\n * renderIteration\n * @param {object} opt\n * @description\n * render element's binding by supplied elementCache\n * This function is desidned for FoOf, If, switch bindings\n */\nconst renderIteration = ({\n elementCache,\n iterationVm,\n bindingAttrs,\n isRegenerate,\n}: {\n elementCache: ElementCache;\n iterationVm: ViewModel;\n bindingAttrs: BindingAttrs;\n isRegenerate: boolean;\n}): void => {\n const bindingUpdateOption = isRegenerate ? createBindingOption(bindingUpdateConditions.init) : createBindingOption();\n\n // enforce render even element is not in DOM tree\n bindingUpdateOption.forceRender = true;\n\n // render and apply binding to template(s)\n // this is an share function therefore passing current APP 'this' context\n // viewModel is a dynamic generated iterationVm\n renderTemplatesBinding({\n ctx: (iterationVm.$root ? iterationVm.$root.APP : iterationVm.APP) as Binder,\n elementCache,\n updateOption: bindingUpdateOption,\n bindingAttrs,\n viewModel: iterationVm,\n });\n\n // Use namespace import to access the function at runtime,\n // which breaks the circular dependency during module initialization\n applyBindingModule.default({\n ctx: (iterationVm.$root ? iterationVm.$root.APP : iterationVm.APP) as Binder,\n elementCache,\n updateOption: bindingUpdateOption,\n bindingAttrs,\n viewModel: iterationVm,\n });\n};\n\nexport default renderIteration;\n","\nimport * as config from './config';\nimport * as util from './util';\nimport type {BindingCache} from './types';\n\nconst createClonedElementCache = (bindingData: BindingCache): BindingCache => {\n const clonedElement = bindingData.el.cloneNode(true);\n bindingData.fragment = document.createDocumentFragment();\n bindingData.fragment.appendChild(clonedElement);\n return bindingData;\n};\n\nconst setCommentPrefix = (bindingData: BindingCache): BindingCache => {\n if (!bindingData || !bindingData.type) {\n return bindingData;\n }\n let commentPrefix = '';\n const dataKeyMarker = bindingData.dataKey ? bindingData.dataKey.replace(util.REGEX.WHITE_SPACES, '_') : '';\n\n switch (bindingData.type) {\n case config.bindingAttrs.forOf:\n commentPrefix = config.commentPrefix.forOf;\n break;\n case config.bindingAttrs.if:\n commentPrefix = config.commentPrefix.if;\n break;\n case config.bindingAttrs.case:\n commentPrefix = config.commentPrefix.case;\n break;\n case config.bindingAttrs.default:\n commentPrefix = config.commentPrefix.default;\n break;\n }\n bindingData.commentPrefix = commentPrefix + dataKeyMarker;\n return bindingData;\n};\n\n/**\n * setDocRangeEndAfter\n * @param {object} node\n * @param {object} bindingData\n * @description\n * recursive execution to find last wrapping comment node\n * and set as bindingData.docRange.setEndAfter\n * if not found deleteContents will has no operation\n * @return {undefined}\n */\nconst setDocRangeEndAfter = (node: Node | null, bindingData: BindingCache): void => {\n if (!bindingData.commentPrefix) {\n setCommentPrefix(bindingData);\n }\n const startTextContent = bindingData.commentPrefix as string;\n const endTextContent = startTextContent + config.commentSuffix;\n node = node.nextSibling;\n\n // check last wrap comment node\n if (node) {\n if (node.nodeType === 8 && node.textContent === endTextContent) {\n return (bindingData.docRange as Range).setEndBefore(node);\n }\n setDocRangeEndAfter(node, bindingData);\n }\n};\n\n/**\n * wrapCommentAround\n * @param {object} bindingData\n * @param {Node} node\n * @return {object} DOM fragment\n * @description\n * wrap frament with comment node\n */\nconst wrapCommentAround = (bindingData: BindingCache, node: Node | DocumentFragment): Node | DocumentFragment => {\n let prefix = '';\n if (!bindingData.commentPrefix) {\n setCommentPrefix(bindingData);\n }\n prefix = bindingData.commentPrefix as string;\n const commentBegin = document.createComment(prefix);\n const commentEnd = document.createComment(prefix + config.commentSuffix);\n // document fragment - logic for ForOf binding\n // check node.parentNode because node could be from cache and no longer in DOM\n if (node.nodeType === 11) {\n node.insertBefore(commentBegin, node.firstChild);\n node.appendChild(commentEnd);\n } else if (node.parentNode) {\n node.parentNode.insertBefore(commentBegin, node);\n util.insertAfter(node.parentNode, commentEnd, node);\n // update bindingData details\n bindingData.previousNonTemplateElement = node.previousSibling;\n bindingData.nextNonTemplateElement = node.nextSibling;\n bindingData.parentElement = node.previousSibling.parentElement;\n }\n\n return node;\n};\n\n/**\n * removeElemnetsByCommentWrap\n * @param {object} bindingData\n * @return {undefined}\n * @description remove elments by range\n */\nconst removeElemnetsByCommentWrap = (bindingData: BindingCache): void => {\n if (!bindingData.docRange) {\n bindingData.docRange = document.createRange();\n }\n const docRange = bindingData.docRange as Range;\n try {\n if (bindingData.previousNonTemplateElement) {\n // update docRange start and end match the wrapped comment node\n docRange.setStartBefore(bindingData.previousNonTemplateElement.nextSibling as Node);\n setDocRangeEndAfter(bindingData.previousNonTemplateElement.nextSibling, bindingData);\n } else {\n // insert before next non template element\n docRange.setStartBefore((bindingData.parentElement as HTMLElement).firstChild as Node);\n setDocRangeEndAfter((bindingData.parentElement as HTMLElement).firstChild, bindingData);\n }\n } catch (err: unknown) {\n console.log('error removeElemnetsByCommentWrap: ', err instanceof Error ? err.message : String(err));\n }\n\n docRange.deleteContents();\n};\n\n/**\n * removeDomTemplateElement\n * @param {object} bindingData\n * @return {object} null\n */\nconst removeDomTemplateElement = (bindingData: BindingCache): void => {\n // first render - forElement is live DOM element so has parentNode\n if (bindingData.el.parentNode) {\n bindingData.el.parentNode.removeChild(bindingData.el);\n return;\n }\n removeElemnetsByCommentWrap(bindingData);\n};\n\nconst insertRenderedElements = (bindingData: BindingCache, fragment: DocumentFragment): void => {\n // insert rendered fragment after the previousNonTemplateElement\n if (bindingData.previousNonTemplateElement) {\n util.insertAfter(bindingData.parentElement, fragment, bindingData.previousNonTemplateElement);\n } else {\n // insert before next non template element\n if (bindingData.nextNonTemplateElement) {\n bindingData.parentElement.insertBefore(fragment, bindingData.nextNonTemplateElement);\n } else if (bindingData.parentElement) {\n // insert from parent\n bindingData.parentElement.appendChild(fragment);\n }\n }\n};\n\nexport {\n createClonedElementCache,\n setCommentPrefix,\n wrapCommentAround,\n removeElemnetsByCommentWrap,\n removeDomTemplateElement,\n setDocRangeEndAfter,\n insertRenderedElements,\n};\n","\nimport {bindingAttrs as configBindingAttrs, bindingDataReference} from './config';\nimport {\n getViewModelPropValue,\n isArray,\n isPlainObject,\n throwErrorMessage,\n cloneDomNode,\n isEmptyObject,\n} from './util';\nimport createBindingCache from './domWalker';\nimport renderIteration from './renderIteration';\nimport {\n wrapCommentAround,\n removeElemnetsByCommentWrap,\n insertRenderedElements,\n} from './commentWrapper';\nimport type {ViewModel, BindingCache, BindingAttrs, ElementCache} from './types';\n\nconst renderForOfBinding = ({bindingData, viewModel, bindingAttrs}: {\n bindingData: BindingCache;\n viewModel: ViewModel;\n bindingAttrs: BindingAttrs;\n}): void => {\n if (!bindingData || !viewModel || !bindingAttrs) {\n return;\n }\n let keys: string[] | undefined;\n let iterationDataLength: number;\n // FIX: Use bindingData.iterator instead of bindingData to get the iteration data\n // The iterator object has the dataKey pointing to the array/object to iterate over\n const iterationData = getViewModelPropValue(viewModel, bindingData.iterator as BindingCache);\n let isRegenerate = false;\n\n // check iterationData and set iterationDataLength\n if (isArray(iterationData)) {\n iterationDataLength = iterationData.length;\n } else if (isPlainObject(iterationData)) {\n keys = Object.keys(iterationData);\n iterationDataLength = keys.length;\n } else {\n // throw error but let script contince to run\n return throwErrorMessage(null, 'iterationData is not an plain object or array');\n }\n\n // flag as pared for-of logic with bindingData.type\n if (!bindingData.type) {\n bindingData.type = configBindingAttrs.forOf;\n wrapCommentAround(bindingData, bindingData.el);\n }\n\n // assign forOf internal id to bindingData once\n if (typeof bindingData.iterationSize === 'undefined') {\n // store iterationDataLength\n bindingData.iterationSize = iterationDataLength;\n // remove orignal node for-of attributes\n bindingData.el.removeAttribute(bindingAttrs.forOf);\n isRegenerate = true;\n } else {\n // only regenerate cache if iterationDataLength changed\n isRegenerate = bindingData.iterationSize !== iterationDataLength;\n // update iterationSize\n bindingData.iterationSize = iterationDataLength;\n }\n\n if (!isRegenerate) {\n (bindingData.iterationBindingCache as ElementCache[])?.forEach((elementCache: ElementCache, i: number) => {\n if (!isEmptyObject(elementCache)) {\n const iterationVm = createIterationViewModel({\n bindingData,\n viewModel,\n iterationData,\n keys,\n index: i,\n });\n renderIteration({\n elementCache,\n iterationVm,\n bindingAttrs,\n isRegenerate: false,\n });\n }\n });\n\n return;\n }\n\n // generate forOfBinding elements into fragment\n const fragment = generateForOfElements(bindingData, viewModel, bindingAttrs, iterationData, keys);\n\n removeElemnetsByCommentWrap(bindingData);\n\n // insert fragment content into DOM\n return insertRenderedElements(bindingData, fragment);\n};\n\n/**\n * createIterationViewModel\n * @description\n * create an virtual viewModel for render binding while in loop iteration\n * $data is the current data in the loop eg. data in array\n * $root is point to top level viewModel\n * $index is the current loop index\n * @param {*} param0\n * @return {object} virtual viewModel\n */\nconst createIterationViewModel = ({bindingData, viewModel, iterationData, keys, index}: {\n bindingData: BindingCache;\n viewModel: ViewModel;\n iterationData: unknown;\n keys: string[] | undefined;\n index: number;\n}): ViewModel => {\n const iterationVm: ViewModel = {};\n const alias = bindingData.iterator?.alias;\n if (alias) {\n iterationVm[alias] = keys ? (iterationData as Record<string, unknown>)[keys[index]] : (iterationData as unknown[])[index];\n }\n // populate common binding data reference\n iterationVm[bindingDataReference.rootDataKey] = viewModel.$root || viewModel;\n iterationVm[bindingDataReference.currentData] = alias ? iterationVm[alias] : undefined;\n iterationVm[bindingDataReference.currentIndex] = index;\n return iterationVm;\n};\n\nconst generateForOfElements = (\n bindingData: BindingCache,\n viewModel: ViewModel,\n bindingAttrs: BindingAttrs,\n iterationData: unknown,\n keys: string[] | undefined,\n): DocumentFragment => {\n const fragment = document.createDocumentFragment();\n const iterationDataLength = bindingData.iterationSize as number;\n let clonedItem: HTMLElement;\n let iterationVm: ViewModel;\n let iterationBindingCache: ElementCache;\n let i = 0;\n\n // create or clear exisitng iterationBindingCache\n if (isArray(bindingData.iterationBindingCache)) {\n (bindingData.iterationBindingCache as ElementCache[]).length = 0;\n } else {\n bindingData.iterationBindingCache = [];\n }\n\n // generate forOf and append to DOM\n for (i = 0; i < iterationDataLength; i += 1) {\n clonedItem = cloneDomNode(bindingData.el);\n\n // create bindingCache per iteration\n iterationBindingCache = createBindingCache({\n rootNode: clonedItem,\n bindingAttrs,\n });\n\n (bindingData.iterationBindingCache as ElementCache[]).push(iterationBindingCache);\n\n if (!isEmptyObject(iterationBindingCache)) {\n // create an iterationVm match iterator alias\n iterationVm = createIterationViewModel({\n bindingData,\n viewModel,\n iterationData,\n keys,\n index: i,\n });\n\n renderIteration({\n elementCache: (bindingData.iterationBindingCache as ElementCache[])[i],\n iterationVm,\n bindingAttrs,\n isRegenerate: true,\n });\n }\n\n fragment.appendChild(clonedItem);\n }\n\n return fragment;\n};\n\nexport default renderForOfBinding;\n","import {maxDatakeyLength} from './config';\nimport {REGEX} from './util';\nimport renderForOfBinding from './renderForOfBinding';\nimport type {BindingCache, ViewModel, BindingAttrs} from './types';\n\n/**\n * forOfBinding\n * @description\n * DOM decleartive for binding.\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n */\nconst forOfBinding = (cache: BindingCache, viewModel: ViewModel, bindingAttrs: BindingAttrs, _forceRender?: boolean): void => {\n const dataKey = cache.dataKey;\n\n if (!dataKey || dataKey.length > maxDatakeyLength) {\n return;\n }\n\n if (!cache.iterator) {\n if (dataKey.length > maxDatakeyLength) {\n return;\n }\n // replace mess spaces with single space\n cache.dataKey = cache.dataKey.replace(REGEX.WHITE_SPACES, ' ');\n const forExpMatch = dataKey.match(REGEX.FOR_OF);\n\n if (!forExpMatch) {\n return;\n }\n\n cache.iterator = {};\n cache.iterator.alias = forExpMatch[1].trim();\n\n if (forExpMatch[2]) {\n cache.iterator.dataKey = forExpMatch[2].trim();\n cache.parentElement = cache.el.parentElement;\n cache.previousNonTemplateElement = cache.el.previousSibling;\n cache.nextNonTemplateElement = cache.el.nextSibling;\n }\n }\n\n renderForOfBinding({\n bindingData: cache,\n viewModel,\n bindingAttrs,\n });\n};\n\nexport default forOfBinding;\n","import {isEmptyObject} from './util';\nimport renderIteration from './renderIteration';\nimport createBindingCache from './domWalker';\nimport {commentSuffix} from './config';\nimport {removeElemnetsByCommentWrap, insertRenderedElements} from './commentWrapper';\nimport type {BindingCache, ViewModel, BindingAttrs, ElementCache} from './types';\n\ninterface RenderIfBindingParams {\n bindingData: BindingCache;\n viewModel: ViewModel;\n bindingAttrs: BindingAttrs;\n}\n\n/**\n * isTargetDomRemoved\n * @description check if DOM between 'start' and 'end' comment tag has been removed\n * @param {object} bindingData\n * @return {boolean}\n */\nconst isTargetDomRemoved = (bindingData: BindingCache): boolean => {\n let ret = false;\n if (bindingData && bindingData.previousNonTemplateElement) {\n const commentStartTextContent = bindingData.previousNonTemplateElement.textContent;\n const endCommentTag = bindingData.previousNonTemplateElement.nextSibling;\n\n if (endCommentTag && endCommentTag.nodeType === 8) {\n if (endCommentTag.textContent === commentStartTextContent + commentSuffix) {\n ret = true;\n }\n }\n }\n return ret;\n};\n\n/**\n * removeIfBinding\n * @description remove if binding DOM and clean up cache\n * @param {object} bindingData\n */\nconst removeIfBinding = (bindingData: BindingCache): void => {\n removeElemnetsByCommentWrap(bindingData);\n // remove cache.IterationBindingCache to prevent memory leak\n if (bindingData.hasIterationBindingCache) {\n delete bindingData.iterationBindingCache;\n delete bindingData.hasIterationBindingCache;\n }\n};\n\n/**\n * renderIfBinding\n * @description render if binding DOM\n * @param {object} bindingData\n * @param {object} viewModel\n * @param {object} bindingAttrs\n */\nconst renderIfBinding = ({bindingData, viewModel, bindingAttrs}: RenderIfBindingParams): void => {\n if (!bindingData.fragment) {\n return;\n }\n\n const isDomRemoved = isTargetDomRemoved(bindingData);\n let rootElement: Node = bindingData.el;\n\n // remove current old DOM.\n // TODO: try preserve DOM\n if (!isDomRemoved && !bindingData.isOnce) {\n removeIfBinding(bindingData);\n // use fragment for create iterationBindingCache\n const firstChild = bindingData.fragment.firstChild;\n if (firstChild) {\n rootElement = firstChild.cloneNode(true);\n }\n }\n\n // walk clonedElement to create iterationBindingCache once\n if (!bindingData.iterationBindingCache || !bindingData.hasIterationBindingCache) {\n bindingData.iterationBindingCache = createBindingCache({\n rootNode: rootElement as HTMLElement,\n bindingAttrs,\n });\n }\n\n // only render if has iterationBindingCache\n // means has other dataBindings to be render\n if (!isEmptyObject(bindingData.iterationBindingCache)) {\n bindingData.hasIterationBindingCache = true;\n renderIteration({\n elementCache: bindingData.iterationBindingCache as ElementCache,\n iterationVm: viewModel,\n bindingAttrs,\n isRegenerate: true,\n });\n }\n\n // insert to new rendered DOM\n // TODO: check unnecessary insertion when DOM is preserved\n insertRenderedElements(bindingData, rootElement as DocumentFragment);\n};\n\nexport {\n renderIfBinding,\n removeIfBinding,\n};\n","import {bindingAttrs as configBindingAttrs, constants} from './config';\nimport {getViewModelPropValue, removeElement} from './util';\nimport {createClonedElementCache, wrapCommentAround} from './commentWrapper';\nimport {renderIfBinding, removeIfBinding} from './renderIfBinding';\nimport type {BindingCache, ViewModel, BindingAttrs} from './types';\n\n/**\n * if-Binding\n * @description\n * DOM decleartive for binding.\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n */\nconst ifBinding = (cache: BindingCache, viewModel: ViewModel, bindingAttrs: BindingAttrs, _forceRender?: boolean): void => {\n const dataKey = cache.dataKey;\n\n // isOnce only return if there is no child bindings\n if (!dataKey || (cache.isOnce && cache.hasIterationBindingCache === false)) {\n return;\n }\n\n cache.elementData = cache.elementData || {};\n cache.type = cache.type || configBindingAttrs.if;\n\n const oldViewModelProValue = cache.elementData.viewModelPropValue;\n // getViewModelPropValue could be return undefined or null\n const viewModelPropValue = getViewModelPropValue(viewModel, cache) || false;\n\n // do nothing if viewModel value not changed and no child bindings\n if (oldViewModelProValue === viewModelPropValue && !cache.hasIterationBindingCache) {\n return;\n }\n\n const shouldRender = Boolean(viewModelPropValue);\n\n // remove this cache from parent array\n if (!shouldRender && cache.isOnce && cache.el.parentNode) {\n removeElement(cache.el);\n // delete cache.fragment;\n removeBindingInQueue({\n viewModel,\n cache,\n });\n return;\n }\n\n // store new show status\n cache.elementData.viewModelPropValue = viewModelPropValue;\n\n // only create fragment once\n // wrap comment tag around\n // remove if attribute from original element to allow later dataBind parsing\n if (!cache.fragment) {\n wrapCommentAround(cache, cache.el);\n cache.el.removeAttribute(bindingAttrs.if);\n createClonedElementCache(cache);\n }\n\n if (!shouldRender) {\n // remove element\n removeIfBinding(cache);\n } else {\n // render element\n renderIfBinding({\n bindingData: cache,\n viewModel,\n bindingAttrs,\n });\n\n // if render once\n // remove this cache from parent array if no child caches\n if (cache.isOnce && !cache.hasIterationBindingCache) {\n // delete cache.fragment;\n removeBindingInQueue({\n viewModel,\n cache,\n });\n }\n }\n};\n\nconst removeBindingInQueue = ({viewModel, cache}: {viewModel: ViewModel; cache: BindingCache}): boolean => {\n let ret = false;\n if (viewModel.APP?.postProcessQueue) {\n const parentRef = cache[constants.PARENT_REF] as BindingCache[];\n viewModel.APP.postProcessQueue.push(\n ((cache: BindingCache, index: number) => () => {\n parentRef.splice(index, 1);\n })(cache, parentRef.indexOf(cache)),\n );\n ret = true;\n }\n return ret;\n};\n\nexport default ifBinding;\n","import {getViewModelPropValue} from './util';\nimport {createClonedElementCache, wrapCommentAround} from './commentWrapper';\nimport {renderIfBinding, removeIfBinding} from './renderIfBinding';\nimport type {BindingCache, ViewModel, BindingAttrs, CaseData} from './types';\n\n/**\n * switch-Binding\n * @description\n * DOM decleartive switch binding.\n * switch parent element wrap direct child with case bindings\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n */\nconst switchBinding = (cache: BindingCache, viewModel: ViewModel, bindingAttrs: BindingAttrs, _forceRender?: boolean): void => {\n const dataKey = cache.dataKey;\n\n if (!dataKey) {\n return;\n }\n\n cache.elementData = cache.elementData || {};\n\n const newExpression = getViewModelPropValue(viewModel, cache);\n\n if (newExpression === cache.elementData.viewModelPropValue) {\n return;\n }\n\n cache.elementData.viewModelPropValue = newExpression;\n\n // build switch cases if not yet defined\n if (!cache.cases) {\n const childrenElements = cache.el.children;\n if (!childrenElements.length) {\n return;\n }\n cache.cases = [];\n for (let i = 0, elementLength = childrenElements.length; i < elementLength; i += 1) {\n let caseData: CaseData | null = null;\n const childElement = childrenElements[i] as HTMLElement;\n if (childElement.hasAttribute(bindingAttrs.case)) {\n caseData = createCaseData(childElement, bindingAttrs.case);\n } else if (childElement.hasAttribute(bindingAttrs.default)) {\n caseData = createCaseData(childElement, bindingAttrs.default);\n caseData.isDefault = true;\n }\n // create fragment by clone node\n // wrap with comment tag\n if (caseData) {\n wrapCommentAround(caseData, caseData.el);\n // remove binding attribute for later dataBind parse\n if (caseData.isDefault) {\n caseData.el.removeAttribute(bindingAttrs.default);\n } else {\n caseData.el.removeAttribute(bindingAttrs.case);\n }\n createClonedElementCache(caseData);\n cache.cases.push(caseData);\n }\n }\n }\n\n if (cache.cases.length) {\n let hasMatch = false;\n // do switch operation - reuse if binding logic\n for (let j = 0, casesLength = cache.cases.length; j < casesLength; j += 1) {\n let newCaseValue: unknown;\n if (cache.cases[j].dataKey) {\n // set back to dataKey if nothing found in viewModel\n newCaseValue = getViewModelPropValue(viewModel, cache.cases[j]) || cache.cases[j].dataKey;\n }\n\n if (newCaseValue === cache.elementData.viewModelPropValue || cache.cases[j].isDefault) {\n hasMatch = true;\n // render element\n renderIfBinding({\n bindingData: cache.cases[j],\n viewModel,\n bindingAttrs,\n });\n\n // remove other elements\n removeUnmatchCases(cache.cases, j);\n break;\n }\n }\n // no match remove all cases\n if (!hasMatch) {\n removeUnmatchCases(cache.cases);\n }\n }\n};\n\nconst removeUnmatchCases = (cases: CaseData[], matchedIndex?: number): void => {\n cases.forEach((caseData: CaseData, index: number) => {\n if (index !== matchedIndex || typeof matchedIndex === 'undefined') {\n removeIfBinding(caseData);\n // remove cache.IterationBindingCache to prevent memory leak\n if (caseData.hasIterationBindingCache) {\n caseData.iterationBindingCache = null;\n caseData.hasIterationBindingCache = false;\n }\n }\n });\n};\n\nconst createCaseData = (node: HTMLElement, attrName: string): CaseData => {\n const caseData: CaseData = {\n el: node,\n dataKey: node.getAttribute(attrName),\n type: attrName,\n };\n return caseData;\n};\n\nexport default switchBinding;\n","import {\n getFormData,\n getViewModelValue,\n resolveViewModelContext,\n resolveParamList,\n} from './util';\nimport type {BindingCache, ViewModel} from './types';\n\n/**\n * Create event handler wrapper\n */\nconst createEventHandlerWrapper = (\n type: string,\n paramList: unknown[],\n handlerFn: Function,\n viewModelContext: ViewModel,\n): EventListener => {\n return function handlerWrap(e: Event): void {\n let formData: Record<string, unknown>;\n let args: unknown[] = [];\n if (type === 'submit') {\n formData = getFormData(e.currentTarget as HTMLFormElement);\n args = [e, e.currentTarget, formData, ...paramList];\n } else {\n args = [e, e.currentTarget, ...paramList];\n }\n handlerFn.apply(viewModelContext, args);\n };\n};\n\ninterface CreateEventBindingParams {\n cache?: BindingCache;\n forceRender?: boolean;\n type?: string;\n viewModel?: ViewModel;\n}\n\nconst createEventBinding = ({\n cache = {} as BindingCache,\n forceRender = false,\n type = '',\n viewModel = {} as ViewModel,\n}: CreateEventBindingParams): void => {\n const handlerName = cache.dataKey;\n let paramList = cache.parameters;\n let viewModelContext: ViewModel;\n const APP = viewModel.APP || viewModel.$root?.APP;\n const rootElement = APP?.$rootElement as HTMLElement | undefined;\n\n if (!type || !handlerName || (!forceRender && rootElement && !rootElement.contains(cache.el))) {\n return;\n }\n\n const handlerFn = getViewModelValue(viewModel, handlerName);\n\n if (typeof handlerFn === 'function') {\n viewModelContext = resolveViewModelContext(viewModel, handlerName);\n paramList = paramList ? resolveParamList(viewModel, paramList) : [];\n\n // Store handler key for this event type on the DOM element itself\n // This prevents duplicate handlers even if multiple cache objects exist for same element\n const handlerKey = `_db_${type}Handler`;\n const el = cache.el as HTMLElement & Record<string, unknown>;\n\n // Check if handler already exists and skip if it's the same\n // This prevents adding duplicate handlers when the same element is processed multiple times\n if (el[handlerKey]) {\n // Handler already exists, remove it before adding new one\n el.removeEventListener(type, el[handlerKey] as EventListener, false);\n }\n\n // Create new handler wrapper\n const handlerWrap = createEventHandlerWrapper(\n type,\n paramList,\n handlerFn,\n viewModelContext,\n );\n\n // Store the handler on the DOM element so we can remove it later\n el[handlerKey] = handlerWrap;\n\n // Add the new event listener\n el.addEventListener(type, handlerWrap, false);\n }\n};\n\nexport default createEventBinding;\n","import hoverBinding from './hoverBinding';\nimport changeBinding from './changeBinding';\nimport modelBinding from './modelBinding';\nimport textBinding from './textBinding';\nimport showBinding from './showBinding';\nimport cssBinding from './cssBinding';\nimport attrBinding from './attrBinding';\nimport forOfBinding from './forOfBinding'; // depends renderForOfBinding -> this , renderIteration\nimport ifBinding from './ifBinding';\nimport switchBinding from './switchBinding';\nimport createEventBinding from './createEventBinding';\nimport type {ElementCache, UpdateOption, BindingAttrs, ViewModel, BindingCache} from './types';\n\ninterface ApplyBindingParams {\n ctx: unknown;\n elementCache: ElementCache;\n updateOption: UpdateOption;\n bindingAttrs: BindingAttrs;\n viewModel: ViewModel;\n}\n\nconst applyBinding = ({ctx: _ctx, elementCache, updateOption, bindingAttrs, viewModel}: ApplyBindingParams): void => {\n if (!elementCache || !updateOption) {\n return;\n }\n\n // the follow binding should be in order for better efficiency\n\n // apply forOf Binding\n if (updateOption.forOfBinding && elementCache[bindingAttrs.forOf] && elementCache[bindingAttrs.forOf].length) {\n elementCache[bindingAttrs.forOf].forEach((cache: BindingCache) => {\n forOfBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n }\n\n // apply attr Binding\n if (updateOption.attrBinding && elementCache[bindingAttrs.attr] && elementCache[bindingAttrs.attr].length) {\n elementCache[bindingAttrs.attr].forEach((cache: BindingCache) => {\n attrBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n }\n\n // apply if Binding\n if (updateOption.ifBinding && elementCache[bindingAttrs.if] && elementCache[bindingAttrs.if].length) {\n elementCache[bindingAttrs.if].forEach((cache: BindingCache) => {\n ifBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n }\n\n // apply show Binding\n if (updateOption.showBinding && elementCache[bindingAttrs.show] && elementCache[bindingAttrs.show].length) {\n elementCache[bindingAttrs.show].forEach((cache: BindingCache) => {\n showBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n }\n\n // apply switch Binding\n if (updateOption.switchBinding && elementCache[bindingAttrs.switch] && elementCache[bindingAttrs.switch].length) {\n elementCache[bindingAttrs.switch].forEach((cache: BindingCache) => {\n switchBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n }\n\n // apply text binding\n if (updateOption.textBinding && elementCache[bindingAttrs.text] && elementCache[bindingAttrs.text].length) {\n elementCache[bindingAttrs.text].forEach((cache: BindingCache) => {\n textBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n }\n\n // apply cssBinding\n if (updateOption.cssBinding && elementCache[bindingAttrs.css] && elementCache[bindingAttrs.css].length) {\n elementCache[bindingAttrs.css].forEach((cache: BindingCache) => {\n cssBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n }\n\n // apply model binding\n if (updateOption.modelBinding && elementCache[bindingAttrs.model] && elementCache[bindingAttrs.model].length) {\n elementCache[bindingAttrs.model].forEach((cache: BindingCache) => {\n modelBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n }\n\n // apply change binding\n if (updateOption.changeBinding && elementCache[bindingAttrs.change] && elementCache[bindingAttrs.change].length) {\n elementCache[bindingAttrs.change].forEach((cache: BindingCache) => {\n changeBinding({\n bindingAttrs,\n cache,\n forceRender: updateOption.forceRender,\n type: 'change',\n viewModel,\n });\n });\n }\n\n // apply submit binding\n if (updateOption.submitBinding && elementCache[bindingAttrs.submit] && elementCache[bindingAttrs.submit].length) {\n elementCache[bindingAttrs.submit].forEach((cache: BindingCache) => {\n createEventBinding({\n cache,\n forceRender: updateOption.forceRender,\n type: 'submit',\n viewModel,\n });\n });\n }\n\n // apply click binding\n if (updateOption.clickBinding && elementCache[bindingAttrs.click] && elementCache[bindingAttrs.click].length) {\n elementCache[bindingAttrs.click].forEach((cache: BindingCache) => {\n createEventBinding({\n cache,\n forceRender: updateOption.forceRender,\n type: 'click',\n viewModel,\n });\n });\n }\n\n // apply double click binding\n if (updateOption.dblclickBinding && elementCache[bindingAttrs.dblclick] && elementCache[bindingAttrs.dblclick].length) {\n elementCache[bindingAttrs.dblclick].forEach((cache: BindingCache) => {\n createEventBinding({\n cache,\n forceRender: updateOption.forceRender,\n type: 'dblclick',\n viewModel,\n });\n });\n }\n\n // apply blur binding\n if (updateOption.blurBinding && elementCache[bindingAttrs.blur] && elementCache[bindingAttrs.blur].length) {\n elementCache[bindingAttrs.blur].forEach((cache: BindingCache) => {\n createEventBinding({\n cache,\n forceRender: updateOption.forceRender,\n type: 'blur',\n viewModel,\n });\n });\n }\n\n // apply focus binding\n if (updateOption.focusBinding && elementCache[bindingAttrs.focus] && elementCache[bindingAttrs.focus].length) {\n elementCache[bindingAttrs.focus].forEach((cache: BindingCache) => {\n createEventBinding({\n cache,\n forceRender: updateOption.forceRender,\n type: 'focus',\n viewModel,\n });\n });\n }\n\n // apply hover binding\n if (updateOption.hoverBinding && elementCache[bindingAttrs.hover] && elementCache[bindingAttrs.hover].length) {\n elementCache[bindingAttrs.hover].forEach((cache: BindingCache) => {\n hoverBinding(cache, viewModel, bindingAttrs, updateOption.forceRender);\n });\n }\n\n // apply input binding - eg html range input\n if (updateOption.inputBinding && elementCache[bindingAttrs.input] && elementCache[bindingAttrs.input].length) {\n elementCache[bindingAttrs.input].forEach((cache: BindingCache) => {\n changeBinding({\n bindingAttrs,\n cache,\n forceRender: updateOption.forceRender,\n type: 'input',\n viewModel,\n });\n });\n }\n};\n\nexport default applyBinding;\n","import {getViewModelPropValue} from './util';\nimport type {BindingCache, ViewModel, BindingAttrs} from './types';\n\n/**\n * showBinding\n * @description\n * DOM decleartive show binding. Make binding show/hide according to viewModel data (boolean)\n * viewModel data can function but must return boolean\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n */\nconst showBinding = (cache: BindingCache, viewModel: ViewModel, _bindingAttrs: BindingAttrs, _forceRender?: boolean): void => {\n const dataKey = cache.dataKey;\n let currentInlineSytle: CSSStyleDeclaration | Record<string, never> = {};\n let currentInlineDisplaySytle = '';\n let shouldShow = true;\n\n if (!dataKey) {\n return;\n }\n\n cache.elementData = cache.elementData || {};\n\n const oldShowStatus = cache.elementData.viewModelPropValue;\n\n // store current element display default style once only\n if (\n typeof cache.elementData.displayStyle === 'undefined' ||\n typeof cache.elementData.computedStyle === 'undefined'\n ) {\n currentInlineSytle = cache.el.style;\n currentInlineDisplaySytle = currentInlineSytle.display;\n // use current inline style if defined\n if (currentInlineDisplaySytle) {\n // set to 'block' if is 'none'\n cache.elementData.displayStyle = currentInlineDisplaySytle === 'none' ? 'block' : currentInlineDisplaySytle;\n cache.elementData.computedStyle = null;\n } else {\n const computeStyle = window.getComputedStyle(cache.el, null).getPropertyValue('display');\n cache.elementData.displayStyle = null;\n cache.elementData.computedStyle = computeStyle;\n }\n }\n\n shouldShow = getViewModelPropValue(viewModel, cache) as boolean;\n\n // treat undefined || null as false.\n // eg if property doesn't exsits in viewModel, it will treat as false to hide element\n shouldShow = Boolean(shouldShow);\n\n // reject if nothing changed\n if (oldShowStatus === shouldShow) {\n return;\n }\n\n if (!shouldShow) {\n if (cache.el.style.display !== 'none') {\n cache.el.style.setProperty('display', 'none');\n }\n } else {\n if (cache.elementData.computedStyle || cache.el.style.display === 'none') {\n if (cache.elementData.computedStyle === 'none') {\n // default display is none in css rule, so use display 'block'\n cache.el.style.setProperty('display', 'block');\n } else {\n // has default displayable type so just remove inline display 'none'\n if (currentInlineSytle.length > 1) {\n cache.el.style.removeProperty('display');\n } else {\n cache.el.removeAttribute('style');\n }\n }\n } else {\n // element default display was inline style, so restore it\n cache.el.style.setProperty('display', cache.elementData.displayStyle);\n }\n }\n\n // store new show status\n cache.elementData.viewModelPropValue = shouldShow;\n};\n\nexport default showBinding;\n","import {getViewModelPropValue} from './util';\nimport type {BindingCache, ViewModel, BindingAttrs} from './types';\n\n/**\n * textBinding\n * * @description\n * DOM decleartive text binding update dom textnode with viewModel data\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n * @param {boolean} forceRender\n */\nconst textBinding = (cache: BindingCache, viewModel: ViewModel, bindingAttrs: BindingAttrs, forceRender: boolean): void => {\n const dataKey = cache.dataKey;\n const APP = viewModel.APP || viewModel.$root?.APP;\n\n // NOTE: this doesn't work for for-of, if and switch bindings because element was not in DOM\n if (!dataKey || (!forceRender && !(APP?.$rootElement as HTMLElement)?.contains(cache.el))) {\n return;\n }\n\n const newValue = getViewModelPropValue(viewModel, cache);\n const oldValue = cache.el.textContent;\n\n if (typeof newValue !== 'undefined' && typeof newValue !== 'object' && newValue !== null) {\n if (newValue !== oldValue) {\n cache.el.textContent = String(newValue);\n }\n }\n};\n\nexport default textBinding;\n","import {\n getViewModelPropValue,\n isPlainObject,\n arrayRemoveMatch,\n each,\n} from './util';\nimport type {BindingCache, ViewModel, BindingAttrs, PlainObject} from './types';\n\n/**\n * cssBinding\n * @description\n * DOM decleartive css binding. update classlist.\n * viewModel data can function but must return JSOL.\n * added css class if value is true\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n * @param {boolean} forceRender\n */\nconst cssBinding = (cache: BindingCache, viewModel: ViewModel, bindingAttrs: BindingAttrs, forceRender: boolean): void => {\n const dataKey = cache.dataKey;\n const APP = viewModel.APP || viewModel.$root?.APP;\n\n if (!dataKey || (!forceRender && !(APP?.$rootElement as HTMLElement)?.contains(cache.el))) {\n return;\n }\n\n cache.elementData = cache.elementData || {};\n cache.elementData.viewModelPropValue = cache.elementData.viewModelPropValue || '';\n\n const oldCssList = cache.elementData.viewModelPropValue;\n let newCssList = '';\n const vmCssListObj = getViewModelPropValue(viewModel, cache);\n let vmCssListArray: string[] = [];\n let isViewDataObject = false;\n let isViewDataString = false;\n let cssList: string[] = [];\n\n if (typeof vmCssListObj === 'string') {\n isViewDataString = true;\n } else if (isPlainObject(vmCssListObj)) {\n isViewDataObject = true;\n } else {\n // reject if vmCssListObj is not an object or string\n return;\n }\n\n if (isViewDataObject) {\n newCssList = JSON.stringify(vmCssListObj);\n } else {\n newCssList = (vmCssListObj as string).replace(/\\s\\s+/g, ' ').trim();\n vmCssListArray = newCssList.split(' ');\n }\n // reject if nothing changed\n if (oldCssList === newCssList) {\n return;\n }\n\n // get current css classes from element\n const domCssList = cache.el.classList;\n // clone domCssList as new array\n const domCssListLength = domCssList.length;\n for (let i = 0; i < domCssListLength; i += 1) {\n cssList.push(domCssList[i]);\n }\n\n if (isViewDataObject) {\n each(vmCssListObj as PlainObject, (k: string, v: unknown) => {\n const i = cssList.indexOf(k);\n if (v === true) {\n cssList.push(k);\n } else if (i !== -1) {\n cssList.splice(i, 1);\n }\n });\n } else if (isViewDataString) {\n // remove oldCssList items from cssList\n const oldCssArray = typeof oldCssList === 'string' && oldCssList ? oldCssList.split(' ') : [];\n cssList = arrayRemoveMatch(cssList, oldCssArray) as string[];\n cssList = cssList.concat(vmCssListArray);\n }\n\n // unique cssList array\n cssList = cssList.filter((v: string, i: number, a: string[]) => {\n return a.indexOf(v) === i;\n });\n\n const cssListString = cssList.join(' ');\n // update element data\n cache.elementData.viewModelPropValue = newCssList;\n // replace all css classes\n cache.el.setAttribute('class', cssListString);\n};\n\nexport default cssBinding;\n","import {getViewModelValue} from './util';\nimport type {BindingCache, ViewModel, BindingAttrs} from './types';\n\n/**\n * modelBinding\n * @description input element data binding. viewModel -> DOM update\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n * @param {boolean} forceRender\n */\nconst modelBinding = (cache: BindingCache, viewModel: ViewModel, bindingAttrs: BindingAttrs, forceRender: boolean): void => {\n const dataKey = cache.dataKey;\n let newValue: unknown = '';\n const APP = viewModel.APP || viewModel.$root?.APP;\n\n if (!dataKey || (!forceRender && !(APP?.$rootElement as HTMLElement)?.contains(cache.el))) {\n return;\n }\n\n newValue = getViewModelValue(viewModel, dataKey);\n\n if (typeof newValue !== 'undefined' && newValue !== null) {\n const $element = cache.el as HTMLInputElement;\n const isCheckbox = $element.type === 'checkbox';\n const isRadio = $element.type === 'radio';\n const inputName = $element.name;\n const $radioGroup = isRadio ? (APP?.$rootElement as HTMLElement).querySelectorAll(`input[name=\"${inputName}\"]`) : [];\n const oldValue = isCheckbox ? $element.checked : $element.value;\n\n // update element value\n if (newValue !== oldValue) {\n if (isCheckbox) {\n $element.checked = Boolean(newValue);\n } else if (isRadio) {\n let i = 0;\n const radioGroupLength = $radioGroup.length;\n\n for (i = 0; i < radioGroupLength; i += 1) {\n const radioInput = $radioGroup[i] as HTMLInputElement;\n if (radioInput.value === newValue) {\n radioInput.checked = true;\n break;\n }\n }\n } else {\n $element.value = String(newValue);\n }\n }\n }\n};\n\nexport default modelBinding;\n","\nimport {bindingDataReference} from './config';\nimport {\n getViewModelValue,\n resolveViewModelContext,\n resolveParamList,\n} from './util';\nimport type {BindingCache, ViewModel, BindingAttrs, PlainObject} from './types';\n\n/**\n * Create mouse enter handler\n */\nconst createMouseEnterHandler = (\n cache: BindingCache,\n handlers: PlainObject,\n inHandlerName: string,\n viewModelContext: ViewModel,\n paramList: unknown[],\n): (e: MouseEvent) => void => {\n return function onMouseEnterHandler(e: MouseEvent) {\n const args = [e, cache.el, ...paramList];\n (handlers[inHandlerName] as Function).apply(viewModelContext, args);\n };\n};\n\n/**\n * Create mouse leave handler\n */\nconst createMouseLeaveHandler = (\n cache: BindingCache,\n handlers: PlainObject,\n outHandlerName: string,\n viewModelContext: ViewModel,\n paramList: unknown[],\n): (e: MouseEvent) => void => {\n return function onMouseLeaveHandler(e: MouseEvent) {\n const args = [e, cache.el, ...paramList];\n (handlers[outHandlerName] as Function).apply(viewModelContext, args);\n };\n};\n\n/**\n * hoverBinding\n * DOM decleartive on hover event binding\n * event handler bind to viewModel method according to the DOM attribute\n * @param {object} cache\n * @param {object} viewModel\n * @param {object} bindingAttrs\n * @param {boolean} forceRender\n */\nconst hoverBinding = (cache: BindingCache, viewModel: ViewModel, bindingAttrs: BindingAttrs, forceRender: boolean): void => {\n const handlerName = cache.dataKey;\n let paramList = cache.parameters;\n const inHandlerName = bindingDataReference.mouseEnterHandlerName;\n const outHandlerName = bindingDataReference.mouseLeaveHandlerName;\n let viewModelContext: ViewModel;\n const APP = viewModel.APP || viewModel.$root?.APP;\n\n cache.elementData = cache.elementData || {};\n\n // TODO: check what is APP.$rootElement.contains(cache.el)\n const rootElement = APP?.$rootElement as HTMLElement | undefined;\n if (!handlerName || (!forceRender && rootElement && !rootElement.contains(cache.el))) {\n return;\n }\n\n const handlers = getViewModelValue(viewModel, handlerName) as PlainObject;\n\n if (handlers && typeof handlers[inHandlerName] === 'function' && typeof handlers[outHandlerName] === 'function') {\n viewModelContext = resolveViewModelContext(viewModel, handlerName);\n paramList = paramList ? resolveParamList(viewModel, paramList) : [];\n\n const onMouseEnterHandler = createMouseEnterHandler(cache, handlers as PlainObject, inHandlerName, viewModelContext, paramList);\n const onMouseLeaveHandler = createMouseLeaveHandler(cache, handlers as PlainObject, outHandlerName, viewModelContext, paramList);\n\n cache.el.removeEventListener('mouseenter', onMouseEnterHandler, false);\n cache.el.removeEventListener('mouseleave', onMouseLeaveHandler, false);\n\n cache.el.addEventListener('mouseenter', onMouseEnterHandler, false);\n cache.el.addEventListener('mouseleave', onMouseLeaveHandler, false);\n }\n};\n\nexport default hoverBinding;\n","import * as util from './util';\n\n/**\n * pubSub\n * @description use jQuery object as pubSub\n * @example EVENTS object strucure:\n * EVENTS = {\n 'EVENT-NAME': [{ 'comp-id': fn }],\n 'EVENT-NAME2': [{ 'comp-id': fn }]\n };\n */\n\ninterface Subscriber {\n [compId: string]: Function | boolean | undefined;\n isOnce?: boolean;\n}\n\ninterface Events {\n [eventName: string]: Subscriber[];\n}\n\nconst EVENTS: Events = {};\n\nexport const subscribeEvent = (instance: unknown = null, eventName: string = '', fn: Function, isOnce: boolean = false): void => {\n if (!instance || typeof instance !== 'object' || !('compId' in instance) || !instance.compId || !eventName || typeof fn !== 'function') {\n return;\n }\n\n let subscriber: Subscriber;\n let isSubscribed = false;\n\n eventName = eventName.replace(util.REGEX.WHITE_SPACES, '');\n EVENTS[eventName] = EVENTS[eventName] || [];\n // check if already subscribed and update callback fn\n const instanceWithViewModel = instance as { compId: string | number; viewModel: unknown };\n isSubscribed = EVENTS[eventName].some((subscriber) => {\n if (subscriber[instanceWithViewModel.compId]) {\n subscriber[instanceWithViewModel.compId] = fn.bind(instanceWithViewModel.viewModel);\n subscriber.isOnce = isOnce;\n return true;\n }\n return false;\n });\n // push if not yet subscribe\n if (!isSubscribed) {\n subscriber = {};\n subscriber[instanceWithViewModel.compId] = fn.bind(instanceWithViewModel.viewModel);\n subscriber.isOnce = isOnce;\n EVENTS[eventName].push(subscriber);\n }\n};\n\nexport const subscribeEventOnce = (instance: unknown = null, eventName: string = '', fn: Function): void => {\n subscribeEvent(instance, eventName, fn, true);\n};\n\nexport const unsubscribeEvent = (compId: string | number = '', eventName: string = ''): void => {\n if (!compId || !eventName) {\n return;\n }\n\n let i = 0;\n let subscribersLength = 0;\n let subscriber: Subscriber;\n\n eventName = eventName.replace(util.REGEX.WHITE_SPACES, '');\n\n if (EVENTS[eventName]) {\n subscribersLength = EVENTS[eventName].length;\n for (i = 0; i < subscribersLength; i += 1) {\n subscriber = EVENTS[eventName][i];\n if (subscriber[compId]) {\n EVENTS[eventName].splice(i, 1);\n break;\n }\n }\n }\n // delete the event if no more subscriber\n if (EVENTS[eventName] && !EVENTS[eventName].length) {\n delete EVENTS[eventName];\n }\n};\n\n/**\n * unsubscribeAllEvent\n * @description unsubscribe all event by compId. eg when a component removed\n * @param {string} compId\n */\nexport const unsubscribeAllEvent = (compId: string | number = ''): void => {\n if (!compId) {\n return;\n }\n Object.keys(EVENTS).forEach((eventName) => {\n unsubscribeEvent(compId, eventName);\n });\n};\n\nexport const publishEvent = (eventName: string = '', ...args: unknown[]): void => {\n if (!eventName || !EVENTS[eventName]) {\n return;\n }\n\n eventName = eventName.replace(util.REGEX.WHITE_SPACES, '');\n\n EVENTS[eventName].forEach((subscriber) => {\n Object.keys(subscriber).forEach((compId) => {\n if (typeof subscriber[compId] === 'function') {\n const ret = subscriber[compId](...args);\n if (subscriber.isOnce) {\n unsubscribeEvent(compId, eventName);\n }\n return ret;\n }\n });\n });\n};\n","import type {ViewModel} from './types';\n\ninterface ReactiveOptions {\n onChange: () => void;\n deep?: boolean;\n trackChanges?: boolean;\n}\n\ninterface ChangeTracker {\n changedPaths: Set<string>;\n}\n\n// WeakMap to store proxy metadata\nconst PROXY_MARKER = Symbol('isReactiveProxy');\nconst ORIGINAL_TARGET = Symbol('originalTarget');\n\n/**\n * Check if an object is already a reactive proxy\n */\nfunction isReactiveProxy(obj: unknown): boolean {\n return obj !== null && typeof obj === 'object' && (obj as Record<symbol, unknown>)[PROXY_MARKER] === true;\n}\n\n/**\n * Get the original target from a proxy\n */\nfunction getOriginalTarget<T>(obj: T): T {\n if (isReactiveProxy(obj)) {\n return (obj as Record<symbol, unknown>)[ORIGINAL_TARGET] as T;\n }\n return obj;\n}\n\n/**\n * Create a reactive proxy that automatically triggers onChange when properties are modified\n * Supports deep proxying for nested objects and arrays\n */\nexport function createReactiveProxy<T extends ViewModel>(\n target: T,\n options: ReactiveOptions,\n path: string = '',\n tracker?: ChangeTracker,\n): T {\n const {onChange, deep = true, trackChanges = false} = options;\n\n // Don't proxy non-objects\n if (target === null || typeof target !== 'object') {\n return target;\n }\n\n // Don't re-proxy already proxied objects\n if (isReactiveProxy(target)) {\n return target;\n }\n\n // Skip proxying special properties to avoid circular issues\n const skipProps = ['APP', '$root', '__proto__', 'constructor'];\n if (skipProps.includes(path)) {\n return target;\n }\n\n // Track changes if enabled\n const changeTracker = tracker || (trackChanges ? {changedPaths: new Set<string>()} : undefined);\n\n // Store proxied nested objects to reuse same proxy\n const proxiedChildren = new Map<string | symbol, unknown>();\n\n const handler: ProxyHandler<T> = {\n set(obj, prop, value) {\n // Skip internal properties\n if (typeof prop === 'symbol') {\n (obj as Record<symbol, unknown>)[prop] = value;\n return true;\n }\n\n const oldValue = obj[prop as keyof T];\n\n // Only trigger if value actually changed\n if (oldValue === value) {\n return true;\n }\n\n // Set the new value\n obj[prop as keyof T] = value;\n\n // Clear cached proxy for this property since value changed\n proxiedChildren.delete(prop);\n\n // Track the changed path\n if (changeTracker) {\n const fullPath = path ? `${path}.${String(prop)}` : String(prop);\n changeTracker.changedPaths.add(fullPath);\n }\n\n // Trigger onChange callback (debounced render)\n onChange();\n\n return true;\n },\n\n get(obj, prop) {\n // Return proxy markers\n if (prop === PROXY_MARKER) {\n return true;\n }\n if (prop === ORIGINAL_TARGET) {\n return obj;\n }\n\n const value = obj[prop as keyof T];\n\n // Don't proxy functions, symbols, or special properties\n if (\n typeof value === 'function' ||\n typeof prop === 'symbol' ||\n skipProps.includes(String(prop))\n ) {\n return value;\n }\n\n // If deep proxying is enabled and value is an object, wrap it in proxy\n if (deep && value !== null && typeof value === 'object') {\n // Return cached proxy if exists\n if (proxiedChildren.has(prop)) {\n return proxiedChildren.get(prop);\n }\n\n const fullPath = path ? `${path}.${String(prop)}` : String(prop);\n const proxied = Array.isArray(value)\n ? createReactiveArray(value as unknown[], onChange, options, fullPath, changeTracker)\n : createReactiveProxy(value as ViewModel, options, fullPath, changeTracker);\n\n // Cache the proxy\n proxiedChildren.set(prop, proxied);\n\n return proxied;\n }\n\n return value;\n },\n\n deleteProperty(obj, prop) {\n if (typeof prop === 'symbol') {\n delete (obj as Record<symbol, unknown>)[prop];\n return true;\n }\n\n delete obj[prop as keyof T];\n\n // Clear cached proxy\n proxiedChildren.delete(prop);\n\n // Track deletion\n if (changeTracker) {\n const fullPath = path ? `${path}.${String(prop)}` : String(prop);\n changeTracker.changedPaths.add(fullPath);\n }\n\n onChange();\n return true;\n },\n };\n\n return new Proxy(target, handler);\n}\n\n/**\n * Special handling for arrays to intercept mutating methods\n */\nexport function createReactiveArray<T extends unknown[]>(\n target: T,\n onChange: () => void,\n options: ReactiveOptions,\n path: string = '',\n tracker?: ChangeTracker,\n): T {\n const {deep = true} = options;\n\n // Don't re-proxy already proxied arrays\n if (isReactiveProxy(target)) {\n return target;\n }\n\n const handler: ProxyHandler<T> = {\n set(obj, prop, value) {\n // Handle symbol properties\n if (typeof prop === 'symbol') {\n (obj as Record<symbol, unknown>)[prop] = value;\n return true;\n }\n\n const oldValue = obj[prop as keyof T];\n\n // Only trigger if value actually changed\n if (oldValue === value) {\n return true;\n }\n\n obj[prop as keyof T] = value;\n\n // Track changes\n if (tracker) {\n const fullPath = path ? `${path}[${String(prop)}]` : `[${String(prop)}]`;\n tracker.changedPaths.add(fullPath);\n }\n\n onChange();\n return true;\n },\n\n get(obj, prop) {\n // Return proxy markers\n if (prop === PROXY_MARKER) {\n return true;\n }\n if (prop === ORIGINAL_TARGET) {\n return obj;\n }\n\n const value = obj[prop as keyof T];\n\n // Intercept array mutating methods\n if (typeof value === 'function') {\n const mutatingMethods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse', 'fill'];\n if (mutatingMethods.includes(String(prop))) {\n return function (this: T, ...args: unknown[]) {\n const result = (value as Function).apply(this, args);\n\n // Track change\n if (tracker) {\n tracker.changedPaths.add(path || 'array');\n }\n\n onChange();\n return result;\n };\n }\n }\n\n // Deep proxy array elements if they are objects\n if (deep && value !== null && typeof value === 'object' && typeof prop !== 'symbol') {\n const fullPath = path ? `${path}[${String(prop)}]` : `[${String(prop)}]`;\n if (Array.isArray(value)) {\n return createReactiveArray(value as unknown[], onChange, options, fullPath, tracker);\n }\n return createReactiveProxy(value as ViewModel, options, fullPath, tracker);\n }\n\n return value;\n },\n\n deleteProperty(obj, prop) {\n if (typeof prop === 'symbol') {\n delete (obj as Record<symbol, unknown>)[prop];\n return true;\n }\n\n delete obj[prop as keyof T];\n\n if (tracker) {\n const fullPath = path ? `${path}[${String(prop)}]` : `[${String(prop)}]`;\n tracker.changedPaths.add(fullPath);\n }\n\n onChange();\n return true;\n },\n };\n\n return new Proxy(target, handler);\n}\n\n/**\n * Utility to get the original object from a reactive proxy\n */\nexport function toRaw<T>(obj: T): T {\n return getOriginalTarget(obj);\n}\n\n/**\n * Check if Proxy is supported\n */\nexport function isProxySupported(): boolean {\n return typeof Proxy !== 'undefined';\n}\n","import * as config from './config';\nimport {debounceRaf} from './util';\nimport createBindingCache from './domWalker';\nimport createBindingOption from './createBindingOption';\nimport applyBinding from './applyBinding';\nimport renderTemplatesBinding from './renderTemplatesBinding';\nimport postProcess from './postProcess';\nimport * as pubSub from './pubSub';\nimport {createReactiveProxy, isProxySupported} from './reactiveProxy';\nimport type {ViewModel, ElementCache, UpdateOption, BindingAttrs, BinderOptions} from './types';\n\nlet compIdIndex = 0;\n\nclass Binder {\n [key: string]: unknown;\n public initRendered: boolean;\n public compId: number;\n public $rootElement: HTMLElement;\n public viewModel: ViewModel;\n public bindingAttrs: BindingAttrs;\n public isServerRendered: boolean;\n public elementCache: ElementCache;\n public postProcessQueue: Array<() => void>;\n public render: (opt?: UpdateOption) => void;\n public isReactive: boolean;\n public originalViewModel: ViewModel;\n private afterRenderCallbacks: Array<() => void>;\n\n constructor($rootElement: HTMLElement, viewModel: ViewModel, bindingAttrs: BindingAttrs, options: BinderOptions = {}) {\n if (!$rootElement || $rootElement.nodeType !== 1 || viewModel === null || typeof viewModel !== 'object') {\n throw new TypeError('$rootElement or viewModel is invalid');\n }\n\n this.initRendered = false;\n\n this.compId = compIdIndex += 1;\n\n this.$rootElement = $rootElement;\n\n this.bindingAttrs = bindingAttrs;\n\n this.isServerRendered = this.$rootElement.getAttribute(config.serverRenderedAttr) !== null;\n\n // Initialize afterRender callbacks array\n this.afterRenderCallbacks = [];\n\n // Initialize render method with debounced version\n this.render = debounceRaf(this._render.bind(this), this) as (opt?: UpdateOption) => void;\n\n // Store original viewModel reference\n this.originalViewModel = viewModel;\n\n // Reactive mode is controlled by options (defaults merged in index.ts)\n // options.reactive is guaranteed to be defined due to merge in index.ts\n this.isReactive = !!options.reactive;\n\n // If reactive mode is enabled, wrap viewModel in proxy\n if (this.isReactive) {\n if (!isProxySupported()) {\n console.warn('Reactive mode requires Proxy support. Falling back to manual mode.');\n this.isReactive = false;\n this.viewModel = viewModel;\n } else {\n this.viewModel = createReactiveProxy(viewModel, {\n onChange: () => this.render(),\n deep: true,\n trackChanges: options.trackChanges,\n });\n }\n } else {\n this.viewModel = viewModel;\n }\n\n // inject instance into viewModel\n this.viewModel.APP = this;\n\n // add $root pointer to viewModel so binding can be refer as $root.something\n this.viewModel.$root = this.viewModel;\n\n // 1st step\n // parsView walk the DOM and create binding cache that holds each element's binding details\n // this binding cache is like AST for render and update\n this.parseView();\n\n // for jquery user set viewModel referece to $rootElement for easy debug\n // otherwise use Expando to attach viewModel to $rootElement\n this.$rootElement[config.bindingDataReference.rootDataKey] = this.viewModel;\n\n return this;\n }\n\n /**\n * parseView\n * @description\n * @return {this}\n * traver from $rootElement to find each data-bind-* element\n * then apply data binding\n */\n public parseView(): this {\n this.elementCache = createBindingCache({\n rootNode: this.$rootElement,\n bindingAttrs: this.bindingAttrs,\n });\n\n // updateElementCache if server rendered on init\n if (this.isServerRendered && !this.initRendered) {\n this.updateElementCache({\n templateCache: true,\n });\n }\n return this;\n }\n\n /**\n * updateElementCache\n * @param {object} opt\n * @description call createBindingCache to parse view and generate bindingCache\n */\n public updateElementCache(\n opt: {\n allCache?: boolean;\n templateCache?: boolean;\n elementCache?: ElementCache;\n isRenderedTemplates?: boolean;\n } = {},\n ): void {\n const elementCache = opt.elementCache || this.elementCache;\n\n if (opt.allCache) {\n // walk dom from root element to regenerate elementCache\n this.elementCache = createBindingCache({\n rootNode: this.$rootElement,\n bindingAttrs: this.bindingAttrs,\n });\n }\n // walk from first rendered template node to create/update child bindingCache\n if (opt.allCache || opt.templateCache) {\n if (elementCache[this.bindingAttrs.tmp] && elementCache[this.bindingAttrs.tmp].length) {\n // Use for loop to handle templates added during rendering\n for (let i = 0; i < elementCache[this.bindingAttrs.tmp].length; i++) {\n const cache = elementCache[this.bindingAttrs.tmp][i];\n // set skipCheck as skipForOfParseFn whenever an node has\n // both template and forOf bindings\n // then the template bindingCache should be an empty object\n let skipForOfParseFn: (() => boolean) | null = null;\n if (cache.el.hasAttribute(this.bindingAttrs.forOf)) {\n skipForOfParseFn = (): boolean => {\n return true;\n };\n }\n cache.bindingCache = createBindingCache({\n rootNode: cache.el,\n bindingAttrs: this.bindingAttrs,\n skipCheck: skipForOfParseFn,\n isRenderedTemplate: opt.isRenderedTemplates,\n });\n }\n }\n }\n }\n\n private _render(opt: UpdateOption = {}): void {\n let updateOption: UpdateOption = {};\n\n if (!this.initRendered) {\n // only update eventsBinding if server rendered\n if (this.isServerRendered) {\n this.$rootElement.removeAttribute(config.serverRenderedAttr);\n updateOption = createBindingOption(config.bindingUpdateConditions.serverRendered, opt);\n } else {\n updateOption = createBindingOption(config.bindingUpdateConditions.init, opt);\n }\n } else {\n // when called again only update visualBinding options\n updateOption = createBindingOption('', opt);\n }\n\n // create postProcessQueue before start rendering\n this.postProcessQueue = [];\n\n const renderBindingOption = {\n ctx: this,\n elementCache: this.elementCache,\n updateOption,\n bindingAttrs: this.bindingAttrs,\n viewModel: this.viewModel,\n };\n\n // always render template binding first\n // render and apply binding to template(s)\n // this is an share function therefore passing 'this' context\n renderTemplatesBinding(renderBindingOption);\n\n // apply bindings to rest of the DOM\n applyBinding(renderBindingOption);\n\n // trigger postProcess\n postProcess(this.postProcessQueue);\n // clear postProcessQueue\n this.postProcessQueue.length = 0;\n delete this.postProcessQueue;\n\n this.initRendered = true;\n\n // Call afterRender callbacks after rendering is fully complete\n this._callAfterRenderCallbacks();\n }\n\n /**\n * Call all registered afterRender callbacks\n * Called automatically after each render completes\n */\n private _callAfterRenderCallbacks(): void {\n if (this.afterRenderCallbacks.length > 0) {\n // Clone array to avoid issues if callbacks modify the array\n const callbacks = this.afterRenderCallbacks.slice();\n for (let i = 0, len = callbacks.length; i < len; i += 1) {\n try {\n callbacks[i]();\n } catch (err) {\n console.error('Error in afterRender callback:', err);\n }\n }\n }\n }\n\n /**\n * Register a callback to be called after each render completes\n * Useful for reactive mode where renders happen automatically\n * @param callback Function to call after render completes\n * @returns this for chaining\n */\n public afterRender(callback: () => void): this {\n if (typeof callback !== 'function') {\n throw new TypeError('afterRender callback must be a function');\n }\n this.afterRenderCallbacks.push(callback);\n return this;\n }\n\n /**\n * Remove a specific afterRender callback\n * @param callback The callback function to remove\n * @returns this for chaining\n */\n public removeAfterRender(callback: () => void): this {\n const index = this.afterRenderCallbacks.indexOf(callback);\n if (index !== -1) {\n this.afterRenderCallbacks.splice(index, 1);\n }\n return this;\n }\n\n /**\n * Clear all afterRender callbacks\n * @returns this for chaining\n */\n public clearAfterRender(): this {\n this.afterRenderCallbacks.length = 0;\n return this;\n }\n\n public subscribe(eventName: string = '', fn: (...args: unknown[]) => void): this {\n pubSub.subscribeEvent(this, eventName, fn);\n return this;\n }\n\n public subscribeOnce(eventName: string = '', fn: (...args: unknown[]) => void): this {\n pubSub.subscribeEventOnce(this, eventName, fn);\n return this;\n }\n\n public unsubscribe(eventName: string = ''): this {\n pubSub.unsubscribeEvent(this.compId, eventName);\n return this;\n }\n\n public unsubscribeAll(): this {\n pubSub.unsubscribeAllEvent(this.compId);\n return this;\n }\n\n public publish(eventName: string = '', ...args: unknown[]): this {\n pubSub.publishEvent(eventName, ...args);\n return this;\n }\n}\n\nexport default Binder;\n","import {\n each,\n throwErrorMessage,\n} from './util';\n\nconst postProcess = (tasks: Function[]): void => {\n if (!tasks || !tasks.length) {\n return;\n }\n\n each(tasks, (index: number, task: Function) => {\n if (typeof task === 'function') {\n try {\n task();\n } catch (err) {\n throwErrorMessage(err, `Error postProcess: ${ String(task)}`);\n }\n }\n });\n};\n\nexport default postProcess;\n","import * as config from './config';\nimport {extend} from './util';\nimport Binder from './binder';\nimport type {PlainObject, ViewModel, BindingAttrs, BinderOptions} from './types';\n\nconst isSupportPromise = typeof window['Promise'] === 'function';\n\nlet bindingAttrs = config.bindingAttrs;\n\n// Global default options for all Binder instances\nconst defaultOptions: BinderOptions = {\n reactive: true, // Enable reactive mode by default\n};\n\ninterface DataBindAPI {\n use: (settings: PlainObject) => DataBindAPI;\n init: ($rootElement: HTMLElement, viewModel: ViewModel | null, options?: BinderOptions) => Binder | void;\n version: string;\n}\n\nconst use = (settings: PlainObject = {}): DataBindAPI => {\n if (settings.bindingAttrs) {\n bindingAttrs = extend(false, {}, settings.bindingAttrs as PlainObject) as unknown as typeof config.bindingAttrs;\n }\n // Allow setting global reactive option\n if (typeof settings.reactive === 'boolean') {\n defaultOptions.reactive = settings.reactive;\n }\n // Allow setting global trackChanges option\n if (typeof settings.trackChanges === 'boolean') {\n defaultOptions.trackChanges = settings.trackChanges;\n }\n // Return API for chaining\n return api;\n};\n\nconst init = ($rootElement: HTMLElement, viewModel: ViewModel | null = null, options?: BinderOptions): Binder | void => {\n if (!isSupportPromise) {\n return console.warn('Browser not support Promise');\n }\n // Merge global defaults with instance-specific options\n // Instance options take precedence over global defaults\n const mergedOptions = {...defaultOptions, ...options};\n return new Binder($rootElement, viewModel, bindingAttrs as unknown as BindingAttrs, mergedOptions);\n};\n\nconst api: DataBindAPI = {\n use,\n init,\n version: '@version@',\n};\n\nexport default api;\n"],"names":["bindingAttrs","comp","tmp","text","click","dblclick","blur","focus","hover","input","change","submit","model","show","css","attr","forOf","if","switch","case","default","serverRenderedAttr","commentPrefix","commentSuffix","bindingDataReference","bindingUpdateConditions","maxDatakeyLength","constants","ONCE","hasIsArray","Array","isArray","REGEX","BAD_TAGS","FOR_OF","FUNCTION_PARAM","HTML_TAG","OBJECT_LITERAL","PIPE","WHITE_SPACES","LINE_BREAKS_TABS","IS_SUPPORT_TEMPLATE","document","createElement","WRAP_MAP","div","thead","col","tr","td","caption","colgroup","tbody","tfoot","th","obj","Object","prototype","toString","call","isJsObject","isPlainObject","ctor","constructor","prot","hasOwnProperty","isEmptyObject","getOwnPropertyNames","length","createHtmlFragment","htmlString","template","innerHTML","removeBadTags","replace","content","fragment","createDocumentFragment","queryContainer","firstTag","match","getFirstHtmlStringTag","wrap","createRange","createContextualFragment","insertAdjacentHTML","query","querySelector","firstChild","appendChild","DANGEROUS_PROPS","isSafeProperty","prop","includes","getViewModelValue","viewModel","_get","path","def","fullPath","split","filter","Boolean","current","step","undefined","setViewModelValue","value","_set","pathArray","key","console","warn","lastKey","target","slice","reduce","a","c","i","nextKey","Math","abs","Number","getViewModelPropValue","bindingCache","dataKey","paramList","parameters","isInvertBoolean","charAt","substring","ret","viewModelContext","resolveViewModelContext","oldViewModelProValue","elementData","viewModelPropValue","resolveParamList","args","concat","el","apply","filtersViewModelPropValue","filters","each","index","filterFn","err","throwErrorMessage","createDeferredObj","dfObj","promise","Promise","resolve","reject","extend","isDeepMerge","sources","source","shift","isMergebleObject","keys","forEach","_extends","fn","keysLength","isArrayObj","TypeError","item","cloneDomNode","element","cloneNode","insertAfter","parentNode","newNode","referenceNode","refNextElement","nextSibling","insertBefore","datakey","bindingDataContext","config","map","param","resolvedParam","trim","emptyElement","node","removeChild","areNodesEqual","node1","node2","nodeType","nodeValue","el2","tagName","updateElementAttributes","existingElement","newElement","newAttrs","attributes","attrsLength","name","getAttribute","setAttribute","createFragmentFromChildren","from","childNodes","child","updateDomWithMinimalChanges","targetElement","newFragment","newNodes","existingNodes","newNodesLength","existingNodesLength","existingNode","replaceChild","errorMessage","message","error","log","bindingAttrsMap","walkDOM","func","parseChildNode","currentNode","firstElementChild","nextElementSibling","rootSkipCheck","defaultSkipCheck","hasAttribute","populateBindingCache","attrObj","type","attrValue","cacheData","filterList","isOnceIndex","v","isOnce","splice","extractFilterList","str","paramlist","params","getFunctionParameterList","push","createBindingCache","rootNode","skipCheck","isRenderedTemplate","window","Node","sourceObj","invertedKey","parseNode","skipNodeCheckFn","isSkipForOfChild","hasAttributes","getAttributesObject","hasSkipChildParseBindings","checkSkipChildParseBindings","iterateList","createBindingOption","condition","opt","visualBindingOptions","templateBinding","textBinding","cssBinding","ifBinding","showBinding","modelBinding","attrBinding","forOfBinding","switchBinding","eventsBindingOptions","changeBinding","clickBinding","dblclickBinding","blurBinding","focusBinding","hoverBinding","inputBinding","submitBinding","serverRenderedOptions","updateOption","forceRender","reUnescapedHtml","reHasUnescapedHtml","RegExp","htmlEscapes","escapeHtmlChar","chr","createChangeHandler","modelDataKey","handlerFn","oldValue","newValue","e","$this","this","isCheckbox","checked","string","strValue","test","_escape","currentTarget","cache","handlerName","APP","_a","$root","rootElement","$rootElement","contains","changeHandler","removeEventListener","addEventListener","_bindingAttrs","_forceRender","isObjLiteralStr","isObjectLiteralString","vmAttrObj","parseBindingObjectString","objectLiteralString","keyVal","JSON","stringify","oldAttrObj","String","_value","removeAttribute","$domFragment","$templateRoot","$templateRootPrepend","$templateRootAppend","nestTemplatesCount","renderTemplate","elementCache","settings","parse","parseStringToJson","viewData","data","isAppend","append","isPrepend","prepend","$currentElement","$element","$indexAttr","$index","parseInt","id","templateElement","getElementById","getTemplateString","htmlFragment","$nestedTemplates","querySelectorAll","nestedTemplatesLength","thisTemplateCache","afterTemplateRender","renderTemplatesBinding","ctx","updateElementCache","templateCache","isRenderedTemplates","applyBindingModule","renderIteration","iterationVm","isRegenerate","bindingUpdateOption","createClonedElementCache","bindingData","clonedElement","setCommentPrefix","dataKeyMarker","util","setDocRangeEndAfter","endTextContent","textContent","docRange","setEndBefore","wrapCommentAround","prefix","commentBegin","createComment","commentEnd","previousNonTemplateElement","previousSibling","nextNonTemplateElement","parentElement","removeElemnetsByCommentWrap","setStartBefore","Error","deleteContents","insertRenderedElements","createIterationViewModel","iterationData","alias","iterator","generateForOfElements","iterationDataLength","iterationSize","clonedItem","iterationBindingCache","forExpMatch","renderForOfBinding","configBindingAttrs","removeIfBinding","hasIterationBindingCache","renderIfBinding","isDomRemoved","commentStartTextContent","endCommentTag","isTargetDomRemoved","removeBindingInQueue","postProcessQueue","parentRef","indexOf","removeUnmatchCases","cases","matchedIndex","caseData","createCaseData","attrName","createEventHandlerWrapper","formData","$form","HTMLFormElement","FormData","getFormData","createEventBinding","handlerKey","handlerWrap","applyBinding","_ctx","shouldRender","currentInlineSytle","currentInlineDisplaySytle","shouldShow","oldShowStatus","displayStyle","computedStyle","style","display","computeStyle","getComputedStyle","getPropertyValue","setProperty","removeProperty","newExpression","childrenElements","children","elementLength","childElement","isDefault","hasMatch","j","casesLength","newCaseValue","_b","oldCssList","newCssList","vmCssListObj","vmCssListArray","isViewDataObject","isViewDataString","cssList","domCssList","classList","domCssListLength","k","oldCssArray","frommArray","_index","arrayRemoveMatch","cssListString","join","isRadio","inputName","$radioGroup","radioGroupLength","radioInput","inHandlerName","outHandlerName","handlers","onMouseEnterHandler","createMouseEnterHandler","onMouseLeaveHandler","createMouseLeaveHandler","EVENTS","subscribeEvent","instance","eventName","compId","subscriber","isSubscribed","instanceWithViewModel","some","bind","unsubscribeEvent","subscribersLength","PROXY_MARKER","Symbol","ORIGINAL_TARGET","isReactiveProxy","createReactiveProxy","options","tracker","onChange","deep","trackChanges","skipProps","changeTracker","changedPaths","Set","proxiedChildren","Map","Proxy","set","delete","add","get","has","proxied","createReactiveArray","deleteProperty","result","compIdIndex","Binder","initRendered","isServerRendered","afterRenderCallbacks","render","debounceRaf","rafId","arguments","cancelAnimationFrame","requestAnimationFrame","_render","originalViewModel","isReactive","reactive","parseView","allCache","skipForOfParseFn","renderBindingOption","tasks","task","_callAfterRenderCallbacks","callbacks","len","afterRender","callback","removeAfterRender","clearAfterRender","subscribe","pubSub","subscribeOnce","subscribeEventOnce","unsubscribe","unsubscribeAll","unsubscribeAllEvent","publish","publishEvent","isSupportPromise","defaultOptions","api","use","init","mergedOptions","version"],"mappings":"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"}
|