-
Notifications
You must be signed in to change notification settings - Fork 27.4k
feat(jqLite): implement jqLite(f) as alias to jqLite(document).ready(f) (also: deprecate the latter in the second commit) #15237
Changes from all commits
ed13fe7
272b511
7d2c5df
983bbf7
8adaec4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,11 @@ | ||
if (window.angular.bootstrap) { | ||
//AngularJS is already loaded, so we can return here... | ||
// AngularJS is already loaded, so we can return here... | ||
if (window.console) { | ||
console.log('WARNING: Tried to load angular more than once.'); | ||
} | ||
return; | ||
} | ||
|
||
//try to bind to jquery now so that one can write jqLite(document).ready() | ||
//but we will rebind on bootstrap again. | ||
// try to bind to jquery now so that one can write jqLite(fn) | ||
// but we will rebind on bootstrap again. | ||
bindJQuery(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
jqLite(window.document).ready(function() { | ||
jqLite(function() { | ||
angularInit(window.document, bootstrap); | ||
}); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,7 +56,7 @@ | |
* - [`after()`](http://api.jquery.com/after/) | ||
* - [`append()`](http://api.jquery.com/append/) | ||
* - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters | ||
* - [`bind()`](http://api.jquery.com/bind/) (_deprecated_ - to be removed in 1.7.0, use [`on()`](http://api.jquery.com/on/)) - Does not support namespaces, selectors or eventData | ||
* - [`bind()`](http://api.jquery.com/bind/) (_deprecated_, use [`on()`](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/) | ||
|
@@ -76,7 +76,7 @@ | |
* - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors | ||
* - [`prepend()`](http://api.jquery.com/prepend/) | ||
* - [`prop()`](http://api.jquery.com/prop/) | ||
* - [`ready()`](http://api.jquery.com/ready/) | ||
* - [`ready()`](http://api.jquery.com/ready/) (_deprecated_, use `angular.element(callback)` instead of `angular.element(document).ready(callback)`) | ||
* - [`remove()`](http://api.jquery.com/remove/) | ||
* - [`removeAttr()`](http://api.jquery.com/removeAttr/) - Does not support multiple attributes | ||
* - [`removeClass()`](http://api.jquery.com/removeClass/) - Does not support a function as first argument | ||
|
@@ -85,7 +85,7 @@ | |
* - [`text()`](http://api.jquery.com/text/) | ||
* - [`toggleClass()`](http://api.jquery.com/toggleClass/) - Does not support a function as first argument | ||
* - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers | ||
* - [`unbind()`](http://api.jquery.com/unbind/) (_deprecated_ - to be removed in 1.7.0, use [`off()`](http://api.jquery.com/off/)) - Does not support namespaces or event object as parameter | ||
* - [`unbind()`](http://api.jquery.com/unbind/) (_deprecated_, use [`off()`](http://api.jquery.com/off/)) - Does not support namespaces or event object as parameter | ||
* - [`val()`](http://api.jquery.com/val/) | ||
* - [`wrap()`](http://api.jquery.com/wrap/) | ||
* | ||
|
@@ -288,6 +288,8 @@ function JQLite(element) { | |
|
||
if (argIsString) { | ||
jqLiteAddNodes(this, jqLiteParseHTML(element)); | ||
} else if (isFunction(element)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Couldn't this go above the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't want to delay the most common path and jQuery has this check below the selector code. Maybe with JITs it's not a problem. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's probably not a problem, but it can't do much damage either (how many times would one call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. jQuery is slightly different as it handles nodes after the function. Maybe we should apply this here as well? That would only require an additional check for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, jQuery does it as it's done here, I read the code incorrectly. |
||
jqLiteReady(element); | ||
} else { | ||
jqLiteAddNodes(this, element); | ||
} | ||
|
@@ -519,29 +521,32 @@ function jqLiteDocumentLoaded(action, win) { | |
} | ||
} | ||
|
||
function jqLiteReady(fn) { | ||
function trigger() { | ||
window.document.removeEventListener('DOMContentLoaded', trigger); | ||
window.removeEventListener('load', trigger); | ||
fn(); | ||
} | ||
|
||
// check if document is already loaded | ||
if (window.document.readyState === 'complete') { | ||
window.setTimeout(fn); | ||
} else { | ||
// We can not use jqLite since we are not done loading and jQuery could be loaded later. | ||
|
||
// Works for modern browsers and IE9 | ||
window.document.addEventListener('DOMContentLoaded', trigger); | ||
|
||
// Fallback to window.onload for others | ||
window.addEventListener('load', trigger); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It does but we no longer have an underlying element and that's what jQuery uses so this is aligning with jQuery. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. Should we document it as breaking change then? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, it shouldn't be possible to exercise the difference from a test, since you can't stop the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, let's document it. I need to think about the phrasing that will make it clear it's an edge case. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...or do you mean it's not a breaking change in your last commit? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I'll assume there's nothing to do here. :D There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I meant let's not consider it a breaking change 😃 |
||
} | ||
} | ||
|
||
////////////////////////////////////////// | ||
// Functions which are declared directly. | ||
////////////////////////////////////////// | ||
var JQLitePrototype = JQLite.prototype = { | ||
ready: function(fn) { | ||
var fired = false; | ||
|
||
function trigger() { | ||
if (fired) return; | ||
fired = true; | ||
fn(); | ||
} | ||
|
||
// check if document is already loaded | ||
if (window.document.readyState === 'complete') { | ||
window.setTimeout(trigger); | ||
} 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. | ||
// eslint-disable-next-line new-cap | ||
JQLite(window).on('load', trigger); // fallback to window.onload for others | ||
} | ||
}, | ||
ready: jqLiteReady, | ||
toString: function() { | ||
var value = []; | ||
forEach(this, function(e) { value.push('' + e);}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!DOCTYPE html> | ||
<html ng-app="test" ng-jq> | ||
<body> | ||
<span class="before-ready">{{beforeReady}}</span> | ||
<span class="after-ready">{{afterReady}}</span> | ||
<span class="after-ready-sync">{{afterReadySync}}</span> | ||
<span class="after-ready-method">{{afterReadyMethod}}</span> | ||
<span class="after-ready-method-sync">{{afterReadyMethodSync}}</span> | ||
<script src="angular.js"></script> | ||
<script src="script.js"></script> | ||
<div id="div-after-scripts">This div is loaded after scripts.</div> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
'use strict'; | ||
|
||
var beforeReady; | ||
(function() { | ||
var divAfterScripts = window.document.getElementById('div-after-scripts'); | ||
beforeReady = divAfterScripts && divAfterScripts.textContent; | ||
})(); | ||
|
||
var afterReady; | ||
angular.element(function() { | ||
var divAfterScripts = window.document.getElementById('div-after-scripts'); | ||
afterReady = divAfterScripts && divAfterScripts.textContent; | ||
}); | ||
|
||
var afterReadyMethod; | ||
angular.element(window.document).ready(function() { | ||
var divAfterScripts = window.document.getElementById('div-after-scripts'); | ||
afterReadyMethod = divAfterScripts && divAfterScripts.textContent; | ||
}); | ||
|
||
var afterReadySync = afterReady; | ||
var afterReadyMethodSync = afterReadyMethod; | ||
|
||
angular | ||
.module('test', []) | ||
.run(function($rootScope) { | ||
$rootScope.beforeReady = beforeReady; | ||
$rootScope.afterReady = afterReady; | ||
$rootScope.afterReadySync = afterReadySync; | ||
$rootScope.afterReadyMethod = afterReadyMethod; | ||
$rootScope.afterReadyMethodSync = afterReadyMethodSync; | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
'use strict'; | ||
|
||
describe('Firing a callback on ready', function() { | ||
it('should not have the div available immediately', function() { | ||
loadFixture('ready'); | ||
expect(element(by.className('before-ready')).getText()) | ||
.toBe(''); | ||
}); | ||
|
||
it('should wait for document ready', function() { | ||
loadFixture('ready'); | ||
expect(element(by.className('after-ready')).getText()) | ||
.toBe('This div is loaded after scripts.'); | ||
expect(element(by.className('after-ready-method')).getText()) | ||
.toBe('This div is loaded after scripts.'); | ||
}); | ||
|
||
it('should be asynchronous', function() { | ||
loadFixture('ready'); | ||
expect(element(by.className('after-ready-sync')).getText()) | ||
.toBe(''); | ||
expect(element(by.className('after-ready-method-sync')).getText()) | ||
.toBe(''); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
document removal in 1.7?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be discussed; see #15221.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conclusion: no removal note.