From 6cc2659f731dce3c2526bf8c2ac730772eeca87b Mon Sep 17 00:00:00 2001 From: BorisMoore Date: Thu, 9 Mar 2017 11:50:33 -0800 Subject: [PATCH] Commit 84 (v0.9.84 - Beta) Feature improvements: - Major update for custom tags - including support for two-way binding to multiple args and props See samples: http://www.jsviews.com/#samples/tag-controls/jqui/draggable-droppable@jsv-draggable and tests: http://www.jsviews.com/test/unit-tests-jsviews.html?testId=f46a512b and also jQuery UI tag control samples such as http://www.jsviews.com/#samples/tag-controls/jqui/resizable and http://www.jsviews.com/#samples/tag-controls/jqui/draggable-droppable. Also many code examples in https://www.jsviews.com/download/sample-tag-controls/jsviews-jqueryui-widgets.js A tag definition can include: tag.bindTo - which specifies two-way bound parameters (one or more args and/or props) tag.linkedElement - which specifies selectors for linkedElems for any of the two-way bound parameters tag.linkedCtxParam - which specifies/names tag contextual parameters for any of the two-way bound parameters mainElement - which specifies selector for an element used for setting id, width or height (otherwise, linkedElem is used) A tag onBind event can set: tag.linkedElem tag.linkedElems tag.mainElem - which is the element used for setting id, width or height (otherwise, linkedElem is used) tag.displayElem - which is the element used for setting class (otherwise, mainElem/linkedElem is used) The following tag methods are available: tag.bndArgs() - which returns array of 'external' bound parameters (after convert, if convert=... is specified) tag.update(...) - which observably updates any ('external') bound parameters (using convertBack, if specified) tag.setValue(...) - which sets tag itself to new ('internal') values of bound parameters tag.getValue(...) - which returns array of current ('internal') values of bound parameters New 'tag contextual parameters' feature - see samples and explanation: http://www.jsviews.com/#samples/tag-controls/jqui/resizable and http://www.jsviews.com/#samples/tag-controls/jqui/draggable-droppable@tag-ctxl-params - Other custom tag improvements: New 'tag boundProps' feature: Tag definition can include: tag.boundProps - which specifies any additional props that are bound, without needing ^myprop=... notation. See sample: http://www.jsviews.com/#samples/tag-controls/range New 'tag contentCtx' feature: Tag definition can include: tag.contentCtx - which specifies the data context within the tag block content. Set contentCtx = true for inheriting parentView context, or to a function, for specifying other context New 'tag argDefault' feature: Tag definition can include: tag.argDefault: false - which prevents the first arg defaulting to current data New 'tag onUpdate: false' feature: Tag definition can include: tag.onUpdate: false - which is equivalent to an onUpdate handler which does nothing but returns false, so tag does not rerender when bound args or props update - Major update for jQuery UI widget-based tag controls library: Extensive new jQueryUI widget controls support and accompanying samples/documentation: http://www.jsviews.com/#download/jqueryui-tagcontrols http://www.jsviews.com/#samples/tag-controls/jqui - New lateRender=true feature: set lateRender=true on any tag, to make the tag render only after completing the data-linking pass. Useful for using expressions such as #childTags('myTag') in data-link expressions. See tests: http://www.jsviews.com/test/unit-tests-jsviews.html?testId=6be4ff95 and sample: http://www.jsviews.com/#samples/tag-controls/jqui/selectable@late-render - {^{on ...}} with no content allows setting width, height, id and class Perf improvements for sorting, moving, refreshing: - Much improved perf for {^{for myArray}}...{{/for}} when making observable changes to underlying array. When using $.observable(myArray).refresh(...) or $.observable(myArray).move(...), the resulting changes to the rendered items no longer result in deleting and re-rendering the moved items. Instead the rendered HTML elements are simply moved to their new positions under the parent element. Bug fixes: - https://github.com/BorisMoore/jsviews/issues/361: Breaking change (radiobuttons) - both radiogroup and directly data-linked radio buttons now behave identically. Neither of them coerce value to string - Bug with setting tag.depends=... (Breaking change: Note that setting fn.depends="myArray" updates for array changes as well as prop change. See: http://www.jsviews.com/test/unit-tests-jsviews.html?testId=303f5bfd - https://github.com/BorisMoore/jsviews/issues/354: Minor 'onError' bug - https://github.com/BorisMoore/jsviews/issues/360: Datepicker bug fix for correct behavior when data-linking to a value of type Date - Several minor bug fixes Unit tests: - Several additional unit tests Other minor breaking changes: - The undocumented lazyLink feature has been removed - The undocumented init: false feature for custom tags has been removed. --- .../04_form-elements_if-binding.html | 2 +- jquery.observable.js | 146 +- jquery.observable.min.js | 4 +- jquery.observable.min.js.map | 2 +- jquery.views.js | 1287 +++-- jquery.views.min.js | 4 +- jquery.views.min.js.map | 2 +- jsrender.js | 318 +- jsrender.min.js | 4 +- jsrender.min.js.map | 2 +- jsviews.js | 1743 ++++--- jsviews.min.js | 6 +- jsviews.min.js.map | 2 +- package.json | 4 +- test/browserify/bundles/1-bundle.js | 320 +- test/browserify/bundles/11-errors-bundle.js | 3354 +++++++------ test/browserify/bundles/12-nested-bundle.js | 320 +- test/browserify/bundles/2-bundle.js | 320 +- test/browserify/bundles/3-bundle.js | 320 +- test/browserify/bundles/4-bundle.js | 148 +- test/browserify/bundles/5-bundle.js | 148 +- test/browserify/bundles/6-bundle.js | 1755 ++++--- test/browserify/bundles/7-bundle.js | 1755 ++++--- test/browserify/bundles/8-bundle.js | 1747 ++++--- test/browserify/bundles/8B-bundle.js | 2065 ++++---- test/browserify/bundles/9-bundle.js | 1747 ++++--- test/unit-tests/tests-jsobservable.js | 306 +- .../tests-jsrender-amd-scriptloader.js | 4 - test/unit-tests/tests-jsrender-no-jquery.js | 259 +- test/unit-tests/tests-jsrender-with-jquery.js | 50 +- .../tests-jsviews-amd-scriptloader.js | 4 +- test/unit-tests/tests-jsviews.js | 4175 ++++++++++++----- 32 files changed, 13976 insertions(+), 8347 deletions(-) diff --git a/demos/step-by-step/04_form-elements_if-binding.html b/demos/step-by-step/04_form-elements_if-binding.html index 4d71c70..ae018f1 100644 --- a/demos/step-by-step/04_form-elements_if-binding.html +++ b/demos/step-by-step/04_form-elements_if-binding.html @@ -79,7 +79,7 @@

Ticket order form

