Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit bda2bba

Browse files
mheveryIgorMinar
authored andcommitted
feat(jqlite): added .inheritedData method and $destroy event.
- refactored .scope() to use .inheritedData() instead. - .bind('$destroy', callback) will call when the DOM element is removed
1 parent ca08c00 commit bda2bba

File tree

3 files changed

+89
-9
lines changed

3 files changed

+89
-9
lines changed

src/Angular.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -985,8 +985,12 @@ function bindJQuery(){
985985
if (jQuery) {
986986
jqLite = jQuery;
987987
extend(jQuery.fn, {
988-
scope: JQLitePrototype.scope
988+
scope: JQLitePrototype.scope,
989+
inheritedData: JQLitePrototype.inheritedData
989990
});
991+
JQLitePatchJQueryRemove('remove', true);
992+
JQLitePatchJQueryRemove('empty');
993+
JQLitePatchJQueryRemove('html');
990994
} else {
991995
jqLite = jqLiteWrap;
992996
}

src/jqLite.js

+57-8
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,46 @@ function camelCase(name) {
9898
});
9999
}
100100

101+
/////////////////////////////////////////////
102+
// jQuery mutation patch
103+
/////////////////////////////////////////////
104+
105+
function JQLitePatchJQueryRemove(name, dispatchThis) {
106+
var originalJqFn = jQuery.fn[name];
107+
originalJqFn = originalJqFn.$original || originalJqFn;
108+
removePatch.$original = originalJqFn;
109+
jQuery.fn[name] = removePatch;
110+
111+
function removePatch() {
112+
var list = [this],
113+
fireEvent = dispatchThis,
114+
set, setIndex, setLength,
115+
element, childIndex, childLength, children,
116+
fns, data;
117+
118+
while(list.length) {
119+
set = list.shift();
120+
for(setIndex = 0, setLength = set.length; setIndex < setLength; setIndex++) {
121+
element = jqLite(set[setIndex]);
122+
if (fireEvent) {
123+
data = element.data('events');
124+
if ( (fns = data && data.$destroy) ) {
125+
forEach(fns, function(fn){
126+
fn.handler();
127+
});
128+
}
129+
} else {
130+
fireEvent = !fireEvent;
131+
}
132+
for(childIndex = 0, childLength = (children = element.children()).length; childIndex < childLength; childIndex++) {
133+
list.push(jQuery(children[childIndex]));
134+
}
135+
}
136+
}
137+
return originalJqFn.apply(this, arguments);
138+
}
139+
}
140+
101141
/////////////////////////////////////////////
102142
function jqLiteWrap(element) {
103143
if (isString(element) && element.charAt(0) != '<') {
@@ -137,9 +177,15 @@ function JQLiteRemoveData(element) {
137177
var cacheId = element[jqName],
138178
cache = jqCache[cacheId];
139179
if (cache) {
140-
forEach(cache.bind || {}, function(fn, type){
141-
removeEventListenerFn(element, type, fn);
142-
});
180+
if (cache.bind) {
181+
forEach(cache.bind, function(fn, type){
182+
if (type == '$destroy') {
183+
fn({});
184+
} else {
185+
removeEventListenerFn(element, type, fn);
186+
}
187+
});
188+
}
143189
delete jqCache[cacheId];
144190
element[jqName] = undefined; // ie does not allow deletion of attributes on elements.
145191
}
@@ -241,13 +287,16 @@ var SPECIAL_ATTR = makeMap("multiple,selected,checked,disabled,readonly,required
241287

242288
forEach({
243289
data: JQLiteData,
290+
inheritedData: function(element, name, value) {
291+
element = jqLite(element);
292+
while (element.length) {
293+
if (value = element.data(name)) return value;
294+
element = element.parent();
295+
}
296+
},
244297

245298
scope: function(element) {
246-
var scope;
247-
while (element && !(scope = jqLite(element).data($$scope))) {
248-
element = element.parentNode;
249-
}
250-
return scope;
299+
return jqLite(element).inheritedData($$scope);
251300
},
252301

253302
removeAttr: function(element,name) {

test/jqLiteSpec.js

+27
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,33 @@ describe('jqLite', function(){
8383
});
8484

8585

86+
describe('inheritedData', function() {
87+
88+
it('should retrieve data attached to the current element', function() {
89+
var element = jqLite('<i>foo</i>');
90+
element.data('myData', 'abc');
91+
expect(element.inheritedData('myData')).toBe('abc');
92+
dealoc(element);
93+
});
94+
95+
96+
it('should walk up the dom to find data', function() {
97+
var element = jqLite('<ul><li><p><b>deep deep</b><p></li></ul>');
98+
var deepChild = jqLite(element[0].getElementsByTagName('b')[0]);
99+
element.data('myData', 'abc');
100+
expect(deepChild.inheritedData('myData')).toBe('abc');
101+
dealoc(element);
102+
});
103+
104+
105+
it('should return undefined when no data was found', function() {
106+
var element = jqLite('<ul><li><p><b>deep deep</b><p></li></ul>');
107+
var deepChild = jqLite(element[0].getElementsByTagName('b')[0]);
108+
expect(deepChild.inheritedData('myData')).toBeFalsy();
109+
dealoc(element);
110+
});
111+
});
112+
86113
describe('scope', function() {
87114
it('should retrieve scope attached to the current element', function() {
88115
var element = jqLite('<i>foo</i>');

0 commit comments

Comments
 (0)