diff --git a/README.md b/README.md
index ef2c953..f935914 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
Ractive.js sortable decorator plugin
====================================
-*Find more Ractive.js plugins at [ractivejs.org/plugins](http://ractivejs.org/plugins)*
+*Find more Ractive.js plugins at [docs.ractivejs.org/latest/plugins](http://docs.ractivejs.org/latest/plugins)*
[See the demo here.](http://ractivejs.github.io/Ractive-decorators-sortable/)
diff --git a/Ractive-decorators-sortable.js b/Ractive-decorators-sortable.js
index bfd8ad6..f511c5c 100644
--- a/Ractive-decorators-sortable.js
+++ b/Ractive-decorators-sortable.js
@@ -3,7 +3,7 @@
Ractive-decorators-sortable
===========================
- Version 0.1.0.
+ Version 0.2.0.
This plugin adds a 'sortable' decorator to Ractive, which enables
elements that correspond to array members to be re-ordered using
@@ -58,18 +58,18 @@
*/
-(function ( global, factory ) {
+var sortableDecorator = (function ( global, factory ) {
'use strict';
// Common JS (i.e. browserify) environment
if ( typeof module !== 'undefined' && module.exports && typeof require === 'function' ) {
- factory( require( 'Ractive' ) );
+ factory( require( 'ractive' ) );
}
// AMD?
else if ( typeof define === 'function' && define.amd ) {
- define([ 'Ractive' ], factory );
+ define([ 'ractive' ], factory );
}
// browser global
@@ -126,7 +126,7 @@
dragstartHandler = function ( event ) {
var storage = this._ractive, lastDotIndex;
- sourceKeypath = storage.keypath;
+ sourceKeypath = storage.keypath.str;
// this decorator only works with array members!
lastDotIndex = sourceKeypath.lastIndexOf( '.' );
@@ -156,7 +156,7 @@
return;
}
- targetKeypath = this._ractive.keypath;
+ targetKeypath = this._ractive.keypath.str;
// this decorator only works with array members!
lastDotIndex = targetKeypath.lastIndexOf( '.' );
@@ -173,13 +173,16 @@
return;
}
+ // add droptarget class to hovered element
+ this.classList.add( sortable.targetClass );
+
// if it's the same index, add droptarget class then abort
if ( targetIndex === sourceIndex ) {
- this.classList.add( sortable.targetClass );
return;
}
- array = ractive.get( sourceArray );
+ // cloning array avoids issues on some generated arrays (TODO investigate)
+ array = ractive.get( sourceArray ).slice();
// remove source from array
source = array.splice( sourceIndex, 1 )[0];
@@ -189,6 +192,9 @@
// add source back to array in new location
array.splice( sourceIndex, 0, source );
+
+ // replace source with updated order from cloned-array (due to .slice())
+ ractive.set( sourceArray, array );
};
removeTargetClass = function () {
@@ -198,5 +204,11 @@
preventDefault = function ( event ) { event.preventDefault(); };
Ractive.decorators.sortable = sortable;
-
-}));
\ No newline at end of file
+
+ return sortable;
+}));
+
+// Common JS (i.e. browserify) environment
+if ( typeof module !== 'undefined' && module.exports) {
+ module.exports = sortableDecorator;
+}
diff --git a/Ractive-decorators-sortable.min.js b/Ractive-decorators-sortable.min.js
index 90fa355..f0db60f 100644
--- a/Ractive-decorators-sortable.min.js
+++ b/Ractive-decorators-sortable.min.js
@@ -1 +1 @@
-!function(a,b){"use strict";if("undefined"!=typeof module&&module.exports&&"function"==typeof require)b(require("Ractive"));else if("function"==typeof define&&define.amd)define(["Ractive"],b);else{if(!a.Ractive)throw new Error("Could not find Ractive! It must be loaded before the Ractive-decorators-sortable plugin");b(a.Ractive)}}("undefined"!=typeof window?window:this,function(a){"use strict";var b,c,d,e,f,g,h,i,j,k;b=function(a){return a.draggable=!0,a.addEventListener("dragstart",g,!1),a.addEventListener("dragenter",h,!1),a.addEventListener("dragleave",i,!1),a.addEventListener("drop",i,!1),a.addEventListener("dragover",j,!1),{teardown:function(){a.removeEventListener("dragstart",g,!1),a.removeEventListener("dragenter",h,!1),a.removeEventListener("dragleave",i,!1),a.removeEventListener("drop",i,!1),a.removeEventListener("dragover",j,!1)}}},b.targetClass="droptarget",k="The sortable decorator only works with elements that correspond to array members",g=function(a){var b,g=this._ractive;if(d=g.keypath,b=d.lastIndexOf("."),-1===b)throw new Error(k);if(e=d.substr(0,b),f=+d.substring(b+1),isNaN(f))throw new Error(k);a.dataTransfer.setData("foo",!0),c=g.root},h=function(){var a,d,g,h,i,j;if(this._ractive.root===c){if(a=this._ractive.keypath,d=a.lastIndexOf("."),-1===d)throw new Error(k);if(g=a.substr(0,d),h=+a.substring(d+1),g===e){if(h===f)return this.classList.add(b.targetClass),void 0;i=c.get(e),j=i.splice(f,1)[0],f=h,i.splice(f,0,j)}}},i=function(){this.classList.remove(b.targetClass)},j=function(a){a.preventDefault()},a.decorators.sortable=b});
\ No newline at end of file
+var sortableDecorator=function(a,b){"use strict";if("undefined"!=typeof module&&module.exports&&"function"==typeof require)b(require("ractive"));else if("function"==typeof define&&define.amd)define(["ractive"],b);else{if(!a.Ractive)throw new Error("Could not find Ractive! It must be loaded before the Ractive-decorators-sortable plugin");b(a.Ractive)}}("undefined"!=typeof window?window:this,function(a){"use strict";var b,c,d,e,f,g,h,i,j,k;return b=function(a){return a.draggable=!0,a.addEventListener("dragstart",g,!1),a.addEventListener("dragenter",h,!1),a.addEventListener("dragleave",i,!1),a.addEventListener("drop",i,!1),a.addEventListener("dragover",j,!1),{teardown:function(){a.removeEventListener("dragstart",g,!1),a.removeEventListener("dragenter",h,!1),a.removeEventListener("dragleave",i,!1),a.removeEventListener("drop",i,!1),a.removeEventListener("dragover",j,!1)}}},b.targetClass="droptarget",k="The sortable decorator only works with elements that correspond to array members",g=function(a){var b,g=this._ractive;if(d=g.keypath.str,b=d.lastIndexOf("."),-1===b)throw new Error(k);if(e=d.substr(0,b),f=+d.substring(b+1),isNaN(f))throw new Error(k);a.dataTransfer.setData("foo",!0),c=g.root},h=function(){var a,d,g,h,i,j;if(this._ractive.root===c){if(a=this._ractive.keypath.str,d=a.lastIndexOf("."),-1===d)throw new Error(k);g=a.substr(0,d),h=+a.substring(d+1),g===e&&(this.classList.add(b.targetClass),h!==f&&(i=c.get(e).slice(),j=i.splice(f,1)[0],f=h,i.splice(f,0,j),c.set(e,i)))}},i=function(){this.classList.remove(b.targetClass)},j=function(a){a.preventDefault()},a.decorators.sortable=b,b});"undefined"!=typeof module&&module.exports&&(module.exports=sortableDecorator);
\ No newline at end of file
diff --git a/index.html b/index.html
index cc30046..7695a13 100644
--- a/index.html
+++ b/index.html
@@ -75,7 +75,7 @@
Ractive.js sortable decorator plugin
download: Ractive-decorators-sortable.js
- more plugins at ractivejs.org/plugins
+ more plugins at docs.ractivejs.org/latest/plugins
diff --git a/lib/Ractive-legacy.js b/lib/Ractive-legacy.js
index 8482370..bfc07cb 100644
--- a/lib/Ractive-legacy.js
+++ b/lib/Ractive-legacy.js
@@ -1,9339 +1,16618 @@
/*
+ Ractive.js v0.7.3
+ Sat Apr 25 2015 13:52:38 GMT-0400 (EDT) - commit da40f81c660ba2f09c45a09a9c20fdd34ee36d80
- Ractive - v0.3.9 - 2013-12-26
- ==============================================================
+ http://ractivejs.org
+ http://twitter.com/RactiveJS
- Next-generation DOM manipulation - http://ractivejs.org
- Follow @RactiveJS for updates
-
- --------------------------------------------------------------
+ Released under the MIT License.
+*/
- Copyright 2013 2013 Rich Harris and contributors
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ global.Ractive = factory()
+}(this, function () { 'use strict';
+
+ var TEMPLATE_VERSION = 3;
+
+ var defaultOptions = {
+
+ // render placement:
+ el: void 0,
+ append: false,
+
+ // template:
+ template: { v: TEMPLATE_VERSION, t: [] },
+
+ // parse: // TODO static delimiters?
+ preserveWhitespace: false,
+ sanitize: false,
+ stripComments: true,
+ delimiters: ["{{", "}}"],
+ tripleDelimiters: ["{{{", "}}}"],
+ interpolate: false,
+
+ // data & binding:
+ data: {},
+ computed: {},
+ magic: false,
+ modifyArrays: true,
+ adapt: [],
+ isolated: false,
+ twoway: true,
+ lazy: false,
+
+ // transitions:
+ noIntro: false,
+ transitionsEnabled: true,
+ complete: void 0,
+
+ // css:
+ css: null,
+ noCssTransform: false
+ };
+
+ var config_defaults = defaultOptions;
+
+ // These are a subset of the easing equations found at
+ // https://raw.github.com/danro/easing-js - license info
+ // follows:
+
+ // --------------------------------------------------
+ // easing.js v0.5.4
+ // Generic set of easing functions with AMD support
+ // https://github.com/danro/easing-js
+ // This code may be freely distributed under the MIT license
+ // http://danro.mit-license.org/
+ // --------------------------------------------------
+ // All functions adapted from Thomas Fuchs & Jeremy Kahn
+ // Easing Equations (c) 2003 Robert Penner, BSD license
+ // https://raw.github.com/danro/easing-js/master/LICENSE
+ // --------------------------------------------------
+
+ // In that library, the functions named easeIn, easeOut, and
+ // easeInOut below are named easeInCubic, easeOutCubic, and
+ // (you guessed it) easeInOutCubic.
+ //
+ // You can add additional easing functions to this list, and they
+ // will be globally available.
+
+ var static_easing = {
+ linear: function (pos) {
+ return pos;
+ },
+ easeIn: function (pos) {
+ return Math.pow(pos, 3);
+ },
+ easeOut: function (pos) {
+ return Math.pow(pos - 1, 3) + 1;
+ },
+ easeInOut: function (pos) {
+ if ((pos /= 0.5) < 1) {
+ return 0.5 * Math.pow(pos, 3);
+ }
+ return 0.5 * (Math.pow(pos - 2, 3) + 2);
+ }
+ };
+
+ /*global console, navigator */
+ var isClient, isJsdom, hasConsole, environment__magic, namespaces, svg, vendors;
+
+ isClient = typeof document === "object";
+
+ isJsdom = typeof navigator !== "undefined" && /jsDom/.test(navigator.appName);
+
+ hasConsole = typeof console !== "undefined" && typeof console.warn === "function" && typeof console.warn.apply === "function";
+
+ try {
+ Object.defineProperty({}, "test", { value: 0 });
+ environment__magic = true;
+ } catch (e) {
+ environment__magic = false;
+ }
+
+ namespaces = {
+ html: "http://www.w3.org/1999/xhtml",
+ mathml: "http://www.w3.org/1998/Math/MathML",
+ svg: "http://www.w3.org/2000/svg",
+ xlink: "http://www.w3.org/1999/xlink",
+ xml: "http://www.w3.org/XML/1998/namespace",
+ xmlns: "http://www.w3.org/2000/xmlns/"
+ };
+
+ if (typeof document === "undefined") {
+ svg = false;
+ } else {
+ svg = document && document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1");
+ }
+
+ vendors = ["o", "ms", "moz", "webkit"];
+
+ var createElement, matches, dom__div, methodNames, unprefixed, prefixed, dom__i, j, makeFunction;
+
+ // Test for SVG support
+ if (!svg) {
+ createElement = function (type, ns) {
+ if (ns && ns !== namespaces.html) {
+ throw "This browser does not support namespaces other than http://www.w3.org/1999/xhtml. The most likely cause of this error is that you're trying to render SVG in an older browser. See http://docs.ractivejs.org/latest/svg-and-older-browsers for more information";
+ }
+
+ return document.createElement(type);
+ };
+ } else {
+ createElement = function (type, ns) {
+ if (!ns || ns === namespaces.html) {
+ return document.createElement(type);
+ }
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation
- files (the "Software"), to deal in the Software without
- restriction, including without limitation the rights to use,
- copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following
- conditions:
+ return document.createElementNS(ns, type);
+ };
+ }
+
+ function getElement(input) {
+ var output;
+
+ if (!input || typeof input === "boolean") {
+ return;
+ }
+
+ if (typeof window === "undefined" || !document || !input) {
+ return null;
+ }
+
+ // We already have a DOM node - no work to do. (Duck typing alert!)
+ if (input.nodeType) {
+ return input;
+ }
+
+ // Get node from string
+ if (typeof input === "string") {
+ // try ID first
+ output = document.getElementById(input);
+
+ // then as selector, if possible
+ if (!output && document.querySelector) {
+ output = document.querySelector(input);
+ }
+
+ // did it work?
+ if (output && output.nodeType) {
+ return output;
+ }
+ }
+
+ // If we've been given a collection (jQuery, Zepto etc), extract the first item
+ if (input[0] && input[0].nodeType) {
+ return input[0];
+ }
+
+ return null;
+ }
+
+ if (!isClient) {
+ matches = null;
+ } else {
+ dom__div = createElement("div");
+ methodNames = ["matches", "matchesSelector"];
+
+ makeFunction = function (methodName) {
+ return function (node, selector) {
+ return node[methodName](selector);
+ };
+ };
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
+ dom__i = methodNames.length;
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ while (dom__i-- && !matches) {
+ unprefixed = methodNames[dom__i];
-*/
+ if (dom__div[unprefixed]) {
+ matches = makeFunction(unprefixed);
+ } else {
+ j = vendors.length;
+ while (j--) {
+ prefixed = vendors[dom__i] + unprefixed.substr(0, 1).toUpperCase() + unprefixed.substring(1);
-(function ( win ) {
-
- 'use strict';
-
- var doc = win.document;
-
- if ( !doc ) {
- return;
- }
-
- // Shims for older browsers
-
- if ( !Date.now ) {
- Date.now = function () { return +new Date(); };
- }
-
- if ( !String.prototype.trim ) {
- String.prototype.trim = function () {
- return this.replace(/^\s+/, '').replace(/\s+$/, '');
- };
- }
-
-
- // Polyfill for Object.keys
- // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys
- if ( !Object.keys ) {
- Object.keys = (function () {
- var hasOwnProperty = Object.prototype.hasOwnProperty,
- hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
- dontEnums = [
- 'toString',
- 'toLocaleString',
- 'valueOf',
- 'hasOwnProperty',
- 'isPrototypeOf',
- 'propertyIsEnumerable',
- 'constructor'
- ],
- dontEnumsLength = dontEnums.length;
-
- return function ( obj ) {
- if ( typeof obj !== 'object' && typeof obj !== 'function' || obj === null ) {
- throw new TypeError( 'Object.keys called on non-object' );
- }
-
- var result = [];
-
- for ( var prop in obj ) {
- if ( hasOwnProperty.call( obj, prop ) ){
- result.push( prop );
- }
- }
-
- if ( hasDontEnumBug ) {
- for ( var i=0; i < dontEnumsLength; i++ ) {
- if ( hasOwnProperty.call( obj, dontEnums[i] ) ){
- result.push( dontEnums[i] );
- }
- }
- }
- return result;
- };
- }());
- }
-
-
- // Array extras
- if ( !Array.prototype.indexOf ) {
- Array.prototype.indexOf = function ( needle, i ) {
- var len;
-
- if ( i === undefined ) {
- i = 0;
- }
-
- if ( i < 0 ) {
- i+= this.length;
- }
-
- if ( i < 0 ) {
- i = 0;
- }
-
- for ( len = this.length; i
+ dom__div.innerHTML = "";
+
+ parentNode = dom__div;
+ node = node.cloneNode();
+
+ dom__div.appendChild(node);
}
- }(config_svg, config_namespaces);
-var config_isClient = function () {
- if (typeof document === 'object') {
+ nodes = parentNode.querySelectorAll(selector);
+
+ i = nodes.length;
+ while (i--) {
+ if (nodes[i] === node) {
return true;
+ }
}
+
return false;
- }();
-var utils_defineProperty = function (isClient) {
+ };
+ }
+ }
- try {
- Object.defineProperty({}, 'test', { value: 0 });
- if (isClient) {
- Object.defineProperty(document.createElement('div'), 'test', { value: 0 });
- }
- return Object.defineProperty;
- } catch (err) {
- return function (obj, prop, desc) {
- obj[prop] = desc.value;
- };
+ function detachNode(node) {
+ if (node && typeof node.parentNode !== "unknown" && node.parentNode) {
+ node.parentNode.removeChild(node);
+ }
+
+ return node;
+ }
+
+ function safeToStringValue(value) {
+ return value == null || !value.toString ? "" : value;
+ }
+
+ var legacy = null;
+
+ var create, defineProperty, defineProperties;
+
+ try {
+ Object.defineProperty({}, "test", { value: 0 });
+
+ if (isClient) {
+ Object.defineProperty(document.createElement("div"), "test", { value: 0 });
+ }
+
+ defineProperty = Object.defineProperty;
+ } catch (err) {
+ // Object.defineProperty doesn't exist, or we're in IE8 where you can
+ // only use it with DOM objects (what were you smoking, MSFT?)
+ defineProperty = function (obj, prop, desc) {
+ obj[prop] = desc.value;
+ };
+ }
+
+ try {
+ try {
+ Object.defineProperties({}, { test: { value: 0 } });
+ } catch (err) {
+ // TODO how do we account for this? noMagic = true;
+ throw err;
+ }
+
+ if (isClient) {
+ Object.defineProperties(createElement("div"), { test: { value: 0 } });
+ }
+
+ defineProperties = Object.defineProperties;
+ } catch (err) {
+ defineProperties = function (obj, props) {
+ var prop;
+
+ for (prop in props) {
+ if (props.hasOwnProperty(prop)) {
+ defineProperty(obj, prop, props[prop]);
+ }
+ }
+ };
+ }
+
+ try {
+ Object.create(null);
+
+ create = Object.create;
+ } catch (err) {
+ // sigh
+ create = (function () {
+ var F = function () {};
+
+ return function (proto, props) {
+ var obj;
+
+ if (proto === null) {
+ return {};
}
- }(config_isClient);
-var utils_defineProperties = function (createElement, defineProperty, isClient) {
- try {
- try {
- Object.defineProperties({}, { test: { value: 0 } });
- } catch (err) {
- throw err;
+ F.prototype = proto;
+ obj = new F();
+
+ if (props) {
+ Object.defineProperties(obj, props);
+ }
+
+ return obj;
+ };
+ })();
+ }
+
+ function utils_object__extend(target) {
+ for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ sources[_key - 1] = arguments[_key];
+ }
+
+ var prop, source;
+
+ while (source = sources.shift()) {
+ for (prop in source) {
+ if (hasOwn.call(source, prop)) {
+ target[prop] = source[prop];
+ }
+ }
+ }
+
+ return target;
+ }
+
+ function fillGaps(target) {
+ for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ sources[_key - 1] = arguments[_key];
+ }
+
+ sources.forEach(function (s) {
+ for (var key in s) {
+ if (s.hasOwnProperty(key) && !(key in target)) {
+ target[key] = s[key];
+ }
+ }
+ });
+
+ return target;
+ }
+
+ var hasOwn = Object.prototype.hasOwnProperty;
+
+ // thanks, http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
+ var is__toString = Object.prototype.toString,
+ arrayLikePattern = /^\[object (?:Array|FileList)\]$/;
+ function isArray(thing) {
+ return is__toString.call(thing) === "[object Array]";
+ }
+
+ function isArrayLike(obj) {
+ return arrayLikePattern.test(is__toString.call(obj));
+ }
+
+ function isEqual(a, b) {
+ if (a === null && b === null) {
+ return true;
+ }
+
+ if (typeof a === "object" || typeof b === "object") {
+ return false;
+ }
+
+ return a === b;
+ }
+
+ function is__isNumeric(thing) {
+ return !isNaN(parseFloat(thing)) && isFinite(thing);
+ }
+
+ function isObject(thing) {
+ return thing && is__toString.call(thing) === "[object Object]";
+ }
+
+ var noop = function () {};
+
+ /* global console */
+ var alreadyWarned = {},
+ log,
+ printWarning,
+ welcome;
+
+ if (hasConsole) {
+ (function () {
+ var welcomeIntro = ["%cRactive.js %c0.7.3 %cin debug mode, %cmore...", "color: rgb(114, 157, 52); font-weight: normal;", "color: rgb(85, 85, 85); font-weight: normal;", "color: rgb(85, 85, 85); font-weight: normal;", "color: rgb(82, 140, 224); font-weight: normal; text-decoration: underline;"];
+ var welcomeMessage = "You're running Ractive 0.7.3 in debug mode - messages will be printed to the console to help you fix problems and optimise your application.\n\nTo disable debug mode, add this line at the start of your app:\n Ractive.DEBUG = false;\n\nTo disable debug mode when your app is minified, add this snippet:\n Ractive.DEBUG = /unminified/.test(function(){/*unminified*/});\n\nGet help and support:\n http://docs.ractivejs.org\n http://stackoverflow.com/questions/tagged/ractivejs\n http://groups.google.com/forum/#!forum/ractive-js\n http://twitter.com/ractivejs\n\nFound a bug? Raise an issue:\n https://github.com/ractivejs/ractive/issues\n\n";
+
+ welcome = function () {
+ var hasGroup = !!console.groupCollapsed;
+ console[hasGroup ? "groupCollapsed" : "log"].apply(console, welcomeIntro);
+ console.log(welcomeMessage);
+ if (hasGroup) {
+ console.groupEnd(welcomeIntro);
+ }
+
+ welcome = noop;
+ };
+
+ printWarning = function (message, args) {
+ welcome();
+
+ // extract information about the instance this message pertains to, if applicable
+ if (typeof args[args.length - 1] === "object") {
+ var options = args.pop();
+ var ractive = options ? options.ractive : null;
+
+ if (ractive) {
+ // if this is an instance of a component that we know the name of, add
+ // it to the message
+ var _name = undefined;
+ if (ractive.component && (_name = ractive.component.name)) {
+ message = "<" + _name + "> " + message;
}
- if (isClient) {
- Object.defineProperties(createElement('div'), { test: { value: 0 } });
+
+ var node = undefined;
+ if (node = options.node || ractive.fragment && ractive.fragment.rendered && ractive.find("*")) {
+ args.push(node);
}
- return Object.defineProperties;
- } catch (err) {
- return function (obj, props) {
- var prop;
- for (prop in props) {
- if (props.hasOwnProperty(prop)) {
- defineProperty(obj, prop, props[prop]);
- }
- }
- };
+ }
}
- }(utils_createElement, utils_defineProperty, config_isClient);
-var utils_normaliseKeypath = function () {
- var regex = /\[\s*(\*|[0-9]|[1-9][0-9]+)\s*\]/g;
- return function (keypath) {
- return (keypath || '').replace(regex, '.$1');
- };
- }();
-var registries_adaptors = {};
-var config_types = {
- TEXT: 1,
- INTERPOLATOR: 2,
- TRIPLE: 3,
- SECTION: 4,
- INVERTED: 5,
- CLOSING: 6,
- ELEMENT: 7,
- PARTIAL: 8,
- COMMENT: 9,
- DELIMCHANGE: 10,
- MUSTACHE: 11,
- TAG: 12,
- ATTRIBUTE: 13,
- COMPONENT: 15,
- NUMBER_LITERAL: 20,
- STRING_LITERAL: 21,
- ARRAY_LITERAL: 22,
- OBJECT_LITERAL: 23,
- BOOLEAN_LITERAL: 24,
- GLOBAL: 26,
- KEY_VALUE_PAIR: 27,
- REFERENCE: 30,
- REFINEMENT: 31,
- MEMBER: 32,
- PREFIX_OPERATOR: 33,
- BRACKETED: 34,
- CONDITIONAL: 35,
- INFIX_OPERATOR: 36,
- INVOCATION: 40
+ console.warn.apply(console, ["%cRactive.js: %c" + message, "color: rgb(114, 157, 52);", "color: rgb(85, 85, 85);"].concat(args));
+ };
+
+ log = function () {
+ console.log.apply(console, arguments);
+ };
+ })();
+ } else {
+ printWarning = log = welcome = noop;
+ }
+
+ function format(message, args) {
+ return message.replace(/%s/g, function () {
+ return args.shift();
+ });
+ }
+
+ function fatal(message) {
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
+
+ message = format(message, args);
+ throw new Error(message);
+ }
+
+ function logIfDebug() {
+ if (_Ractive.DEBUG) {
+ log.apply(null, arguments);
+ }
+ }
+
+ function warn(message) {
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
+
+ message = format(message, args);
+ printWarning(message, args);
+ }
+
+ function warnOnce(message) {
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
+
+ message = format(message, args);
+
+ if (alreadyWarned[message]) {
+ return;
+ }
+
+ alreadyWarned[message] = true;
+ printWarning(message, args);
+ }
+
+ function warnIfDebug() {
+ if (_Ractive.DEBUG) {
+ warn.apply(null, arguments);
+ }
+ }
+
+ function warnOnceIfDebug() {
+ if (_Ractive.DEBUG) {
+ warnOnce.apply(null, arguments);
+ }
+ }
+
+ // Error messages that are used (or could be) in multiple places
+ var badArguments = "Bad arguments";
+ var noRegistryFunctionReturn = "A function was specified for \"%s\" %s, but no %s was returned";
+ var missingPlugin = function (name, type) {
+ return "Missing \"" + name + "\" " + type + " plugin. You may need to download a plugin via http://docs.ractivejs.org/latest/plugins#" + type + "s";
+ };
+
+ function findInViewHierarchy(registryName, ractive, name) {
+ var instance = findInstance(registryName, ractive, name);
+ return instance ? instance[registryName][name] : null;
+ }
+
+ function findInstance(registryName, ractive, name) {
+ while (ractive) {
+ if (name in ractive[registryName]) {
+ return ractive;
+ }
+
+ if (ractive.isolated) {
+ return null;
+ }
+
+ ractive = ractive.parent;
+ }
+ }
+
+ var interpolate = function (from, to, ractive, type) {
+ if (from === to) {
+ return snap(to);
+ }
+
+ if (type) {
+
+ var interpol = findInViewHierarchy("interpolators", ractive, type);
+ if (interpol) {
+ return interpol(from, to) || snap(to);
+ }
+
+ fatal(missingPlugin(type, "interpolator"));
+ }
+
+ return static_interpolators.number(from, to) || static_interpolators.array(from, to) || static_interpolators.object(from, to) || snap(to);
+ };
+
+ var shared_interpolate = interpolate;
+
+ function snap(to) {
+ return function () {
+ return to;
};
-var utils_isArray = function () {
+ }
- var toString = Object.prototype.toString;
- return function (thing) {
- return toString.call(thing) === '[object Array]';
- };
- }();
-var shared_clearCache = function () {
-
- return function clearCache(ractive, keypath) {
- var cacheMap, wrappedProperty;
- if (wrappedProperty = ractive._wrapped[keypath]) {
- if (wrappedProperty.teardown() !== false) {
- ractive._wrapped[keypath] = null;
- }
- }
- ractive._cache[keypath] = undefined;
- if (cacheMap = ractive._cacheMap[keypath]) {
- while (cacheMap.length) {
- clearCache(ractive, cacheMap.pop());
- }
- }
- };
- }();
-var shared_getValueFromCheckboxes = function () {
-
- return function (ractive, keypath) {
- var value, checkboxes, checkbox, len, i, rootEl;
- value = [];
- rootEl = ractive.rendered ? ractive.el : ractive.fragment.docFrag;
- checkboxes = rootEl.querySelectorAll('input[type="checkbox"][name="{{' + keypath + '}}"]');
- len = checkboxes.length;
- for (i = 0; i < len; i += 1) {
- checkbox = checkboxes[i];
- if (checkbox.hasAttribute('checked') || checkbox.checked) {
- value[value.length] = checkbox._ractive.value;
- }
- }
- return value;
- };
- }();
-var shared_preDomUpdate = function (getValueFromCheckboxes) {
-
- return function (ractive) {
- var deferred, evaluator, selectValue, attribute, keypath, radio;
- deferred = ractive._deferred;
- while (evaluator = deferred.evals.pop()) {
- evaluator.update().deferred = false;
- }
- while (selectValue = deferred.selectValues.pop()) {
- selectValue.deferredUpdate();
- }
- while (attribute = deferred.attrs.pop()) {
- attribute.update().deferred = false;
- }
- while (keypath = deferred.checkboxes.pop()) {
- ractive.set(keypath, getValueFromCheckboxes(ractive, keypath));
- }
- while (radio = deferred.radios.pop()) {
- radio.update();
- }
- };
- }(shared_getValueFromCheckboxes);
-var shared_postDomUpdate = function () {
-
- return function (ractive) {
- var deferred, focusable, query, decorator, transition, observer;
- deferred = ractive._deferred;
- if (focusable = deferred.focusable) {
- focusable.focus();
- deferred.focusable = null;
- }
- while (query = deferred.liveQueries.pop()) {
- query._sort();
- }
- while (decorator = deferred.decorators.pop()) {
- decorator.init();
- }
- while (transition = deferred.transitions.pop()) {
- transition.init();
- }
- while (observer = deferred.observers.pop()) {
- observer.update();
- }
- };
- }();
-var shared_makeTransitionManager = function () {
+ var interpolators = {
+ number: function (from, to) {
+ var delta;
- var makeTransitionManager = function (root, callback) {
- var transitionManager, elementsToDetach, detachNodes, nodeHasNoTransitioningChildren;
- if (root._parent && root._parent._transitionManager) {
- return root._parent._transitionManager;
- }
- elementsToDetach = [];
- detachNodes = function () {
- var i, element;
- i = elementsToDetach.length;
- while (i--) {
- element = elementsToDetach[i];
- if (nodeHasNoTransitioningChildren(element.node)) {
- element.detach();
- elementsToDetach.splice(i, 1);
- }
- }
- };
- nodeHasNoTransitioningChildren = function (node) {
- var i, candidate;
- i = transitionManager.active.length;
- while (i--) {
- candidate = transitionManager.active[i];
- if (node.contains(candidate)) {
- return false;
- }
- }
- return true;
- };
- transitionManager = {
- active: [],
- push: function (node) {
- transitionManager.active[transitionManager.active.length] = node;
- },
- pop: function (node) {
- var index;
- index = transitionManager.active.indexOf(node);
- if (index === -1) {
- return;
- }
- transitionManager.active.splice(index, 1);
- detachNodes();
- if (!transitionManager.active.length && transitionManager._ready) {
- transitionManager.complete();
- }
- },
- complete: function () {
- if (callback) {
- callback.call(root);
- }
- },
- ready: function () {
- detachNodes();
- transitionManager._ready = true;
- if (!transitionManager.active.length) {
- transitionManager.complete();
- }
- },
- detachWhenReady: function (element) {
- elementsToDetach[elementsToDetach.length] = element;
- }
- };
- return transitionManager;
- };
- return makeTransitionManager;
- }();
-var shared_notifyDependants = function () {
-
- var notifyDependants, lastKey, starMaps = {};
- lastKey = /[^\.]+$/;
- notifyDependants = function (ractive, keypath, onlyDirect) {
- var i;
- if (ractive._patternObservers.length) {
- notifyPatternObservers(ractive, keypath, keypath, onlyDirect, true);
- }
- for (i = 0; i < ractive._deps.length; i += 1) {
- notifyDependantsAtPriority(ractive, keypath, i, onlyDirect);
- }
- };
- notifyDependants.multiple = function (ractive, keypaths, onlyDirect) {
- var i, j, len;
- len = keypaths.length;
- if (ractive._patternObservers.length) {
- i = len;
- while (i--) {
- notifyPatternObservers(ractive, keypaths[i], keypaths[i], onlyDirect, true);
- }
- }
- for (i = 0; i < ractive._deps.length; i += 1) {
- if (ractive._deps[i]) {
- j = len;
- while (j--) {
- notifyDependantsAtPriority(ractive, keypaths[j], i, onlyDirect);
- }
- }
- }
+ if (!is__isNumeric(from) || !is__isNumeric(to)) {
+ return null;
+ }
+
+ from = +from;
+ to = +to;
+
+ delta = to - from;
+
+ if (!delta) {
+ return function () {
+ return from;
};
- return notifyDependants;
- function notifyDependantsAtPriority(ractive, keypath, priority, onlyDirect) {
- var depsByKeypath = ractive._deps[priority];
- if (!depsByKeypath) {
- return;
- }
- updateAll(depsByKeypath[keypath]);
- if (onlyDirect) {
- return;
- }
- cascade(ractive._depsMap[keypath], ractive, priority);
- }
- function updateAll(deps) {
- var i, len;
- if (deps) {
- len = deps.length;
- for (i = 0; i < len; i += 1) {
- deps[i].update();
- }
- }
+ }
+
+ return function (t) {
+ return from + t * delta;
+ };
+ },
+
+ array: function (from, to) {
+ var intermediate, interpolators, len, i;
+
+ if (!isArray(from) || !isArray(to)) {
+ return null;
+ }
+
+ intermediate = [];
+ interpolators = [];
+
+ i = len = Math.min(from.length, to.length);
+ while (i--) {
+ interpolators[i] = shared_interpolate(from[i], to[i]);
+ }
+
+ // surplus values - don't interpolate, but don't exclude them either
+ for (i = len; i < from.length; i += 1) {
+ intermediate[i] = from[i];
+ }
+
+ for (i = len; i < to.length; i += 1) {
+ intermediate[i] = to[i];
+ }
+
+ return function (t) {
+ var i = len;
+
+ while (i--) {
+ intermediate[i] = interpolators[i](t);
}
- function cascade(childDeps, ractive, priority, onlyDirect) {
- var i;
- if (childDeps) {
- i = childDeps.length;
- while (i--) {
- notifyDependantsAtPriority(ractive, childDeps[i], priority, onlyDirect);
- }
- }
+
+ return intermediate;
+ };
+ },
+
+ object: function (from, to) {
+ var properties, len, interpolators, intermediate, prop;
+
+ if (!isObject(from) || !isObject(to)) {
+ return null;
+ }
+
+ properties = [];
+ intermediate = {};
+ interpolators = {};
+
+ for (prop in from) {
+ if (hasOwn.call(from, prop)) {
+ if (hasOwn.call(to, prop)) {
+ properties.push(prop);
+ interpolators[prop] = shared_interpolate(from[prop], to[prop]);
+ } else {
+ intermediate[prop] = from[prop];
+ }
}
- function notifyPatternObservers(ractive, registeredKeypath, actualKeypath, isParentOfChangedKeypath, isTopLevelCall) {
- var i, patternObserver, children, child, key, childActualKeypath, potentialWildcardMatches, cascade;
- i = ractive._patternObservers.length;
- while (i--) {
- patternObserver = ractive._patternObservers[i];
- if (patternObserver.regex.test(actualKeypath)) {
- patternObserver.update(actualKeypath);
- }
- }
- if (isParentOfChangedKeypath) {
- return;
- }
- cascade = function (keypath) {
- if (children = ractive._depsMap[keypath]) {
- i = children.length;
- while (i--) {
- child = children[i];
- key = lastKey.exec(child)[0];
- childActualKeypath = actualKeypath + '.' + key;
- notifyPatternObservers(ractive, child, childActualKeypath);
- }
- }
- };
- if (isTopLevelCall) {
- potentialWildcardMatches = getPotentialWildcardMatches(actualKeypath);
- potentialWildcardMatches.forEach(cascade);
- } else {
- cascade(registeredKeypath);
- }
+ }
+
+ for (prop in to) {
+ if (hasOwn.call(to, prop) && !hasOwn.call(from, prop)) {
+ intermediate[prop] = to[prop];
}
- function getPotentialWildcardMatches(keypath) {
- var keys, starMap, mapper, i, result, wildcardKeypath;
- keys = keypath.split('.');
- starMap = getStarMap(keys.length);
- result = [];
- mapper = function (star, i) {
- return star ? '*' : keys[i];
- };
- i = starMap.length;
- while (i--) {
- wildcardKeypath = starMap[i].map(mapper).join('.');
- if (!result[wildcardKeypath]) {
- result[result.length] = wildcardKeypath;
- result[wildcardKeypath] = true;
- }
- }
- return result;
- }
- function getStarMap(num) {
- var ones = '', max, binary, starMap, mapper, i;
- if (!starMaps[num]) {
- starMap = [];
- while (ones.length < num) {
- ones += 1;
- }
- max = parseInt(ones, 2);
- mapper = function (digit) {
- return digit === '1';
- };
- for (i = 0; i <= max; i += 1) {
- binary = i.toString(2);
- while (binary.length < num) {
- binary = '0' + binary;
- }
- starMap[i] = Array.prototype.map.call(binary, mapper);
- }
- starMaps[num] = starMap;
- }
- return starMaps[num];
- }
- }();
-var Ractive_prototype_get_arrayAdaptor = function (types, defineProperty, isArray, clearCache, preDomUpdate, postDomUpdate, makeTransitionManager, notifyDependants) {
-
- var arrayAdaptor, notifyArrayDependants, ArrayWrapper, patchArrayMethods, unpatchArrayMethods, patchedArrayProto, testObj, mutatorMethods, noop, errorMessage;
- arrayAdaptor = {
- filter: function (object) {
- return isArray(object) && (!object._ractive || !object._ractive.setting);
- },
- wrap: function (ractive, array, keypath) {
- return new ArrayWrapper(ractive, array, keypath);
- }
- };
- ArrayWrapper = function (ractive, array, keypath) {
- this.root = ractive;
- this.value = array;
- this.keypath = keypath;
- if (!array._ractive) {
- defineProperty(array, '_ractive', {
- value: {
- wrappers: [],
- instances: [],
- setting: false
- },
- configurable: true
- });
- patchArrayMethods(array);
- }
- if (!array._ractive.instances[ractive._guid]) {
- array._ractive.instances[ractive._guid] = 0;
- array._ractive.instances.push(ractive);
- }
- array._ractive.instances[ractive._guid] += 1;
- array._ractive.wrappers.push(this);
- };
- ArrayWrapper.prototype = {
- get: function () {
- return this.value;
- },
- teardown: function () {
- var array, storage, wrappers, instances, index;
- array = this.value;
- storage = array._ractive;
- wrappers = storage.wrappers;
- instances = storage.instances;
- if (storage.setting) {
- return false;
- }
- index = wrappers.indexOf(this);
- if (index === -1) {
- throw new Error(errorMessage);
- }
- wrappers.splice(index, 1);
- if (!wrappers.length) {
- delete array._ractive;
- unpatchArrayMethods(this.value);
- } else {
- instances[this.root._guid] -= 1;
- if (!instances[this.root._guid]) {
- index = instances.indexOf(this.root);
- if (index === -1) {
- throw new Error(errorMessage);
- }
- instances.splice(index, 1);
- }
- }
- }
- };
- notifyArrayDependants = function (array, methodName, args) {
- var notifyKeypathDependants, queueDependants, wrappers, wrapper, i;
- notifyKeypathDependants = function (root, keypath) {
- var depsByKeypath, deps, keys, upstreamQueue, smartUpdateQueue, dumbUpdateQueue, i, changed, start, end, childKeypath, lengthUnchanged;
- if (methodName === 'sort' || methodName === 'reverse') {
- root.set(keypath, array);
- return;
- }
- clearCache(root, keypath);
- smartUpdateQueue = [];
- dumbUpdateQueue = [];
- for (i = 0; i < root._deps.length; i += 1) {
- depsByKeypath = root._deps[i];
- if (!depsByKeypath) {
- continue;
- }
- deps = depsByKeypath[keypath];
- if (deps) {
- queueDependants(keypath, deps, smartUpdateQueue, dumbUpdateQueue);
- preDomUpdate(root);
- while (smartUpdateQueue.length) {
- smartUpdateQueue.pop().smartUpdate(methodName, args);
- }
- while (dumbUpdateQueue.length) {
- dumbUpdateQueue.pop().update();
- }
- }
- }
- if (methodName === 'splice' && args.length > 2 && args[1]) {
- changed = Math.min(args[1], args.length - 2);
- start = args[0];
- end = start + changed;
- if (args[1] === args.length - 2) {
- lengthUnchanged = true;
- }
- for (i = start; i < end; i += 1) {
- childKeypath = keypath + '.' + i;
- notifyDependants(root, childKeypath);
- }
- }
- preDomUpdate(root);
- upstreamQueue = [];
- keys = keypath.split('.');
- while (keys.length) {
- keys.pop();
- upstreamQueue[upstreamQueue.length] = keys.join('.');
- }
- notifyDependants.multiple(root, upstreamQueue, true);
- if (!lengthUnchanged) {
- notifyDependants(root, keypath + '.length', true);
- }
- };
- queueDependants = function (keypath, deps, smartUpdateQueue, dumbUpdateQueue) {
- var k, dependant;
- k = deps.length;
- while (k--) {
- dependant = deps[k];
- if (dependant.type === types.REFERENCE) {
- dependant.update();
- } else if (dependant.keypath === keypath && dependant.type === types.SECTION && !dependant.inverted && dependant.docFrag) {
- smartUpdateQueue[smartUpdateQueue.length] = dependant;
- } else {
- dumbUpdateQueue[dumbUpdateQueue.length] = dependant;
- }
- }
- };
- wrappers = array._ractive.wrappers;
- i = wrappers.length;
- while (i--) {
- wrapper = wrappers[i];
- notifyKeypathDependants(wrapper.root, wrapper.keypath);
- }
- };
- patchedArrayProto = [];
- mutatorMethods = [
- 'pop',
- 'push',
- 'reverse',
- 'shift',
- 'sort',
- 'splice',
- 'unshift'
- ];
- noop = function () {
- };
- mutatorMethods.forEach(function (methodName) {
- var method = function () {
- var result, instances, instance, i, previousTransitionManagers = {}, transitionManagers = {};
- result = Array.prototype[methodName].apply(this, arguments);
- instances = this._ractive.instances;
- i = instances.length;
- while (i--) {
- instance = instances[i];
- previousTransitionManagers[instance._guid] = instance._transitionManager;
- instance._transitionManager = transitionManagers[instance._guid] = makeTransitionManager(instance, noop);
- }
- this._ractive.setting = true;
- notifyArrayDependants(this, methodName, arguments);
- this._ractive.setting = false;
- i = instances.length;
- while (i--) {
- instance = instances[i];
- instance._transitionManager = previousTransitionManagers[instance._guid];
- transitionManagers[instance._guid].ready();
- preDomUpdate(instance);
- postDomUpdate(instance);
- }
- return result;
- };
- defineProperty(patchedArrayProto, methodName, { value: method });
- });
- testObj = {};
- if (testObj.__proto__) {
- patchArrayMethods = function (array) {
- array.__proto__ = patchedArrayProto;
- };
- unpatchArrayMethods = function (array) {
- array.__proto__ = Array.prototype;
- };
- } else {
- patchArrayMethods = function (array) {
- var i, methodName;
- i = mutatorMethods.length;
- while (i--) {
- methodName = mutatorMethods[i];
- defineProperty(array, methodName, {
- value: patchedArrayProto[methodName],
- configurable: true
- });
- }
- };
- unpatchArrayMethods = function (array) {
- var i;
- i = mutatorMethods.length;
- while (i--) {
- delete array[mutatorMethods[i]];
- }
- };
+ }
+
+ len = properties.length;
+
+ return function (t) {
+ var i = len,
+ prop;
+
+ while (i--) {
+ prop = properties[i];
+
+ intermediate[prop] = interpolators[prop](t);
}
- errorMessage = 'Something went wrong in a rather interesting way';
- return arrayAdaptor;
- }(config_types, utils_defineProperty, utils_isArray, shared_clearCache, shared_preDomUpdate, shared_postDomUpdate, shared_makeTransitionManager, shared_notifyDependants);
-var Ractive_prototype_get_magicAdaptor = function () {
- var magicAdaptor, MagicWrapper;
- try {
- Object.defineProperty({}, 'test', { value: 0 });
- } catch (err) {
- return false;
- }
- magicAdaptor = {
- filter: function (object, keypath) {
- return !!keypath;
- },
- wrap: function (ractive, object, keypath) {
- return new MagicWrapper(ractive, object, keypath);
- }
- };
- MagicWrapper = function (ractive, object, keypath) {
- var wrapper = this, keys, prop, objKeypath, descriptor, wrappers, oldGet, oldSet, get, set;
- this.ractive = ractive;
- this.keypath = keypath;
- keys = keypath.split('.');
- this.prop = keys.pop();
- objKeypath = keys.join('.');
- this.obj = objKeypath ? ractive.get(objKeypath) : ractive.data;
- descriptor = this.originalDescriptor = Object.getOwnPropertyDescriptor(this.obj, this.prop);
- if (descriptor && descriptor.set && (wrappers = descriptor.set._ractiveWrappers)) {
- if (wrappers.indexOf(this) === -1) {
- wrappers.push(this);
- }
- return;
- }
- if (descriptor && !descriptor.configurable) {
- throw new Error('Cannot use magic mode with property "' + prop + '" - object is not configurable');
- }
- if (descriptor) {
- this.value = descriptor.value;
- oldGet = descriptor.get;
- oldSet = descriptor.set;
- }
- get = oldGet || function () {
- return wrapper.value;
- };
- set = function (value) {
- var wrappers, wrapper, i;
- if (oldSet) {
- oldSet(value);
- }
- wrappers = set._ractiveWrappers;
- i = wrappers.length;
- while (i--) {
- wrapper = wrappers[i];
- if (!wrapper.resetting) {
- wrapper.ractive.set(wrapper.keypath, value);
- }
- }
- };
- set._ractiveWrappers = [this];
- Object.defineProperty(this.obj, this.prop, {
- get: get,
- set: set,
- enumerable: true,
- configurable: true
- });
- };
- MagicWrapper.prototype = {
- get: function () {
- return this.value;
- },
- reset: function (value) {
- this.resetting = true;
- this.value = value;
- this.resetting = false;
- },
- teardown: function () {
- var descriptor, set, value, wrappers;
- descriptor = Object.getOwnPropertyDescriptor(this.obj, this.prop);
- set = descriptor.set;
- wrappers = set._ractiveWrappers;
- wrappers.splice(wrappers.indexOf(this), 1);
- if (!wrappers.length) {
- value = this.obj[this.prop];
- Object.defineProperty(this.obj, this.prop, this.originalDescriptor || {
- writable: true,
- enumerable: true,
- configrable: true
- });
- this.obj[this.prop] = value;
- }
- }
- };
- return magicAdaptor;
- }();
-var shared_adaptIfNecessary = function (adaptorRegistry, arrayAdaptor, magicAdaptor) {
-
- var prefixers = {};
- return function (ractive, keypath, value, isExpressionResult) {
- var len, i, adaptor, wrapped;
- len = ractive.adaptors.length;
- for (i = 0; i < len; i += 1) {
- adaptor = ractive.adaptors[i];
- if (typeof adaptor === 'string') {
- if (!adaptorRegistry[adaptor]) {
- throw new Error('Missing adaptor "' + adaptor + '"');
- }
- adaptor = ractive.adaptors[i] = adaptorRegistry[adaptor];
- }
- if (adaptor.filter(value, keypath, ractive)) {
- wrapped = ractive._wrapped[keypath] = adaptor.wrap(ractive, value, keypath, getPrefixer(keypath));
- wrapped.value = value;
- return;
- }
- }
- if (!isExpressionResult) {
- if (ractive.magic && magicAdaptor.filter(value, keypath, ractive)) {
- ractive._wrapped[keypath] = magicAdaptor.wrap(ractive, value, keypath);
- } else if (ractive.modifyArrays && arrayAdaptor.filter(value, keypath, ractive)) {
- ractive._wrapped[keypath] = arrayAdaptor.wrap(ractive, value, keypath);
- }
- }
- };
- function prefixKeypath(obj, prefix) {
- var prefixed = {}, key;
- if (!prefix) {
- return obj;
- }
- prefix += '.';
- for (key in obj) {
- if (obj.hasOwnProperty(key)) {
- prefixed[prefix + key] = obj[key];
- }
- }
- return prefixed;
- }
- function getPrefixer(rootKeypath) {
- var rootDot;
- if (!prefixers[rootKeypath]) {
- rootDot = rootKeypath ? rootKeypath + '.' : '';
- prefixers[rootKeypath] = function (relativeKeypath, value) {
- var obj;
- if (typeof relativeKeypath === 'string') {
- obj = {};
- obj[rootDot + relativeKeypath] = value;
- return obj;
- }
- if (typeof relativeKeypath === 'object') {
- return rootDot ? prefixKeypath(relativeKeypath, rootKeypath) : relativeKeypath;
- }
- };
- }
- return prefixers[rootKeypath];
+ return intermediate;
+ };
+ }
+ };
+
+ var static_interpolators = interpolators;
+
+ // This function takes a keypath such as 'foo.bar.baz', and returns
+ // all the variants of that keypath that include a wildcard in place
+ // of a key, such as 'foo.bar.*', 'foo.*.baz', 'foo.*.*' and so on.
+ // These are then checked against the dependants map (ractive.viewmodel.depsMap)
+ // to see if any pattern observers are downstream of one or more of
+ // these wildcard keypaths (e.g. 'foo.bar.*.status')
+ var utils_getPotentialWildcardMatches = getPotentialWildcardMatches;
+
+ var starMaps = {};
+ function getPotentialWildcardMatches(keypath) {
+ var keys, starMap, mapper, i, result, wildcardKeypath;
+
+ keys = keypath.split(".");
+ if (!(starMap = starMaps[keys.length])) {
+ starMap = getStarMap(keys.length);
+ }
+
+ result = [];
+
+ mapper = function (star, i) {
+ return star ? "*" : keys[i];
+ };
+
+ i = starMap.length;
+ while (i--) {
+ wildcardKeypath = starMap[i].map(mapper).join(".");
+
+ if (!result.hasOwnProperty(wildcardKeypath)) {
+ result.push(wildcardKeypath);
+ result[wildcardKeypath] = true;
+ }
+ }
+
+ return result;
+ }
+
+ // This function returns all the possible true/false combinations for
+ // a given number - e.g. for two, the possible combinations are
+ // [ true, true ], [ true, false ], [ false, true ], [ false, false ].
+ // It does so by getting all the binary values between 0 and e.g. 11
+ function getStarMap(num) {
+ var ones = "",
+ max,
+ binary,
+ starMap,
+ mapper,
+ i,
+ j,
+ l,
+ map;
+
+ if (!starMaps[num]) {
+ starMap = [];
+
+ while (ones.length < num) {
+ ones += 1;
+ }
+
+ max = parseInt(ones, 2);
+
+ mapper = function (digit) {
+ return digit === "1";
+ };
+
+ for (i = 0; i <= max; i += 1) {
+ binary = i.toString(2);
+ while (binary.length < num) {
+ binary = "0" + binary;
}
- }(registries_adaptors, Ractive_prototype_get_arrayAdaptor, Ractive_prototype_get_magicAdaptor);
-var Ractive_prototype_get__get = function (normaliseKeypath, adaptorRegistry, adaptIfNecessary) {
- var get, _get, retrieve;
- get = function (keypath) {
- return _get(this, keypath);
- };
- _get = function (ractive, keypath) {
- var cache, cached, value, wrapped, evaluator;
- keypath = normaliseKeypath(keypath);
- cache = ractive._cache;
- if ((cached = cache[keypath]) !== undefined) {
- return cached;
- }
- if (wrapped = ractive._wrapped[keypath]) {
- value = wrapped.value;
- } else if (!keypath) {
- adaptIfNecessary(ractive, '', ractive.data);
- value = ractive.data;
- } else if (evaluator = ractive._evaluators[keypath]) {
- value = evaluator.value;
- } else {
- value = retrieve(ractive, keypath);
- }
- cache[keypath] = value;
- return value;
- };
- retrieve = function (ractive, keypath) {
- var keys, key, parentKeypath, parentValue, cacheMap, value, wrapped;
- keys = keypath.split('.');
- key = keys.pop();
- parentKeypath = keys.join('.');
- parentValue = _get(ractive, parentKeypath);
- if (wrapped = ractive._wrapped[parentKeypath]) {
- parentValue = wrapped.get();
- }
- if (parentValue === null || parentValue === undefined) {
- return;
- }
- if (!(cacheMap = ractive._cacheMap[parentKeypath])) {
- ractive._cacheMap[parentKeypath] = [keypath];
- } else {
- if (cacheMap.indexOf(keypath) === -1) {
- cacheMap[cacheMap.length] = keypath;
- }
- }
- value = parentValue[key];
- adaptIfNecessary(ractive, keypath, value);
- ractive._cache[keypath] = value;
- return value;
- };
- return get;
- }(utils_normaliseKeypath, registries_adaptors, shared_adaptIfNecessary);
-var utils_isObject = function () {
+ map = [];
+ l = binary.length;
+ for (j = 0; j < l; j++) {
+ map.push(mapper(binary[j]));
+ }
+ starMap[i] = map;
+ }
- var toString = Object.prototype.toString;
- return function (thing) {
- return typeof thing === 'object' && toString.call(thing) === '[object Object]';
- };
- }();
-var utils_isEqual = function () {
+ starMaps[num] = starMap;
+ }
- return function (a, b) {
- if (a === null && b === null) {
- return true;
- }
- if (typeof a === 'object' || typeof b === 'object') {
- return false;
- }
- return a === b;
- };
- }();
-var shared_resolveRef = function () {
-
- var resolveRef;
- resolveRef = function (ractive, ref, contextStack) {
- var keypath, keys, lastKey, contextKeys, innerMostContext, postfix, parentKeypath, parentValue, wrapped, context, ancestorErrorMessage;
- ancestorErrorMessage = 'Could not resolve reference - too many "../" prefixes';
- if (ref === '.') {
- if (!contextStack.length) {
- return '';
- }
- keypath = contextStack[contextStack.length - 1];
- } else if (ref.charAt(0) === '.') {
- context = contextStack[contextStack.length - 1];
- contextKeys = context ? context.split('.') : [];
- if (ref.substr(0, 3) === '../') {
- while (ref.substr(0, 3) === '../') {
- if (!contextKeys.length) {
- throw new Error(ancestorErrorMessage);
- }
- contextKeys.pop();
- ref = ref.substring(3);
- }
- contextKeys.push(ref);
- keypath = contextKeys.join('.');
- } else if (!context) {
- keypath = ref.substring(1);
- } else {
- keypath = context + ref;
- }
- } else {
- keys = ref.split('.');
- lastKey = keys.pop();
- postfix = keys.length ? '.' + keys.join('.') : '';
- contextStack = contextStack.concat();
- while (contextStack.length) {
- innerMostContext = contextStack.pop();
- parentKeypath = innerMostContext + postfix;
- parentValue = ractive.get(parentKeypath);
- if (wrapped = ractive._wrapped[parentKeypath]) {
- parentValue = wrapped.get();
- }
- if (typeof parentValue === 'object' && parentValue !== null && parentValue.hasOwnProperty(lastKey)) {
- keypath = innerMostContext + '.' + ref;
- break;
- }
- }
- if (!keypath && ractive.get(ref) !== undefined) {
- keypath = ref;
- }
- }
- return keypath ? keypath.replace(/^\./, '') : keypath;
- };
- return resolveRef;
- }();
-var shared_attemptKeypathResolution = function (resolveRef) {
-
- var push = Array.prototype.push;
- return function (ractive) {
- var unresolved, keypath, leftover;
- while (unresolved = ractive._pendingResolution.pop()) {
- keypath = resolveRef(ractive, unresolved.ref, unresolved.contextStack);
- if (keypath !== undefined) {
- unresolved.resolve(keypath);
- } else {
- (leftover || (leftover = [])).push(unresolved);
- }
- }
- if (leftover) {
- push.apply(ractive._pendingResolution, leftover);
- }
- };
- }(shared_resolveRef);
-var shared_processDeferredUpdates = function (preDomUpdate, postDomUpdate) {
+ return starMaps[num];
+ }
- return function (ractive) {
- preDomUpdate(ractive);
- postDomUpdate(ractive);
- };
- }(shared_preDomUpdate, shared_postDomUpdate);
-var Ractive_prototype_shared_replaceData = function () {
-
- return function (ractive, keypath, value) {
- var keys, accumulated, wrapped, obj, key, currentKeypath, keypathToClear;
- keys = keypath.split('.');
- accumulated = [];
- if (wrapped = ractive._wrapped['']) {
- if (wrapped.set) {
- wrapped.set(keys.join('.'), value);
- }
- obj = wrapped.get();
- } else {
- obj = ractive.data;
- }
- while (keys.length > 1) {
- key = accumulated[accumulated.length] = keys.shift();
- currentKeypath = accumulated.join('.');
- if (wrapped = ractive._wrapped[currentKeypath]) {
- if (wrapped.set) {
- wrapped.set(keys.join('.'), value);
- }
- obj = wrapped.get();
- } else {
- if (!obj.hasOwnProperty(key)) {
- if (!keypathToClear) {
- keypathToClear = currentKeypath;
- }
- obj[key] = /^\s*[0-9]+\s*$/.test(keys[0]) ? [] : {};
- }
- obj = obj[key];
- }
- }
- key = keys[0];
- obj[key] = value;
- return keypathToClear;
- };
- }();
-var Ractive_prototype_set = function (isObject, isEqual, normaliseKeypath, clearCache, notifyDependants, attemptKeypathResolution, makeTransitionManager, processDeferredUpdates, replaceData) {
-
- var set, updateModel, getUpstreamChanges, resetWrapped;
- set = function (keypath, value, complete) {
- var map, changes, upstreamChanges, previousTransitionManager, transitionManager, i, changeHash;
- changes = [];
- if (isObject(keypath)) {
- map = keypath;
- complete = value;
- }
- if (map) {
- for (keypath in map) {
- if (map.hasOwnProperty(keypath)) {
- value = map[keypath];
- keypath = normaliseKeypath(keypath);
- updateModel(this, keypath, value, changes);
- }
- }
- } else {
- keypath = normaliseKeypath(keypath);
- updateModel(this, keypath, value, changes);
- }
- if (!changes.length) {
- return;
- }
- previousTransitionManager = this._transitionManager;
- this._transitionManager = transitionManager = makeTransitionManager(this, complete);
- upstreamChanges = getUpstreamChanges(changes);
- if (upstreamChanges.length) {
- notifyDependants.multiple(this, upstreamChanges, true);
- }
- notifyDependants.multiple(this, changes);
- if (this._pendingResolution.length) {
- attemptKeypathResolution(this);
- }
- processDeferredUpdates(this);
- this._transitionManager = previousTransitionManager;
- transitionManager.ready();
- if (!this.firingChangeEvent) {
- this.firingChangeEvent = true;
- changeHash = {};
- i = changes.length;
- while (i--) {
- changeHash[changes[i]] = this.get(changes[i]);
- }
- this.fire('change', changeHash);
- this.firingChangeEvent = false;
- }
- return this;
- };
- updateModel = function (ractive, keypath, value, changes) {
- var cached, previous, wrapped, keypathToClear, evaluator;
- if ((wrapped = ractive._wrapped[keypath]) && wrapped.reset) {
- if (resetWrapped(ractive, keypath, value, wrapped, changes) !== false) {
- return;
- }
- }
- if (evaluator = ractive._evaluators[keypath]) {
- evaluator.value = value;
- }
- cached = ractive._cache[keypath];
- previous = ractive.get(keypath);
- if (previous !== value && !evaluator) {
- keypathToClear = replaceData(ractive, keypath, value);
- } else {
- if (value === cached && typeof value !== 'object') {
- return;
- }
- }
- clearCache(ractive, keypathToClear || keypath);
- changes[changes.length] = keypath;
- };
- getUpstreamChanges = function (changes) {
- var upstreamChanges = [''], i, keypath, keys, upstreamKeypath;
- i = changes.length;
- while (i--) {
- keypath = changes[i];
- keys = keypath.split('.');
- while (keys.length > 1) {
- keys.pop();
- upstreamKeypath = keys.join('.');
- if (!upstreamChanges[upstreamKeypath]) {
- upstreamChanges[upstreamChanges.length] = upstreamKeypath;
- upstreamChanges[upstreamKeypath] = true;
- }
- }
- }
- return upstreamChanges;
- };
- resetWrapped = function (ractive, keypath, value, wrapped, changes) {
- var previous, cached, cacheMap, i;
- previous = wrapped.get();
- if (!isEqual(previous, value)) {
- if (wrapped.reset(value) === false) {
- return false;
- }
- }
- value = wrapped.get();
- cached = ractive._cache[keypath];
- if (!isEqual(cached, value)) {
- ractive._cache[keypath] = value;
- cacheMap = ractive._cacheMap[keypath];
- if (cacheMap) {
- i = cacheMap.length;
- while (i--) {
- clearCache(ractive, cacheMap[i]);
- }
- }
- changes[changes.length] = keypath;
- }
- };
- return set;
- }(utils_isObject, utils_isEqual, utils_normaliseKeypath, shared_clearCache, shared_notifyDependants, shared_attemptKeypathResolution, shared_makeTransitionManager, shared_processDeferredUpdates, Ractive_prototype_shared_replaceData);
-var Ractive_prototype_update = function (makeTransitionManager, attemptKeypathResolution, clearCache, notifyDependants, processDeferredUpdates) {
-
- return function (keypath, complete) {
- var transitionManager, previousTransitionManager;
- if (typeof keypath === 'function') {
- complete = keypath;
- keypath = '';
- }
- previousTransitionManager = this._transitionManager;
- this._transitionManager = transitionManager = makeTransitionManager(this, complete);
- attemptKeypathResolution(this);
- clearCache(this, keypath || '');
- notifyDependants(this, keypath || '');
- processDeferredUpdates(this);
- this._transitionManager = previousTransitionManager;
- transitionManager.ready();
- if (typeof keypath === 'string') {
- this.fire('update', keypath);
- } else {
- this.fire('update');
- }
- return this;
- };
- }(shared_makeTransitionManager, shared_attemptKeypathResolution, shared_clearCache, shared_notifyDependants, shared_processDeferredUpdates);
-var utils_arrayContentsMatch = function (isArray) {
+ var refPattern = /\[\s*(\*|[0-9]|[1-9][0-9]+)\s*\]/g;
+ var patternPattern = /\*/;
+ var keypathCache = {};
- return function (a, b) {
- var i;
- if (!isArray(a) || !isArray(b)) {
- return false;
- }
- if (a.length !== b.length) {
- return false;
- }
- i = a.length;
- while (i--) {
- if (a[i] !== b[i]) {
- return false;
- }
- }
- return true;
- };
- }(utils_isArray);
-var Ractive_prototype_updateModel = function (getValueFromCheckboxes, arrayContentsMatch, isEqual) {
-
- return function (keypath, cascade) {
- var values, deferredCheckboxes, i;
- if (typeof keypath !== 'string') {
- keypath = '';
- cascade = true;
- }
- consolidateChangedValues(this, keypath, values = {}, deferredCheckboxes = [], cascade);
- if (i = deferredCheckboxes.length) {
- while (i--) {
- keypath = deferredCheckboxes[i];
- values[keypath] = getValueFromCheckboxes(this, keypath);
- }
- }
- this.set(values);
- };
- function consolidateChangedValues(ractive, keypath, values, deferredCheckboxes, cascade) {
- var bindings, childDeps, i, binding, oldValue, newValue;
- bindings = ractive._twowayBindings[keypath];
- if (bindings) {
- i = bindings.length;
- while (i--) {
- binding = bindings[i];
- if (binding.radioName && !binding.node.checked) {
- continue;
- }
- if (binding.checkboxName) {
- if (binding.changed() && !deferredCheckboxes[keypath]) {
- deferredCheckboxes[keypath] = true;
- deferredCheckboxes[deferredCheckboxes.length] = keypath;
- }
- continue;
- }
- oldValue = binding.attr.value;
- newValue = binding.value();
- if (arrayContentsMatch(oldValue, newValue)) {
- continue;
- }
- if (!isEqual(oldValue, newValue)) {
- values[keypath] = newValue;
- }
- }
- }
- if (!cascade) {
- return;
- }
- childDeps = ractive._depsMap[keypath];
- if (childDeps) {
- i = childDeps.length;
- while (i--) {
- consolidateChangedValues(ractive, childDeps[i], values, deferredCheckboxes, cascade);
- }
- }
- }
- }(shared_getValueFromCheckboxes, utils_arrayContentsMatch, utils_isEqual);
-var Ractive_prototype_animate_requestAnimationFrame = function () {
+ var Keypath = function (str) {
+ var keys = str.split(".");
- if (typeof window === 'undefined') {
- return;
+ this.str = str;
+
+ if (str[0] === "@") {
+ this.isSpecial = true;
+ this.value = decodeKeypath(str);
+ }
+
+ this.firstKey = keys[0];
+ this.lastKey = keys.pop();
+
+ this.isPattern = patternPattern.test(str);
+
+ this.parent = str === "" ? null : getKeypath(keys.join("."));
+ this.isRoot = !str;
+ };
+
+ Keypath.prototype = {
+ equalsOrStartsWith: function (keypath) {
+ return keypath === this || this.startsWith(keypath);
+ },
+
+ join: function (str) {
+ return getKeypath(this.isRoot ? String(str) : this.str + "." + str);
+ },
+
+ replace: function (oldKeypath, newKeypath) {
+ if (this === oldKeypath) {
+ return newKeypath;
+ }
+
+ if (this.startsWith(oldKeypath)) {
+ return newKeypath === null ? newKeypath : getKeypath(this.str.replace(oldKeypath.str + ".", newKeypath.str + "."));
+ }
+ },
+
+ startsWith: function (keypath) {
+ if (!keypath) {
+ // TODO under what circumstances does this happen?
+ return false;
+ }
+
+ return keypath && this.str.substr(0, keypath.str.length + 1) === keypath.str + ".";
+ },
+
+ toString: function () {
+ throw new Error("Bad coercion");
+ },
+
+ valueOf: function () {
+ throw new Error("Bad coercion");
+ },
+
+ wildcardMatches: function () {
+ return this._wildcardMatches || (this._wildcardMatches = utils_getPotentialWildcardMatches(this.str));
+ }
+ };
+ function assignNewKeypath(target, property, oldKeypath, newKeypath) {
+ var existingKeypath = target[property];
+
+ if (existingKeypath && (existingKeypath.equalsOrStartsWith(newKeypath) || !existingKeypath.equalsOrStartsWith(oldKeypath))) {
+ return;
+ }
+
+ target[property] = existingKeypath ? existingKeypath.replace(oldKeypath, newKeypath) : newKeypath;
+ return true;
+ }
+
+ function decodeKeypath(keypath) {
+ var value = keypath.slice(2);
+
+ if (keypath[1] === "i") {
+ return is__isNumeric(value) ? +value : value;
+ } else {
+ return value;
+ }
+ }
+
+ function getKeypath(str) {
+ if (str == null) {
+ return str;
+ }
+
+ // TODO it *may* be worth having two versions of this function - one where
+ // keypathCache inherits from null, and one for IE8. Depends on how
+ // much of an overhead hasOwnProperty is - probably negligible
+ if (!keypathCache.hasOwnProperty(str)) {
+ keypathCache[str] = new Keypath(str);
+ }
+
+ return keypathCache[str];
+ }
+
+ function getMatchingKeypaths(ractive, keypath) {
+ var keys, key, matchingKeypaths;
+
+ keys = keypath.str.split(".");
+ matchingKeypaths = [rootKeypath];
+
+ while (key = keys.shift()) {
+ if (key === "*") {
+ // expand to find all valid child keypaths
+ matchingKeypaths = matchingKeypaths.reduce(expand, []);
+ } else {
+ if (matchingKeypaths[0] === rootKeypath) {
+ // first key
+ matchingKeypaths[0] = getKeypath(key);
+ } else {
+ matchingKeypaths = matchingKeypaths.map(concatenate(key));
}
- (function (vendors, lastTime, window) {
- var x, setTimeout;
- if (window.requestAnimationFrame) {
- return;
- }
- for (x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
- window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
- }
- if (!window.requestAnimationFrame) {
- setTimeout = window.setTimeout;
- window.requestAnimationFrame = function (callback) {
- var currTime, timeToCall, id;
- currTime = Date.now();
- timeToCall = Math.max(0, 16 - (currTime - lastTime));
- id = setTimeout(function () {
- callback(currTime + timeToCall);
- }, timeToCall);
- lastTime = currTime + timeToCall;
- return id;
- };
- }
- }([
- 'ms',
- 'moz',
- 'webkit',
- 'o'
- ], 0, window));
- return window.requestAnimationFrame;
- }();
-var Ractive_prototype_animate_animations = function (rAF) {
-
- var queue = [];
- var animations = {
- tick: function () {
- var i, animation;
- for (i = 0; i < queue.length; i += 1) {
- animation = queue[i];
- if (!animation.tick()) {
- queue.splice(i--, 1);
- }
- }
- if (queue.length) {
- rAF(animations.tick);
- } else {
- animations.running = false;
- }
- },
- add: function (animation) {
- queue[queue.length] = animation;
- if (!animations.running) {
- animations.running = true;
- animations.tick();
- }
- },
- abort: function (keypath, root) {
- var i = queue.length, animation;
- while (i--) {
- animation = queue[i];
- if (animation.root === root && animation.keypath === keypath) {
- animation.stop();
- }
- }
- }
- };
- return animations;
- }(Ractive_prototype_animate_requestAnimationFrame);
-var utils_warn = function () {
+ }
+ }
- if (typeof console !== 'undefined' && typeof console.warn === 'function' && typeof console.warn.apply === 'function') {
- return function () {
- console.warn.apply(console, arguments);
- };
+ return matchingKeypaths;
+
+ function expand(matchingKeypaths, keypath) {
+ var wrapper, value, keys;
+
+ if (keypath.isRoot) {
+ keys = [].concat(Object.keys(ractive.viewmodel.data), Object.keys(ractive.viewmodel.mappings), Object.keys(ractive.viewmodel.computations));
+ } else {
+ wrapper = ractive.viewmodel.wrapped[keypath.str];
+ value = wrapper ? wrapper.get() : ractive.viewmodel.get(keypath);
+
+ keys = value ? Object.keys(value) : null;
+ }
+
+ if (keys) {
+ keys.forEach(function (key) {
+ if (key !== "_ractive" || !isArray(value)) {
+ matchingKeypaths.push(keypath.join(key));
+ }
+ });
+ }
+
+ return matchingKeypaths;
+ }
+ }
+
+ function concatenate(key) {
+ return function (keypath) {
+ return keypath.join(key);
+ };
+ }
+ function normalise(ref) {
+ return ref ? ref.replace(refPattern, ".$1") : "";
+ }
+
+ var rootKeypath = getKeypath("");
+
+ var shared_add = add;
+ var shared_add__errorMessage = "Cannot add to a non-numeric value";
+ function add(root, keypath, d) {
+ if (typeof keypath !== "string" || !is__isNumeric(d)) {
+ throw new Error("Bad arguments");
+ }
+
+ var value = undefined,
+ changes = undefined;
+
+ if (/\*/.test(keypath)) {
+ changes = {};
+
+ getMatchingKeypaths(root, getKeypath(normalise(keypath))).forEach(function (keypath) {
+ var value = root.viewmodel.get(keypath);
+
+ if (!is__isNumeric(value)) {
+ throw new Error(shared_add__errorMessage);
}
- return function () {
- };
- }();
-var utils_isNumeric = function () {
- return function (thing) {
- return !isNaN(parseFloat(thing)) && isFinite(thing);
+ changes[keypath.str] = value + d;
+ });
+
+ return root.set(changes);
+ }
+
+ value = root.get(keypath);
+
+ if (!is__isNumeric(value)) {
+ throw new Error(shared_add__errorMessage);
+ }
+
+ return root.set(keypath, +value + d);
+ }
+
+ var prototype_add = Ractive$add;
+ function Ractive$add(keypath, d) {
+ return shared_add(this, keypath, d === undefined ? 1 : +d);
+ }
+
+ var requestAnimationFrame;
+
+ // If window doesn't exist, we don't need requestAnimationFrame
+ if (typeof window === "undefined") {
+ requestAnimationFrame = null;
+ } else {
+ // https://gist.github.com/paulirish/1579671
+ (function (vendors, lastTime, window) {
+
+ var x, setTimeout;
+
+ if (window.requestAnimationFrame) {
+ return;
+ }
+
+ for (x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
+ window.requestAnimationFrame = window[vendors[x] + "RequestAnimationFrame"];
+ }
+
+ if (!window.requestAnimationFrame) {
+ setTimeout = window.setTimeout;
+
+ window.requestAnimationFrame = function (callback) {
+ var currTime, timeToCall, id;
+
+ currTime = Date.now();
+ timeToCall = Math.max(0, 16 - (currTime - lastTime));
+ id = setTimeout(function () {
+ callback(currTime + timeToCall);
+ }, timeToCall);
+
+ lastTime = currTime + timeToCall;
+ return id;
};
- }();
-var shared_interpolate = function (isArray, isObject, isNumeric) {
+ }
+ })(vendors, 0, window);
- var interpolate = function (from, to) {
- if (isNumeric(from) && isNumeric(to)) {
- return makeNumberInterpolator(+from, +to);
- }
- if (isArray(from) && isArray(to)) {
- return makeArrayInterpolator(from, to);
- }
- if (isObject(from) && isObject(to)) {
- return makeObjectInterpolator(from, to);
- }
- return function () {
- return to;
- };
+ requestAnimationFrame = window.requestAnimationFrame;
+ }
+
+ var rAF = requestAnimationFrame;
+
+ var getTime;
+
+ if (typeof window !== "undefined" && window.performance && typeof window.performance.now === "function") {
+ getTime = function () {
+ return window.performance.now();
+ };
+ } else {
+ getTime = function () {
+ return Date.now();
+ };
+ }
+
+ var utils_getTime = getTime;
+
+ var deprecations = {
+ construct: {
+ deprecated: "beforeInit",
+ replacement: "onconstruct"
+ },
+ render: {
+ deprecated: "init",
+ message: "The \"init\" method has been deprecated " + "and will likely be removed in a future release. " + "You can either use the \"oninit\" method which will fire " + "only once prior to, and regardless of, any eventual ractive " + "instance being rendered, or if you need to access the " + "rendered DOM, use \"onrender\" instead. " + "See http://docs.ractivejs.org/latest/migrating for more information."
+ },
+ complete: {
+ deprecated: "complete",
+ replacement: "oncomplete"
+ }
+ };
+
+ function Hook(event) {
+ this.event = event;
+ this.method = "on" + event;
+ this.deprecate = deprecations[event];
+ }
+
+ Hook.prototype.fire = function (ractive, arg) {
+ function call(method) {
+ if (ractive[method]) {
+ arg ? ractive[method](arg) : ractive[method]();
+ return true;
+ }
+ }
+
+ call(this.method);
+
+ if (!ractive[this.method] && this.deprecate && call(this.deprecate.deprecated)) {
+ if (this.deprecate.message) {
+ warnIfDebug(this.deprecate.message);
+ } else {
+ warnIfDebug("The method \"%s\" has been deprecated in favor of \"%s\" and will likely be removed in a future release. See http://docs.ractivejs.org/latest/migrating for more information.", this.deprecate.deprecated, this.deprecate.replacement);
+ }
+ }
+
+ arg ? ractive.fire(this.event, arg) : ractive.fire(this.event);
+ };
+
+ var hooks_Hook = Hook;
+
+ function addToArray(array, value) {
+ var index = array.indexOf(value);
+
+ if (index === -1) {
+ array.push(value);
+ }
+ }
+
+ function arrayContains(array, value) {
+ for (var i = 0, c = array.length; i < c; i++) {
+ if (array[i] == value) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ function arrayContentsMatch(a, b) {
+ var i;
+
+ if (!isArray(a) || !isArray(b)) {
+ return false;
+ }
+
+ if (a.length !== b.length) {
+ return false;
+ }
+
+ i = a.length;
+ while (i--) {
+ if (a[i] !== b[i]) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ function ensureArray(x) {
+ if (typeof x === "string") {
+ return [x];
+ }
+
+ if (x === undefined) {
+ return [];
+ }
+
+ return x;
+ }
+
+ function lastItem(array) {
+ return array[array.length - 1];
+ }
+
+ function removeFromArray(array, member) {
+ var index = array.indexOf(member);
+
+ if (index !== -1) {
+ array.splice(index, 1);
+ }
+ }
+
+ function toArray(arrayLike) {
+ var array = [],
+ i = arrayLike.length;
+ while (i--) {
+ array[i] = arrayLike[i];
+ }
+
+ return array;
+ }
+
+ var _Promise,
+ PENDING = {},
+ FULFILLED = {},
+ REJECTED = {};
+
+ if (typeof Promise === "function") {
+ // use native Promise
+ _Promise = Promise;
+ } else {
+ _Promise = function (callback) {
+ var fulfilledHandlers = [],
+ rejectedHandlers = [],
+ state = PENDING,
+ result,
+ dispatchHandlers,
+ makeResolver,
+ fulfil,
+ reject,
+ promise;
+
+ makeResolver = function (newState) {
+ return function (value) {
+ if (state !== PENDING) {
+ return;
+ }
+
+ result = value;
+ state = newState;
+
+ dispatchHandlers = makeDispatcher(state === FULFILLED ? fulfilledHandlers : rejectedHandlers, result);
+
+ // dispatch onFulfilled and onRejected handlers asynchronously
+ wait(dispatchHandlers);
};
- return interpolate;
- function makeNumberInterpolator(from, to) {
- var delta = to - from;
- if (!delta) {
- return function () {
- return from;
- };
- }
- return function (t) {
- return from + t * delta;
+ };
+
+ fulfil = makeResolver(FULFILLED);
+ reject = makeResolver(REJECTED);
+
+ try {
+ callback(fulfil, reject);
+ } catch (err) {
+ reject(err);
+ }
+
+ promise = {
+ // `then()` returns a Promise - 2.2.7
+ then: function (onFulfilled, onRejected) {
+ var promise2 = new _Promise(function (fulfil, reject) {
+
+ var processResolutionHandler = function (handler, handlers, forward) {
+
+ // 2.2.1.1
+ if (typeof handler === "function") {
+ handlers.push(function (p1result) {
+ var x;
+
+ try {
+ x = handler(p1result);
+ utils_Promise__resolve(promise2, x, fulfil, reject);
+ } catch (err) {
+ reject(err);
+ }
+ });
+ } else {
+ // Forward the result of promise1 to promise2, if resolution handlers
+ // are not given
+ handlers.push(forward);
+ }
};
- }
- function makeArrayInterpolator(from, to) {
- var intermediate, interpolators, len, i;
- intermediate = [];
- interpolators = [];
- i = len = Math.min(from.length, to.length);
- while (i--) {
- interpolators[i] = interpolate(from[i], to[i]);
- }
- for (i = len; i < from.length; i += 1) {
- intermediate[i] = from[i];
- }
- for (i = len; i < to.length; i += 1) {
- intermediate[i] = to[i];
+
+ // 2.2
+ processResolutionHandler(onFulfilled, fulfilledHandlers, fulfil);
+ processResolutionHandler(onRejected, rejectedHandlers, reject);
+
+ if (state !== PENDING) {
+ // If the promise has resolved already, dispatch the appropriate handlers asynchronously
+ wait(dispatchHandlers);
}
- return function (t) {
- var i = len;
- while (i--) {
- intermediate[i] = interpolators[i](t);
- }
- return intermediate;
- };
+ });
+
+ return promise2;
}
- function makeObjectInterpolator(from, to) {
- var properties = [], len, interpolators, intermediate, prop;
- intermediate = {};
- interpolators = {};
- for (prop in from) {
- if (from.hasOwnProperty(prop)) {
- if (to.hasOwnProperty(prop)) {
- properties[properties.length] = prop;
- interpolators[prop] = interpolate(from[prop], to[prop]);
- } else {
- intermediate[prop] = from[prop];
- }
- }
- }
- for (prop in to) {
- if (to.hasOwnProperty(prop) && !from.hasOwnProperty(prop)) {
- intermediate[prop] = to[prop];
- }
- }
- len = properties.length;
- return function (t) {
- var i = len, prop;
- while (i--) {
- prop = properties[i];
- intermediate[prop] = interpolators[prop](t);
- }
- return intermediate;
- };
+ };
+
+ promise["catch"] = function (onRejected) {
+ return this.then(null, onRejected);
+ };
+
+ return promise;
+ };
+
+ _Promise.all = function (promises) {
+ return new _Promise(function (fulfil, reject) {
+ var result = [],
+ pending,
+ i,
+ processPromise;
+
+ if (!promises.length) {
+ fulfil(result);
+ return;
}
- }(utils_isArray, utils_isObject, utils_isNumeric);
-var Ractive_prototype_animate_Animation = function (warn, interpolate) {
- var Animation = function (options) {
- var key;
- this.startTime = Date.now();
- for (key in options) {
- if (options.hasOwnProperty(key)) {
- this[key] = options[key];
- }
- }
- this.interpolator = interpolate(this.from, this.to);
- this.running = true;
- };
- Animation.prototype = {
- tick: function () {
- var elapsed, t, value, timeNow, index, keypath;
- keypath = this.keypath;
- if (this.running) {
- timeNow = Date.now();
- elapsed = timeNow - this.startTime;
- if (elapsed >= this.duration) {
- if (keypath !== null) {
- this.root.set(keypath, this.to);
- }
- if (this.step) {
- this.step(1, this.to);
- }
- if (this.complete) {
- this.complete(1, this.to);
- }
- index = this.root._animations.indexOf(this);
- if (index === -1) {
- warn('Animation was not found');
- }
- this.root._animations.splice(index, 1);
- this.running = false;
- return false;
- }
- t = this.easing ? this.easing(elapsed / this.duration) : elapsed / this.duration;
- if (keypath !== null) {
- value = this.interpolator(t);
- this.root.set(keypath, value);
- }
- if (this.step) {
- this.step(t, value);
- }
- return true;
- }
- return false;
- },
- stop: function () {
- var index;
- this.running = false;
- index = this.root._animations.indexOf(this);
- if (index === -1) {
- warn('Animation was not found');
- }
- this.root._animations.splice(index, 1);
- }
+ processPromise = function (promise, i) {
+ if (promise && typeof promise.then === "function") {
+ promise.then(function (value) {
+ result[i] = value;
+ --pending || fulfil(result);
+ }, reject);
+ } else {
+ result[i] = promise;
+ --pending || fulfil(result);
+ }
};
- return Animation;
- }(utils_warn, shared_interpolate);
-var registries_easing = function () {
- return {
- linear: function (pos) {
- return pos;
- },
- easeIn: function (pos) {
- return Math.pow(pos, 3);
- },
- easeOut: function (pos) {
- return Math.pow(pos - 1, 3) + 1;
- },
- easeInOut: function (pos) {
- if ((pos /= 0.5) < 1) {
- return 0.5 * Math.pow(pos, 3);
- }
- return 0.5 * (Math.pow(pos - 2, 3) + 2);
- }
- };
- }();
-var Ractive_prototype_animate__animate = function (isEqual, animations, Animation, easingRegistry) {
+ pending = i = promises.length;
+ while (i--) {
+ processPromise(promises[i], i);
+ }
+ });
+ };
- var noAnimation = {
- stop: function () {
- }
- };
- return function (keypath, to, options) {
- var k, animation, animations, easing, duration, step, complete, makeValueCollector, currentValues, collectValue, dummy, dummyOptions;
- if (typeof keypath === 'object') {
- options = to || {};
- easing = options.easing;
- duration = options.duration;
- animations = [];
- step = options.step;
- complete = options.complete;
- if (step || complete) {
- currentValues = {};
- options.step = null;
- options.complete = null;
- makeValueCollector = function (keypath) {
- return function (t, value) {
- currentValues[keypath] = value;
- };
- };
- }
- for (k in keypath) {
- if (keypath.hasOwnProperty(k)) {
- if (step || complete) {
- collectValue = makeValueCollector(k);
- options = {
- easing: easing,
- duration: duration
- };
- if (step) {
- options.step = collectValue;
- }
- if (complete) {
- options.complete = collectValue;
- }
- }
- animations[animations.length] = animate(this, k, keypath[k], options);
- }
- }
- if (step || complete) {
- dummyOptions = {
- easing: easing,
- duration: duration
- };
- if (step) {
- dummyOptions.step = function (t) {
- step(t, currentValues);
- };
- }
- if (complete) {
- dummyOptions.complete = function (t) {
- complete(t, currentValues);
- };
- }
- animations[animations.length] = dummy = animate(this, null, null, dummyOptions);
- }
- return {
- stop: function () {
- while (animations.length) {
- animations.pop().stop();
- }
- if (dummy) {
- dummy.stop();
- }
- }
- };
- }
- options = options || {};
- animation = animate(this, keypath, to, options);
- return {
- stop: function () {
- animation.stop();
- }
- };
- };
- function animate(root, keypath, to, options) {
- var easing, duration, animation, from;
- if (keypath !== null) {
- from = root.get(keypath);
- }
- animations.abort(keypath, root);
- if (isEqual(from, to)) {
- if (options.complete) {
- options.complete(1, options.to);
- }
- return noAnimation;
- }
- if (options.easing) {
- if (typeof options.easing === 'function') {
- easing = options.easing;
- } else {
- if (root.easing && root.easing[options.easing]) {
- easing = root.easing[options.easing];
- } else {
- easing = easingRegistry[options.easing];
- }
- }
- if (typeof easing !== 'function') {
- easing = null;
- }
- }
- duration = options.duration === undefined ? 400 : options.duration;
- animation = new Animation({
- keypath: keypath,
- from: from,
- to: to,
- root: root,
- duration: duration,
- easing: easing,
- step: options.step,
- complete: options.complete
- });
- animations.add(animation);
- root._animations[root._animations.length] = animation;
- return animation;
- }
- }(utils_isEqual, Ractive_prototype_animate_animations, Ractive_prototype_animate_Animation, registries_easing);
-var Ractive_prototype_on = function () {
-
- return function (eventName, callback) {
- var self = this, listeners, n;
- if (typeof eventName === 'object') {
- listeners = [];
- for (n in eventName) {
- if (eventName.hasOwnProperty(n)) {
- listeners[listeners.length] = this.on(n, eventName[n]);
- }
- }
- return {
- cancel: function () {
- while (listeners.length) {
- listeners.pop().cancel();
- }
- }
- };
- }
- if (!this._subs[eventName]) {
- this._subs[eventName] = [callback];
- } else {
- this._subs[eventName].push(callback);
- }
- return {
- cancel: function () {
- self.off(eventName, callback);
- }
- };
- };
- }();
-var Ractive_prototype_off = function () {
-
- return function (eventName, callback) {
- var subscribers, index;
- if (!callback) {
- if (!eventName) {
- this._subs = {};
- } else {
- this._subs[eventName] = [];
- }
- }
- subscribers = this._subs[eventName];
- if (subscribers) {
- index = subscribers.indexOf(callback);
- if (index !== -1) {
- subscribers.splice(index, 1);
- }
- }
- };
- }();
-var shared_registerDependant = function () {
-
- return function (dependant) {
- var depsByKeypath, deps, keys, parentKeypath, map, ractive, keypath, priority;
- ractive = dependant.root;
- keypath = dependant.keypath;
- priority = dependant.priority;
- depsByKeypath = ractive._deps[priority] || (ractive._deps[priority] = {});
- deps = depsByKeypath[keypath] || (depsByKeypath[keypath] = []);
- deps[deps.length] = dependant;
- dependant.registered = true;
- if (!keypath) {
- return;
- }
- keys = keypath.split('.');
- while (keys.length) {
- keys.pop();
- parentKeypath = keys.join('.');
- map = ractive._depsMap[parentKeypath] || (ractive._depsMap[parentKeypath] = []);
- if (map[keypath] === undefined) {
- map[keypath] = 0;
- map[map.length] = keypath;
- }
- map[keypath] += 1;
- keypath = parentKeypath;
- }
- };
- }();
-var shared_unregisterDependant = function () {
-
- return function (dependant) {
- var deps, index, keys, parentKeypath, map, ractive, keypath, priority;
- ractive = dependant.root;
- keypath = dependant.keypath;
- priority = dependant.priority;
- deps = ractive._deps[priority][keypath];
- index = deps.indexOf(dependant);
- if (index === -1 || !dependant.registered) {
- throw new Error('Attempted to remove a dependant that was no longer registered! This should not happen. If you are seeing this bug in development please raise an issue at https://github.com/RactiveJS/Ractive/issues - thanks');
- }
- deps.splice(index, 1);
- dependant.registered = false;
- if (!keypath) {
- return;
- }
- keys = keypath.split('.');
- while (keys.length) {
- keys.pop();
- parentKeypath = keys.join('.');
- map = ractive._depsMap[parentKeypath];
- map[keypath] -= 1;
- if (!map[keypath]) {
- map.splice(map.indexOf(keypath), 1);
- map[keypath] = undefined;
- }
- keypath = parentKeypath;
- }
- };
- }();
-var Ractive_prototype_observe_Observer = function (isEqual) {
-
- var Observer = function (ractive, keypath, callback, options) {
- var self = this;
- this.root = ractive;
- this.keypath = keypath;
- this.callback = callback;
- this.defer = options.defer;
- this.debug = options.debug;
- this.proxy = {
- update: function () {
- self.reallyUpdate();
- }
- };
- this.priority = 0;
- this.context = options && options.context ? options.context : ractive;
- };
- Observer.prototype = {
- init: function (immediate) {
- if (immediate !== false) {
- this.update();
- } else {
- this.value = this.root.get(this.keypath);
- }
- },
- update: function () {
- if (this.defer && this.ready) {
- this.root._deferred.observers.push(this.proxy);
- return;
- }
- this.reallyUpdate();
- },
- reallyUpdate: function () {
- var oldValue, newValue;
- oldValue = this.value;
- newValue = this.root.get(this.keypath);
- this.value = newValue;
- if (this.updating) {
- return;
- }
- this.updating = true;
- if (!isEqual(newValue, oldValue) || !this.ready) {
- try {
- this.callback.call(this.context, newValue, oldValue, this.keypath);
- } catch (err) {
- if (this.debug || this.root.debug) {
- throw err;
- }
- }
- }
- this.updating = false;
- }
- };
- return Observer;
- }(utils_isEqual);
-var Ractive_prototype_observe_getPattern = function () {
-
- return function (ractive, pattern) {
- var keys, key, values, toGet, newToGet, expand, concatenate;
- keys = pattern.split('.');
- toGet = [];
- expand = function (keypath) {
- var value, key;
- value = ractive._wrapped[keypath] ? ractive._wrapped[keypath].get() : ractive.get(keypath);
- for (key in value) {
- newToGet.push(keypath + '.' + key);
- }
- };
- concatenate = function (keypath) {
- return keypath + '.' + key;
- };
- while (key = keys.shift()) {
- if (key === '*') {
- newToGet = [];
- toGet.forEach(expand);
- toGet = newToGet;
- } else {
- if (!toGet[0]) {
- toGet[0] = key;
- } else {
- toGet = toGet.map(concatenate);
- }
- }
- }
- values = {};
- toGet.forEach(function (keypath) {
- values[keypath] = ractive.get(keypath);
- });
- return values;
- };
- }();
-var Ractive_prototype_observe_PatternObserver = function (isEqual, getPattern) {
-
- var PatternObserver, wildcard = /\*/;
- PatternObserver = function (ractive, keypath, callback, options) {
- this.root = ractive;
- this.callback = callback;
- this.defer = options.defer;
- this.debug = options.debug;
- this.keypath = keypath;
- this.regex = new RegExp('^' + keypath.replace(/\./g, '\\.').replace(/\*/g, '[^\\.]+') + '$');
- this.values = {};
- if (this.defer) {
- this.proxies = [];
- }
- this.priority = 'pattern';
- this.context = options && options.context ? options.context : ractive;
- };
- PatternObserver.prototype = {
- init: function (immediate) {
- var values, keypath;
- values = getPattern(this.root, this.keypath);
- if (immediate !== false) {
- for (keypath in values) {
- if (values.hasOwnProperty(keypath)) {
- this.update(keypath);
- }
- }
- } else {
- this.values = values;
- }
- },
- update: function (keypath) {
- var values;
- if (wildcard.test(keypath)) {
- values = getPattern(this.root, keypath);
- for (keypath in values) {
- if (values.hasOwnProperty(keypath)) {
- this.update(keypath);
- }
- }
- return;
- }
- if (this.defer && this.ready) {
- this.root._deferred.observers.push(this.getProxy(keypath));
- return;
- }
- this.reallyUpdate(keypath);
- },
- reallyUpdate: function (keypath) {
- var value = this.root.get(keypath);
- if (this.updating) {
- this.values[keypath] = value;
- return;
- }
- this.updating = true;
- if (!isEqual(value, this.values[keypath]) || !this.ready) {
- try {
- this.callback.call(this.context, value, this.values[keypath], keypath);
- } catch (err) {
- if (this.debug || this.root.debug) {
- throw err;
- }
- }
- this.values[keypath] = value;
- }
- this.updating = false;
- },
- getProxy: function (keypath) {
- var self = this;
- if (!this.proxies[keypath]) {
- this.proxies[keypath] = {
- update: function () {
- self.reallyUpdate(keypath);
- }
- };
- }
- return this.proxies[keypath];
- }
- };
- return PatternObserver;
- }(utils_isEqual, Ractive_prototype_observe_getPattern);
-var Ractive_prototype_observe_getObserverFacade = function (normaliseKeypath, registerDependant, unregisterDependant, Observer, PatternObserver) {
-
- var wildcard = /\*/, emptyObject = {};
- return function getObserverFacade(ractive, keypath, callback, options) {
- var observer, isPatternObserver;
- keypath = normaliseKeypath(keypath);
- options = options || emptyObject;
- if (wildcard.test(keypath)) {
- observer = new PatternObserver(ractive, keypath, callback, options);
- ractive._patternObservers.push(observer);
- isPatternObserver = true;
- } else {
- observer = new Observer(ractive, keypath, callback, options);
- }
- registerDependant(observer);
- observer.init(options.init);
- observer.ready = true;
- return {
- cancel: function () {
- var index;
- if (isPatternObserver) {
- index = ractive._patternObservers.indexOf(observer);
- if (index !== -1) {
- ractive._patternObservers.splice(index, 1);
- }
- }
- unregisterDependant(observer);
- }
- };
- };
- }(utils_normaliseKeypath, shared_registerDependant, shared_unregisterDependant, Ractive_prototype_observe_Observer, Ractive_prototype_observe_PatternObserver);
-var Ractive_prototype_observe__observe = function (isObject, getObserverFacade) {
-
- return function observe(keypath, callback, options) {
- var observers = [], k;
- if (isObject(keypath)) {
- options = callback;
- for (k in keypath) {
- if (keypath.hasOwnProperty(k)) {
- callback = keypath[k];
- observers[observers.length] = getObserverFacade(this, k, callback, options);
- }
- }
- return {
- cancel: function () {
- while (observers.length) {
- observers.pop().cancel();
- }
- }
- };
- }
- return getObserverFacade(this, keypath, callback, options);
- };
- }(utils_isObject, Ractive_prototype_observe_getObserverFacade);
-var Ractive_prototype_fire = function () {
+ _Promise.resolve = function (value) {
+ return new _Promise(function (fulfil) {
+ fulfil(value);
+ });
+ };
- return function (eventName) {
- var args, i, len, subscribers = this._subs[eventName];
- if (!subscribers) {
- return;
- }
- args = Array.prototype.slice.call(arguments, 1);
- for (i = 0, len = subscribers.length; i < len; i += 1) {
- subscribers[i].apply(this, args);
- }
+ _Promise.reject = function (reason) {
+ return new _Promise(function (fulfil, reject) {
+ reject(reason);
+ });
+ };
+ }
+
+ var utils_Promise = _Promise;
+
+ // TODO use MutationObservers or something to simulate setImmediate
+ function wait(callback) {
+ setTimeout(callback, 0);
+ }
+
+ function makeDispatcher(handlers, result) {
+ return function () {
+ var handler;
+
+ while (handler = handlers.shift()) {
+ handler(result);
+ }
+ };
+ }
+
+ function utils_Promise__resolve(promise, x, fulfil, reject) {
+ // Promise Resolution Procedure
+ var then;
+
+ // 2.3.1
+ if (x === promise) {
+ throw new TypeError("A promise's fulfillment handler cannot return the same promise");
+ }
+
+ // 2.3.2
+ if (x instanceof _Promise) {
+ x.then(fulfil, reject);
+ }
+
+ // 2.3.3
+ else if (x && (typeof x === "object" || typeof x === "function")) {
+ try {
+ then = x.then; // 2.3.3.1
+ } catch (e) {
+ reject(e); // 2.3.3.2
+ return;
+ }
+
+ // 2.3.3.3
+ if (typeof then === "function") {
+ var called, resolvePromise, rejectPromise;
+
+ resolvePromise = function (y) {
+ if (called) {
+ return;
+ }
+ called = true;
+ utils_Promise__resolve(promise, y, fulfil, reject);
};
- }();
-var Ractive_prototype_find = function () {
- return function (selector) {
- if (!this.el) {
- return null;
- }
- return this.fragment.find(selector);
+ rejectPromise = function (r) {
+ if (called) {
+ return;
+ }
+ called = true;
+ reject(r);
};
- }();
-var utils_matches = function (isClient, createElement) {
- var div, methodNames, unprefixed, prefixed, vendors, i, j, makeFunction;
- if (!isClient) {
+ try {
+ then.call(x, resolvePromise, rejectPromise);
+ } catch (e) {
+ if (!called) {
+ // 2.3.3.3.4.1
+ reject(e); // 2.3.3.3.4.2
+ called = true;
return;
+ }
}
- div = createElement('div');
- methodNames = [
- 'matches',
- 'matchesSelector'
- ];
- vendors = [
- 'o',
- 'ms',
- 'moz',
- 'webkit'
- ];
- makeFunction = function (methodName) {
- return function (node, selector) {
- return node[methodName](selector);
- };
- };
- i = methodNames.length;
- while (i--) {
- unprefixed = methodNames[i];
- if (div[unprefixed]) {
- return makeFunction(unprefixed);
- }
- j = vendors.length;
- while (j--) {
- prefixed = vendors[i] + unprefixed.substr(0, 1).toUpperCase() + unprefixed.substring(1);
- if (div[prefixed]) {
- return makeFunction(prefixed);
- }
- }
+ } else {
+ fulfil(x);
+ }
+ } else {
+ fulfil(x);
+ }
+ }
+
+ var getInnerContext = function (fragment) {
+ do {
+ if (fragment.context !== undefined) {
+ return fragment.context;
+ }
+ } while (fragment = fragment.parent);
+
+ return rootKeypath;
+ };
+
+ var shared_resolveRef = resolveRef;
+
+ function resolveRef(ractive, ref, fragment) {
+ var keypath;
+
+ ref = normalise(ref);
+
+ // If a reference begins '~/', it's a top-level reference
+ if (ref.substr(0, 2) === "~/") {
+ keypath = getKeypath(ref.substring(2));
+ createMappingIfNecessary(ractive, keypath.firstKey, fragment);
+ }
+
+ // If a reference begins with '.', it's either a restricted reference or
+ // an ancestor reference...
+ else if (ref[0] === ".") {
+ keypath = resolveAncestorRef(getInnerContext(fragment), ref);
+
+ if (keypath) {
+ createMappingIfNecessary(ractive, keypath.firstKey, fragment);
+ }
+ }
+
+ // ...otherwise we need to figure out the keypath based on context
+ else {
+ keypath = resolveAmbiguousReference(ractive, getKeypath(ref), fragment);
+ }
+
+ return keypath;
+ }
+
+ function resolveAncestorRef(baseContext, ref) {
+ var contextKeys;
+
+ // TODO...
+ if (baseContext != undefined && typeof baseContext !== "string") {
+ baseContext = baseContext.str;
+ }
+
+ // {{.}} means 'current context'
+ if (ref === ".") return getKeypath(baseContext);
+
+ contextKeys = baseContext ? baseContext.split(".") : [];
+
+ // ancestor references (starting "../") go up the tree
+ if (ref.substr(0, 3) === "../") {
+ while (ref.substr(0, 3) === "../") {
+ if (!contextKeys.length) {
+ throw new Error("Could not resolve reference - too many \"../\" prefixes");
}
- return function (node, selector) {
- var nodes, i;
- nodes = (node.parentNode || node.document).querySelectorAll(selector);
- i = nodes.length;
- while (i--) {
- if (nodes[i] === node) {
- return true;
- }
- }
- return false;
- };
- }(config_isClient, utils_createElement);
-var Ractive_prototype_shared_makeQuery_test = function (matches) {
-
- return function (item, noDirty) {
- var itemMatches = this._isComponentQuery ? !this.selector || item.name === this.selector : matches(item.node, this.selector);
- if (itemMatches) {
- this.push(item.node || item.instance);
- if (!noDirty) {
- this._makeDirty();
- }
- return true;
- }
- };
- }(utils_matches);
-var Ractive_prototype_shared_makeQuery_cancel = function () {
- return function () {
- var liveQueries, selector, index;
- liveQueries = this._root[this._isComponentQuery ? 'liveComponentQueries' : 'liveQueries'];
- selector = this.selector;
- index = liveQueries.indexOf(selector);
- if (index !== -1) {
- liveQueries.splice(index, 1);
- liveQueries[selector] = null;
- }
- };
- }();
-var Ractive_prototype_shared_makeQuery_sortByItemPosition = function () {
-
- return function (a, b) {
- var ancestryA, ancestryB, oldestA, oldestB, mutualAncestor, indexA, indexB, fragments, fragmentA, fragmentB;
- ancestryA = getAncestry(a.component || a._ractive.proxy);
- ancestryB = getAncestry(b.component || b._ractive.proxy);
- oldestA = ancestryA[ancestryA.length - 1];
- oldestB = ancestryB[ancestryB.length - 1];
- while (oldestA && oldestA === oldestB) {
- ancestryA.pop();
- ancestryB.pop();
- mutualAncestor = oldestA;
- oldestA = ancestryA[ancestryA.length - 1];
- oldestB = ancestryB[ancestryB.length - 1];
- }
- oldestA = oldestA.component || oldestA;
- oldestB = oldestB.component || oldestB;
- fragmentA = oldestA.parentFragment;
- fragmentB = oldestB.parentFragment;
- if (fragmentA === fragmentB) {
- indexA = fragmentA.items.indexOf(oldestA);
- indexB = fragmentB.items.indexOf(oldestB);
- return indexA - indexB || ancestryA.length - ancestryB.length;
- }
- if (fragments = mutualAncestor.fragments) {
- indexA = fragments.indexOf(fragmentA);
- indexB = fragments.indexOf(fragmentB);
- return indexA - indexB || ancestryA.length - ancestryB.length;
- }
- throw new Error('An unexpected condition was met while comparing the position of two components. Please file an issue at https://github.com/RactiveJS/Ractive/issues - thanks!');
- };
- function getParent(item) {
- var parentFragment;
- if (parentFragment = item.parentFragment) {
- return parentFragment.owner;
- }
- if (item.component && (parentFragment = item.component.parentFragment)) {
- return parentFragment.owner;
- }
+ contextKeys.pop();
+ ref = ref.substring(3);
+ }
+
+ contextKeys.push(ref);
+ return getKeypath(contextKeys.join("."));
+ }
+
+ // not an ancestor reference - must be a restricted reference (prepended with "." or "./")
+ if (!baseContext) {
+ return getKeypath(ref.replace(/^\.\/?/, ""));
+ }
+
+ return getKeypath(baseContext + ref.replace(/^\.\//, "."));
+ }
+
+ function resolveAmbiguousReference(ractive, ref, fragment, isParentLookup) {
+ var context, key, parentValue, hasContextChain, parentKeypath;
+
+ if (ref.isRoot) {
+ return ref;
+ }
+
+ key = ref.firstKey;
+
+ while (fragment) {
+ context = fragment.context;
+ fragment = fragment.parent;
+
+ if (!context) {
+ continue;
+ }
+
+ hasContextChain = true;
+ parentValue = ractive.viewmodel.get(context);
+
+ if (parentValue && (typeof parentValue === "object" || typeof parentValue === "function") && key in parentValue) {
+ return context.join(ref.str);
+ }
+ }
+
+ // Root/computed/mapped property?
+ if (isRootProperty(ractive.viewmodel, key)) {
+ return ref;
+ }
+
+ // If this is an inline component, and it's not isolated, we
+ // can try going up the scope chain
+ if (ractive.parent && !ractive.isolated) {
+ hasContextChain = true;
+ fragment = ractive.component.parentFragment;
+
+ key = getKeypath(key);
+
+ if (parentKeypath = resolveAmbiguousReference(ractive.parent, key, fragment, true)) {
+ // We need to create an inter-component binding
+ ractive.viewmodel.map(key, {
+ origin: ractive.parent.viewmodel,
+ keypath: parentKeypath
+ });
+
+ return ref;
+ }
+ }
+
+ // If there's no context chain, and the instance is either a) isolated or
+ // b) an orphan, then we know that the keypath is identical to the reference
+ if (!isParentLookup && !hasContextChain) {
+ // the data object needs to have a property by this name,
+ // to prevent future failed lookups
+ ractive.viewmodel.set(ref, undefined);
+ return ref;
+ }
+ }
+
+ function createMappingIfNecessary(ractive, key) {
+ var parentKeypath;
+
+ if (!ractive.parent || ractive.isolated || isRootProperty(ractive.viewmodel, key)) {
+ return;
+ }
+
+ key = getKeypath(key);
+
+ if (parentKeypath = resolveAmbiguousReference(ractive.parent, key, ractive.component.parentFragment, true)) {
+ ractive.viewmodel.map(key, {
+ origin: ractive.parent.viewmodel,
+ keypath: parentKeypath
+ });
+ }
+ }
+
+ function isRootProperty(viewmodel, key) {
+ // special case for reference to root
+ return key === "" || key in viewmodel.data || key in viewmodel.computations || key in viewmodel.mappings;
+ }
+
+ function teardown(x) {
+ x.teardown();
+ }
+
+ function methodCallers__unbind(x) {
+ x.unbind();
+ }
+
+ function methodCallers__unrender(x) {
+ x.unrender();
+ }
+
+ function cancel(x) {
+ x.cancel();
+ }
+
+ var TransitionManager = function (callback, parent) {
+ this.callback = callback;
+ this.parent = parent;
+
+ this.intros = [];
+ this.outros = [];
+
+ this.children = [];
+ this.totalChildren = this.outroChildren = 0;
+
+ this.detachQueue = [];
+ this.decoratorQueue = [];
+ this.outrosComplete = false;
+
+ if (parent) {
+ parent.addChild(this);
+ }
+ };
+
+ TransitionManager.prototype = {
+ addChild: function (child) {
+ this.children.push(child);
+
+ this.totalChildren += 1;
+ this.outroChildren += 1;
+ },
+
+ decrementOutros: function () {
+ this.outroChildren -= 1;
+ check(this);
+ },
+
+ decrementTotal: function () {
+ this.totalChildren -= 1;
+ check(this);
+ },
+
+ add: function (transition) {
+ var list = transition.isIntro ? this.intros : this.outros;
+ list.push(transition);
+ },
+
+ addDecorator: function (decorator) {
+ this.decoratorQueue.push(decorator);
+ },
+
+ remove: function (transition) {
+ var list = transition.isIntro ? this.intros : this.outros;
+ removeFromArray(list, transition);
+ check(this);
+ },
+
+ init: function () {
+ this.ready = true;
+ check(this);
+ },
+
+ detachNodes: function () {
+ this.decoratorQueue.forEach(teardown);
+ this.detachQueue.forEach(detach);
+ this.children.forEach(detachNodes);
+ }
+ };
+
+ function detach(element) {
+ element.detach();
+ }
+
+ function detachNodes(tm) {
+ tm.detachNodes();
+ }
+
+ function check(tm) {
+ if (!tm.ready || tm.outros.length || tm.outroChildren) return;
+
+ // If all outros are complete, and we haven't already done this,
+ // we notify the parent if there is one, otherwise
+ // start detaching nodes
+ if (!tm.outrosComplete) {
+ if (tm.parent) {
+ tm.parent.decrementOutros(tm);
+ } else {
+ tm.detachNodes();
+ }
+
+ tm.outrosComplete = true;
+ }
+
+ // Once everything is done, we can notify parent transition
+ // manager and call the callback
+ if (!tm.intros.length && !tm.totalChildren) {
+ if (typeof tm.callback === "function") {
+ tm.callback();
+ }
+
+ if (tm.parent) {
+ tm.parent.decrementTotal();
+ }
+ }
+ }
+
+ var global_TransitionManager = TransitionManager;
+
+ var batch,
+ runloop,
+ unresolved = [],
+ changeHook = new hooks_Hook("change");
+
+ runloop = {
+ start: function (instance, returnPromise) {
+ var promise, fulfilPromise;
+
+ if (returnPromise) {
+ promise = new utils_Promise(function (f) {
+ return fulfilPromise = f;
+ });
+ }
+
+ batch = {
+ previousBatch: batch,
+ transitionManager: new global_TransitionManager(fulfilPromise, batch && batch.transitionManager),
+ views: [],
+ tasks: [],
+ ractives: [],
+ instance: instance
+ };
+
+ if (instance) {
+ batch.ractives.push(instance);
+ }
+
+ return promise;
+ },
+
+ end: function () {
+ flushChanges();
+
+ batch.transitionManager.init();
+ if (!batch.previousBatch && !!batch.instance) batch.instance.viewmodel.changes = [];
+ batch = batch.previousBatch;
+ },
+
+ addRactive: function (ractive) {
+ if (batch) {
+ addToArray(batch.ractives, ractive);
+ }
+ },
+
+ registerTransition: function (transition) {
+ transition._manager = batch.transitionManager;
+ batch.transitionManager.add(transition);
+ },
+
+ registerDecorator: function (decorator) {
+ batch.transitionManager.addDecorator(decorator);
+ },
+
+ addView: function (view) {
+ batch.views.push(view);
+ },
+
+ addUnresolved: function (thing) {
+ unresolved.push(thing);
+ },
+
+ removeUnresolved: function (thing) {
+ removeFromArray(unresolved, thing);
+ },
+
+ // synchronise node detachments with transition ends
+ detachWhenReady: function (thing) {
+ batch.transitionManager.detachQueue.push(thing);
+ },
+
+ scheduleTask: function (task, postRender) {
+ var _batch;
+
+ if (!batch) {
+ task();
+ } else {
+ _batch = batch;
+ while (postRender && _batch.previousBatch) {
+ // this can't happen until the DOM has been fully updated
+ // otherwise in some situations (with components inside elements)
+ // transitions and decorators will initialise prematurely
+ _batch = _batch.previousBatch;
}
- function getAncestry(item) {
- var ancestry, ancestor;
- ancestry = [item];
- ancestor = getParent(item);
- while (ancestor) {
- ancestry.push(ancestor);
- ancestor = getParent(ancestor);
- }
- return ancestry;
+
+ _batch.tasks.push(task);
+ }
+ }
+ };
+
+ var global_runloop = runloop;
+
+ function flushChanges() {
+ var i, thing, changeHash;
+
+ while (batch.ractives.length) {
+ thing = batch.ractives.pop();
+ changeHash = thing.viewmodel.applyChanges();
+
+ if (changeHash) {
+ changeHook.fire(thing, changeHash);
+ }
+ }
+
+ attemptKeypathResolution();
+
+ // Now that changes have been fully propagated, we can update the DOM
+ // and complete other tasks
+ for (i = 0; i < batch.views.length; i += 1) {
+ batch.views[i].update();
+ }
+ batch.views.length = 0;
+
+ for (i = 0; i < batch.tasks.length; i += 1) {
+ batch.tasks[i]();
+ }
+ batch.tasks.length = 0;
+
+ // If updating the view caused some model blowback - e.g. a triple
+ // containing