mirror of
https://github.com/danbee/mpd-client
synced 2025-03-04 08:39:09 +00:00
Update CanJS to 2.0.4.
This commit is contained in:
parent
6bc65a23a8
commit
ecdc1c8983
@ -1,8 +1,8 @@
|
|||||||
/*!
|
/*!
|
||||||
* CanJS - 2.0.3
|
* CanJS - 2.0.4
|
||||||
* http://canjs.us/
|
* http://canjs.us/
|
||||||
* Copyright (c) 2013 Bitovi
|
* Copyright (c) 2013 Bitovi
|
||||||
* Thu, 19 Dec 2013 10:56:42 GMT
|
* Mon, 23 Dec 2013 19:49:28 GMT
|
||||||
* Licensed MIT
|
* Licensed MIT
|
||||||
* Includes: can/view/ejs
|
* Includes: can/view/ejs
|
||||||
* Download from: http://canjs.com
|
* Download from: http://canjs.com
|
||||||
|
|||||||
650
assets/js/libs/can.jquery.js
Normal file → Executable file
650
assets/js/libs/can.jquery.js
Normal file → Executable file
@ -1,8 +1,8 @@
|
|||||||
/*!
|
/*!
|
||||||
* CanJS - 2.0.3
|
* CanJS - 2.0.4
|
||||||
* http://canjs.us/
|
* http://canjs.us/
|
||||||
* Copyright (c) 2013 Bitovi
|
* Copyright (c) 2013 Bitovi
|
||||||
* Thu, 19 Dec 2013 10:56:41 GMT
|
* Mon, 23 Dec 2013 19:49:25 GMT
|
||||||
* Licensed MIT
|
* Licensed MIT
|
||||||
* Includes: can/component,can/construct,can/map,can/list,can/observe,can/compute,can/model,can/view,can/control,can/route,can/control/route,can/view/mustache,can/view/bindings,can/view/live,can/view/scope,can/util/string
|
* Includes: can/component,can/construct,can/map,can/list,can/observe,can/compute,can/model,can/view,can/control,can/route,can/control/route,can/view/mustache,can/view/bindings,can/view/live,can/view/scope,can/util/string
|
||||||
* Download from: http://canjs.com
|
* Download from: http://canjs.com
|
||||||
@ -30,7 +30,7 @@
|
|||||||
return object._cid = (name || "") + (++cid)
|
return object._cid = (name || "") + (++cid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
can.VERSION = '2.0.3';
|
can.VERSION = '2.0.4';
|
||||||
|
|
||||||
can.simpleExtend = function(d, s) {
|
can.simpleExtend = function(d, s) {
|
||||||
for (var prop in s) {
|
for (var prop in s) {
|
||||||
@ -58,6 +58,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (elements.hasOwnProperty) {
|
} else if (elements.hasOwnProperty) {
|
||||||
|
if (can.Map && elements instanceof can.Map) {
|
||||||
|
can.__reading && can.__reading(elements, '__keys');
|
||||||
|
elements = elements.__get()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (key in elements) {
|
for (key in elements) {
|
||||||
if (elements.hasOwnProperty(key)) {
|
if (elements.hasOwnProperty(key)) {
|
||||||
if (callback.call(context || elements[key], elements[key], key, elements) === false) {
|
if (callback.call(context || elements[key], elements[key], key, elements) === false) {
|
||||||
@ -78,6 +84,8 @@
|
|||||||
// Given a list of elements, check if they are in the dom, if they
|
// Given a list of elements, check if they are in the dom, if they
|
||||||
// are in the dom, trigger inserted on them.
|
// are in the dom, trigger inserted on them.
|
||||||
can.inserted = function(elems) {
|
can.inserted = function(elems) {
|
||||||
|
// prevent mutations from changing the looping
|
||||||
|
elems = can.makeArray(elems);
|
||||||
var inDocument = false,
|
var inDocument = false,
|
||||||
checked = false,
|
checked = false,
|
||||||
children;
|
children;
|
||||||
@ -96,8 +104,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (inDocument && elem.getElementsByTagName) {
|
if (inDocument && elem.getElementsByTagName) {
|
||||||
can.trigger(elem, "inserted", [], false);
|
|
||||||
children = can.makeArray(elem.getElementsByTagName("*"));
|
children = can.makeArray(elem.getElementsByTagName("*"));
|
||||||
|
can.trigger(elem, "inserted", [], false);
|
||||||
for (var j = 0, child;
|
for (var j = 0, child;
|
||||||
(child = children[j]) !== undefined; j++) {
|
(child = children[j]) !== undefined; j++) {
|
||||||
// Trigger the destroyed event
|
// Trigger the destroyed event
|
||||||
@ -356,6 +364,11 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
},
|
||||||
|
proxy: function(fn, context) {
|
||||||
|
return function() {
|
||||||
|
return fn.apply(context, arguments)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1240,27 +1253,6 @@
|
|||||||
// A map that temporarily houses a reference
|
// A map that temporarily houses a reference
|
||||||
// to maps that have already been made for a plain ole JS object
|
// to maps that have already been made for a plain ole JS object
|
||||||
madeMap = null,
|
madeMap = null,
|
||||||
addToMap = function(obj, instance) {
|
|
||||||
var teardown = false;
|
|
||||||
if (!madeMap) {
|
|
||||||
teardown = true;
|
|
||||||
madeMap = {}
|
|
||||||
}
|
|
||||||
// record if it has a Cid before we add one
|
|
||||||
var hasCid = obj._cid;
|
|
||||||
var cid = can.cid(obj);
|
|
||||||
|
|
||||||
// only update if there already isn't one
|
|
||||||
if (!madeMap[cid]) {
|
|
||||||
|
|
||||||
madeMap[cid] = {
|
|
||||||
obj: obj,
|
|
||||||
instance: instance,
|
|
||||||
added: !hasCid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return teardown;
|
|
||||||
},
|
|
||||||
teardownMap = function() {
|
teardownMap = function() {
|
||||||
for (var cid in madeMap) {
|
for (var cid in madeMap) {
|
||||||
if (madeMap[cid].added) {
|
if (madeMap[cid].added) {
|
||||||
@ -1273,6 +1265,7 @@
|
|||||||
return madeMap && madeMap[obj._cid] && madeMap[obj._cid].instance
|
return madeMap && madeMap[obj._cid] && madeMap[obj._cid].instance
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var Map = can.Map = can.Construct.extend({
|
var Map = can.Map = can.Construct.extend({
|
||||||
|
|
||||||
setup: function() {
|
setup: function() {
|
||||||
@ -1284,9 +1277,13 @@
|
|||||||
if (!this.defaults) {
|
if (!this.defaults) {
|
||||||
this.defaults = {};
|
this.defaults = {};
|
||||||
}
|
}
|
||||||
|
// a list of the compute properties
|
||||||
|
this._computes = [];
|
||||||
for (var prop in this.prototype) {
|
for (var prop in this.prototype) {
|
||||||
if (typeof this.prototype[prop] !== "function") {
|
if (typeof this.prototype[prop] !== "function") {
|
||||||
this.defaults[prop] = this.prototype[prop];
|
this.defaults[prop] = this.prototype[prop];
|
||||||
|
} else if (this.prototype[prop].isComputed) {
|
||||||
|
this._computes.push(prop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1298,6 +1295,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
_computes: [],
|
||||||
// keep so it can be overwritten
|
// keep so it can be overwritten
|
||||||
bind: can.bindAndSetup,
|
bind: can.bindAndSetup,
|
||||||
on: can.bindAndSetup,
|
on: can.bindAndSetup,
|
||||||
@ -1305,6 +1303,28 @@
|
|||||||
off: can.unbindAndTeardown,
|
off: can.unbindAndTeardown,
|
||||||
id: "id",
|
id: "id",
|
||||||
helpers: {
|
helpers: {
|
||||||
|
addToMap: function(obj, instance) {
|
||||||
|
var teardown;
|
||||||
|
if (!madeMap) {
|
||||||
|
teardown = teardownMap;
|
||||||
|
madeMap = {}
|
||||||
|
}
|
||||||
|
// record if it has a Cid before we add one
|
||||||
|
var hasCid = obj._cid;
|
||||||
|
var cid = can.cid(obj);
|
||||||
|
|
||||||
|
// only update if there already isn't one
|
||||||
|
if (!madeMap[cid]) {
|
||||||
|
|
||||||
|
madeMap[cid] = {
|
||||||
|
obj: obj,
|
||||||
|
instance: instance,
|
||||||
|
added: !hasCid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return teardown;
|
||||||
|
},
|
||||||
|
|
||||||
canMakeObserve: function(obj) {
|
canMakeObserve: function(obj) {
|
||||||
return obj && !can.isDeferred(obj) && (can.isArray(obj) || can.isPlainObject(obj) || (obj instanceof can.Map));
|
return obj && !can.isDeferred(obj) && (can.isArray(obj) || can.isPlainObject(obj) || (obj instanceof can.Map));
|
||||||
},
|
},
|
||||||
@ -1388,30 +1408,28 @@
|
|||||||
// Sets all `attrs`.
|
// Sets all `attrs`.
|
||||||
this._init = 1;
|
this._init = 1;
|
||||||
this._setupComputes();
|
this._setupComputes();
|
||||||
var teardownMapping = obj && addToMap(obj, this);
|
var teardownMapping = obj && can.Map.helpers.addToMap(obj, this);
|
||||||
|
|
||||||
var data = can.extend(can.extend(true, {}, this.constructor.defaults || {}), obj)
|
var data = can.extend(can.extend(true, {}, this.constructor.defaults || {}), obj)
|
||||||
this.attr(data);
|
this.attr(data);
|
||||||
if (teardownMapping) {
|
|
||||||
teardownMap()
|
teardownMapping && teardownMapping()
|
||||||
}
|
|
||||||
this.bind('change', can.proxy(this._changes, this));
|
this.bind('change', can.proxy(this._changes, this));
|
||||||
|
|
||||||
delete this._init;
|
delete this._init;
|
||||||
},
|
},
|
||||||
|
|
||||||
_setupComputes: function() {
|
_setupComputes: function() {
|
||||||
var prototype = this.constructor.prototype;
|
var computes = this.constructor._computes;
|
||||||
this._computedBindings = {}
|
this._computedBindings = {};
|
||||||
for (var prop in prototype) {
|
for (var i = 0, len = computes.length, prop; i < len; i++) {
|
||||||
if (prototype[prop] && prototype[prop].isComputed) {
|
prop = computes[i];
|
||||||
this[prop] = prototype[prop].clone(this);
|
this[prop] = this[prop].clone(this);
|
||||||
this._computedBindings[prop] = {
|
this._computedBindings[prop] = {
|
||||||
count: 0
|
count: 0
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
_bindsetup: makeBindSetup(),
|
_bindsetup: makeBindSetup(),
|
||||||
_bindteardown: function() {
|
_bindteardown: function() {
|
||||||
@ -1724,6 +1742,16 @@
|
|||||||
|
|
||||||
// Helpers for `observable` lists.
|
// Helpers for `observable` lists.
|
||||||
var splice = [].splice,
|
var splice = [].splice,
|
||||||
|
// test if splice works correctly
|
||||||
|
spliceRemovesProps = (function() {
|
||||||
|
// IE's splice doesn't remove properties
|
||||||
|
var obj = {
|
||||||
|
0: "a",
|
||||||
|
length: 1
|
||||||
|
};
|
||||||
|
splice.call(obj, 0, 1);
|
||||||
|
return !obj[0];
|
||||||
|
})(),
|
||||||
|
|
||||||
list = Map(
|
list = Map(
|
||||||
|
|
||||||
@ -1738,11 +1766,18 @@
|
|||||||
this.length = 0;
|
this.length = 0;
|
||||||
can.cid(this, ".map")
|
can.cid(this, ".map")
|
||||||
this._init = 1;
|
this._init = 1;
|
||||||
|
instances = instances || [];
|
||||||
|
|
||||||
|
|
||||||
if (can.isDeferred(instances)) {
|
if (can.isDeferred(instances)) {
|
||||||
this.replace(instances)
|
this.replace(instances)
|
||||||
} else {
|
} else {
|
||||||
|
var teardownMapping = instances.length && can.Map.helpers.addToMap(instances, this);
|
||||||
this.push.apply(this, can.makeArray(instances || []));
|
this.push.apply(this, can.makeArray(instances || []));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
teardownMapping && teardownMapping();
|
||||||
|
|
||||||
// this change needs to be ignored
|
// this change needs to be ignored
|
||||||
this.bind('change', can.proxy(this._changes, this));
|
this.bind('change', can.proxy(this._changes, this));
|
||||||
can.simpleExtend(this, options);
|
can.simpleExtend(this, options);
|
||||||
@ -1803,6 +1838,13 @@
|
|||||||
howMany = args[1] = this.length - index;
|
howMany = args[1] = this.length - index;
|
||||||
}
|
}
|
||||||
var removed = splice.apply(this, args);
|
var removed = splice.apply(this, args);
|
||||||
|
|
||||||
|
if (!spliceRemovesProps) {
|
||||||
|
for (var i = this.length; i < removed.length + this.length; i++) {
|
||||||
|
delete this[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
can.batch.start();
|
can.batch.start();
|
||||||
if (howMany > 0) {
|
if (howMany > 0) {
|
||||||
this._triggerChange("" + index, "remove", undefined, removed);
|
this._triggerChange("" + index, "remove", undefined, removed);
|
||||||
@ -1977,7 +2019,6 @@
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
can.List = Map.List = list;
|
can.List = Map.List = list;
|
||||||
return can.List;
|
return can.List;
|
||||||
})(__m2, __m12);
|
})(__m2, __m12);
|
||||||
@ -3157,6 +3198,7 @@
|
|||||||
// elements whos default value we should set
|
// elements whos default value we should set
|
||||||
defaultValue: ["input", "textarea"],
|
defaultValue: ["input", "textarea"],
|
||||||
// a map of parent element to child elements
|
// a map of parent element to child elements
|
||||||
|
|
||||||
tagMap: {
|
tagMap: {
|
||||||
"": "span",
|
"": "span",
|
||||||
table: "tbody",
|
table: "tbody",
|
||||||
@ -3177,11 +3219,11 @@
|
|||||||
th: "tr",
|
th: "tr",
|
||||||
li: "ul"
|
li: "ul"
|
||||||
},
|
},
|
||||||
|
// Used to determine the parentNode if el is directly within a documentFragment
|
||||||
getParentNode: function(el, defaultParentNode) {
|
getParentNode: function(el, defaultParentNode) {
|
||||||
return defaultParentNode && el.parentNode.nodeType === 11 ? defaultParentNode : el.parentNode;
|
return defaultParentNode && el.parentNode.nodeType === 11 ? defaultParentNode : el.parentNode;
|
||||||
},
|
},
|
||||||
// set an attribute on an element
|
// Set an attribute on an element
|
||||||
setAttr: function(el, attrName, val) {
|
setAttr: function(el, attrName, val) {
|
||||||
var tagName = el.nodeName.toString().toLowerCase(),
|
var tagName = el.nodeName.toString().toLowerCase(),
|
||||||
prop = elements.attrMap[attrName];
|
prop = elements.attrMap[attrName];
|
||||||
@ -3200,14 +3242,14 @@
|
|||||||
el.setAttribute(attrName, val);
|
el.setAttribute(attrName, val);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// gets the value of an attribute
|
// Gets the value of an attribute.
|
||||||
getAttr: function(el, attrName) {
|
getAttr: function(el, attrName) {
|
||||||
// Default to a blank string for IE7/8
|
// Default to a blank string for IE7/8
|
||||||
return (elements.attrMap[attrName] && el[elements.attrMap[attrName]] ?
|
return (elements.attrMap[attrName] && el[elements.attrMap[attrName]] ?
|
||||||
el[elements.attrMap[attrName]] :
|
el[elements.attrMap[attrName]] :
|
||||||
el.getAttribute(attrName)) || '';
|
el.getAttribute(attrName)) || '';
|
||||||
},
|
},
|
||||||
// removes the attribute
|
// Removes the attribute.
|
||||||
removeAttr: function(el, attrName) {
|
removeAttr: function(el, attrName) {
|
||||||
var setter = elements.attrMap[attrName];
|
var setter = elements.attrMap[attrName];
|
||||||
if (typeof prop === "function") {
|
if (typeof prop === "function") {
|
||||||
@ -3221,6 +3263,7 @@
|
|||||||
el.removeAttribute(attrName);
|
el.removeAttribute(attrName);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// Gets a "pretty" value for something
|
||||||
contentText: function(text) {
|
contentText: function(text) {
|
||||||
if (typeof text == 'string') {
|
if (typeof text == 'string') {
|
||||||
return text;
|
return text;
|
||||||
@ -3230,9 +3273,25 @@
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
return "" + text;
|
return "" + text;
|
||||||
|
},
|
||||||
|
|
||||||
|
after: function(oldElements, newFrag) {
|
||||||
|
var last = oldElements[oldElements.length - 1];
|
||||||
|
|
||||||
|
// Insert it in the `document` or `documentFragment`
|
||||||
|
if (last.nextSibling) {
|
||||||
|
can.insertBefore(last.parentNode, newFrag, last.nextSibling)
|
||||||
|
} else {
|
||||||
|
can.appendChild(last.parentNode, newFrag);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
replace: function(oldElements, newFrag) {
|
||||||
|
elements.after(oldElements, newFrag);
|
||||||
|
can.remove(can.$(oldElements));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// TODO: this doesn't seem to be doing anything
|
||||||
// feature detect if setAttribute works with styles
|
// feature detect if setAttribute works with styles
|
||||||
(function() {
|
(function() {
|
||||||
// feature detect if
|
// feature detect if
|
||||||
@ -3412,12 +3471,14 @@
|
|||||||
fn(el);
|
fn(el);
|
||||||
});
|
});
|
||||||
|
|
||||||
var helperTags = hookupOptions.options.read('helpers._tags', {}).value,
|
var tagName = hookupOptions.tagName,
|
||||||
tagName = hookupOptions.tagName,
|
helperTagCallback = hookupOptions.options.read('helpers._tags.' + tagName, {
|
||||||
tagCallback = (helperTags && helperTags[tagName]) || Scanner.tags[tagName]
|
isArgument: true,
|
||||||
|
proxyMethods: false
|
||||||
|
}).value,
|
||||||
|
tagCallback = helperTagCallback || Scanner.tags[tagName];
|
||||||
|
|
||||||
|
// If this was an element like <foo-bar> that doesn't have a component, just render its content
|
||||||
// if this was an element like <foo-bar> that doesn't have a component, just render its content
|
|
||||||
var scope = hookupOptions.scope,
|
var scope = hookupOptions.scope,
|
||||||
res = tagCallback ? tagCallback(el, hookupOptions) : scope;
|
res = tagCallback ? tagCallback(el, hookupOptions) : scope;
|
||||||
|
|
||||||
@ -3707,7 +3768,10 @@
|
|||||||
default:
|
default:
|
||||||
// Track the current tag
|
// Track the current tag
|
||||||
if (lastToken === '<') {
|
if (lastToken === '<') {
|
||||||
tagName = token.split(/\s|!--/)[0];
|
|
||||||
|
tagName = token.substr(0, 3) === "!--" ?
|
||||||
|
"!--" : token.split(/\s/)[0];
|
||||||
|
|
||||||
var isClosingTag = false;
|
var isClosingTag = false;
|
||||||
|
|
||||||
if (tagName.indexOf("/") === 0) {
|
if (tagName.indexOf("/") === 0) {
|
||||||
@ -3905,10 +3969,11 @@
|
|||||||
return Scanner;
|
return Scanner;
|
||||||
})(__m19, __m21);
|
})(__m19, __m21);
|
||||||
|
|
||||||
// ## view/node_lists.js
|
// ## view/node_lists/node_lists.js
|
||||||
var __m24 = (function(can) {
|
var __m24 = (function(can) {
|
||||||
|
|
||||||
// text node expando test
|
// In some browsers, text nodes can not take expando properties.
|
||||||
|
// We test that here.
|
||||||
var canExpando = true;
|
var canExpando = true;
|
||||||
try {
|
try {
|
||||||
document.createTextNode('')._ = 0;
|
document.createTextNode('')._ = 0;
|
||||||
@ -3916,12 +3981,10 @@
|
|||||||
canExpando = false;
|
canExpando = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// a mapping of element ids to nodeList ids
|
// A mapping of element ids to nodeList id
|
||||||
var nodeMap = {},
|
var nodeMap = {},
|
||||||
// a mapping of ids to text nodes
|
// A mapping of ids to text nodes
|
||||||
textNodeMap = {},
|
textNodeMap = {},
|
||||||
// a mapping of nodeList ids to nodeList
|
|
||||||
nodeListMap = {},
|
|
||||||
expando = "ejs_" + Math.random(),
|
expando = "ejs_" + Math.random(),
|
||||||
_id = 0,
|
_id = 0,
|
||||||
id = function(node) {
|
id = function(node) {
|
||||||
@ -3942,98 +4005,90 @@
|
|||||||
return "text_" + _id;
|
return "text_" + _id;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// removes a nodeListId from a node's nodeListIds
|
splice = [].splice;
|
||||||
removeNodeListId = function(node, nodeListId) {
|
|
||||||
var nodeListIds = nodeMap[id(node)];
|
|
||||||
if (nodeListIds) {
|
|
||||||
var index = can.inArray(nodeListId, nodeListIds);
|
|
||||||
|
|
||||||
if (index >= 0) {
|
|
||||||
nodeListIds.splice(index, 1);
|
|
||||||
}
|
|
||||||
if (!nodeListIds.length) {
|
|
||||||
delete nodeMap[id(node)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
addNodeListId = function(node, nodeListId) {
|
|
||||||
var nodeListIds = nodeMap[id(node)];
|
|
||||||
if (!nodeListIds) {
|
|
||||||
nodeListIds = nodeMap[id(node)] = [];
|
|
||||||
}
|
|
||||||
nodeListIds.push(nodeListId);
|
|
||||||
};
|
|
||||||
|
|
||||||
var nodeLists = {
|
var nodeLists = {
|
||||||
id: id,
|
id: id,
|
||||||
// replaces the contents of one node list with the nodes in another list
|
|
||||||
replace: function(oldNodeList, newNodes) {
|
|
||||||
// for each node in the node list
|
|
||||||
oldNodeList = can.makeArray(oldNodeList);
|
|
||||||
|
|
||||||
// try every set
|
|
||||||
//can.each( oldNodeList, function(node){
|
|
||||||
var node = oldNodeList[0]
|
|
||||||
// for each nodeList the node is in
|
|
||||||
can.each(can.makeArray(nodeMap[id(node)]), function(nodeListId) {
|
|
||||||
|
|
||||||
// if startNode to endNode is
|
|
||||||
// within list, replace that list
|
|
||||||
// I think the problem is not the WHOLE part is being
|
|
||||||
// matched
|
|
||||||
var nodeList = nodeListMap[nodeListId],
|
|
||||||
startIndex = can.inArray(node, nodeList),
|
|
||||||
endIndex = can.inArray(oldNodeList[oldNodeList.length - 1], nodeList);
|
|
||||||
|
|
||||||
|
|
||||||
// remove this nodeListId from each node
|
update: function(nodeList, newNodes) {
|
||||||
if (startIndex >= 0 && endIndex >= 0) {
|
// Unregister all childNodes.
|
||||||
for (var i = startIndex; i <= endIndex; i++) {
|
can.each(nodeList.childNodeLists, function(nodeList) {
|
||||||
var n = nodeList[i];
|
nodeLists.unregister(nodeList)
|
||||||
removeNodeListId(n, nodeListId);
|
})
|
||||||
}
|
nodeList.childNodeLists = [];
|
||||||
// swap in new nodes into the nodeLIst
|
|
||||||
nodeList.splice.apply(nodeList, [startIndex, endIndex - startIndex + 1].concat(newNodes));
|
|
||||||
|
|
||||||
// tell these new nodes they belong to the nodeList
|
// Remove old node pointers to this list.
|
||||||
can.each(newNodes, function(node) {
|
can.each(nodeList, function(node) {
|
||||||
addNodeListId(node, nodeListId);
|
delete nodeMap[id(node)];
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
nodeLists.unregister(nodeList);
|
var newNodes = can.makeArray(newNodes);
|
||||||
|
|
||||||
|
// indicate the new nodes belong to this list
|
||||||
|
can.each(newNodes, function(node) {
|
||||||
|
nodeMap[id(node)] = nodeList;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var oldListLength = nodeList.length,
|
||||||
|
firstNode = nodeList[0];
|
||||||
|
// Replace oldNodeLists's contents'
|
||||||
|
splice.apply(nodeList, [0, oldListLength].concat(newNodes));
|
||||||
|
|
||||||
|
// update all parent nodes so they are able to replace the correct elements
|
||||||
|
var parentNodeList = nodeList;
|
||||||
|
while (parentNodeList = parentNodeList.parentNodeList) {
|
||||||
|
splice.apply(parentNodeList, [can.inArray(firstNode, parentNodeList), oldListLength].concat(newNodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
register: function(nodeList, unregistered, parent) {
|
||||||
|
|
||||||
|
// add an id to the nodeList
|
||||||
|
nodeList.unregistered = unregistered,
|
||||||
|
|
||||||
|
nodeList.childNodeLists = [];
|
||||||
|
|
||||||
|
if (!parent) {
|
||||||
|
// find the parent by looking up where this node is
|
||||||
|
if (nodeList.length > 1) {
|
||||||
|
throw "does not work"
|
||||||
}
|
}
|
||||||
});
|
var nodeId = id(nodeList[0]);
|
||||||
//});
|
parent = nodeMap[nodeId];
|
||||||
},
|
|
||||||
// registers a list of nodes
|
|
||||||
register: function(nodeList) {
|
|
||||||
var nLId = id(nodeList);
|
|
||||||
nodeListMap[nLId] = nodeList;
|
|
||||||
|
|
||||||
can.each(nodeList, function(node) {
|
|
||||||
addNodeListId(node, nLId);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
}
|
||||||
|
nodeList.parentNodeList = parent;
|
||||||
|
parent && parent.childNodeLists.push(nodeList);
|
||||||
|
return nodeList;
|
||||||
},
|
},
|
||||||
// removes mappings
|
// removes node in all parent nodes and unregisters all childNodes
|
||||||
|
|
||||||
unregister: function(nodeList) {
|
unregister: function(nodeList) {
|
||||||
var nLId = id(nodeList);
|
if (!nodeList.isUnregistered) {
|
||||||
can.each(nodeList, function(node) {
|
nodeList.isUnregistered = true;
|
||||||
removeNodeListId(node, nLId);
|
// unregister all childNodeLists
|
||||||
});
|
delete nodeList.parentNodeList;
|
||||||
delete nodeListMap[nLId];
|
can.each(nodeList, function(node) {
|
||||||
|
var nodeId = id(node);
|
||||||
|
delete nodeMap[nodeId]
|
||||||
|
});
|
||||||
|
// this can unbind which will call itself
|
||||||
|
nodeList.unregistered && nodeList.unregistered();
|
||||||
|
can.each(nodeList.childNodeLists, function(nodeList) {
|
||||||
|
nodeLists.unregister(nodeList)
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
nodeMap: nodeMap,
|
nodeMap: nodeMap,
|
||||||
nodeListMap: nodeListMap
|
|
||||||
}
|
|
||||||
var ids = function(nodeList) {
|
|
||||||
return nodeList.map(function(n) {
|
|
||||||
return id(n) + ":" + (n.innerHTML || n.nodeValue)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return nodeLists;
|
return nodeLists;
|
||||||
|
|
||||||
})(__m2);
|
})(__m2, __m21);
|
||||||
|
|
||||||
// ## view/live/live.js
|
// ## view/live/live.js
|
||||||
var __m23 = (function(can, elements, view, nodeLists) {
|
var __m23 = (function(can, elements, view, nodeLists) {
|
||||||
@ -4048,12 +4103,21 @@
|
|||||||
// `setup(HTMLElement, bind(data), unbind(data)) -> data`
|
// `setup(HTMLElement, bind(data), unbind(data)) -> data`
|
||||||
// Calls bind right away, but will call unbind
|
// Calls bind right away, but will call unbind
|
||||||
// if the element is "destroyed" (removed from the DOM).
|
// if the element is "destroyed" (removed from the DOM).
|
||||||
|
var setupCount = 0;
|
||||||
var setup = function(el, bind, unbind) {
|
var setup = function(el, bind, unbind) {
|
||||||
var teardown = function() {
|
// Removing an element can call teardown which
|
||||||
unbind(data)
|
// unregister the nodeList which calls teardown
|
||||||
can.unbind.call(el, 'removed', teardown);
|
var tornDown = false,
|
||||||
return true
|
teardown = function() {
|
||||||
},
|
if (!tornDown) {
|
||||||
|
tornDown = true;
|
||||||
|
unbind(data)
|
||||||
|
can.unbind.call(el, 'removed', teardown);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
},
|
||||||
data = {
|
data = {
|
||||||
// returns true if no parent
|
// returns true if no parent
|
||||||
teardownCheck: function(parent) {
|
teardownCheck: function(parent) {
|
||||||
@ -4083,65 +4147,82 @@
|
|||||||
getAttributeParts = function(newVal) {
|
getAttributeParts = function(newVal) {
|
||||||
return (newVal || "").replace(/['"]/g, '').split('=')
|
return (newVal || "").replace(/['"]/g, '').split('=')
|
||||||
},
|
},
|
||||||
// #### insertElementsAfter
|
splice = [].splice;
|
||||||
// Appends elements after the last item in oldElements.
|
|
||||||
insertElementsAfter = function(oldElements, newFrag) {
|
|
||||||
var last = oldElements[oldElements.length - 1];
|
|
||||||
|
|
||||||
// Insert it in the `document` or `documentFragment`
|
|
||||||
if (last.nextSibling) {
|
|
||||||
can.insertBefore(last.parentNode, newFrag, last.nextSibling)
|
|
||||||
} else {
|
|
||||||
can.appendChild(last.parentNode, newFrag);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var live = {
|
var live = {
|
||||||
nodeLists: nodeLists,
|
|
||||||
|
|
||||||
list: function(el, compute, func, context, parentNode) {
|
list: function(el, compute, render, context, parentNode) {
|
||||||
// A mapping of the index to an array
|
|
||||||
// of elements that represent the item.
|
|
||||||
// Each array is registered so child or parent
|
// A nodeList of all elements this live-list manages.
|
||||||
// live structures can update the elements
|
// This is here so that if this live list is within another section
|
||||||
var nodesMap = [],
|
// that section is able to remove the items in this list.
|
||||||
// called when an item is added
|
var masterNodeList = [el],
|
||||||
|
// A mapping of the index of an item to an array
|
||||||
|
// of elements that represent the item.
|
||||||
|
// Each array is registered so child or parent
|
||||||
|
// live structures can update the elements.
|
||||||
|
itemIndexToNodeListsMap = [],
|
||||||
|
// A mapping of items to their indicies'
|
||||||
|
indexMap = [],
|
||||||
|
|
||||||
|
// Called when items are added to the list.
|
||||||
add = function(ev, items, index) {
|
add = function(ev, items, index) {
|
||||||
// check that the placeholder textNode still has a parent.
|
|
||||||
// it's possible someone removed the contents of
|
|
||||||
// this element without removing the parent
|
|
||||||
if (data.teardownCheck(text.parentNode)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect new html and mappings
|
// Collect new html and mappings
|
||||||
var frag = document.createDocumentFragment(),
|
var frag = document.createDocumentFragment(),
|
||||||
newMappings = [];
|
newNodeLists = [],
|
||||||
can.each(items, function(item, key) {
|
newIndicies = [];
|
||||||
var itemHTML = func.call(context, item, (key + index)),
|
|
||||||
itemFrag = can.view.frag(itemHTML, parentNode);
|
|
||||||
|
|
||||||
newMappings.push(can.makeArray(itemFrag.childNodes));
|
// For each new item,
|
||||||
frag.appendChild(itemFrag);
|
can.each(items, function(item, key) {
|
||||||
|
|
||||||
|
var itemIndex = can.compute(key + index),
|
||||||
|
// get its string content
|
||||||
|
itemHTML = render.call(context, item, itemIndex),
|
||||||
|
// and convert it into elements.
|
||||||
|
itemFrag = can.view.fragment(itemHTML)
|
||||||
|
|
||||||
|
|
||||||
|
// Add those elements to the mappings.
|
||||||
|
newNodeLists.push(
|
||||||
|
// Register those nodes with nodeLists.
|
||||||
|
nodeLists.register(can.makeArray(itemFrag.childNodes), undefined, masterNodeList));
|
||||||
|
|
||||||
|
// Hookup the fragment (which sets up child live-bindings) and
|
||||||
|
// add it to the collection of all added elements.
|
||||||
|
frag.appendChild(can.view.hookup(itemFrag));
|
||||||
|
newIndicies.push(itemIndex)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Inserting at the end of the list
|
// Check if we are adding items at the end
|
||||||
if (!nodesMap[index]) {
|
if (!itemIndexToNodeListsMap[index]) {
|
||||||
insertElementsAfter(
|
|
||||||
index == 0 ? [text] :
|
elements.after(
|
||||||
nodesMap[index - 1], frag)
|
// If we are adding items to an empty list
|
||||||
|
index == 0 ?
|
||||||
|
// add those items after the placeholder text element.
|
||||||
|
[text] :
|
||||||
|
// otherwise, add them after the last element in the previous index.
|
||||||
|
itemIndexToNodeListsMap[index - 1], frag)
|
||||||
} else {
|
} else {
|
||||||
var el = nodesMap[index][0];
|
// Add elements before the next index's first element.
|
||||||
|
var el = itemIndexToNodeListsMap[index][0];
|
||||||
can.insertBefore(el.parentNode, frag, el);
|
can.insertBefore(el.parentNode, frag, el);
|
||||||
}
|
}
|
||||||
// register each item
|
|
||||||
can.each(newMappings, function(nodeList) {
|
splice.apply(itemIndexToNodeListsMap, [index, 0].concat(newNodeLists));
|
||||||
nodeLists.register(nodeList)
|
|
||||||
});
|
// update indices after insert point
|
||||||
[].splice.apply(nodesMap, [index, 0].concat(newMappings));
|
splice.apply(indexMap, [index, 0].concat(newIndicies));
|
||||||
|
for (var i = index + newIndicies.length, len = indexMap.length; i < len; i++) {
|
||||||
|
indexMap[i](i)
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
// Remove can be called during teardown or when items are
|
|
||||||
// removed from the element.
|
// Called when items are removed or when the bindings are torn down.
|
||||||
remove = function(ev, items, index, duringTeardown) {
|
remove = function(ev, items, index, duringTeardown) {
|
||||||
|
|
||||||
// If this is because an element was removed, we should
|
// If this is because an element was removed, we should
|
||||||
@ -4151,61 +4232,72 @@
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var removedMappings = nodesMap.splice(index, items.length),
|
var removedMappings = itemIndexToNodeListsMap.splice(index, items.length),
|
||||||
itemsToRemove = [];
|
itemsToRemove = [];
|
||||||
|
|
||||||
can.each(removedMappings, function(nodeList) {
|
can.each(removedMappings, function(nodeList) {
|
||||||
// add items that we will remove all at once
|
// add items that we will remove all at once
|
||||||
[].push.apply(itemsToRemove, nodeList)
|
[].push.apply(itemsToRemove, nodeList)
|
||||||
// Update any parent lists to remove these items
|
// Update any parent lists to remove these items
|
||||||
nodeLists.replace(nodeList, []);
|
nodeLists.update(nodeList, []);
|
||||||
// unregister the list
|
// unregister the list
|
||||||
nodeLists.unregister(nodeList);
|
nodeLists.unregister(nodeList);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
// update indices after remove point
|
||||||
|
indexMap.splice(index, items.length)
|
||||||
|
for (var i = index, len = indexMap.length; i < len; i++) {
|
||||||
|
indexMap[i](i)
|
||||||
|
}
|
||||||
|
|
||||||
can.remove(can.$(itemsToRemove));
|
can.remove(can.$(itemsToRemove));
|
||||||
},
|
},
|
||||||
parentNode = elements.getParentNode(el, parentNode),
|
parentNode = elements.getParentNode(el, parentNode),
|
||||||
text = document.createTextNode(""),
|
text = document.createTextNode(""),
|
||||||
list;
|
// The current list.
|
||||||
|
list,
|
||||||
|
|
||||||
var teardownList = function() {
|
// Called when the list is replaced with a new list or the binding is torn-down.
|
||||||
// there might be no list right away, and the list might be a plain
|
teardownList = function() {
|
||||||
// array
|
// there might be no list right away, and the list might be a plain
|
||||||
list && list.unbind && list.unbind("add", add).unbind("remove", remove);
|
// array
|
||||||
// use remove to clean stuff up for us
|
list && list.unbind && list.unbind("add", add).unbind("remove", remove);
|
||||||
remove({}, {
|
// use remove to clean stuff up for us
|
||||||
length: nodesMap.length
|
remove({}, {
|
||||||
}, 0, true);
|
length: itemIndexToNodeListsMap.length
|
||||||
}
|
}, 0, true);
|
||||||
|
},
|
||||||
|
// Called when the list is replaced or setup.
|
||||||
|
updateList = function(ev, newList, oldList) {
|
||||||
|
teardownList();
|
||||||
|
// make an empty list if the compute returns null or undefined
|
||||||
|
list = newList || [];
|
||||||
|
// list might be a plain array
|
||||||
|
list.bind && list.bind("add", add).bind("remove", remove);
|
||||||
|
add({}, list, 0);
|
||||||
|
}
|
||||||
|
|
||||||
var updateList = function(ev, newList, oldList) {
|
|
||||||
teardownList();
|
|
||||||
// make an empty list if the compute returns null or undefined
|
|
||||||
list = newList || [];
|
|
||||||
// list might be a plain array
|
|
||||||
list.bind && list.bind("add", add).bind("remove", remove);
|
|
||||||
add({}, list, 0);
|
|
||||||
}
|
|
||||||
insertElementsAfter([el], text);
|
|
||||||
can.remove(can.$(el));
|
|
||||||
|
|
||||||
// Setup binding and teardown to add and remove events
|
// Setup binding and teardown to add and remove events
|
||||||
var data = setup(parentNode, function() {
|
var data = setup(parentNode, function() {
|
||||||
can.isFunction(compute) && compute.bind("change", updateList)
|
can.isFunction(compute) && compute.bind("change", updateList)
|
||||||
}, function() {
|
}, function() {
|
||||||
can.isFunction(compute) && compute.unbind("change", updateList)
|
can.isFunction(compute) && compute.unbind("change", updateList)
|
||||||
teardownList()
|
teardownList()
|
||||||
})
|
});
|
||||||
|
|
||||||
|
live.replace(masterNodeList, text, data.teardownCheck)
|
||||||
|
|
||||||
|
// run the list setup
|
||||||
updateList({}, can.isFunction(compute) ? compute() : compute)
|
updateList({}, can.isFunction(compute) ? compute() : compute)
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
html: function(el, compute, parentNode) {
|
html: function(el, compute, parentNode) {
|
||||||
var parentNode = elements.getParentNode(el, parentNode),
|
var parentNode = elements.getParentNode(el, parentNode),
|
||||||
|
|
||||||
data = listen(parentNode, compute, function(ev, newVal, oldVal) {
|
data = listen(parentNode, compute, function(ev, newVal, oldVal) {
|
||||||
|
// TODO: remove teardownCheck in 2.1
|
||||||
var attached = nodes[0].parentNode;
|
var attached = nodes[0].parentNode;
|
||||||
// update the nodes in the DOM with the new rendered value
|
// update the nodes in the DOM with the new rendered value
|
||||||
if (attached) {
|
if (attached) {
|
||||||
@ -4214,37 +4306,52 @@
|
|||||||
data.teardownCheck(nodes[0].parentNode);
|
data.teardownCheck(nodes[0].parentNode);
|
||||||
});
|
});
|
||||||
|
|
||||||
var nodes,
|
var nodes = [el],
|
||||||
makeAndPut = function(val) {
|
makeAndPut = function(val) {
|
||||||
// create the fragment, but don't hook it up
|
var frag = can.view.fragment("" + val),
|
||||||
// we need to insert it into the document first
|
oldNodes = can.makeArray(nodes);
|
||||||
var frag = can.view.frag(val, parentNode),
|
|
||||||
// keep a reference to each node
|
// We need to mark each node as belonging to the node list.
|
||||||
newNodes = can.makeArray(frag.childNodes);
|
nodeLists.update(nodes, frag.childNodes)
|
||||||
// Insert it in the `document` or `documentFragment`
|
|
||||||
insertElementsAfter(nodes || [el], frag)
|
frag = can.view.hookup(frag, parentNode)
|
||||||
// nodes hasn't been set yet
|
|
||||||
if (!nodes) {
|
elements.replace(oldNodes, frag)
|
||||||
can.remove(can.$(el));
|
|
||||||
nodes = newNodes;
|
|
||||||
// set the teardown nodeList
|
|
||||||
data.nodeList = nodes;
|
|
||||||
nodeLists.register(nodes);
|
|
||||||
} else {
|
|
||||||
// Update node Array's to point to new nodes
|
|
||||||
// and then remove the old nodes.
|
|
||||||
// It has to be in this order for Mootools
|
|
||||||
// and IE because somehow, after an element
|
|
||||||
// is removed from the DOM, it loses its
|
|
||||||
// expando values.
|
|
||||||
var nodesToRemove = can.makeArray(nodes);
|
|
||||||
nodeLists.replace(nodes, newNodes);
|
|
||||||
can.remove(can.$(nodesToRemove));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
makeAndPut(compute(), [el]);
|
|
||||||
|
data.nodeList = nodes;
|
||||||
|
// register the span so nodeLists knows the parentNodeList
|
||||||
|
nodeLists.register(nodes, data.teardownCheck)
|
||||||
|
makeAndPut(compute());
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
replace: function(nodes, val, teardown) {
|
||||||
|
var oldNodes = nodes.slice(0),
|
||||||
|
frag;
|
||||||
|
|
||||||
|
nodeLists.register(nodes, teardown);
|
||||||
|
if (typeof val === "string") {
|
||||||
|
frag = can.view.fragment(val)
|
||||||
|
} else if (val.nodeType !== 11) {
|
||||||
|
frag = document.createDocumentFragment();
|
||||||
|
frag.appendChild(val)
|
||||||
|
} else {
|
||||||
|
frag = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to mark each node as belonging to the node list.
|
||||||
|
nodeLists.update(nodes, frag.childNodes)
|
||||||
|
|
||||||
|
if (typeof val === "string") {
|
||||||
|
// if it was a string, check for hookups
|
||||||
|
frag = can.view.hookup(frag, nodes[0].parentNode);
|
||||||
|
}
|
||||||
|
elements.replace(oldNodes, frag);
|
||||||
|
|
||||||
|
return nodes;
|
||||||
|
},
|
||||||
|
|
||||||
text: function(el, compute, parentNode) {
|
text: function(el, compute, parentNode) {
|
||||||
var parent = elements.getParentNode(el, parentNode);
|
var parent = elements.getParentNode(el, parentNode);
|
||||||
|
|
||||||
@ -4254,20 +4361,16 @@
|
|||||||
if (typeof node.nodeValue != 'unknown') {
|
if (typeof node.nodeValue != 'unknown') {
|
||||||
node.nodeValue = "" + newVal;
|
node.nodeValue = "" + newVal;
|
||||||
}
|
}
|
||||||
|
// TODO: remove in 2.1
|
||||||
data.teardownCheck(node.parentNode);
|
data.teardownCheck(node.parentNode);
|
||||||
});
|
}),
|
||||||
|
// The text node that will be updated
|
||||||
|
node = document.createTextNode(compute());
|
||||||
|
|
||||||
var node = document.createTextNode(compute());
|
// Replace the placeholder with the live node and do the nodeLists thing.
|
||||||
|
live.replace([el], node, data.teardownCheck);
|
||||||
if (el.parentNode !== parent) {
|
|
||||||
parent = el.parentNode;
|
|
||||||
parent.insertBefore(node, el);
|
|
||||||
parent.removeChild(el);
|
|
||||||
} else {
|
|
||||||
parent.insertBefore(node, el);
|
|
||||||
parent.removeChild(el);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
attributes: function(el, compute, currentValue) {
|
attributes: function(el, compute, currentValue) {
|
||||||
var setAttrs = function(newVal) {
|
var setAttrs = function(newVal) {
|
||||||
var parts = getAttributeParts(newVal),
|
var parts = getAttributeParts(newVal),
|
||||||
@ -4372,6 +4475,8 @@
|
|||||||
return /^["'].*["']$/.test(val) ? val.substr(1, val.length - 2) : val
|
return /^["'].*["']$/.test(val) ? val.substr(1, val.length - 2) : val
|
||||||
}
|
}
|
||||||
can.view.live = live;
|
can.view.live = live;
|
||||||
|
can.view.nodeLists = nodeLists;
|
||||||
|
can.view.elements = elements;
|
||||||
return live;
|
return live;
|
||||||
|
|
||||||
})(__m2, __m21, __m19, __m24);
|
})(__m2, __m21, __m19, __m24);
|
||||||
@ -4538,6 +4643,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (listData) {
|
if (listData) {
|
||||||
|
unbind && unbind();
|
||||||
return "<" + tag + can.view.hook(function(el, parentNode) {
|
return "<" + tag + can.view.hook(function(el, parentNode) {
|
||||||
live.list(el, listData.list, listData.renderer, self, parentNode);
|
live.list(el, listData.list, listData.renderer, self, parentNode);
|
||||||
}) + "></" + tag + ">";
|
}) + "></" + tag + ">";
|
||||||
@ -4558,7 +4664,8 @@
|
|||||||
if (status === 0 && !contentProp) {
|
if (status === 0 && !contentProp) {
|
||||||
// Return an element tag with a hookup in place of the content
|
// Return an element tag with a hookup in place of the content
|
||||||
return "<" + tag + can.view.hook(
|
return "<" + tag + can.view.hook(
|
||||||
escape ?
|
// if value is an object, it's likely something returned by .safeString
|
||||||
|
escape && typeof value != "object" ?
|
||||||
// If we are escaping, replace the parentNode with
|
// If we are escaping, replace the parentNode with
|
||||||
// a text node who's value is `func`'s return value.
|
// a text node who's value is `func`'s return value.
|
||||||
|
|
||||||
@ -5443,25 +5550,23 @@
|
|||||||
// Implements the `each` built-in helper.
|
// Implements the `each` built-in helper.
|
||||||
|
|
||||||
'each': function(expr, options) {
|
'each': function(expr, options) {
|
||||||
if (!expr) {
|
// Check if this is a list or a compute that resolves to a list, and setup
|
||||||
return;
|
// the incremental live-binding
|
||||||
}
|
|
||||||
|
|
||||||
if (expr.isComputed || isObserveLike(expr) && typeof expr.attr('length') !== 'undefined') {
|
|
||||||
return can.view.lists && can.view.lists(expr, function(item, key) {
|
|
||||||
// Create a compute that listens to whenever the index of the item in our list changes.
|
|
||||||
var index = function() {
|
|
||||||
var exprResolved = Mustache.resolve(expr),
|
|
||||||
fromIndex = key < (exprResolved).attr('length') ? key : undefined;
|
|
||||||
|
|
||||||
return (exprResolved).indexOf(item, fromIndex);
|
// First, see what we are dealing with. It's ok to read the compute
|
||||||
};
|
// because can.view.text is only temporarily binding to what is going on here.
|
||||||
|
// Calling can.view.lists prevents anything from listening on that compute.
|
||||||
|
var resolved = Mustache.resolve(expr);
|
||||||
|
|
||||||
|
if (resolved instanceof can.List) {
|
||||||
|
return can.view.lists && can.view.lists(expr, function(item, index) {
|
||||||
return options.fn(options.scope.add({
|
return options.fn(options.scope.add({
|
||||||
"@index": index
|
"@index": index
|
||||||
}).add(item));
|
}).add(item));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
expr = Mustache.resolve(expr);
|
expr = resolved;
|
||||||
|
|
||||||
if ( !! expr && isArrayLike(expr)) {
|
if ( !! expr && isArrayLike(expr)) {
|
||||||
var result = [];
|
var result = [];
|
||||||
@ -5888,6 +5993,9 @@
|
|||||||
scope: this.scope
|
scope: this.scope
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
// if this component has a template (that we've already converted to a renderer)
|
// if this component has a template (that we've already converted to a renderer)
|
||||||
if (this.constructor.renderer) {
|
if (this.constructor.renderer) {
|
||||||
// add content to tags
|
// add content to tags
|
||||||
@ -5899,15 +6007,33 @@
|
|||||||
helpers._tags.content = function(el, rendererOptions) {
|
helpers._tags.content = function(el, rendererOptions) {
|
||||||
// first check if there was content within the custom tag
|
// first check if there was content within the custom tag
|
||||||
// otherwise, render what was within <content>, the default code
|
// otherwise, render what was within <content>, the default code
|
||||||
var subtemplate = hookupOptions.subtemplate || rendererOptions.subtemplate
|
var subtemplate = hookupOptions.subtemplate || rendererOptions.subtemplate;
|
||||||
|
|
||||||
if (subtemplate) {
|
if (subtemplate) {
|
||||||
var frag = can.view.frag(subtemplate(rendererOptions.scope, rendererOptions.options.add(helpers)));
|
|
||||||
can.insertBefore(el.parentNode, frag, el);
|
|
||||||
can.remove(can.$(el));
|
// rendererOptions.options is a scope of helpers where `<content>` was found, so
|
||||||
|
// the right helpers should already be available.
|
||||||
|
// However, _tags.content is going to point to this current content callback. We need to
|
||||||
|
// remove that so it will walk up the chain
|
||||||
|
|
||||||
|
delete helpers._tags.content;
|
||||||
|
|
||||||
|
can.view.live.replace([el], subtemplate(
|
||||||
|
// This is the context of where `<content>` was found
|
||||||
|
// which will have the the component's context
|
||||||
|
rendererOptions.scope,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rendererOptions.options));
|
||||||
|
|
||||||
|
// restore the content tag so it could potentially be used again (as in lists)
|
||||||
|
helpers._tags.content = arguments.callee;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// render the component's template
|
// render the component's template
|
||||||
var frag = this.constructor.renderer(renderedScope, helpers);
|
var frag = this.constructor.renderer(renderedScope, hookupOptions.options.add(helpers));
|
||||||
} else {
|
} else {
|
||||||
// otherwise render the contents between the
|
// otherwise render the contents between the
|
||||||
var frag = can.view.frag(hookupOptions.subtemplate ? hookupOptions.subtemplate(renderedScope, hookupOptions.options.add(helpers)) : "");
|
var frag = can.view.frag(hookupOptions.subtemplate ? hookupOptions.subtemplate(renderedScope, hookupOptions.options.add(helpers)) : "");
|
||||||
|
|||||||
10
assets/js/libs/can.jquery.min.js
vendored
10
assets/js/libs/can.jquery.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user