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

feat(jqLite): implement jqLite(f) as alias to jqLite(document).ready(f) (also: deprecate the latter in the second commit) #15237

Closed
wants to merge 5 commits into from

Conversation

mgol
Copy link
Member

@mgol mgol commented Oct 9, 2016

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 to jqLite(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:

@mgol mgol added this to the 1.7.0 milestone Oct 9, 2016
@mgol mgol self-assigned this Oct 9, 2016
@mgol mgol modified the milestones: 1.6.0-rc.0, 1.7.0 Oct 9, 2016

function trigger() {
if (fired) return;
fired = true;
Copy link
Contributor

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?

Copy link
Member Author

@mgol mgol Oct 10, 2016

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. 😄

Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Contributor

@petebacondarwin petebacondarwin left a 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;
Copy link
Contributor

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)`)
Copy link
Contributor

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?

Copy link
Member Author

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.

Copy link
Member Author

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)) {
Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Member

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.

Copy link
Member Author

@mgol mgol Oct 10, 2016

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.

Copy link
Member Author

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);
Copy link
Member

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).

Copy link
Member Author

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.

Copy link
Member

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?

Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member Author

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?

Copy link
Member Author

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

Copy link
Member

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 😃

Copy link
Member

@gkalpak gkalpak left a 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)) {
Copy link
Member

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);
Copy link
Member

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);
Copy link
Member

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.

mgol added 4 commits October 12, 2016 14:46
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
@gkalpak
Copy link
Member

gkalpak commented Oct 12, 2016

Still LGTM


// check if document is already loaded
if (window.document.readyState === 'complete') {
window.setTimeout(trigger);
Copy link
Collaborator

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, fixed.

Copy link
Member Author

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. :)

@mgol mgol closed this in beab3ba Oct 12, 2016
@mgol mgol deleted the ready branch October 12, 2016 17:33
ellimist pushed a commit to ellimist/angular.js that referenced this pull request Mar 15, 2017
This change aligns jqLite with the jQuery implementation.

Closes angular#15237
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants