-
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
Conversation
|
||
function trigger() { | ||
if (fired) return; | ||
fired = true; |
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.
I know the old code didn't do this, but shouldn't we just remove the event handlers rather than setting a flag?
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.
Good idea. I jut copied it without analysing the contents too much. 😄
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.
Since we are wiring up both DOMContentLoaded
and load
events, is it not possible that they will both be triggered even if we remove the event handlers from inside the trigger
function?
In other words, if the browser queues up both handlers before either handler has run, then removing the handlers inside one of the handlers would not prevent the other from running.
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.
Doubt it. I'd imagine it would be considered a browser bug if any browsers behaved like that, otherwise you also couldn't add a handler for load
in DOMContentReady
which is almost certainly expected to work.
There's also precedent since this is how jQuery does it, so it's pretty battle tested.
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.
I added a "refactor" in a separate commit.
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.
LGTM - we can do the refactor (if it works) of removing the event handlers in another PR later.
|
||
function trigger() { | ||
if (fired) return; | ||
fired = true; |
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.
Since we are wiring up both DOMContentLoaded
and load
events, is it not possible that they will both be triggered even if we remove the event handlers from inside the trigger
function?
In other words, if the browser queues up both handlers before either handler has run, then removing the handlers inside one of the handlers would not prevent the other from running.
@@ -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)`) |
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.
@@ -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 comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't this go above the instanceof JQLite
check?
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.
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 comment
The 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 jqLite(fn)
?).
So if jQuery has it this way, let's leave it as is.
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.
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 nodeType
.
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.
OK, jQuery does it as it's done here, I read the code incorrectly.
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 comment
The reason will be displayed to describe this comment to others. Learn more.
By using addEventListener
(here and above) doesn't it mean the people can't use .triggerHandler()
?
It could break apps (and even more likely tests).
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.
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 comment
The 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 comment
The 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 DOMContentLoaded
/load
events. So, it's fine, I guess.
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.
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 comment
The 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 comment
The 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 comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I meant let's not consider it a breaking change 😃
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.
LGTM
@@ -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 comment
The 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 jqLite(fn)
?).
So if jQuery has it this way, let's leave it as is.
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 comment
The reason will be displayed to describe this comment to others. Learn more.
OK. Should we document it as breaking change then?
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 comment
The 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 DOMContentLoaded
/load
events. So, it's fine, I guess.
jQuery has supported this form for a long time. As of jQuery 3.0 this form is the preferred one and all others are deprecated so jqLite(f) is now also supported. All internal invocations of jqLite(document).ready(f) (& equivalent) have been replaced by jqLite(f). Tests for these methods have been added as jqLite#ready had no explicit tests so far.
Use jqLite(fn) instead of jqLite(document).ready(fn).
We're not going to remove the aliases before jQuery does.
This change aligns jqLite with the jQuery implementation. Closes angular#15237
Still LGTM |
|
||
// check if document is already loaded | ||
if (window.document.readyState === 'complete') { | ||
window.setTimeout(trigger); |
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.
Should this just be window.setTimeout(fn)
since we aren't adding the listeners?
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.
Good point, fixed.
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.
It looks more & more similar to the jQuery code. :)
This change aligns jqLite with the jQuery implementation. Closes angular#15237
What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
Feature
What is the current behavior? (You can also link to an open issue here)
jqLite(callback)
is not supported.What is the new behavior (if this is a feature change)?
jqLite(callback)
is an alias tojqLite(document).ready(callback)
. The latter is now deprecated.Does this PR introduce a breaking change?
No.
Please check if the PR fulfills these requirements
Other information: