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

Commit f1b94b4

Browse files
mgolpetebacondarwin
authored andcommitted
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.
1 parent 0bfa293 commit f1b94b4

30 files changed

+154
-119
lines changed

docs/components/angular-bootstrap/bootstrap-prettify.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ directive.ngEmbedApp = ['$templateCache', '$browser', '$rootScope', '$location',
228228
}]);
229229
if (attrs.ngEmbedApp) modules.push(attrs.ngEmbedApp);
230230

231-
element.bind('click', function(event) {
231+
element.on('click', function(event) {
232232
if (event.target.attributes.getNamedItem('ng-click')) {
233233
event.preventDefault();
234234
}

docs/components/angular-bootstrap/bootstrap.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ directive.dropdownToggle =
1313
close && close();
1414
});
1515

16-
element.parent().bind('click', function(event) {
16+
element.parent().on('click', function(event) {
1717
close && close();
1818
});
1919

20-
element.bind('click', function(event) {
20+
element.on('click', function(event) {
2121
event.preventDefault();
2222
event.stopPropagation();
2323

@@ -35,13 +35,13 @@ directive.dropdownToggle =
3535
close = function (event) {
3636
event && event.preventDefault();
3737
event && event.stopPropagation();
38-
$document.unbind('click', close);
38+
$document.off('click', close);
3939
element.parent().removeClass('open');
4040
close = null;
4141
openElement = null;
4242
}
4343

44-
$document.bind('click', close);
44+
$document.on('click', close);
4545
}
4646
});
4747
}
@@ -161,7 +161,7 @@ directive.tabbable = function() {
161161
}
162162

163163
navTabs.append(li);
164-
li.bind('click', function(event) {
164+
li.on('click', function(event) {
165165
event.preventDefault();
166166
event.stopPropagation();
167167
if (ngModel.$setViewValue) {
@@ -330,7 +330,7 @@ directive.tabPane = function() {
330330
require: '^tabbable',
331331
restrict: 'C',
332332
link: function(scope, element, attrs, tabsCtrl) {
333-
element.bind('$remove', tabsCtrl.addPane(element, attrs));
333+
element.on('$remove', tabsCtrl.addPane(element, attrs));
334334
}
335335
};
336336
};

docs/content/guide/compiler.ngdoc

+3-3
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,13 @@ Here is a directive which makes any element draggable. Notice the `draggable` at
7777
backgroundColor: 'lightgrey',
7878
cursor: 'pointer'
7979
});
80-
element.bind('mousedown', function(event) {
80+
element.on('mousedown', function(event) {
8181
// Prevent default dragging of selected content
8282
event.preventDefault();
8383
startX = event.screenX - x;
8484
startY = event.screenY - y;
85-
$document.bind('mousemove', mousemove);
86-
$document.bind('mouseup', mouseup);
85+
$document.on('mousemove', mousemove);
86+
$document.on('mouseup', mouseup);
8787
});
8888

8989
function mousemove(event) {

docs/content/guide/concepts.ngdoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ in HTML.
303303
require: 'ngModel',
304304
link: function(scope, elm, attrs, ctrl) {
305305
// view -> model
306-
elm.bind('blur', function() {
306+
elm.on('blur', function() {
307307
scope.$apply(function() {
308308
ctrl.$setViewValue(elm.html());
309309
});

docs/content/guide/dev_guide.services.$location.ngdoc

+2-2
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ In this examples we use `<base href="/base/index.html" />`
450450
input = angular.element('<input type="text">').val(browser.url()),
451451
delay;
452452

453-
input.bind('keypress keyup keydown', function() {
453+
input.on('keypress keyup keydown', function() {
454454
if (!delay) {
455455
delay = setTimeout(fireUrlChange, 250);
456456
}
@@ -469,7 +469,7 @@ In this examples we use `<base href="/base/index.html" />`
469469
};
470470
});
471471
}]);
472-
root.bind('click', function(e) {
472+
root.on('click', function(e) {
473473
e.stopPropagation();
474474
});
475475
}

docs/content/guide/directive.ngdoc

+2-2
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ In this example we will build a directive that displays the current time.
232232

233233
// listen on DOM destroy (removal) event, and cancel the next UI update
234234
// to prevent updating time after the DOM element was removed.
235-
element.bind('$destroy', function() {
235+
element.on('$destroy', function() {
236236
$timeout.cancel(timeoutId);
237237
});
238238

@@ -687,7 +687,7 @@ Following is an example of building a reusable widget.
687687
opened = true;
688688

689689
// Clicking on title should open/close the zippy
690-
title.bind('click', toggle);
690+
title.on('click', toggle);
691691

692692
// Toggle the closed/opened state
693693
function toggle() {

docs/content/guide/forms.ngdoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ The following example shows how to add two-way data-binding to contentEditable e
293293
require: 'ngModel',
294294
link: function(scope, elm, attrs, ctrl) {
295295
// view -> model
296-
elm.bind('blur', function() {
296+
elm.on('blur', function() {
297297
scope.$apply(function() {
298298
ctrl.$setViewValue(elm.html());
299299
});

docs/src/templates/js/docs.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,10 @@ docsApp.serviceFactory.docsSearch = ['$rootScope','lunrSearch', 'NG_PAGES',
162162
docsApp.directive.focused = function($timeout) {
163163
return function(scope, element, attrs) {
164164
element[0].focus();
165-
element.bind('focus', function() {
165+
element.on('focus', function() {
166166
scope.$apply(attrs.focused + '=true');
167167
});
168-
element.bind('blur', function() {
168+
element.on('blur', function() {
169169
// have to use $timeout, so that we close the drop-down after the user clicks,
170170
// otherwise when the user clicks we process the closing before we process the click.
171171
$timeout(function() {
@@ -610,7 +610,7 @@ docsApp.controller.DocsController = function($scope, $location, $window, $cookie
610610
$location.path('/api').replace();
611611
}
612612
// bind escape to hash reset callback
613-
angular.element(window).bind('keydown', function(e) {
613+
angular.element(window).on('keydown', function(e) {
614614
if (e.keyCode === 27) {
615615
$scope.$apply(function() {
616616
$scope.subpage = false;

src/Angular.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ function trim(value) {
454454
function isElement(node) {
455455
return node &&
456456
(node.nodeName // we are a direct element
457-
|| (node.bind && node.find)); // we have a bind and find method part of jQuery API
457+
|| (node.on && node.find)); // we have an on and find method part of jQuery API
458458
}
459459

460460
/**

src/jqLite.js

+25-14
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
* - [after()](http://api.jquery.com/after/)
3333
* - [append()](http://api.jquery.com/append/)
3434
* - [attr()](http://api.jquery.com/attr/)
35-
* - [bind()](http://api.jquery.com/bind/) - Does not support namespaces
35+
* - [bind()](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
3636
* - [children()](http://api.jquery.com/children/) - Does not support selectors
3737
* - [clone()](http://api.jquery.com/clone/)
3838
* - [contents()](http://api.jquery.com/contents/)
@@ -43,6 +43,8 @@
4343
* - [hasClass()](http://api.jquery.com/hasClass/)
4444
* - [html()](http://api.jquery.com/html/)
4545
* - [next()](http://api.jquery.com/next/) - Does not support selectors
46+
* - [on()](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
47+
* - [off()](http://api.jquery.com/off/) - Does not support namespaces or selectors
4648
* - [parent()](http://api.jquery.com/parent/) - Does not support selectors
4749
* - [prepend()](http://api.jquery.com/prepend/)
4850
* - [prop()](http://api.jquery.com/prop/)
@@ -55,7 +57,7 @@
5557
* - [text()](http://api.jquery.com/text/)
5658
* - [toggleClass()](http://api.jquery.com/toggleClass/)
5759
* - [triggerHandler()](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers.
58-
* - [unbind()](http://api.jquery.com/unbind/) - Does not support namespaces
60+
* - [unbind()](http://api.jquery.com/off/) - Does not support namespaces
5961
* - [val()](http://api.jquery.com/val/)
6062
* - [wrap()](http://api.jquery.com/wrap/)
6163
*
@@ -90,6 +92,7 @@ function jqNextId() { return ++jqId; }
9092

9193
var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
9294
var MOZ_HACK_REGEXP = /^moz([A-Z])/;
95+
var jqLiteError = minErr('jqLite');
9396

9497
/**
9598
* Converts snake_case to camelCase.
@@ -153,7 +156,7 @@ function JQLite(element) {
153156
}
154157
if (!(this instanceof JQLite)) {
155158
if (isString(element) && element.charAt(0) != '<') {
156-
throw minErr('jqLite')('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
159+
throw jqLiteError('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
157160
}
158161
return new JQLite(element);
159162
}
@@ -183,7 +186,9 @@ function JQLiteDealoc(element){
183186
}
184187
}
185188

186-
function JQLiteUnbind(element, type, fn) {
189+
function JQLiteOff(element, type, fn) {
190+
if ( arguments.length > 4 ) throw jqLiteError('off_args', 'jqLite#off() does not support the `selector` parameter');
191+
187192
var events = JQLiteExpandoStore(element, 'events'),
188193
handle = JQLiteExpandoStore(element, 'handle');
189194

@@ -216,7 +221,7 @@ function JQLiteRemoveData(element, name) {
216221

217222
if (expandoStore.handle) {
218223
expandoStore.events.$destroy && expandoStore.handle({}, '$destroy');
219-
JQLiteUnbind(element);
224+
JQLiteOff(element);
220225
}
221226
delete jqCache[expandoId];
222227
element[jqName] = undefined; // ie does not allow deletion of attributes on elements.
@@ -338,9 +343,9 @@ var JQLitePrototype = JQLite.prototype = {
338343
if (document.readyState === 'complete'){
339344
setTimeout(trigger);
340345
} else {
341-
this.bind('DOMContentLoaded', trigger); // works for modern browsers and IE9
346+
this.on('DOMContentLoaded', trigger); // works for modern browsers and IE9
342347
// we can not use jqLite since we are not done loading and jQuery could be loaded later.
343-
JQLite(window).bind('load', trigger); // fallback to window.onload for others
348+
JQLite(window).on('load', trigger); // fallback to window.onload for others
344349
}
345350
},
346351
toString: function() {
@@ -609,7 +614,9 @@ forEach({
609614

610615
dealoc: JQLiteDealoc,
611616

612-
bind: function bindFn(element, type, fn){
617+
on: function onFn(element, type, fn, other1){
618+
if ( isDefined(other1) ) throw jqLiteError('on_args', 'jqLite#on() does not support the `selector` or `eventData` parameters');
619+
613620
var events = JQLiteExpandoStore(element, 'events'),
614621
handle = JQLiteExpandoStore(element, 'handle');
615622

@@ -649,8 +656,8 @@ forEach({
649656
// http://www.quirksmode.org/js/events_mouse.html#link8
650657
var eventmap = { mouseleave : "mouseout", mouseenter : "mouseover"};
651658

652-
bindFn(element, eventmap[type], function(event) {
653-
var ret, target = this, related = event.relatedTarget;
659+
onFn(element, eventmap[type], function(event) {
660+
var target = this, related = event.relatedTarget;
654661
// For mousenter/leave call the handler if related is outside the target.
655662
// NB: No relatedTarget if the mouse left/entered the browser window
656663
if ( !related || (related !== target && !contains(target, related)) ){
@@ -668,7 +675,7 @@ forEach({
668675
});
669676
},
670677

671-
unbind: JQLiteUnbind,
678+
off: JQLiteOff,
672679

673680
replaceWith: function(element, replaceNode) {
674681
var index, parent = element.parentNode;
@@ -790,19 +797,23 @@ forEach({
790797
/**
791798
* chaining functions
792799
*/
793-
JQLite.prototype[name] = function(arg1, arg2) {
800+
JQLite.prototype[name] = function(arg1, arg2, arg3) {
794801
var value;
795802
for(var i=0; i < this.length; i++) {
796803
if (value == undefined) {
797-
value = fn(this[i], arg1, arg2);
804+
value = fn(this[i], arg1, arg2, arg3);
798805
if (value !== undefined) {
799806
// any function which returns a value needs to be wrapped
800807
value = jqLite(value);
801808
}
802809
} else {
803-
JQLiteAddNodes(value, fn(this[i], arg1, arg2));
810+
JQLiteAddNodes(value, fn(this[i], arg1, arg2, arg3));
804811
}
805812
}
806813
return value == undefined ? this : value;
807814
};
815+
816+
// bind legacy bind/unbind to on/off
817+
JQLite.prototype.bind = JQLite.prototype.on;
818+
JQLite.prototype.unbind = JQLite.prototype.off;
808819
});

src/ng/browser.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,9 @@ function Browser(window, document, $log, $sniffer) {
212212
// changed by push/replaceState
213213

214214
// html5 history api - popstate event
215-
if ($sniffer.history) jqLite(window).bind('popstate', fireUrlChange);
215+
if ($sniffer.history) jqLite(window).on('popstate', fireUrlChange);
216216
// hashchange event
217-
if ($sniffer.hashchange) jqLite(window).bind('hashchange', fireUrlChange);
217+
if ($sniffer.hashchange) jqLite(window).on('hashchange', fireUrlChange);
218218
// polling
219219
else self.addPollFn(fireUrlChange);
220220

src/ng/compile.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ function $CompileProvider($provide) {
471471
transcludeScope.$$transcluded = true;
472472

473473
return transcludeFn(transcludeScope, cloneFn).
474-
bind('$destroy', bind(transcludeScope, transcludeScope.$destroy));
474+
on('$destroy', bind(transcludeScope, transcludeScope.$destroy));
475475
};
476476
})(childTranscludeFn || transcludeFn)
477477
);

src/ng/directive/a.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ var htmlAnchorDirective = valueFn({
3333
}
3434

3535
return function(scope, element) {
36-
element.bind('click', function(event){
36+
element.on('click', function(event){
3737
// if we have no href url, then don't navigate anywhere.
3838
if (!element.attr('href')) {
3939
event.preventDefault();

src/ng/directive/form.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ var formDirectiveFactory = function(isNgForm) {
324324

325325
// unregister the preventDefault listener so that we don't not leak memory but in a
326326
// way that will achieve the prevention of the default action.
327-
formElement.bind('$destroy', function() {
327+
formElement.on('$destroy', function() {
328328
$timeout(function() {
329329
removeEventListenerFn(formElement[0], 'submit', preventDefaultListener);
330330
}, 0, false);
@@ -338,7 +338,7 @@ var formDirectiveFactory = function(isNgForm) {
338338
scope[alias] = controller;
339339
}
340340
if (parentFormCtrl) {
341-
formElement.bind('$destroy', function() {
341+
formElement.on('$destroy', function() {
342342
parentFormCtrl.$removeControl(controller);
343343
if (alias) {
344344
scope[alias] = undefined;

0 commit comments

Comments
 (0)