aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Angular.js6
-rw-r--r--src/jqLite.js65
-rw-r--r--test/jqLiteSpec.js27
3 files changed, 89 insertions, 9 deletions
diff --git a/src/Angular.js b/src/Angular.js
index 367a7752..407fc263 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -985,8 +985,12 @@ function bindJQuery(){
if (jQuery) {
jqLite = jQuery;
extend(jQuery.fn, {
- scope: JQLitePrototype.scope
+ scope: JQLitePrototype.scope,
+ inheritedData: JQLitePrototype.inheritedData
});
+ JQLitePatchJQueryRemove('remove', true);
+ JQLitePatchJQueryRemove('empty');
+ JQLitePatchJQueryRemove('html');
} else {
jqLite = jqLiteWrap;
}
diff --git a/src/jqLite.js b/src/jqLite.js
index 13bd55ba..ae540e89 100644
--- a/src/jqLite.js
+++ b/src/jqLite.js
@@ -99,6 +99,46 @@ function camelCase(name) {
}
/////////////////////////////////////////////
+// jQuery mutation patch
+/////////////////////////////////////////////
+
+function JQLitePatchJQueryRemove(name, dispatchThis) {
+ var originalJqFn = jQuery.fn[name];
+ originalJqFn = originalJqFn.$original || originalJqFn;
+ removePatch.$original = originalJqFn;
+ jQuery.fn[name] = removePatch;
+
+ function removePatch() {
+ var list = [this],
+ fireEvent = dispatchThis,
+ set, setIndex, setLength,
+ element, childIndex, childLength, children,
+ fns, data;
+
+ while(list.length) {
+ set = list.shift();
+ for(setIndex = 0, setLength = set.length; setIndex < setLength; setIndex++) {
+ element = jqLite(set[setIndex]);
+ if (fireEvent) {
+ data = element.data('events');
+ if ( (fns = data && data.$destroy) ) {
+ forEach(fns, function(fn){
+ fn.handler();
+ });
+ }
+ } else {
+ fireEvent = !fireEvent;
+ }
+ for(childIndex = 0, childLength = (children = element.children()).length; childIndex < childLength; childIndex++) {
+ list.push(jQuery(children[childIndex]));
+ }
+ }
+ }
+ return originalJqFn.apply(this, arguments);
+ }
+}
+
+/////////////////////////////////////////////
function jqLiteWrap(element) {
if (isString(element) && element.charAt(0) != '<') {
throw new Error('selectors not implemented');
@@ -137,9 +177,15 @@ function JQLiteRemoveData(element) {
var cacheId = element[jqName],
cache = jqCache[cacheId];
if (cache) {
- forEach(cache.bind || {}, function(fn, type){
- removeEventListenerFn(element, type, fn);
- });
+ if (cache.bind) {
+ forEach(cache.bind, function(fn, type){
+ if (type == '$destroy') {
+ fn({});
+ } else {
+ removeEventListenerFn(element, type, fn);
+ }
+ });
+ }
delete jqCache[cacheId];
element[jqName] = undefined; // ie does not allow deletion of attributes on elements.
}
@@ -241,13 +287,16 @@ var SPECIAL_ATTR = makeMap("multiple,selected,checked,disabled,readonly,required
forEach({
data: JQLiteData,
+ inheritedData: function(element, name, value) {
+ element = jqLite(element);
+ while (element.length) {
+ if (value = element.data(name)) return value;
+ element = element.parent();
+ }
+ },
scope: function(element) {
- var scope;
- while (element && !(scope = jqLite(element).data($$scope))) {
- element = element.parentNode;
- }
- return scope;
+ return jqLite(element).inheritedData($$scope);
},
removeAttr: function(element,name) {
diff --git a/test/jqLiteSpec.js b/test/jqLiteSpec.js
index 24795331..f66b6244 100644
--- a/test/jqLiteSpec.js
+++ b/test/jqLiteSpec.js
@@ -83,6 +83,33 @@ describe('jqLite', function(){
});
+ describe('inheritedData', function() {
+
+ it('should retrieve data attached to the current element', function() {
+ var element = jqLite('<i>foo</i>');
+ element.data('myData', 'abc');
+ expect(element.inheritedData('myData')).toBe('abc');
+ dealoc(element);
+ });
+
+
+ it('should walk up the dom to find data', function() {
+ var element = jqLite('<ul><li><p><b>deep deep</b><p></li></ul>');
+ var deepChild = jqLite(element[0].getElementsByTagName('b')[0]);
+ element.data('myData', 'abc');
+ expect(deepChild.inheritedData('myData')).toBe('abc');
+ dealoc(element);
+ });
+
+
+ it('should return undefined when no data was found', function() {
+ var element = jqLite('<ul><li><p><b>deep deep</b><p></li></ul>');
+ var deepChild = jqLite(element[0].getElementsByTagName('b')[0]);
+ expect(deepChild.inheritedData('myData')).toBeFalsy();
+ dealoc(element);
+ });
+ });
+
describe('scope', function() {
it('should retrieve scope attached to the current element', function() {
var element = jqLite('<i>foo</i>');