aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMisko Hevery2011-02-13 16:13:21 -0800
committerMisko Hevery2011-02-16 08:59:57 -0500
commitc90abf057b0370cf5beb62aa960f1df008c802ef (patch)
tree039525ec1ee518175010693efd278fa105815285 /src
parentcdc093a463e8f8a925cbb9f2b55bedf0a1d8e7e8 (diff)
downloadangular.js-c90abf057b0370cf5beb62aa960f1df008c802ef.tar.bz2
Changed the angular.compile(element)(scope[, cloneAttachNode])
Diffstat (limited to 'src')
-rw-r--r--src/Angular.js20
-rw-r--r--src/Compiler.js15
-rw-r--r--src/jqLite.js9
-rw-r--r--src/widgets.js29
4 files changed, 40 insertions, 33 deletions
diff --git a/src/Angular.js b/src/Angular.js
index 87be29a7..6e5786ec 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -803,17 +803,18 @@ function merge(src, dst) {
</pre>
*
* @param {string|DOMElement} element Element or HTML to compile into a template function.
- * @returns {function([scope][, element])} a template function which is used to bind element
+ * @returns {function([scope][, cloneAttachFn])} a template function which is used to bind element
* and scope. Where:
*
* * `scope` - {@link angular.scope scope} A scope to bind to. If none specified, then a new
* root scope is created.
- * * `element` - {@link angular.element element} Element to use as the template. If none
- * specified then reuse the element from `angular.compile(element)`. If `true`
- * then clone the `angular.compile(element)`. The element must be either the same
- * element as `angular.compile(element)` or an identical clone to
- * `angular.compile(element)`. Using an element with differnt structure will cause
- * unpredictable behavior.
+ * * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the
+ * `template` and call the `cloneAttachFn` allowing the caller to attach the
+ * clonned elements to the DOM at the approriate place. The `cloneAttachFn` is
+ * called as: <br/> `cloneAttachFn(clonedElement, scope)`:
+ *
+ * * `clonedElement` - is a clone of the originale `element` passed into the compiler.
+ * * `scope` - is the current scope with which the linking function is working with.
*
* Calling the template function returns object: `{scope:?, view:?}`, where:
*
@@ -1006,7 +1007,7 @@ function toKeyValue(obj) {
function angularInit(config){
if (config.autobind) {
// TODO default to the source of angular.js
- var scope = compile(window.document)(null, createScope({'$config':config})),
+ var scope = compile(window.document)(createScope({'$config':config})).scope,
$browser = scope.$service('$browser');
if (config.css)
@@ -1048,8 +1049,7 @@ function bindJQuery(){
if (jQuery) {
jqLite = jQuery;
extend(jQuery.fn, {
- scope: JQLitePrototype.scope,
- cloneNode: JQLitePrototype.cloneNode
+ scope: JQLitePrototype.scope
});
} else {
jqLite = jqLiteWrap;
diff --git a/src/Compiler.js b/src/Compiler.js
index 77c83846..78d7a2b0 100644
--- a/src/Compiler.js
+++ b/src/Compiler.js
@@ -93,14 +93,17 @@ Compiler.prototype = {
}
}
template = this.templatize(templateElement, index, 0) || new Template();
- return function(scope, element){
- scope = scope || createScope();
- element = element === true
- ? templateElement.cloneNode()
- : (element ? jqLite(element) : templateElement);
+ return function(scope, cloneConnectFn){
+ // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart
+ // and sometimes changes the structure of the DOM.
+ var element = cloneConnectFn
+ ? JQLitePrototype.clone.call(templateElement) // IMPORTAN!!!
+ : templateElement;
+ scope = scope || createScope();
element.data($$scope, scope);
- template.attach(element, scope);
scope.$element = element;
+ (cloneConnectFn||noop)(element, scope);
+ template.attach(element, scope);
scope.$eval();
return {scope:scope, view:element};
};
diff --git a/src/jqLite.js b/src/jqLite.js
index 8a507212..c4a10a0b 100644
--- a/src/jqLite.js
+++ b/src/jqLite.js
@@ -72,7 +72,7 @@ function JQLite(element) {
}
}
-function JQLiteCloneNode(element) {
+function JQLiteClone(element) {
return element.cloneNode(true);
}
@@ -370,12 +370,15 @@ forEach({
return element.parentNode || null;
},
+ next: function(element) {
+ return element.nextSibling;
+ },
+
find: function(element, selector) {
return element.getElementsByTagName(selector);
},
- clone: JQLiteCloneNode,
- cloneNode: JQLiteCloneNode
+ clone: JQLiteClone
}, function(fn, name){
/**
* chaining functions
diff --git a/src/widgets.js b/src/widgets.js
index ce877c71..d58e7789 100644
--- a/src/widgets.js
+++ b/src/widgets.js
@@ -790,10 +790,10 @@ var ngSwitch = angularWidget('ng:switch', function (element){
forEach(cases, function(switchCase){
if (!found && switchCase.when(childScope, value)) {
found = true;
- var caseElement = switchCase.element.cloneNode();
- element.append(caseElement);
childScope.$tryEval(switchCase.change, element);
- switchCase.template(childScope, caseElement);
+ switchCase.template(childScope, function(caseElement){
+ element.append(caseElement);
+ });
}
});
});
@@ -886,11 +886,11 @@ angularWidget('a', function() {
</doc:scenario>
</doc:example>
*/
-angularWidget("@ng:repeat", function(expression, element){
+angularWidget('@ng:repeat', function(expression, element){
element.removeAttr('ng:repeat');
- element.replaceWith(jqLite("<!-- ng:repeat: " + expression + " --!>"));
+ element.replaceWith(jqLite('<!-- ng:repeat: ' + expression + ' --!>'));
var linker = this.compile(element);
- return function(reference){
+ return function(iterStartElement){
var match = expression.match(/^\s*(.+)\s+in\s+(.*)\s*$/),
lhs, rhs, valueIdent, keyIdent;
if (! match) {
@@ -910,10 +910,9 @@ angularWidget("@ng:repeat", function(expression, element){
var children = [], currentScope = this;
this.$onEval(function(){
var index = 0,
- cloneElement,
childCount = children.length,
- lastElement = reference,
- collection = this.$tryEval(rhs, reference),
+ lastIterElement = iterStartElement,
+ collection = this.$tryEval(rhs, iterStartElement),
is_array = isArray(collection),
collectionLength = 0,
childScope,
@@ -934,6 +933,7 @@ angularWidget("@ng:repeat", function(expression, element){
childScope = children[index];
childScope[valueIdent] = collection[key];
if (keyIdent) childScope[keyIdent] = key;
+ lastIterElement = childScope.$element;
} else {
// grow children
childScope = createScope(currentScope);
@@ -943,13 +943,14 @@ angularWidget("@ng:repeat", function(expression, element){
childScope.$position = index == 0
? 'first'
: (index == collectionLength - 1 ? 'last' : 'middle');
- lastElement.after(cloneElement = element.cloneNode());
- cloneElement.attr('ng:repeat-index', index);
- linker(childScope, cloneElement);
children.push(childScope);
+ linker(childScope, function(clone){
+ clone.attr('ng:repeat-index', index);
+ lastIterElement.after(clone);
+ lastIterElement = clone;
+ });
}
childScope.$eval();
- lastElement = childScope.$element;
index ++;
}
}
@@ -957,7 +958,7 @@ angularWidget("@ng:repeat", function(expression, element){
while(children.length > index) {
children.pop().$element.remove();
}
- }, reference);
+ }, iterStartElement);
};
});