Skip to content

Manipulation: Detect sneaky no-content replaceWith input #2206

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

gibson042
Copy link
Member

Fixes gh-2204

   raw     gz Compared to master @ 892625b3c36eda6bb6ac226d15e0a158ba35cf21    
  +153    +39 dist/jquery.js                                                   
    +8     +7 dist/jquery.min.js

@dmethvin
Copy link
Member

Wow, that was harder than it would have first appeared. Is there a reason to keep the list of elements versus just a flag?

@gibson042
Copy link
Member Author

I know. 😞 This is essentially implementing a second output from jQuery.buildFragment—any flag would have to hang off of an existing input, but none of them looked palatable so I optimized on size.

@dmethvin
Copy link
Member

I looked at it for a while and couldn't figure out a better way.

@@ -201,7 +201,7 @@ jQuery.extend({
return clone;
},

buildFragment: function( elems, context, scripts, selection ) {
buildFragment: function( elems, context, scripts, selection, ignored ) {
Copy link
Member

Choose a reason for hiding this comment

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

Should we make buildFragment private and change it signature, 5 arguments usually considered as bad API, even for helpers. One object as an argument?

Copy link
Member

Choose a reason for hiding this comment

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

This is performance-critical code, I'm afraid wrapping it in an object might have a perf penalty (and it'll almost certainly be larger).

As for making it fully private, it seems like a good idea. We should do that with almost everything that's not documented IMO.

Copy link
Member

Choose a reason for hiding this comment

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

This is performance-critical code, I'm afraid wrapping it in an object might have a perf penalty (and it'll almost certainly be larger).

Need proof for that statement

Copy link
Member

Choose a reason for hiding this comment

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

The burden of proof is on the person that wants to introduce a change, i.e. here it's you. ;)

I just said it might introduce a perf penalty, I don't know.

Copy link
Member

Choose a reason for hiding this comment

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

I think the bigger issue is why buildFragment is so complex that it needs that many args, and why we had to add another one. I thought for sure there would be an easier way to deal with this crazy edge case, but couldn't find a reasonable way around it. It is a pretty hot path in our code.

Copy link
Member Author

Choose a reason for hiding this comment

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

In short, because of self-manipulation. .replaceWith is the worst offender, but it's basically a problem any time there's a nonempty intersection between the input and the context collection, and exacerbated by the fact that .domManip lies in between the outer method and buildFragment.

That said, the scripts parameter is probably unnecessary and safe to remove when buildFragment is made private. In fact, that's an opportunity to look at more sweeping changes... why exactly do we pluck nodes from the DOM and into a fragment in buildFragment instead of .domManip anyway? It's an operation that parseHTML has to undo!

@markelog
Copy link
Member

I looked at it for a while and couldn't figure out a better way.

How about #2223

gibson042 added a commit that referenced this pull request Apr 30, 2015
Fixes gh-2204
Ref 642e9a4
Closes gh-1752
Closes gh-2206

(cherry picked from commit 4b27ae1)

Conflicts:
	src/manipulation.js
	test/unit/manipulation.js
@gibson042 gibson042 closed this in 4b27ae1 Apr 30, 2015
gibson042 added a commit that referenced this pull request Nov 10, 2015
@lock lock bot locked as resolved and limited conversation to collaborators Jan 19, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Stealth-empty input to replaceWith leaves content in place
5 participants