orderDetails = { name: "", selectedMovie: "none", - selectedCurrency: 1, + selectedCurrency: "1", request: "" }, diff --git a/jquery.observable.js b/jquery.observable.js index 419e134..ad41029 100644 --- a/jquery.observable.js +++ b/jquery.observable.js @@ -1,9 +1,9 @@ -/*! JsObservable v0.9.83 (Beta): http://jsviews.com/#jsobservable */ +/*! JsObservable v0.9.84 (Beta): http://jsviews.com/#jsobservable */ /* * Subcomponent of JsViews * Data change events for data-linking * - * Copyright 2016, Boris Moore + * Copyright 2017, Boris Moore * Released under the MIT License. */ @@ -44,7 +44,7 @@ if (!$ || !$.fn) { throw "JsObservable requires jQuery"; // We require jQuery } -var versionNumber = "v0.9.83", +var versionNumber = "v0.9.84", $observe, $observable, $views = $.views = @@ -120,7 +120,8 @@ if (!$.observe) { : data; }, - resolvePathObjects = function(paths, root, callback) { + dependsPaths = function(paths, root, callback) { + // Process depends = ... paths to resolve objects, and recursively process functions. paths = paths ? $isArray(paths) ? paths @@ -136,7 +137,7 @@ if (!$.observe) { for (i = 0; i < l; i++) { path = paths[i]; if ($isFunction(path)) { - out = out.concat(resolvePathObjects(path.call(root, root, callback), root)); + out = out.concat(dependsPaths(path.call(root, root, callback), root, callback)); continue; } else if ("" + path !== path) { root = nextObj = path; @@ -150,6 +151,10 @@ if (!$.observe) { } out.push(path); } + if (out.length) { + out.unshift({_ar: 1}); // Switch on allowArray, for depends paths. + out.push({_ar: -1}); + } return out; }, @@ -161,7 +166,7 @@ if (!$.observe) { delete cbBindingsStore[cbBindingsId]; // This binding collection is empty, so remove from store }, - onObservableChange = function(ev, eventArgs) { + onDataChange = function(ev, eventArgs) { function isOb(val) { return typeof val === OBJECT && (paths[0] || allowArray && $isArray(val)); } @@ -174,7 +179,7 @@ if (!$.observe) { ctx = ev.data, observeAll = ctx.observeAll, cb = ctx.cb, - allowArray = !cb.noArray, + allowArray = ctx.arOk, paths = ctx.paths, ns = ctx.ns; @@ -188,17 +193,17 @@ if (!$.observe) { parentObs = [ev.target].concat(observeAll.parents()); if (isOb(oldValue)) { - observe_apply(allowArray, ns, [oldValue], paths, cb, true, filter, [parentObs], allPath); // unobserve + observe_apply(undefined, ns, [oldValue], paths, cb, true, filter, [parentObs], allPath); // unobserve } if (isOb(value)) { - observe_apply(allowArray, ns, [value], paths, cb, undefined, filter, [parentObs], allPath); + observe_apply(undefined, ns, [value], paths, cb, undefined, filter, [parentObs], allPath); } } else { if (isOb(oldValue)) { // oldValue is an object, so unobserve - observe_apply(allowArray, ns, [oldValue], paths, cb, true); // unobserve + observe_apply(undefined, ns, [oldValue], paths, cb, true); // unobserve } if (isOb(value)) { // value is an object, so observe - observe_apply(allowArray, ns, [value], paths, cb); + observe_apply(undefined, ns, [value], paths, cb); } } ctx.cb(ev, eventArgs); @@ -262,6 +267,7 @@ if (!$.observe) { updatedTgt = undefined; cb.apply(this, arguments); // Observe this object (invoke the callback) } + wrappedCb._wrp = 1; var l, isObject, newAllPath, nextParentObs, updatedTgt, obId, notRemoving = !objMap || objMap.un || !unobserve; // true unless it is an observeAll call (not unobserveAll) and we are removing a listener (not adding one) @@ -329,7 +335,7 @@ if (!$.observe) { $unobserve = function() { [].push.call(arguments, true); // Add true as additional final argument - return $observe.apply(this, arguments); + return $observe.apply(undefined, arguments); }; $observe = function() { @@ -355,21 +361,22 @@ if (!$.observe) { data = events[el] && events[el].data; if (data && (off && data.ns !== initialNs // When observing, don't unbind dups unless they have the same namespace - || !off && data.ns === initialNs && data.cb && data.cb._cId === callback._cId)) - // When observing and doing array binding, don't bind dups if they have the same namespace (Dups can happen e.g. with {^{for people ~foo=people}}) + || !off && data.ns === initialNs && data.cb && data.cb._cId === callback._cId && (!callback._wrp || data.cb._wrp))) + // When observing and doing array binding, don't bind dups if they have the same namespace (Dups can happen e.g. with {^{for people ^~foo=people}}) { return; } } } if (unobserve || off) { - $(boundObOrArr).off(namespace, onObservableChange); + $(boundObOrArr).off(namespace, onDataChange); } else { evData = isArrayBinding ? {} : { fullPath: path, paths: pathStr ? [pathStr] : [], - prop: prop + prop: prop, + arOk: allowArray }; evData.ns = initialNs; evData.cb = callback; @@ -393,7 +400,7 @@ if (!$.observe) { filter: filter }; } - $(boundObOrArr).on(namespace, null, evData, onObservableChange); + $(boundObOrArr).on(namespace, null, evData, onDataChange); if (cbBindings) { // Add object to cbBindings cbBindings[$data(object).obId || $data(object, "obId", observeObjKey++)] = object; @@ -441,7 +448,8 @@ if (!$.observe) { function bindArray(arr, unbind, isArray, relPath) { if (allowArray) { - // This is a call to observe that does not come from observeAndBind (tag binding), so we allow arrayChange binding + // allowArray is 1 if this is a call to observe that does not come from observeAndBind (tag binding), or is from a `depends` path, + // so we allow arrayChange binding. Otherwise allowArray is zero. var prevObj = object, prevAllPath = allPath; @@ -516,12 +524,12 @@ if (!$.observe) { while (initNsArrLen--) { initialNs = initNsArr[initNsArrLen]; - if (root && (path = paths[0], !path || path + "" !== path)) { + if (root && !paths[0]) { if ($isArray(root)) { - bindArray(root, unobserve, true); - } else if (unobserve) { - // remove onObservableChange handlers that wrap that callback - observeOnOff(ns, ""); + bindArray(root, unobserve, true); // observe(array, handler) + } + if (unobserve) { + observeOnOff(ns, ""); // unobserve(objectOrArray[, handler]) } } if (unobserve && !l && !root) { // unobserve() - unobserves all @@ -532,7 +540,6 @@ if (!$.observe) { if ($isArray(object)) { bindArray(object, unobserve, unobserve); } else { - // remove onObservableChange handlers that wrap that callback observeOnOff(ns, ""); } } @@ -544,9 +551,13 @@ if (!$.observe) { if (path === "") { continue; } + if (path && path._ar) { + allowArray += path._ar; // Switch on allowArray for depends paths, and off, afterwards. + continue; + } if (path && path._cp) { // Contextual parameter - contextCb = $sub._gccb(path[0]); // getContextCb: Get context callback for the contextual view (where contextual param evaluated/assigned) - origRoot = root = path[0].data; // Contextual data + contextCb = $sub._gccb(path[0]); // getContextCb: Get context callback for the contextual view (where contextual param evaluated/assigned) + origRoot = root = path[0].data; // Contextual data path = path[1]; } object = root; @@ -585,7 +596,6 @@ if (!$.observe) { // This is a compiled function for binding to an object returned by a helper/data function. // Set current object on exprOb.ob, and get innerCb for updating the object innerCb = unobserve ? path.cb : getInnerCb(path); - innerCb.noArray = !allowArray; // innerCb._ctx = callback._ctx; Could pass context (e.g. linkCtx) for use in a depends = function() {} call, so depends is different for different linkCtx's innerCb._cId = callback._cId; // Set the same cbBindingsStore key as for callback, so when callback is disposed, disposal of innerCb happens too. @@ -600,8 +610,6 @@ if (!$.observe) { } path = origRoot; object = undefined; - } else { - object = path; // For top-level calls, objects in the paths array become the origRoot for subsequent paths. } } parts = [root = path]; @@ -664,23 +672,21 @@ if (!$.observe) { allPath += "." + prop; } prop = object[prop]; + if (!parts[0]) { + bindArray(prop, unobserve); // [un]observe(object, "arrayProperty") observes array changes on property of type array + } } if ($isFunction(prop)) { if (dep = prop.depends) { - // This is a computed observable. We will observe any declared dependencies - innerObserve([object], resolvePathObjects(dep, object, callback), callback, contextCb, unobserve); + // This is a computed observable. We will observe any declared dependencies. + // Pass {_ar: ...} objects to switch on allowArray, for depends paths, then return to contextual allowArray value + innerObserve([object], dependsPaths(dep, object, callback), callback, contextCb, unobserve); } break; } object = prop; - if (unobserve && object === root && (i>l-2 || paths[i+1] + "" !== paths[i+1])) { - // unobserve all handlers of object, if not followed by string path. - // e.g.$.unobserve(object1, object2, "path", object3) will unobserve all from object1 and object3, and just "path" listener from object2 - observeOnOff(ns, ""); - } } } - bindArray(object, unobserve); } } if (cbId) { @@ -692,9 +698,9 @@ if (!$.observe) { } var initialNs, - allowArray = this != false, // If this === false, this is a call from observeAndBind - doing binding of datalink expressions. We don't bind + allowArray = this == 1 ? 0 : 1, // If this == 1, this is a call from observeAndBind - doing binding of datalink expressions. We don't bind // arrayChange events in this scenario. Instead, {^{for}} and similar do specific arrayChange binding to the tagCtx.args[0] value, in onAfterLink. - // Note deliberately using this != false, rather than this !== false because of IE<10 bug- see jsviews/issues/237 + // Note deliberately using this == 1, rather than this === 1 because of IE<10 bug- see jsviews/issues/237 paths = slice.call(arguments), origRoot = paths[0]; @@ -719,23 +725,6 @@ if (!$.observe) { //========================== Initialize ========================== - $sub.getDeps = function() { - var args = arguments; - return function() { - var arg, dep, - deps = [], - l = args.length; - while (l--) { - arg = args[l--]; - dep = args[l]; - if (dep) { - deps = deps.concat($isFunction(dep) ? dep(arg, arg) : dep); - } - } - return deps; - }; - }; - $.observable = $observable; $observable._fltr = function(allPath, object, parentObs, filter) { if (filter && $isFunction(filter) @@ -824,25 +813,25 @@ if (!$.observe) { } } - if (property !== value || nonStrict && property != value) { // Optional non-strict equality, since serializeArray, and form-based editors can map numbers to strings, etc. + if ((property !== value || nonStrict && property != value) + // Optional non-strict equality, since serializeArray, and form-based editors can map numbers to strings, etc. // Date objects don't support != comparison. Treat as special case. - if (!(property instanceof Date) || property > value || property < value) { - if (setter) { - setter.call(leaf, value); //set - value = getter.call(leaf); //get updated value - } else if (removeProp = value === remove) { - if (property !== undefined) { - delete leaf[path]; - value = undefined; - } else { - path = undefined; // If value was already undefined, don't trigger handler for removeProp - } - } else if (path) { - leaf[path] = value; - } - if (path) { - this._trigger(leaf, {change: "set", path: path, value: value, oldValue: property, remove: removeProp}); + && (!(property instanceof Date && value instanceof Date) || property > value || property < value)) { + if (setter) { + setter.call(leaf, value); //set + value = getter.call(leaf); //get updated value + } else if (removeProp = value === remove) { + if (property !== undefined) { + delete leaf[path]; + value = undefined; + } else { + path = undefined; // If value was already undefined, don't trigger handler for removeProp } + } else if (path) { + leaf[path] = value; + } + if (path) { + this._trigger(leaf, {change: "set", path: path, value: value, oldValue: property, remove: removeProp}); } } }, @@ -943,11 +932,13 @@ if (!$.observe) { newIndex = _data.length; } splice.apply(_data, [newIndex, 0].concat(items)); //re-insert - this._trigger({change: "move", oldIndex: oldIndex, index: newIndex, items: items}, oldLength); + if (newIndex !== oldIndex) { + this._trigger({change: "move", oldIndex: oldIndex, index: newIndex, items: items}, oldLength); + } } }, - refresh: function(newItems, sort) { + refresh: function(newItems) { function insertAdded() { if (k) { self.insert(j-k, addedItems); // Not found in original array - so insert @@ -1005,7 +996,7 @@ if (!$.observe) { $_data = $([_data]); if (self._srt) { eventArgs.refresh = true; // We are sorting during refresh - } else if (length !== oldLength) { // We have finished sort operations during refresh + } else if (length !== oldLength) { // We have finished sort operations during refresh $_data.triggerHandler(propertyChangeStr, {change: "set", path: "length", value: length, oldValue: oldLength}); } $_data.triggerHandler(arrayChangeStr + (self._ns ? "." + /^\S+/.exec(self._ns)[0] : ""), eventArgs); // If white-space separated namespaces, use first one only @@ -1061,7 +1052,7 @@ if (!$.observe) { } }, map.srcFlt); } - if (mapDef.obsTgt ) { + if (mapDef.obsTgt) { $observable(map.tgt).observeAll(map.obt = function(ev, eventArgs) { if (!changing) { changing = true; @@ -1123,6 +1114,7 @@ if (!$.observe) { } : undefined; // In IE8 cannot do delete global._jsv }; + $sub._dp = dependsPaths; } return $; diff --git a/jquery.observable.min.js b/jquery.observable.min.js index d4138b8..723d4f4 100644 --- a/jquery.observable.min.js +++ b/jquery.observable.min.js @@ -1,3 +1,3 @@ -/*! JsObservable v0.9.83 (Beta): http://jsviews.com/#jsobservable */ -!function(t,e){var n=e.jQuery;"object"==typeof exports?module.exports=n?t(e,n):function(n){return t(e,n)}:"function"==typeof define&&define.amd?define(["jquery"],function(n){return t(e,n)}):t(e,!1)}(function(t,e){"use strict";var n=e===!1;if(e=e||t.jQuery,!e||!e.fn)throw"JsObservable requires jQuery";var r,i,o="v0.9.83",s=e.views=e.views||n&&t.jsrender&&jsrender.views||{jsviews:o,sub:{settings:{}},settings:{advanced:function(t){return l=c.advanced=c.advanced||{_jsv:!0},t?("_jsv"in t&&(l._jsv=t._jsv),a.advSet(),s.settings):l}}},a=s.sub,c=a.settings,l=c.advanced,f=e.isFunction,u=e.expando,p=e.isArray,d="object";if(!e.observe){var h=e.event.special,v=[].slice,g=[].splice,_=[].concat,b=parseInt,y=/\S+/g,m=a.propChng=a.propChng||"propertyChange",I=a.arrChng=a.arrChng||"arrayChange",j={},A=m+".observe",w=1,x=1,F=1,P=e.hasData,S=e.data,C={},T=function(t){return t._cId=t._cId||".obs"+x++},k=function(t,e){return this._data=e,this._ns=t,this},O=function(t,e){return this._data=e,this._ns=t,this},V=function(t){return p(t)?[t]:t},D=function(t,e,n){t=t?p(t)?t:[t]:[];var r,i,o=e,s=o,a=t&&t.length,c=[];for(r=0;rat-2||rt[h+1]+""!==rt[h+1])&&o(nt,"")}l(st,M)}}return J&&H(U,J),{cbId:J,bnd:U,s:j}}}var n,r=0!=this,o=v.call(arguments),s=o[0];return s+""===s&&r&&(n=s,o.shift(),s=o[0]),t.apply(1,o)},i=function(t,e){return 1===arguments.length&&(e=t,t=""),p(e)?new O(t,e):new k(t,e)},a.getDeps=function(){var t=arguments;return function(){for(var e,n,r=[],i=t.length;i--;)e=t[i--],n=t[i],n&&(r=r.concat(f(n)?n(e,e):n));return r}},e.observable=i,i._fltr=function(t,e,n,r){if(!r||!f(r)||r(t,e,n))return e=f(e)?e.set&&e.call(n[0]):e,typeof e===d&&e},i.Object=k,i.Array=O,e.observe=i.observe=r,e.unobserve=i.unobserve=E,i._apply=q,k.prototype={_data:null,observeAll:M,unobserveAll:B,data:function(){return this._data},setProperty:function(t,e,n){t=t||"";var r,i,o,s=t+""!==t,a=this,c=a._data;if(c)if(s)if(n=e,p(t))for(r=t.length;r--;)i=t[r],a.setProperty(i.name,i.value,void 0===n||n);else for(r in t)a.setProperty(r,t[r],n);else if(t!==u){for(o=t.split(/[.^]/);c&&o.length>1;)c=c[o.shift()];c&&a._setProperty(c,o[0],e,n)}return a},removeProperty:function(t){return this.setProperty(t,C),this},_setProperty:function(t,e,n,r){var i,o,s,a=e?t[e]:t;f(a)&&a.set&&(t=t._wrp||t,o=a,i=o.set===!0?o:o.set,a=o.call(t)),(a!==n||r&&a!=n)&&(!(a instanceof Date)||a>n||a-1&&(e=p(e)?e:[e],e.length&&this._insert(t,e)),this},_insert:function(t,e){var n=this._data,r=n.length;t>r&&(t=r),g.apply(n,[t,0].concat(e)),this._trigger({change:"insert",index:t,items:e},r)},remove:function(t,e){var n,r=this._data;return void 0===t&&(t=r.length-1),t=b(t),e=e?b(e):0===e?0:1,e>0&&t>-1&&(n=r.slice(t,t+e),(e=n.length)&&this._remove(t,e,n)),this},_remove:function(t,e,n){var r=this._data,i=r.length;r.splice(t,e),this._trigger({change:"remove",index:t,items:n},i)},move:function(t,e,n){return n=n?b(n):0===n?0:1,t=b(t),e=b(e),n>0&&t>-1&&e>-1&&t!==e&&this._move(t,e,n),this},_move:function(t,e,n){var r,i=this._data,o=i.length,s=t+n-o;s>0&&(n-=s),n&&(r=i.splice(t,n),e>i.length&&(e=i.length),g.apply(i,[e,0].concat(r)),this._trigger({change:"move",oldIndex:t,index:e,items:r},o))},refresh:function(t,e){function n(){o&&(c.insert(i-o,l),d+=o,r+=o,o=0,l=[])}var r,i,o,s,a,c=this,l=[],f=c._data,u=f.slice(),p=f.length,d=p,h=t.length;for(c._srt=!0,i=o=0;ii&&c.remove(i,d-i),c._srt=void 0,c._trigger({change:"refresh",oldItems:u},p),c},_trigger:function(t,n){var r=this,i=r._data,o=i.length,s=e([i]);r._srt?t.refresh=!0:o!==n&&s.triggerHandler(m,{change:"set",path:"length",value:o,oldValue:n}),s.triggerHandler(I+(r._ns?"."+/^\S+/.exec(r._ns)[0]:""),t)}},h[m]=h[I]={remove:function(t){var n,r,i,o,s,a=t.data;if(a&&(a.off=!0,a=a.cb)&&(n=j[a._cId])){for(i=e._data(this).events[t.type],o=i.length;o--&&!r;)r=(s=i[o].data)&&s.cb&&s.cb._cId===a._cId;r||(delete n[S(this).obId],H(n,a._cId))}}},s.map=function(t){function n(e,n,r,o){var s,a=this;this.src&&this.unmap(),typeof e===d&&(a.src=e,a.tgt=r||a.tgt||[],a.options=n||a.options,a.update(),o||(t.obsSrc&&i(a.src).observeAll(a.obs=function(e,n){s||(s=!0,t.obsSrc(a,e,n),s=void 0)},a.srcFlt),t.obsTgt&&i(a.tgt).observeAll(a.obt=function(e,n){s||(s=!0,t.obsTgt(a,e,n),s=void 0)},a.tgtFlt)))}return f(t)&&(t={getTgt:t}),t.baseMap&&(t=e.extend({},t.baseMap,t)),t.map=function(t,e,r,i){return new n(t,e,r,i)},(n.prototype={srcFlt:t.srcFlt||z,tgtFlt:t.tgtFlt||z,update:function(e){var n=this;i(n.tgt).refresh(t.getTgt(n.src,n.options=e||n.options))},unmap:function(){var t=this;t.src&&(t.obs&&i(t.src).unobserveAll(t.obs,t.srcFlt),t.obt&&i(t.tgt).unobserveAll(t.obt,t.tgtFlt),t.src=void 0)},map:n,_def:t}).constructor=n,t},a.advSet=function(){a._gccb=this._gccb,t._jsv=c.advanced._jsv?{cbBindings:j}:void 0}}return e},window); +/*! JsObservable v0.9.84 (Beta): http://jsviews.com/#jsobservable */ +!function(t,e){var n=e.jQuery;"object"==typeof exports?module.exports=n?t(e,n):function(n){return t(e,n)}:"function"==typeof define&&define.amd?define(["jquery"],function(n){return t(e,n)}):t(e,!1)}(function(t,e){"use strict";var n=e===!1;if(e=e||t.jQuery,!e||!e.fn)throw"JsObservable requires jQuery";var r,i,o="v0.9.84",s=e.views=e.views||n&&t.jsrender&&jsrender.views||{jsviews:o,sub:{settings:{}},settings:{advanced:function(t){return l=c.advanced=c.advanced||{_jsv:!0},t?("_jsv"in t&&(l._jsv=t._jsv),a.advSet(),s.settings):l}}},a=s.sub,c=a.settings,l=c.advanced,f=e.isFunction,u=e.expando,p=e.isArray,d="object";if(!e.observe){var h=e.event.special,v=[].slice,g=[].splice,_=[].concat,b=parseInt,y=/\S+/g,m=a.propChng=a.propChng||"propertyChange",I=a.arrChng=a.arrChng||"arrayChange",j={},w=m+".observe",A=1,x=1,F=1,P=e.hasData,S=e.data,k={},C=function(t){return t._cId=t._cId||".obs"+x++},O=function(t,e){return this._data=e,this._ns=t,this},T=function(t,e){return this._data=e,this._ns=t,this},V=function(t){return p(t)?[t]:t},D=function(t,e,n){t=t?p(t)?t:[t]:[];var r,i,o=e,s=o,a=t&&t.length,c=[];for(r=0;r1;)c=c[o.shift()];c&&a._setProperty(c,o[0],e,n)}return a},removeProperty:function(t){return this.setProperty(t,k),this},_setProperty:function(t,e,n,r){var i,o,s,a=e?t[e]:t;f(a)&&a.set&&(t=t._wrp||t,o=a,i=o.set===!0?o:o.set,a=o.call(t)),(a!==n||r&&a!=n)&&(!(a instanceof Date&&n instanceof Date)||a>n||a-1&&(e=p(e)?e:[e],e.length&&this._insert(t,e)),this},_insert:function(t,e){var n=this._data,r=n.length;t>r&&(t=r),g.apply(n,[t,0].concat(e)),this._trigger({change:"insert",index:t,items:e},r)},remove:function(t,e){var n,r=this._data;return void 0===t&&(t=r.length-1),t=b(t),e=e?b(e):0===e?0:1,e>0&&t>-1&&(n=r.slice(t,t+e),(e=n.length)&&this._remove(t,e,n)),this},_remove:function(t,e,n){var r=this._data,i=r.length;r.splice(t,e),this._trigger({change:"remove",index:t,items:n},i)},move:function(t,e,n){return n=n?b(n):0===n?0:1,t=b(t),e=b(e),n>0&&t>-1&&e>-1&&t!==e&&this._move(t,e,n),this},_move:function(t,e,n){var r,i=this._data,o=i.length,s=t+n-o;s>0&&(n-=s),n&&(r=i.splice(t,n),e>i.length&&(e=i.length),g.apply(i,[e,0].concat(r)),e!==t&&this._trigger({change:"move",oldIndex:t,index:e,items:r},o))},refresh:function(t){function e(){i&&(a.insert(r-i,c),p+=i,n+=i,i=0,c=[])}var n,r,i,o,s,a=this,c=[],l=a._data,f=l.slice(),u=l.length,p=u,d=t.length;for(a._srt=!0,r=i=0;rr&&a.remove(r,p-r),a._srt=void 0,a._trigger({change:"refresh",oldItems:f},u),a},_trigger:function(t,n){var r=this,i=r._data,o=i.length,s=e([i]);r._srt?t.refresh=!0:o!==n&&s.triggerHandler(m,{change:"set",path:"length",value:o,oldValue:n}),s.triggerHandler(I+(r._ns?"."+/^\S+/.exec(r._ns)[0]:""),t)}},h[m]=h[I]={remove:function(t){var n,r,i,o,s,a=t.data;if(a&&(a.off=!0,a=a.cb)&&(n=j[a._cId])){for(i=e._data(this).events[t.type],o=i.length;o--&&!r;)r=(s=i[o].data)&&s.cb&&s.cb._cId===a._cId;r||(delete n[S(this).obId],H(n,a._cId))}}},s.map=function(t){function n(e,n,r,o){var s,a=this;this.src&&this.unmap(),typeof e===d&&(a.src=e,a.tgt=r||a.tgt||[],a.options=n||a.options,a.update(),o||(t.obsSrc&&i(a.src).observeAll(a.obs=function(e,n){s||(s=!0,t.obsSrc(a,e,n),s=void 0)},a.srcFlt),t.obsTgt&&i(a.tgt).observeAll(a.obt=function(e,n){s||(s=!0,t.obsTgt(a,e,n),s=void 0)},a.tgtFlt)))}return f(t)&&(t={getTgt:t}),t.baseMap&&(t=e.extend({},t.baseMap,t)),t.map=function(t,e,r,i){return new n(t,e,r,i)},(n.prototype={srcFlt:t.srcFlt||z,tgtFlt:t.tgtFlt||z,update:function(e){var n=this;i(n.tgt).refresh(t.getTgt(n.src,n.options=e||n.options))},unmap:function(){var t=this;t.src&&(t.obs&&i(t.src).unobserveAll(t.obs,t.srcFlt),t.obt&&i(t.tgt).unobserveAll(t.obt,t.tgtFlt),t.src=void 0)},map:n,_def:t}).constructor=n,t},a.advSet=function(){a._gccb=this._gccb,t._jsv=c.advanced._jsv?{cbBindings:j}:void 0},a._dp=D}return e},window); //# sourceMappingURL=jquery.observable.min.js.map diff --git a/jquery.observable.min.js.map b/jquery.observable.min.js.map index e0f807f..a9e24a5 100644 --- a/jquery.observable.min.js.map +++ b/jquery.observable.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["jquery.observable.js"],"names":["factory","global","$","jQuery","exports","module","define","amd","setGlobals","fn","$observe","$observable","versionNumber","$views","views","jsrender","jsviews","sub","settings","advanced","value","$subSettingsAdvanced","$subSettings","_jsv","$sub","advSet","$isFunction","isFunction","$expando","expando","$isArray","isArray","OBJECT","observe","$eventSpecial","event","special","slice","splice","concat","PARSEINT","parseInt","rNotWhite","propertyChangeStr","propChng","arrayChangeStr","arrChng","cbBindingsStore","observeStr","observeObjKey","observeCbKey","observeInnerCbKey","$hasData","hasData","$data","data","remove","getCbKey","cb","_cId","ObjectObservable","ns","this","_data","_ns","ArrayObservable","wrapArray","resolvePathObjects","paths","root","callback","i","path","object","nextObj","l","length","out","call","push","removeCbBindings","cbBindings","cbBindingsId","onObservableChange","ev","eventArgs","isOb","val","allowArray","off","allPath","filter","parentObs","oldValue","ctx","observeAll","noArray","type","array","prop","_path","target","parents","observe_apply","undefined","args","apply","arguments","shift","$observeAll","unobserve","$unobserveAll","namespace","objMap","observeArrayItems","arr","unobs","newAllPath","filterAndObserveAll","obj","nestedArray","newObject","newParentObs","_fltr","nextParentObs","updatedTgt","unshift","wrappedCb","change","items","isObject","obId","notRemoving","un","shallowFilter","indexOf","$unobserve","innerObserve","observeOnOff","pathStr","isArrayBinding","j","evData","obIdExpando","boundObOrArr","prntObs","allPth","initialNs","events","el","fullPath","replace","all","inArray","on","getInnerCb","exprOb","origRt","ob","contextCb","sb","newObj","bindArray","unbind","relPath","prevObj","prevAllPath","p","skip","parts","dep","cbId","inId","innerContextCb","depth","innerCb","initNsArr","initNsArrLen","lastArg","pop","_inId","match","_cp","_gccb","origRoot","split","join","bnd","prm","nodeType","observable","depends","s","getDeps","arg","deps","set","Object","Array","_apply","prototype","unobserveAll","setProperty","nonStrict","key","pair","multi","self","name","_setProperty","removeProperty","leaf","setter","getter","removeProp","property","_wrp","Date","_trigger","triggerHandler","exec","insert","index","_insert","oldLength","numToRemove","_remove","move","oldIndex","newIndex","numToMove","_move","excess","refresh","newItems","sort","insertAdded","k","addedItems","dataLength","newItem","num","oldItems","newLength","_srt","$_data","handleObj","found","map","mapDef","Map","source","options","unbound","changing","src","unmap","tgt","update","obsSrc","obs","srcFlt","obsTgt","obt","tgtFlt","getTgt","baseMap","extend","_def","constructor","window"],"mappings":"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","file":"jquery.observable.min.js","sourcesContent":["/*! JsObservable v0.9.83 (Beta): http://jsviews.com/#jsobservable */\n/*\n * Subcomponent of JsViews\n * Data change events for data-linking\n *\n * Copyright 2016, Boris Moore\n * Released under the MIT License.\n */\n\n//jshint -W018, -W041\n\n(function(factory, global) {\n\t// global var is the this object, which is window when running in the usual browser environment\n\tvar $ = global.jQuery;\n\n\tif (typeof exports === \"object\") { // CommonJS e.g. Browserify\n\t\tmodule.exports = $\n\t\t\t? factory(global, $)\n\t\t\t: function($) { // If no global jQuery, take jQuery passed as parameter: require(\"jsobservable\")(jQuery)\n\t\t\t\treturn factory(global, $);\n\t\t\t};\n\t} else if (typeof define === \"function\" && define.amd) { // AMD script loader, e.g. RequireJS\n\t\tdefine([\"jquery\"], function($) {\n\t\t\treturn factory(global, $); // Require jQuery\n\t\t});\n\t} else { // Browser using plain ', @@ -112,7 +113,7 @@ var activeBody, rTagDatalink, $view, $viewsLinkAttr, linkViewsSel, wrapMap, view html: HTML, text: "text" }, - valueBinding = {from: "value", to: "value"}, + valueBinding = {from: VALUE, to: VALUE}, isCleanCall = 0, oldCleanData = $.cleanData, oldJsvDelimiters = $viewsSettings.delimiters, @@ -152,63 +153,81 @@ $observe = $observable.observe; // Event handlers //=============== -function elemChangeHandler(ev, params, sourceValue) { - var setter, cancel, fromAttr, linkCtx, cvtBack, cnvtName, target, $source, view, binding, - oldLinkCtx, onBeforeChange, onAfterChange, tag, to, eventArgs, exprOb, contextCb, - source = ev.target, - bindings = source._jsvBnd; - - // _jsvBnd is a string with the syntax: "&bindingId1&bindingId2" - while (binding = rSplitBindings.exec(bindings)) { - if (binding = bindingStore[binding[1]]) { - if (to = binding.to) { - // The binding has a 'to' field, which is of the form [[targetObject, toPath], cvtBack] - linkCtx = binding.linkCtx; - view = linkCtx.view; - tag = linkCtx.tag || view.tag; - $source = $(source); - onBeforeChange = view.hlp(onBeforeChangeStr); // TODO Can we optimize this and other instances of same? - onAfterChange = view.hlp(onAfterChangeStr); // TODO Can we optimize this and other instances of same - fromAttr = defaultAttr(source); - setter = fnSetters[fromAttr]; - if (sourceValue === undefined) { - sourceValue = $isFunction(fromAttr) - ? fromAttr(source) - : setter - ? $source[setter]() - : $source.attr(fromAttr); - } - cnvtName = to[1]; - to = to[0]; // [object, path] - to = to + "" === to ? [linkCtx.data, to] : to; - if (cnvtName) { - if ($isFunction(cnvtName)) { - cvtBack = cnvtName; - } else { - cvtBack = view.getRsc("converters", cnvtName); - } - } - if (linkCtx.elem.nodeName === "SELECT") { - linkCtx.elem._jsvSel = sourceValue = sourceValue || (linkCtx.elem.multiple ? [] : sourceValue); - // data-link to string or (multiselect) array of strings + if (sourceElem.multiple && sourceValues[0] === null) { + // Case where sourceValues was undefined, and set to [null] by $source[setter]() above + sourceValues = [[]]; } + sourceElem._jsvSel = sourceValues; + } + origVals = sourceValues; + if (cvtBack) { + sourceValues = cvtBack.apply(tag, sourceValues); + sourceValues = tos.length>1 ? sourceValues : [sourceValues]; + } - // Set linkCtx on view, dynamically, just during this handler call - oldLinkCtx = view.linkCtx; - view.linkCtx = linkCtx; + // Set linkCtx on view, dynamically, just during this handler call + oldLinkCtx = view.linkCtx; + view.linkCtx = linkCtx; + sourceElem._jsvChg = true; // Set 'changing' marker to prevent tag change event triggering its own refresh + l = tos.length; + while (l--) { + to = tos[l]; + to = to + "" === to ? [linkCtx.data, to] : to; // [object, path] + target = to[0]; + tcpTag = to.tag; // If this is a tag contextual parameter - the owner tag + sourceValue = (to[1] === "_jsvCp" + ? origVals // If to target is for tag contextual parameter set to static expression (or uninitialized) - we are + // binding to tag.ctx.foo.data._jsvCp - and we use original values, without applying cvtBack converter + : sourceValues // Otherwise use the converted value + )[l]; eventArgs = { change: "change", - oldValue: linkCtx._val, + data: tcpTag || target, // For tag contextual parameter, this is the tag + path: to[1] || to.ind, // For tag contextual parameter, this is the index of the parameter in tag.bindTo value: sourceValue }; if ((!onBeforeChange || !(cancel = onBeforeChange.call(linkCtx, ev, eventArgs) === false)) && - (!tag || !tag.onBeforeChange || !(cancel = tag.onBeforeChange(ev, eventArgs) === false)) && - sourceValue !== undefined) { - target = to[0]; // [object, path] - if (sourceValue !== undefined && target) { + (!tag || !tag.onBeforeChange || !(cancel = tag.onBeforeChange(ev, eventArgs) === false))) { + + if (tcpTag) { + // The source is a tag contextual parameter (linkedCtxParam: [..., "~myTagParam", ...], which is updating + sourceValues = []; + sourceValues[to.ind] = sourceValue; + tcpTag.update.apply(tcpTag, sourceValues); + tcpTag.setValue.apply(tcpTag, sourceValues); + } else if (sourceValue !== undefined && target) { + if (tcpTag = ev && (sourceEl = ev.target)._jsvInd === l && sourceEl._jsvLkEl) { + // The source is a tag linkedElem (linkedElement: [..., "elemSelector", ...], which is updating + sourceValues = []; + sourceValues[l] = origVals[l]; + tcpTag.setValue.apply(tcpTag, sourceValues); + } if (target._jsv) { contextCb = linkCtx._ctxCb; // This is a computed value exprOb = target; @@ -222,31 +241,50 @@ function elemChangeHandler(ev, params, sourceValue) { exprOb = exprOb.sb; } } - if (tag) { - tag._.chging = true; // marker to prevent tag change event triggering its own refresh - } $observable(target).setProperty(to[1], sourceValue); // 2way binding change event - observably updating bound object if (onAfterChange) { onAfterChange.call(linkCtx, ev, eventArgs); } - if (tag) { - if (tag.onAfterChange) { - tag.onAfterChange(ev, eventArgs); - } - tag._.chging = undefined; // clear the marker - } - linkCtx._val = sourceValue; + } + if (tag && tag.onAfterChange) { + tag.onAfterChange(ev, eventArgs); } } - view.linkCtx = oldLinkCtx; } + sourceElem._jsvChg = undefined; // Clear marker + view.linkCtx = oldLinkCtx; } } } -function propertyChangeHandler(ev, eventArgs, linkFn) { +function onElemChange(ev) { + var bindId, + source = ev.target, + fromAttr = defaultAttr(source), + setter = fnSetters[fromAttr], + sourceValues = []; + + if (!source._jsvTr || ev.delegateTarget !== activeBody) { // If this is an element using trigger, ignore event delegated (bubbled) to activeBody + sourceValues[source._jsvInd || 0] = $isFunction(fromAttr) + ? fromAttr(source) + : (source = $(source), setter + ? source[setter]() + : source.attr(fromAttr)); + + ev.target._jsvChg = true; // // Set 'changing' marker to prevent linkedElem change event triggering its own refresh + while (bindId = rSplitBindings.exec(ev.target._jsvBnd)) { + // _jsvBnd is a string with the syntax: "&bindingId1&bindingId2" + updateBindToData(bindId[1], sourceValues, ev); + } + ev.target._jsvChg = undefined; // Clear marker + } +} + +function onDataLinkedTagChange(ev, eventArgs) { + // Update or initial rendering of any tag (including {{:}}) whether inline or data-linked element. var attr, sourceValue, noUpdate, forceUpdate, hasError, onError, linkCtx = this, + linkFn = linkCtx.fn, tag = linkCtx.tag, source = linkCtx.data, target = linkCtx.elem, @@ -261,78 +299,77 @@ function propertyChangeHandler(ev, eventArgs, linkFn) { if (parentElem && (!onEvent || !(eventArgs && onEvent.call(linkCtx, ev, eventArgs) === false)) // If data changed, the ev.data is set to be the path. Use that to filter the handler action... - && !(eventArgs && ev.data.prop !== "*" && ev.data.prop !== eventArgs.path)) { + && (!eventArgs || ev.data.prop === "*" || ev.data.prop === eventArgs.path)) { if (eventArgs) { linkCtx.eventArgs = eventArgs; } if (eventArgs || linkCtx._toLk) { // If eventArgs are defined, this is a data update - // Otherwise this is the initial data-link rendering call. Bind on this the first time it get called + // Otherwise this is the initial data-link rendering call. Bind on this the first time it gets called linkCtx._toLk = 0; // Remove flag to skip unneccessary rebinding next time if (linkFn._er) { // data-link="exprUsingTagOrCvt with onerror=..." - e.g. {tag ... {cvt:... {:... convert='cvt' try { - sourceValue = linkFn(source, view); + sourceValue = linkFn(source, view, $sub); // Compiled link expression + // For data-link="{:xxx}" with no cvt or cvtBk returns value. Otherwise returns tagCtxs } catch (e) { hasError = linkFn._er; onError = onRenderError(e,view,(new Function("data,view", "return " + hasError + ";"))(source, view)); sourceValue = [{props: {}, args: [onError]}]; } } else { - sourceValue = linkFn(source, view, $sub); + sourceValue = linkFn(source, view, $sub); // Compiled link expression + // For data-link="{:xxx}" with no cvt or cvtBk returns value. Otherwise returns tagCtxs } // Compiled link expression for linkTag: return value for data-link="{:xxx}" with no cvt or cvtBk, otherwise tagCtx or tagCtxs - - attr = getTargetVal(sourceValue, linkCtx, tag = linkCtx.tag, - linkCtx.attr || defaultAttr(target, true, cvt !== undefined) - ); - + attr = tag && tag.attr || linkCtx.attr || defaultAttr(target, true, cvt !== undefined); + if (attr === VALUE && (tag && tag.parentElem || linkCtx.elem).type === CHECKBOX) { + attr = CHECKED; + } + // For {{: ...}} without a convert or convertBack, (tag and linkFn._tag undefined) we already have the sourceValue, and we are done if (tag) { // Existing tag instance forceUpdate = hasError || tag._er; // If the new tagCtxs hasError or the previous tagCtxs had error, then force update sourceValue = sourceValue[0] ? sourceValue : [sourceValue]; - noUpdate = !forceUpdate && eventArgs && tag.onUpdate && tag.onUpdate(ev, eventArgs, sourceValue) === false; - mergeCtxs(tag, sourceValue, forceUpdate); + // Tag will update unless tag.onUpdate is false or is a function which returns false + noUpdate = !forceUpdate && (tag.onUpdate === false || eventArgs && $isFunction(tag.onUpdate) && tag.onUpdate(ev, eventArgs, sourceValue) === false); + + mergeCtxs(tag, sourceValue, forceUpdate); // Merge new tagCtxs (in sourceValue var) with current tagCtxs on tag instance - if (noUpdate || attr === NONE) { - // onUpdate returned false, or attr === "none", or this is an update coming from the tag's own change event - // - so don't refresh the tag: we just use the new tagCtxs merged from the sourceValue, - // (which may optionally have been modifed in onUpdate()...) and then bind, and we are done + if (target._jsvChg && (attr === HTML || attr === VALUE) || noUpdate || attr === NONE) { + // This is an update coming from the tag itself (linkedElem change), or else onUpdate returned false, or attr === "none" callAfterLink(tag, ev, eventArgs); - observeAndBind(linkCtx, source, target); + if (!target._jsvChg) { + // onUpdate returned false, or attr === "none" - so don't refresh the tag: we just use the new tagCtxs merged + // from the sourceValue (which may optionally have been modifed in onUpdate()...) and then bind, and we are done + observeAndBind(linkCtx, source, target); + } view.linkCtx = oldLinkCtx; return; } - if (tag._.chging) { - return; - } if (tag.onUnbind) { tag.onUnbind(tag.tagCtx, linkCtx, tag.ctx, ev, eventArgs); } sourceValue = tag.tagName === ":" // Call convertVal if it is a {{cvt:...}} - otherwise call renderTag - ? $sub._cnvt(tag.cvt, view, sourceValue[0]) - : $sub._tag(tag, view, view.tmpl, sourceValue, true, onError); + ? $sub._cnvt(tag.cvt, view, sourceValue[0]) // convertVal() // convertVal(converter, view, tagCtx, onError) + : $sub._tag(tag, view, view.tmpl, sourceValue, true, onError); // renderTag(tagName, parentView, tmpl, tagCtxs, isUpdate, onError) } else if (linkFn._tag) { - // For {{: ...}} without a convert or convertBack, we already have the sourceValue, and we are done // For {{: ...}} with either cvt or cvtBack we call convertVal to get the sourceValue and instantiate the tag // If cvt is undefined then this is a tag, and we call renderTag to get the rendered content and instantiate the tag cvt = cvt === "" ? TRUE : cvt; // If there is a cvtBack but no cvt, set cvt to "true" sourceValue = cvt // Call convertVal if it is a {{cvt:...}} - otherwise call renderTag - ? $sub._cnvt(cvt, view, sourceValue[0] || sourceValue) // convertVal - : $sub._tag(linkFn._tag, view, view.tmpl, sourceValue, true, onError); // renderTag + ? $sub._cnvt(cvt, view, sourceValue[0] || sourceValue) // convertVal(converter, view, tagCtx, onError) + : $sub._tag(linkFn._tag, view, view.tmpl, sourceValue, true, onError); // renderTag(tagName, parentView, tmpl, tagCtxs, isUpdate, onError) - addLinkMethods(tag = linkCtx.tag, true); // In both convertVal and renderTag we have instantiated a tag + addLinkMethods(tag = linkCtx.tag); // In both convertVal and renderTag we have instantiated a tag attr = linkCtx.attr || attr; // linkCtx.attr may have been set to tag.attr during tag instantiation in renderTag } - - if (updateContent(sourceValue, linkCtx, attr, tag) - && eventArgs - && (onEvent = view.hlp(onAfterChangeStr))) { + if (updateContent(sourceValue, linkCtx, attr, tag) && eventArgs && (onEvent = view.hlp(onAfterChangeStr))) { onEvent.call(linkCtx, ev, eventArgs); } linkCtx._noUpd = 0; // For data-link="^{...}" remove _noUpd flag so updates on subsequent calls @@ -350,57 +387,18 @@ function propertyChangeHandler(ev, eventArgs, linkFn) { } } -function getTargetVal(sourceValue, linkCtx, tag, attr) { - var currentValue, setter, css, $target, - target = tag && tag.parentElem || linkCtx.elem; - - if (sourceValue !== undefined) { - $target = $(target); - attr = tag && tag.attr || attr; - if ($isFunction(sourceValue)) { - error(linkCtx.expr + ": missing parens"); - } - - if (css = /^css-/.test(attr) && attr.slice(4)) { - currentValue = $.style(target, css); - if (+sourceValue === sourceValue) { - // Optimization for perf on integer values - e.g. css-width{:width+'px'} - currentValue = parseInt(currentValue); - } - } else if (attr !== "link") { // attr === "link" is for tag controls which do data binding but have no rendered output or target - if (attr === "value") { - if (target.type === CHECKBOX) { - currentValue = $target.prop(attr = CHECKED); - } - } else if (attr === RADIO) { - if (target.value === ("" + sourceValue)) { - currentValue = $target.prop(CHECKED); - } else { - return attr; - } - } - - if (currentValue === undefined) { - setter = fnSetters[attr]; - currentValue = setter ? $target[setter]() : $target.attr(attr); - } - } - linkCtx._val = currentValue; - } - return attr; -} - function setDefer(elem, value) { - elem._df = value; // Use both an expando and an attribute to track defered tokens. Attribute is needed for querySelectorAll for getViewInfos (childTags) + elem._df = value; // Use both an expando and an attribute to track deferred tokens. Attribute is needed for querySelectorAll for getViewInfos (childTags) elem[(value ? "set" : "remove") + "Attribute"](deferAttr, ""); } function updateContent(sourceValue, linkCtx, attr, tag) { - // When called for a tag, either in tag.refresh() or propertyChangeHandler(), returns a promise (and supports async) - // When called (in propertyChangeHandler) for target HTML returns true - // When called (in propertyChangeHandler) for other targets returns boolean for "changed" - var setter, prevNode, nextNode, promise, nodesToRemove, useProp, tokens, id, openIndex, closeIndex, testElem, nodeName, cStyle, jsvSel, - renders = attr !== NONE && sourceValue !== undefined && !linkCtx._noUpd, // For data-link="^{...}", don't update the first time (no initial render) - e.g. to leave server rendered values. + // When called for a tag, either in tag.refresh() or onDataLinkedTagChange(), returns tag + // When called (in onDataLinkedTagChange) for target HTML returns true + // When called (in onDataLinkedTagChange) for other targets returns boolean for "changed" + var setter, prevNode, nextNode, late, nodesToRemove, useProp, tokens, id, openIndex, closeIndex, testElem, nodeName, cStyle, jsvSel, + renders = attr !== NONE && sourceValue !== undefined && !linkCtx._noUpd && !(linkCtx.elem._jsvChg && (attr === VALUE || attr === HTML)), + // For data-link="^{...}", don't update the first time (no initial render) - e.g. to leave server rendered values. source = linkCtx.data, target = tag && tag.parentElem || linkCtx.elem, targetParent = target.parentNode, @@ -408,8 +406,6 @@ function updateContent(sourceValue, linkCtx, attr, tag) { view = linkCtx.view, targetVal = linkCtx._val, oldLinkCtx = view.linkCtx, - // If not a tag we can use the ._val obtained from getTargetVal() - // and only update when the new value (sourceValue) has changed from the previous one change = tag; if (tag) { @@ -420,6 +416,7 @@ function updateContent(sourceValue, linkCtx, attr, tag) { nextNode = tag._nxt; } if (!renders) { + linkCtx._val = sourceValue; return; } @@ -480,14 +477,14 @@ function updateContent(sourceValue, linkCtx, attr, tag) { // useProp = true; attr = CHECKED; - sourceValue = target.value === ("" + sourceValue); + sourceValue = target.value === sourceValue; // If the data value corresponds to the value attribute of this radio button input, set the checked property to true // Otherwise set the checked property to false } else if (attr === "selected" || attr === "disabled" || attr === "multiple" || attr === "readonly") { sourceValue = (sourceValue && sourceValue !== "false") ? attr : null; // Use attr, not prop, so when the options (for example) are changed dynamically, but include the previously selected value, // they will still be selected after the change - } else if (attr === "value" && target.nodeName === "SELECT") { + } else if (attr === VALUE && target.nodeName === "SELECT") { target._jsvSel = $isArray(sourceValue) ? sourceValue : "" + sourceValue; // If not array, coerce to string @@ -499,6 +496,7 @@ function updateContent(sourceValue, linkCtx, attr, tag) { view.linkCtx = linkCtx; if (tag && tag._.inline) { nodesToRemove = tag.nodes(true); + bindingStore[tag._tgId].to = undefined; if (tag._elCnt) { if (prevNode && prevNode !== nextNode) { // This prevNode will be removed from the DOM, so transfer the view tokens on prevNode to nextNode of this 'viewToRefresh' @@ -527,15 +525,13 @@ function updateContent(sourceValue, linkCtx, attr, tag) { $(nodesToRemove).remove(); // Note if !tag._elCnt removing the nodesToRemove will process and dispose view and tag bindings contained within the updated tag control // Insert and link new content - promise = view.link(view.data, target, prevNode, nextNode, sourceValue, tag && {tag: tag._tgId, lazyLink: tag.tagCtx.props.lazyLink}); + late = view.link(view.data, target, prevNode, nextNode, sourceValue, tag && {tag: tag._tgId}); } else { // data-linked value targeting innerHTML: data-link="html{:expr}" or contenteditable="true" renders = renders && targetVal !== sourceValue; if (renders) { $target.empty(); - } - if (renders) { - promise = view.link(source, target, prevNode, nextNode, sourceValue, tag && {tag: tag._tgId}); + late = view.link(source, target, prevNode, nextNode, sourceValue, tag && {tag: tag._tgId}); } } // Remove dynamically added linkCtx and ctx from view @@ -555,7 +551,7 @@ function updateContent(sourceValue, linkCtx, attr, tag) { } if ((jsvSel = targetParent._jsvSel) // Setting value of