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/
|
||||
* Copyright (c) 2013 Bitovi
|
||||
* Thu, 19 Dec 2013 10:56:42 GMT
|
||||
* Mon, 23 Dec 2013 19:49:28 GMT
|
||||
* Licensed MIT
|
||||
* Includes: can/view/ejs
|
||||
* Download from: http://canjs.com
|
||||
|
||||
652
assets/js/libs/can.jquery.js
Normal file → Executable file
652
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/
|
||||
* Copyright (c) 2013 Bitovi
|
||||
* Thu, 19 Dec 2013 10:56:41 GMT
|
||||
* Mon, 23 Dec 2013 19:49:25 GMT
|
||||
* 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
|
||||
* Download from: http://canjs.com
|
||||
@ -30,7 +30,7 @@
|
||||
return object._cid = (name || "") + (++cid)
|
||||
}
|
||||
}
|
||||
can.VERSION = '2.0.3';
|
||||
can.VERSION = '2.0.4';
|
||||
|
||||
can.simpleExtend = function(d, s) {
|
||||
for (var prop in s) {
|
||||
@ -58,6 +58,12 @@
|
||||
}
|
||||
}
|
||||
} else if (elements.hasOwnProperty) {
|
||||
if (can.Map && elements instanceof can.Map) {
|
||||
can.__reading && can.__reading(elements, '__keys');
|
||||
elements = elements.__get()
|
||||
}
|
||||
|
||||
|
||||
for (key in elements) {
|
||||
if (elements.hasOwnProperty(key)) {
|
||||
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
|
||||
// are in the dom, trigger inserted on them.
|
||||
can.inserted = function(elems) {
|
||||
// prevent mutations from changing the looping
|
||||
elems = can.makeArray(elems);
|
||||
var inDocument = false,
|
||||
checked = false,
|
||||
children;
|
||||
@ -96,8 +104,8 @@
|
||||
}
|
||||
|
||||
if (inDocument && elem.getElementsByTagName) {
|
||||
can.trigger(elem, "inserted", [], false);
|
||||
children = can.makeArray(elem.getElementsByTagName("*"));
|
||||
can.trigger(elem, "inserted", [], false);
|
||||
for (var j = 0, child;
|
||||
(child = children[j]) !== undefined; j++) {
|
||||
// Trigger the destroyed event
|
||||
@ -356,6 +364,11 @@
|
||||
|
||||
}
|
||||
return this;
|
||||
},
|
||||
proxy: function(fn, context) {
|
||||
return function() {
|
||||
return fn.apply(context, arguments)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -1240,27 +1253,6 @@
|
||||
// A map that temporarily houses a reference
|
||||
// to maps that have already been made for a plain ole JS object
|
||||
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() {
|
||||
for (var cid in madeMap) {
|
||||
if (madeMap[cid].added) {
|
||||
@ -1273,6 +1265,7 @@
|
||||
return madeMap && madeMap[obj._cid] && madeMap[obj._cid].instance
|
||||
};
|
||||
|
||||
|
||||
var Map = can.Map = can.Construct.extend({
|
||||
|
||||
setup: function() {
|
||||
@ -1284,9 +1277,13 @@
|
||||
if (!this.defaults) {
|
||||
this.defaults = {};
|
||||
}
|
||||
// a list of the compute properties
|
||||
this._computes = [];
|
||||
for (var prop in this.prototype) {
|
||||
if (typeof this.prototype[prop] !== "function") {
|
||||
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
|
||||
bind: can.bindAndSetup,
|
||||
on: can.bindAndSetup,
|
||||
@ -1305,6 +1303,28 @@
|
||||
off: can.unbindAndTeardown,
|
||||
id: "id",
|
||||
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) {
|
||||
return obj && !can.isDeferred(obj) && (can.isArray(obj) || can.isPlainObject(obj) || (obj instanceof can.Map));
|
||||
},
|
||||
@ -1388,30 +1408,28 @@
|
||||
// Sets all `attrs`.
|
||||
this._init = 1;
|
||||
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)
|
||||
this.attr(data);
|
||||
if (teardownMapping) {
|
||||
teardownMap()
|
||||
}
|
||||
|
||||
teardownMapping && teardownMapping()
|
||||
|
||||
this.bind('change', can.proxy(this._changes, this));
|
||||
|
||||
delete this._init;
|
||||
},
|
||||
|
||||
_setupComputes: function() {
|
||||
var prototype = this.constructor.prototype;
|
||||
this._computedBindings = {}
|
||||
for (var prop in prototype) {
|
||||
if (prototype[prop] && prototype[prop].isComputed) {
|
||||
this[prop] = prototype[prop].clone(this);
|
||||
this._computedBindings[prop] = {
|
||||
count: 0
|
||||
}
|
||||
var computes = this.constructor._computes;
|
||||
this._computedBindings = {};
|
||||
for (var i = 0, len = computes.length, prop; i < len; i++) {
|
||||
prop = computes[i];
|
||||
this[prop] = this[prop].clone(this);
|
||||
this._computedBindings[prop] = {
|
||||
count: 0
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
_bindsetup: makeBindSetup(),
|
||||
_bindteardown: function() {
|
||||
@ -1724,6 +1742,16 @@
|
||||
|
||||
// Helpers for `observable` lists.
|
||||
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(
|
||||
|
||||
@ -1738,11 +1766,18 @@
|
||||
this.length = 0;
|
||||
can.cid(this, ".map")
|
||||
this._init = 1;
|
||||
instances = instances || [];
|
||||
|
||||
|
||||
if (can.isDeferred(instances)) {
|
||||
this.replace(instances)
|
||||
} else {
|
||||
var teardownMapping = instances.length && can.Map.helpers.addToMap(instances, this);
|
||||
this.push.apply(this, can.makeArray(instances || []));
|
||||
}
|
||||
|
||||
teardownMapping && teardownMapping();
|
||||
|
||||
// this change needs to be ignored
|
||||
this.bind('change', can.proxy(this._changes, this));
|
||||
can.simpleExtend(this, options);
|
||||
@ -1803,6 +1838,13 @@
|
||||
howMany = args[1] = this.length - index;
|
||||
}
|
||||
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();
|
||||
if (howMany > 0) {
|
||||
this._triggerChange("" + index, "remove", undefined, removed);
|
||||
@ -1977,7 +2019,6 @@
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
can.List = Map.List = list;
|
||||
return can.List;
|
||||
})(__m2, __m12);
|
||||
@ -3157,6 +3198,7 @@
|
||||
// elements whos default value we should set
|
||||
defaultValue: ["input", "textarea"],
|
||||
// a map of parent element to child elements
|
||||
|
||||
tagMap: {
|
||||
"": "span",
|
||||
table: "tbody",
|
||||
@ -3177,11 +3219,11 @@
|
||||
th: "tr",
|
||||
li: "ul"
|
||||
},
|
||||
|
||||
// Used to determine the parentNode if el is directly within a documentFragment
|
||||
getParentNode: function(el, defaultParentNode) {
|
||||
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) {
|
||||
var tagName = el.nodeName.toString().toLowerCase(),
|
||||
prop = elements.attrMap[attrName];
|
||||
@ -3200,14 +3242,14 @@
|
||||
el.setAttribute(attrName, val);
|
||||
}
|
||||
},
|
||||
// gets the value of an attribute
|
||||
// Gets the value of an attribute.
|
||||
getAttr: function(el, attrName) {
|
||||
// Default to a blank string for IE7/8
|
||||
return (elements.attrMap[attrName] && el[elements.attrMap[attrName]] ?
|
||||
el[elements.attrMap[attrName]] :
|
||||
el.getAttribute(attrName)) || '';
|
||||
},
|
||||
// removes the attribute
|
||||
// Removes the attribute.
|
||||
removeAttr: function(el, attrName) {
|
||||
var setter = elements.attrMap[attrName];
|
||||
if (typeof prop === "function") {
|
||||
@ -3221,6 +3263,7 @@
|
||||
el.removeAttribute(attrName);
|
||||
}
|
||||
},
|
||||
// Gets a "pretty" value for something
|
||||
contentText: function(text) {
|
||||
if (typeof text == 'string') {
|
||||
return text;
|
||||
@ -3230,9 +3273,25 @@
|
||||
return '';
|
||||
}
|
||||
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
|
||||
(function() {
|
||||
// feature detect if
|
||||
@ -3412,12 +3471,14 @@
|
||||
fn(el);
|
||||
});
|
||||
|
||||
var helperTags = hookupOptions.options.read('helpers._tags', {}).value,
|
||||
tagName = hookupOptions.tagName,
|
||||
tagCallback = (helperTags && helperTags[tagName]) || Scanner.tags[tagName]
|
||||
var tagName = hookupOptions.tagName,
|
||||
helperTagCallback = hookupOptions.options.read('helpers._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,
|
||||
res = tagCallback ? tagCallback(el, hookupOptions) : scope;
|
||||
|
||||
@ -3707,7 +3768,10 @@
|
||||
default:
|
||||
// Track the current tag
|
||||
if (lastToken === '<') {
|
||||
tagName = token.split(/\s|!--/)[0];
|
||||
|
||||
tagName = token.substr(0, 3) === "!--" ?
|
||||
"!--" : token.split(/\s/)[0];
|
||||
|
||||
var isClosingTag = false;
|
||||
|
||||
if (tagName.indexOf("/") === 0) {
|
||||
@ -3905,10 +3969,11 @@
|
||||
return Scanner;
|
||||
})(__m19, __m21);
|
||||
|
||||
// ## view/node_lists.js
|
||||
// ## view/node_lists/node_lists.js
|
||||
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;
|
||||
try {
|
||||
document.createTextNode('')._ = 0;
|
||||
@ -3916,12 +3981,10 @@
|
||||
canExpando = false;
|
||||
}
|
||||
|
||||
// a mapping of element ids to nodeList ids
|
||||
// A mapping of element ids to nodeList id
|
||||
var nodeMap = {},
|
||||
// a mapping of ids to text nodes
|
||||
// A mapping of ids to text nodes
|
||||
textNodeMap = {},
|
||||
// a mapping of nodeList ids to nodeList
|
||||
nodeListMap = {},
|
||||
expando = "ejs_" + Math.random(),
|
||||
_id = 0,
|
||||
id = function(node) {
|
||||
@ -3942,98 +4005,90 @@
|
||||
return "text_" + _id;
|
||||
}
|
||||
},
|
||||
// removes a nodeListId from a node's nodeListIds
|
||||
removeNodeListId = function(node, nodeListId) {
|
||||
var nodeListIds = nodeMap[id(node)];
|
||||
if (nodeListIds) {
|
||||
var index = can.inArray(nodeListId, nodeListIds);
|
||||
splice = [].splice;
|
||||
|
||||
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 = {
|
||||
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
|
||||
if (startIndex >= 0 && endIndex >= 0) {
|
||||
for (var i = startIndex; i <= endIndex; i++) {
|
||||
var n = nodeList[i];
|
||||
removeNodeListId(n, nodeListId);
|
||||
}
|
||||
// swap in new nodes into the nodeLIst
|
||||
nodeList.splice.apply(nodeList, [startIndex, endIndex - startIndex + 1].concat(newNodes));
|
||||
update: function(nodeList, newNodes) {
|
||||
// Unregister all childNodes.
|
||||
can.each(nodeList.childNodeLists, function(nodeList) {
|
||||
nodeLists.unregister(nodeList)
|
||||
})
|
||||
nodeList.childNodeLists = [];
|
||||
|
||||
// tell these new nodes they belong to the nodeList
|
||||
can.each(newNodes, function(node) {
|
||||
addNodeListId(node, nodeListId);
|
||||
});
|
||||
} else {
|
||||
nodeLists.unregister(nodeList);
|
||||
// Remove old node pointers to this list.
|
||||
can.each(nodeList, function(node) {
|
||||
delete nodeMap[id(node)];
|
||||
});
|
||||
|
||||
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"
|
||||
}
|
||||
});
|
||||
//});
|
||||
},
|
||||
// registers a list of nodes
|
||||
register: function(nodeList) {
|
||||
var nLId = id(nodeList);
|
||||
nodeListMap[nLId] = nodeList;
|
||||
|
||||
can.each(nodeList, function(node) {
|
||||
addNodeListId(node, nLId);
|
||||
});
|
||||
var nodeId = id(nodeList[0]);
|
||||
parent = nodeMap[nodeId];
|
||||
|
||||
}
|
||||
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) {
|
||||
var nLId = id(nodeList);
|
||||
can.each(nodeList, function(node) {
|
||||
removeNodeListId(node, nLId);
|
||||
});
|
||||
delete nodeListMap[nLId];
|
||||
if (!nodeList.isUnregistered) {
|
||||
nodeList.isUnregistered = true;
|
||||
// unregister all childNodeLists
|
||||
delete nodeList.parentNodeList;
|
||||
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,
|
||||
nodeListMap: nodeListMap
|
||||
}
|
||||
var ids = function(nodeList) {
|
||||
return nodeList.map(function(n) {
|
||||
return id(n) + ":" + (n.innerHTML || n.nodeValue)
|
||||
})
|
||||
}
|
||||
return nodeLists;
|
||||
|
||||
})(__m2);
|
||||
})(__m2, __m21);
|
||||
|
||||
// ## view/live/live.js
|
||||
var __m23 = (function(can, elements, view, nodeLists) {
|
||||
@ -4048,12 +4103,21 @@
|
||||
// `setup(HTMLElement, bind(data), unbind(data)) -> data`
|
||||
// Calls bind right away, but will call unbind
|
||||
// if the element is "destroyed" (removed from the DOM).
|
||||
var setupCount = 0;
|
||||
var setup = function(el, bind, unbind) {
|
||||
var teardown = function() {
|
||||
unbind(data)
|
||||
can.unbind.call(el, 'removed', teardown);
|
||||
return true
|
||||
},
|
||||
// Removing an element can call teardown which
|
||||
// unregister the nodeList which calls teardown
|
||||
var tornDown = false,
|
||||
teardown = function() {
|
||||
if (!tornDown) {
|
||||
tornDown = true;
|
||||
unbind(data)
|
||||
can.unbind.call(el, 'removed', teardown);
|
||||
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
data = {
|
||||
// returns true if no parent
|
||||
teardownCheck: function(parent) {
|
||||
@ -4083,65 +4147,82 @@
|
||||
getAttributeParts = function(newVal) {
|
||||
return (newVal || "").replace(/['"]/g, '').split('=')
|
||||
},
|
||||
// #### insertElementsAfter
|
||||
// Appends elements after the last item in oldElements.
|
||||
insertElementsAfter = function(oldElements, newFrag) {
|
||||
var last = oldElements[oldElements.length - 1];
|
||||
splice = [].splice;
|
||||
|
||||
// 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 = {
|
||||
nodeLists: nodeLists,
|
||||
|
||||
list: function(el, compute, func, context, parentNode) {
|
||||
// A mapping of the index to an array
|
||||
// of elements that represent the item.
|
||||
// Each array is registered so child or parent
|
||||
// live structures can update the elements
|
||||
var nodesMap = [],
|
||||
// called when an item is added
|
||||
list: function(el, compute, render, context, parentNode) {
|
||||
|
||||
|
||||
// A nodeList of all elements this live-list manages.
|
||||
// This is here so that if this live list is within another section
|
||||
// that section is able to remove the items in this list.
|
||||
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) {
|
||||
// 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
|
||||
var frag = document.createDocumentFragment(),
|
||||
newMappings = [];
|
||||
can.each(items, function(item, key) {
|
||||
var itemHTML = func.call(context, item, (key + index)),
|
||||
itemFrag = can.view.frag(itemHTML, parentNode);
|
||||
newNodeLists = [],
|
||||
newIndicies = [];
|
||||
|
||||
newMappings.push(can.makeArray(itemFrag.childNodes));
|
||||
frag.appendChild(itemFrag);
|
||||
// For each new item,
|
||||
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
|
||||
if (!nodesMap[index]) {
|
||||
insertElementsAfter(
|
||||
index == 0 ? [text] :
|
||||
nodesMap[index - 1], frag)
|
||||
// Check if we are adding items at the end
|
||||
if (!itemIndexToNodeListsMap[index]) {
|
||||
|
||||
elements.after(
|
||||
// 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 {
|
||||
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);
|
||||
}
|
||||
// register each item
|
||||
can.each(newMappings, function(nodeList) {
|
||||
nodeLists.register(nodeList)
|
||||
});
|
||||
[].splice.apply(nodesMap, [index, 0].concat(newMappings));
|
||||
|
||||
splice.apply(itemIndexToNodeListsMap, [index, 0].concat(newNodeLists));
|
||||
|
||||
// update indices after insert point
|
||||
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) {
|
||||
|
||||
// If this is because an element was removed, we should
|
||||
@ -4151,61 +4232,72 @@
|
||||
return
|
||||
}
|
||||
|
||||
var removedMappings = nodesMap.splice(index, items.length),
|
||||
var removedMappings = itemIndexToNodeListsMap.splice(index, items.length),
|
||||
itemsToRemove = [];
|
||||
|
||||
can.each(removedMappings, function(nodeList) {
|
||||
// add items that we will remove all at once
|
||||
[].push.apply(itemsToRemove, nodeList)
|
||||
// Update any parent lists to remove these items
|
||||
nodeLists.replace(nodeList, []);
|
||||
nodeLists.update(nodeList, []);
|
||||
// unregister the list
|
||||
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));
|
||||
},
|
||||
parentNode = elements.getParentNode(el, parentNode),
|
||||
text = document.createTextNode(""),
|
||||
list;
|
||||
// The current list.
|
||||
list,
|
||||
|
||||
var teardownList = function() {
|
||||
// there might be no list right away, and the list might be a plain
|
||||
// array
|
||||
list && list.unbind && list.unbind("add", add).unbind("remove", remove);
|
||||
// use remove to clean stuff up for us
|
||||
remove({}, {
|
||||
length: nodesMap.length
|
||||
}, 0, true);
|
||||
}
|
||||
// Called when the list is replaced with a new list or the binding is torn-down.
|
||||
teardownList = function() {
|
||||
// there might be no list right away, and the list might be a plain
|
||||
// array
|
||||
list && list.unbind && list.unbind("add", add).unbind("remove", remove);
|
||||
// use remove to clean stuff up for us
|
||||
remove({}, {
|
||||
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() {
|
||||
can.isFunction(compute) && compute.bind("change", updateList)
|
||||
}, function() {
|
||||
can.isFunction(compute) && compute.unbind("change", updateList)
|
||||
teardownList()
|
||||
})
|
||||
});
|
||||
|
||||
live.replace(masterNodeList, text, data.teardownCheck)
|
||||
|
||||
// run the list setup
|
||||
updateList({}, can.isFunction(compute) ? compute() : compute)
|
||||
|
||||
|
||||
},
|
||||
|
||||
html: function(el, compute, parentNode) {
|
||||
var parentNode = elements.getParentNode(el, parentNode),
|
||||
|
||||
data = listen(parentNode, compute, function(ev, newVal, oldVal) {
|
||||
// TODO: remove teardownCheck in 2.1
|
||||
var attached = nodes[0].parentNode;
|
||||
// update the nodes in the DOM with the new rendered value
|
||||
if (attached) {
|
||||
@ -4214,37 +4306,52 @@
|
||||
data.teardownCheck(nodes[0].parentNode);
|
||||
});
|
||||
|
||||
var nodes,
|
||||
var nodes = [el],
|
||||
makeAndPut = function(val) {
|
||||
// create the fragment, but don't hook it up
|
||||
// we need to insert it into the document first
|
||||
var frag = can.view.frag(val, parentNode),
|
||||
// keep a reference to each node
|
||||
newNodes = can.makeArray(frag.childNodes);
|
||||
// Insert it in the `document` or `documentFragment`
|
||||
insertElementsAfter(nodes || [el], frag)
|
||||
// nodes hasn't been set yet
|
||||
if (!nodes) {
|
||||
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));
|
||||
}
|
||||
var frag = can.view.fragment("" + val),
|
||||
oldNodes = can.makeArray(nodes);
|
||||
|
||||
// We need to mark each node as belonging to the node list.
|
||||
nodeLists.update(nodes, frag.childNodes)
|
||||
|
||||
frag = can.view.hookup(frag, parentNode)
|
||||
|
||||
elements.replace(oldNodes, frag)
|
||||
};
|
||||
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) {
|
||||
var parent = elements.getParentNode(el, parentNode);
|
||||
|
||||
@ -4254,20 +4361,16 @@
|
||||
if (typeof node.nodeValue != 'unknown') {
|
||||
node.nodeValue = "" + newVal;
|
||||
}
|
||||
// TODO: remove in 2.1
|
||||
data.teardownCheck(node.parentNode);
|
||||
});
|
||||
}),
|
||||
// The text node that will be updated
|
||||
node = document.createTextNode(compute());
|
||||
|
||||
var node = document.createTextNode(compute());
|
||||
|
||||
if (el.parentNode !== parent) {
|
||||
parent = el.parentNode;
|
||||
parent.insertBefore(node, el);
|
||||
parent.removeChild(el);
|
||||
} else {
|
||||
parent.insertBefore(node, el);
|
||||
parent.removeChild(el);
|
||||
}
|
||||
// Replace the placeholder with the live node and do the nodeLists thing.
|
||||
live.replace([el], node, data.teardownCheck);
|
||||
},
|
||||
|
||||
attributes: function(el, compute, currentValue) {
|
||||
var setAttrs = function(newVal) {
|
||||
var parts = getAttributeParts(newVal),
|
||||
@ -4372,6 +4475,8 @@
|
||||
return /^["'].*["']$/.test(val) ? val.substr(1, val.length - 2) : val
|
||||
}
|
||||
can.view.live = live;
|
||||
can.view.nodeLists = nodeLists;
|
||||
can.view.elements = elements;
|
||||
return live;
|
||||
|
||||
})(__m2, __m21, __m19, __m24);
|
||||
@ -4538,6 +4643,7 @@
|
||||
}
|
||||
|
||||
if (listData) {
|
||||
unbind && unbind();
|
||||
return "<" + tag + can.view.hook(function(el, parentNode) {
|
||||
live.list(el, listData.list, listData.renderer, self, parentNode);
|
||||
}) + "></" + tag + ">";
|
||||
@ -4558,7 +4664,8 @@
|
||||
if (status === 0 && !contentProp) {
|
||||
// Return an element tag with a hookup in place of the content
|
||||
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
|
||||
// a text node who's value is `func`'s return value.
|
||||
|
||||
@ -5443,25 +5550,23 @@
|
||||
// Implements the `each` built-in helper.
|
||||
|
||||
'each': function(expr, options) {
|
||||
if (!expr) {
|
||||
return;
|
||||
}
|
||||
// Check if this is a list or a compute that resolves to a list, and setup
|
||||
// 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({
|
||||
"@index": index
|
||||
}).add(item));
|
||||
});
|
||||
}
|
||||
expr = Mustache.resolve(expr);
|
||||
expr = resolved;
|
||||
|
||||
if ( !! expr && isArrayLike(expr)) {
|
||||
var result = [];
|
||||
@ -5888,6 +5993,9 @@
|
||||
scope: this.scope
|
||||
});
|
||||
|
||||
|
||||
var self = this;
|
||||
|
||||
// if this component has a template (that we've already converted to a renderer)
|
||||
if (this.constructor.renderer) {
|
||||
// add content to tags
|
||||
@ -5899,15 +6007,33 @@
|
||||
helpers._tags.content = function(el, rendererOptions) {
|
||||
// first check if there was content within the custom tag
|
||||
// otherwise, render what was within <content>, the default code
|
||||
var subtemplate = hookupOptions.subtemplate || rendererOptions.subtemplate
|
||||
var subtemplate = hookupOptions.subtemplate || rendererOptions.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
|
||||
var frag = this.constructor.renderer(renderedScope, helpers);
|
||||
var frag = this.constructor.renderer(renderedScope, hookupOptions.options.add(helpers));
|
||||
} else {
|
||||
// otherwise render the contents between the
|
||||
var frag = can.view.frag(hookupOptions.subtemplate ? hookupOptions.subtemplate(renderedScope, hookupOptions.options.add(helpers)) : "");
|
||||
@ -6948,4 +7074,4 @@
|
||||
})(__m2, __m27, __m8);
|
||||
|
||||
window['can'] = __m4;
|
||||
})();
|
||||
})();
|
||||
|
||||
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