aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichał Gołębiowski2013-06-19 20:52:50 +0100
committerPete Bacon Darwin2013-06-19 20:53:24 +0100
commitf1b94b4b599ab701bc75b55bbbbb73c5ef329a93 (patch)
tree033c39426a25c8ac86dc7dc4efb1b4d05fe05272 /src
parent0bfa29377d7a77b360ecd3209d56eeb4f68a5043 (diff)
downloadangular.js-f1b94b4b599ab701bc75b55bbbbb73c5ef329a93.tar.bz2
feat(jqLite): switch bind/unbind to more recent jQuery on/off
jQuery switched to a completely new event binding implementation as of 1.7.0, centering around on/off methods instead of previous bind/unbind. This patch makes jqLite match this implementation while still supporting previous bind/unbind methods.
Diffstat (limited to 'src')
-rw-r--r--src/Angular.js2
-rw-r--r--src/jqLite.js39
-rw-r--r--src/ng/browser.js4
-rw-r--r--src/ng/compile.js2
-rw-r--r--src/ng/directive/a.js2
-rw-r--r--src/ng/directive/form.js4
-rw-r--r--src/ng/directive/input.js16
-rw-r--r--src/ng/directive/ngEventDirs.js4
-rw-r--r--src/ng/directive/select.js8
-rw-r--r--src/ng/location.js2
-rw-r--r--src/ngMobile/directive/ngClick.js14
-rw-r--r--src/ngMobile/swipe.js8
-rw-r--r--src/ngMock/angular-mocks.js4
-rw-r--r--src/ngScenario/Application.js2
14 files changed, 61 insertions, 50 deletions
diff --git a/src/Angular.js b/src/Angular.js
index 2fb8f66c..50d7d76c 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -454,7 +454,7 @@ function trim(value) {
function isElement(node) {
return node &&
(node.nodeName // we are a direct element
- || (node.bind && node.find)); // we have a bind and find method part of jQuery API
+ || (node.on && node.find)); // we have an on and find method part of jQuery API
}
/**
diff --git a/src/jqLite.js b/src/jqLite.js
index 95203957..9e3bb013 100644
--- a/src/jqLite.js
+++ b/src/jqLite.js
@@ -32,7 +32,7 @@
* - [after()](http://api.jquery.com/after/)
* - [append()](http://api.jquery.com/append/)
* - [attr()](http://api.jquery.com/attr/)
- * - [bind()](http://api.jquery.com/bind/) - Does not support namespaces
+ * - [bind()](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
* - [children()](http://api.jquery.com/children/) - Does not support selectors
* - [clone()](http://api.jquery.com/clone/)
* - [contents()](http://api.jquery.com/contents/)
@@ -43,6 +43,8 @@
* - [hasClass()](http://api.jquery.com/hasClass/)
* - [html()](http://api.jquery.com/html/)
* - [next()](http://api.jquery.com/next/) - Does not support selectors
+ * - [on()](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
+ * - [off()](http://api.jquery.com/off/) - Does not support namespaces or selectors
* - [parent()](http://api.jquery.com/parent/) - Does not support selectors
* - [prepend()](http://api.jquery.com/prepend/)
* - [prop()](http://api.jquery.com/prop/)
@@ -55,7 +57,7 @@
* - [text()](http://api.jquery.com/text/)
* - [toggleClass()](http://api.jquery.com/toggleClass/)
* - [triggerHandler()](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers.
- * - [unbind()](http://api.jquery.com/unbind/) - Does not support namespaces
+ * - [unbind()](http://api.jquery.com/off/) - Does not support namespaces
* - [val()](http://api.jquery.com/val/)
* - [wrap()](http://api.jquery.com/wrap/)
*
@@ -90,6 +92,7 @@ function jqNextId() { return ++jqId; }
var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
var MOZ_HACK_REGEXP = /^moz([A-Z])/;
+var jqLiteError = minErr('jqLite');
/**
* Converts snake_case to camelCase.
@@ -153,7 +156,7 @@ function JQLite(element) {
}
if (!(this instanceof JQLite)) {
if (isString(element) && element.charAt(0) != '<') {
- throw minErr('jqLite')('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
+ throw jqLiteError('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
}
return new JQLite(element);
}
@@ -183,7 +186,9 @@ function JQLiteDealoc(element){
}
}
-function JQLiteUnbind(element, type, fn) {
+function JQLiteOff(element, type, fn) {
+ if ( arguments.length > 4 ) throw jqLiteError('off_args', 'jqLite#off() does not support the `selector` parameter');
+
var events = JQLiteExpandoStore(element, 'events'),
handle = JQLiteExpandoStore(element, 'handle');
@@ -216,7 +221,7 @@ function JQLiteRemoveData(element, name) {
if (expandoStore.handle) {
expandoStore.events.$destroy && expandoStore.handle({}, '$destroy');
- JQLiteUnbind(element);
+ JQLiteOff(element);
}
delete jqCache[expandoId];
element[jqName] = undefined; // ie does not allow deletion of attributes on elements.
@@ -338,9 +343,9 @@ var JQLitePrototype = JQLite.prototype = {
if (document.readyState === 'complete'){
setTimeout(trigger);
} else {
- this.bind('DOMContentLoaded', trigger); // works for modern browsers and IE9
+ 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.
- JQLite(window).bind('load', trigger); // fallback to window.onload for others
+ JQLite(window).on('load', trigger); // fallback to window.onload for others
}
},
toString: function() {
@@ -609,7 +614,9 @@ forEach({
dealoc: JQLiteDealoc,
- bind: function bindFn(element, type, fn){
+ on: function onFn(element, type, fn, other1){
+ if ( isDefined(other1) ) throw jqLiteError('on_args', 'jqLite#on() does not support the `selector` or `eventData` parameters');
+
var events = JQLiteExpandoStore(element, 'events'),
handle = JQLiteExpandoStore(element, 'handle');
@@ -649,8 +656,8 @@ forEach({
// http://www.quirksmode.org/js/events_mouse.html#link8
var eventmap = { mouseleave : "mouseout", mouseenter : "mouseover"};
- bindFn(element, eventmap[type], function(event) {
- var ret, target = this, related = event.relatedTarget;
+ onFn(element, eventmap[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)) ){
@@ -668,7 +675,7 @@ forEach({
});
},
- unbind: JQLiteUnbind,
+ off: JQLiteOff,
replaceWith: function(element, replaceNode) {
var index, parent = element.parentNode;
@@ -790,19 +797,23 @@ forEach({
/**
* chaining functions
*/
- JQLite.prototype[name] = function(arg1, arg2) {
+ JQLite.prototype[name] = function(arg1, arg2, arg3) {
var value;
for(var i=0; i < this.length; i++) {
if (value == undefined) {
- value = fn(this[i], arg1, arg2);
+ value = fn(this[i], arg1, arg2, arg3);
if (value !== undefined) {
// any function which returns a value needs to be wrapped
value = jqLite(value);
}
} else {
- JQLiteAddNodes(value, fn(this[i], arg1, arg2));
+ JQLiteAddNodes(value, fn(this[i], arg1, arg2, arg3));
}
}
return value == undefined ? this : value;
};
+
+ // bind legacy bind/unbind to on/off
+ JQLite.prototype.bind = JQLite.prototype.on;
+ JQLite.prototype.unbind = JQLite.prototype.off;
});
diff --git a/src/ng/browser.js b/src/ng/browser.js
index 7a32993f..f1f80bdf 100644
--- a/src/ng/browser.js
+++ b/src/ng/browser.js
@@ -212,9 +212,9 @@ function Browser(window, document, $log, $sniffer) {
// changed by push/replaceState
// html5 history api - popstate event
- if ($sniffer.history) jqLite(window).bind('popstate', fireUrlChange);
+ if ($sniffer.history) jqLite(window).on('popstate', fireUrlChange);
// hashchange event
- if ($sniffer.hashchange) jqLite(window).bind('hashchange', fireUrlChange);
+ if ($sniffer.hashchange) jqLite(window).on('hashchange', fireUrlChange);
// polling
else self.addPollFn(fireUrlChange);
diff --git a/src/ng/compile.js b/src/ng/compile.js
index faef4772..851f2404 100644
--- a/src/ng/compile.js
+++ b/src/ng/compile.js
@@ -471,7 +471,7 @@ function $CompileProvider($provide) {
transcludeScope.$$transcluded = true;
return transcludeFn(transcludeScope, cloneFn).
- bind('$destroy', bind(transcludeScope, transcludeScope.$destroy));
+ on('$destroy', bind(transcludeScope, transcludeScope.$destroy));
};
})(childTranscludeFn || transcludeFn)
);
diff --git a/src/ng/directive/a.js b/src/ng/directive/a.js
index 7ee8f572..8213afb9 100644
--- a/src/ng/directive/a.js
+++ b/src/ng/directive/a.js
@@ -33,7 +33,7 @@ var htmlAnchorDirective = valueFn({
}
return function(scope, element) {
- element.bind('click', function(event){
+ element.on('click', function(event){
// if we have no href url, then don't navigate anywhere.
if (!element.attr('href')) {
event.preventDefault();
diff --git a/src/ng/directive/form.js b/src/ng/directive/form.js
index ca055cb1..5eec23f1 100644
--- a/src/ng/directive/form.js
+++ b/src/ng/directive/form.js
@@ -324,7 +324,7 @@ var formDirectiveFactory = function(isNgForm) {
// unregister the preventDefault listener so that we don't not leak memory but in a
// way that will achieve the prevention of the default action.
- formElement.bind('$destroy', function() {
+ formElement.on('$destroy', function() {
$timeout(function() {
removeEventListenerFn(formElement[0], 'submit', preventDefaultListener);
}, 0, false);
@@ -338,7 +338,7 @@ var formDirectiveFactory = function(isNgForm) {
scope[alias] = controller;
}
if (parentFormCtrl) {
- formElement.bind('$destroy', function() {
+ formElement.on('$destroy', function() {
parentFormCtrl.$removeControl(controller);
if (alias) {
scope[alias] = undefined;
diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js
index 31a3ba5d..dfa52e85 100644
--- a/src/ng/directive/input.js
+++ b/src/ng/directive/input.js
@@ -411,7 +411,7 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
// if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the
// input event on backspace, delete or cut
if ($sniffer.hasEvent('input')) {
- element.bind('input', listener);
+ element.on('input', listener);
} else {
var timeout;
@@ -424,7 +424,7 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
}
};
- element.bind('keydown', function(event) {
+ element.on('keydown', function(event) {
var key = event.keyCode;
// ignore
@@ -435,11 +435,11 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
});
// if user paste into input using mouse, we need "change" event to catch it
- element.bind('change', listener);
+ element.on('change', listener);
// if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
if ($sniffer.hasEvent('paste')) {
- element.bind('paste cut', deferListener);
+ element.on('paste cut', deferListener);
}
}
@@ -624,7 +624,7 @@ function radioInputType(scope, element, attr, ctrl) {
element.attr('name', nextUid());
}
- element.bind('click', function() {
+ element.on('click', function() {
if (element[0].checked) {
scope.$apply(function() {
ctrl.$setViewValue(attr.value);
@@ -647,7 +647,7 @@ function checkboxInputType(scope, element, attr, ctrl) {
if (!isString(trueValue)) trueValue = true;
if (!isString(falseValue)) falseValue = false;
- element.bind('click', function() {
+ element.on('click', function() {
scope.$apply(function() {
ctrl.$setViewValue(element[0].checked);
});
@@ -876,7 +876,7 @@ var VALID_CLASS = 'ng-valid',
};
// Listen for change events to enable binding
- element.bind('blur keyup change', function() {
+ element.on('blur keyup change', function() {
scope.$apply(read);
});
read(); // initialize
@@ -1138,7 +1138,7 @@ var ngModelDirective = function() {
formCtrl.$addControl(modelCtrl);
- element.bind('$destroy', function() {
+ element.on('$destroy', function() {
formCtrl.$removeControl(modelCtrl);
});
}
diff --git a/src/ng/directive/ngEventDirs.js b/src/ng/directive/ngEventDirs.js
index 43047ad9..9420f720 100644
--- a/src/ng/directive/ngEventDirs.js
+++ b/src/ng/directive/ngEventDirs.js
@@ -43,7 +43,7 @@ forEach(
ngEventDirectives[directiveName] = ['$parse', function($parse) {
return function(scope, element, attr) {
var fn = $parse(attr[directiveName]);
- element.bind(lowercase(name), function(event) {
+ element.on(lowercase(name), function(event) {
scope.$apply(function() {
fn(scope, {$event:event});
});
@@ -265,7 +265,7 @@ forEach(
</doc:example>
*/
var ngSubmitDirective = ngDirective(function(scope, element, attrs) {
- element.bind('submit', function() {
+ element.on('submit', function() {
scope.$apply(attrs.ngSubmit);
});
});
diff --git a/src/ng/directive/select.js b/src/ng/directive/select.js
index 0d5221fb..a62f706c 100644
--- a/src/ng/directive/select.js
+++ b/src/ng/directive/select.js
@@ -257,7 +257,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
}
};
- selectElement.bind('change', function() {
+ selectElement.on('change', function() {
scope.$apply(function() {
if (unknownOption.parent()) unknownOption.remove();
ngModelCtrl.$setViewValue(selectElement.val());
@@ -283,7 +283,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
}
});
- selectElement.bind('change', function() {
+ selectElement.on('change', function() {
scope.$apply(function() {
var array = [];
forEach(selectElement.find('option'), function(option) {
@@ -334,7 +334,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
// clear contents, we'll add what's needed based on the model
selectElement.html('');
- selectElement.bind('change', function() {
+ selectElement.on('change', function() {
scope.$apply(function() {
var optionGroup,
collection = valuesFn(scope) || [],
@@ -598,7 +598,7 @@ var optionDirective = ['$interpolate', function($interpolate) {
selectCtrl.addOption(attr.value);
}
- element.bind('$destroy', function() {
+ element.on('$destroy', function() {
selectCtrl.removeOption(attr.value);
});
};
diff --git a/src/ng/location.js b/src/ng/location.js
index de629d42..ba3901b2 100644
--- a/src/ng/location.js
+++ b/src/ng/location.js
@@ -511,7 +511,7 @@ function $LocationProvider(){
$location = new LocationMode(appBase, '#' + hashPrefix);
$location.$$parse($location.$$rewrite(initialUrl));
- $rootElement.bind('click', function(event) {
+ $rootElement.on('click', function(event) {
// TODO(vojta): rewrite link when opening in new tab/window (in legacy browser)
// currently we open nice url link and redirect then
diff --git a/src/ngMobile/directive/ngClick.js b/src/ngMobile/directive/ngClick.js
index a6f6ed19..3fa68cb4 100644
--- a/src/ngMobile/directive/ngClick.js
+++ b/src/ngMobile/directive/ngClick.js
@@ -185,7 +185,7 @@ ngMobile.directive('ngClick', ['$parse', '$timeout', '$rootElement',
element.removeClass(ACTIVE_CLASS_NAME);
}
- element.bind('touchstart', function(event) {
+ element.on('touchstart', function(event) {
tapping = true;
tapElement = event.target ? event.target : event.srcElement; // IE uses srcElement.
// Hack for Safari, which can target text nodes instead of containers.
@@ -203,15 +203,15 @@ ngMobile.directive('ngClick', ['$parse', '$timeout', '$rootElement',
touchStartY = e.clientY;
});
- element.bind('touchmove', function(event) {
+ element.on('touchmove', function(event) {
resetState();
});
- element.bind('touchcancel', function(event) {
+ element.on('touchcancel', function(event) {
resetState();
});
- element.bind('touchend', function(event) {
+ element.on('touchend', function(event) {
var diff = Date.now() - startTime;
var touches = (event.changedTouches && event.changedTouches.length) ? event.changedTouches :
@@ -248,17 +248,17 @@ ngMobile.directive('ngClick', ['$parse', '$timeout', '$rootElement',
// Fallback click handler.
// Busted clicks don't get this far, and adding this handler allows ng-tap to be used on
// desktop as well, to allow more portable sites.
- element.bind('click', function(event) {
+ element.on('click', function(event) {
scope.$apply(function() {
clickHandler(scope, {$event: event});
});
});
- element.bind('mousedown', function(event) {
+ element.on('mousedown', function(event) {
element.addClass(ACTIVE_CLASS_NAME);
});
- element.bind('mousemove mouseup', function(event) {
+ element.on('mousemove mouseup', function(event) {
element.removeClass(ACTIVE_CLASS_NAME);
});
diff --git a/src/ngMobile/swipe.js b/src/ngMobile/swipe.js
index 612d65fd..99e58eee 100644
--- a/src/ngMobile/swipe.js
+++ b/src/ngMobile/swipe.js
@@ -75,7 +75,7 @@ ngMobile.factory('$swipe', [function() {
// Whether a swipe is active.
var active = false;
- element.bind('touchstart mousedown', function(event) {
+ element.on('touchstart mousedown', function(event) {
startCoords = getCoordinates(event);
active = true;
totalX = 0;
@@ -84,12 +84,12 @@ ngMobile.factory('$swipe', [function() {
eventHandlers['start'] && eventHandlers['start'](startCoords);
});
- element.bind('touchcancel', function(event) {
+ element.on('touchcancel', function(event) {
active = false;
eventHandlers['cancel'] && eventHandlers['cancel']();
});
- element.bind('touchmove mousemove', function(event) {
+ element.on('touchmove mousemove', function(event) {
if (!active) return;
// Android will send a touchcancel if it thinks we're starting to scroll.
@@ -124,7 +124,7 @@ ngMobile.factory('$swipe', [function() {
}
});
- element.bind('touchend mouseup', function(event) {
+ element.on('touchend mouseup', function(event) {
if (!active) return;
active = false;
eventHandlers['end'] && eventHandlers['end'](getCoordinates(event));
diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js
index a35e0f2f..7681449b 100644
--- a/src/ngMock/angular-mocks.js
+++ b/src/ngMock/angular-mocks.js
@@ -1710,7 +1710,7 @@ angular.mock.clearDataCache = function() {
if (cache.hasOwnProperty(key)) {
var handle = cache[key].handle;
- handle && angular.element(handle.elem).unbind();
+ handle && angular.element(handle.elem).off();
delete cache[key];
}
}
@@ -1750,7 +1750,7 @@ window.jstestdriver && (function(window) {
currentSpec = null;
if (injector) {
- injector.get('$rootElement').unbind();
+ injector.get('$rootElement').off();
injector.get('$browser').pollFns.length = 0;
}
diff --git a/src/ngScenario/Application.js b/src/ngScenario/Application.js
index a1ef47c7..15cd42e3 100644
--- a/src/ngScenario/Application.js
+++ b/src/ngScenario/Application.js
@@ -64,7 +64,7 @@ angular.scenario.Application.prototype.navigateTo = function(url, loadFn, errorF
frame = self.getFrame_();
frame.load(function() {
- frame.unbind();
+ frame.off();
try {
var $window = self.getWindow_();