mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-20 00:10:26 +00:00
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
This commit is contained in:
parent
ca08c004c8
commit
bda2bba2be
3 changed files with 89 additions and 9 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,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) != '<') {
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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>');
|
||||
|
|
|
|||
Loading…
Reference in a new issue