Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
178 changes: 50 additions & 128 deletions src/jqLite.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,17 @@ JQLite.expando = 'ng339';

var jqCache = JQLite.cache = {},
jqId = 1,
addEventListenerFn = (window.document.addEventListener
? function(element, type, fn) {element.addEventListener(type, fn, false);}
: function(element, type, fn) {element.attachEvent('on' + type, fn);}),
removeEventListenerFn = (window.document.removeEventListener
? function(element, type, fn) {element.removeEventListener(type, fn, false); }
: function(element, type, fn) {element.detachEvent('on' + type, fn); });
addEventListenerFn = function(element, type, fn) {
element.addEventListener(type, fn, false);
},
removeEventListenerFn = function(element, type, fn) {
element.removeEventListener(type, fn, false);
};

/*
* !!! This is an undocumented "private" function !!!
*/
var jqData = JQLite._data = function(node) {
JQLite._data = function(node) {
//jQuery always returns an object on cache miss
return this.cache[node[this.expando]] || {};
};
Expand All @@ -122,6 +122,7 @@ function jqNextId() { return ++jqId; }

var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
var MOZ_HACK_REGEXP = /^moz([A-Z])/;
var MOUSE_EVENT_MAP= { mouseleave : "mouseout", mouseenter : "mouseover"};
var jqLiteMinErr = minErr('jqLite');

/**
Expand Down Expand Up @@ -156,6 +157,7 @@ wrapMap.optgroup = wrapMap.option;
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
wrapMap.th = wrapMap.td;


function jqLiteIsTextNode(html) {
return !HTML_REGEXP.test(html);
}
Expand All @@ -167,7 +169,7 @@ function jqLiteAcceptsData(node) {
}

function jqLiteBuildFragment(html, context) {
var elem, tmp, tag, wrap,
var tmp, tag, wrap,
fragment = context.createDocumentFragment(),
nodes = [], i;

Expand Down Expand Up @@ -260,16 +262,23 @@ function jqLiteDealoc(element, onlyDescendants){
function jqLiteOff(element, type, fn, unsupported) {
if (isDefined(unsupported)) throw jqLiteMinErr('offargs', 'jqLite#off() does not support the `selector` argument');

var events = jqLiteExpandoStore(element, 'events'),
handle = jqLiteExpandoStore(element, 'handle');
var events = jqLiteExpandoStore(element, 'events');
var handle = jqLiteExpandoStore(element, 'handle');
var i;
var types;

if (!handle) return; //no listeners registered

if (isUndefined(type)) {
forEach(events, function(eventHandler, type) {
removeEventListenerFn(element, type, eventHandler);
types = Object.keys(events);
i = types.length;
while (i--) {
type = types[i];
if (type !== '$destroy') {
removeEventListenerFn(element, type, events[type]);
}
delete events[type];
});
}
} else {
forEach(type.split(' '), function(type) {
if (isUndefined(fn)) {
Expand Down Expand Up @@ -312,7 +321,7 @@ function jqLiteExpandoStore(element, key, value) {
}
expandoStore[key] = value;
} else {
return expandoStore && expandoStore[key];
return key ? expandoStore && expandoStore[key] : expandoStore;
}
}

Expand Down Expand Up @@ -449,23 +458,11 @@ function jqLiteRemove(element, keepData) {
//////////////////////////////////////////
var JQLitePrototype = JQLite.prototype = {
ready: function(fn) {
var fired = false;

function trigger() {
if (fired) return;
fired = true;
fn();
}

// check if document already is loaded
if (document.readyState === 'complete'){
setTimeout(trigger);
setTimeout(fn);
} else {
this.on('DOMContentLoaded', trigger); // works for modern browsers and IE9
// we can not use jqLite since we are not done loading and jQuery could be loaded later.
// jshint -W064
JQLite(window).on('load', trigger); // fallback to window.onload for others
// jshint +W064
this.on('DOMContentLoaded', fn);
}
},
toString: function() {
Expand Down Expand Up @@ -555,22 +552,7 @@ forEach({
if (isDefined(value)) {
element.style[name] = value;
} else {
var val;

if (msie <= 8) {
// this is some IE specific weirdness that jQuery 1.6.4 does not sure why
val = element.currentStyle && element.currentStyle[name];
if (val === '') val = 'auto';
}

val = val || element.style[name];

if (msie <= 8) {
// jquery weirdness :-/
val = (val === '') ? undefined : val;
}

return val;
return element.style[name];
}
},

Expand Down Expand Up @@ -701,56 +683,22 @@ forEach({

function createEventHandler(element, events) {
var eventHandler = function (event, type) {
if (!event.preventDefault) {
event.preventDefault = function() {
event.returnValue = false; //ie
};
}

if (!event.stopPropagation) {
event.stopPropagation = function() {
event.cancelBubble = true; //ie
};
}

if (!event.target) {
event.target = event.srcElement || document;
}

if (isUndefined(event.defaultPrevented)) {
var prevent = event.preventDefault;
event.preventDefault = function() {
event.defaultPrevented = true;
prevent.call(event);
};
event.defaultPrevented = false;
}

// jQuery specific api
event.isDefaultPrevented = function() {
return event.defaultPrevented || event.returnValue === false;
return event.defaultPrevented;
};

// Copy event handlers in case event handlers array is modified during execution.
var eventHandlersCopy = shallowCopy(events[type || event.type] || []);

forEach(eventHandlersCopy, function(fn) {
fn.call(element, event);
});

// Remove monkey-patched methods (IE),
// as they would cause memory leaks in IE8.
if (msie <= 8) {
// IE7/8 does not allow to delete property on native object
event.preventDefault = null;
event.stopPropagation = null;
event.isDefaultPrevented = null;
} else {
// It shouldn't affect normal browsers (native methods are defined on prototype).
delete event.preventDefault;
delete event.stopPropagation;
delete event.isDefaultPrevented;
for (var i = 0, ii = eventHandlersCopy.length; i < ii; i++) {
eventHandlersCopy[i].call(element, event);
}
};

// TODO: this is a hack for angularMocks/clearDataCache that makes it possible to deregister all
// events on `element`
eventHandler.elem = element;
return eventHandler;
}
Expand All @@ -771,63 +719,46 @@ forEach({
return;
}

var events = jqLiteExpandoStore(element, 'events'),
handle = jqLiteExpandoStore(element, 'handle');
var expandoStore = jqLiteExpandoStore(element);
var events = expandoStore && expandoStore.events;
var handle = expandoStore && expandoStore.handle;

if (!events) jqLiteExpandoStore(element, 'events', events = {});
if (!handle) jqLiteExpandoStore(element, 'handle', handle = createEventHandler(element, events));

forEach(type.split(' '), function(type){
var types = type.split(' ');
var i = types.length;

while (i--) {
type = types[i];
var eventFns = events[type];

if (!eventFns) {
if (type == 'mouseenter' || type == 'mouseleave') {
var contains = document.body.contains || document.body.compareDocumentPosition ?
function( a, b ) {
// jshint bitwise: false
var adown = a.nodeType === 9 ? a.documentElement : a,
bup = b && b.parentNode;
return a === bup || !!( bup && bup.nodeType === 1 && (
adown.contains ?
adown.contains( bup ) :
a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
));
} :
function( a, b ) {
if ( b ) {
while ( (b = b.parentNode) ) {
if ( b === a ) {
return true;
}
}
}
return false;
};

events[type] = [];
events[type] = [];

if (type === 'mouseenter' || type === 'mouseleave') {
// Refer to jQuery's implementation of mouseenter & mouseleave
// Read about mouseenter and mouseleave:
// http://www.quirksmode.org/js/events_mouse.html#link8
var eventmap = { mouseleave : "mouseout", mouseenter : "mouseover"};

onFn(element, eventmap[type], function(event) {
onFn(element, MOUSE_EVENT_MAP[type], function(event) {
var target = this, related = event.relatedTarget;
// For mousenter/leave call the handler if related is outside the target.
// NB: No relatedTarget if the mouse left/entered the browser window
if ( !related || (related !== target && !contains(target, related)) ){
if ( !related || (related !== target && !target.contains(related)) ){
handle(event, type);
}
});

} else {
addEventListenerFn(element, type, handle);
events[type] = [];
if (type !== '$destroy') {
addEventListenerFn(element, type, handle);
}
}
eventFns = events[type];
}
eventFns.push(fn);
});
}
},

off: jqLiteOff,
Expand Down Expand Up @@ -932,16 +863,7 @@ forEach({
},

next: function(element) {
if (element.nextElementSibling) {
return element.nextElementSibling;
}

// IE8 doesn't have nextElementSibling
var elm = element.nextSibling;
while (elm != null && elm.nodeType !== 1) {
elm = elm.nextSibling;
}
return elm;
return element.nextElementSibling;
},

find: function(element, selector) {
Expand Down
13 changes: 10 additions & 3 deletions src/ng/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -877,9 +877,16 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
? JQLitePrototype.clone.call($compileNodes) // IMPORTANT!!!
: $compileNodes;

forEach(transcludeControllers, function(instance, name) {
$linkNode.data('$' + name + 'Controller', instance);
});
if (transcludeControllers) {
var names = Object.keys(transcludeControllers);
var i = names.length;
var name;

while (i--) {
name = names[i];
$linkNode.data('$' + name + 'Controller', transcludeControllers[name]);
}
}

$linkNode.data('$scope', scope);

Expand Down