Skip to content
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

Define cloning steps for an select element #644

Closed
bes-internal opened this issue May 3, 2018 · 21 comments
Closed

Define cloning steps for an select element #644

bes-internal opened this issue May 3, 2018 · 21 comments

Comments

@bes-internal
Copy link

The standard in this place is vague. https://dom.spec.whatwg.org/#concept-node-clone
Now all browsers is copying the internal state of radio buttons, checkboxes, inputs type file when deep clone node, but not selected value of select element.
It is logical to bring everything to a consistent form (copy internal state for all interactive elements)

Reason: cloneNode(true) does not clone value of select. Examlple https://codepen.io/anon/pen/bMWKdO
Discussion of spec https://stackoverflow.com/questions/27193301/node-clonenode-inconsistent-with-dom-spec

@annevk
Copy link
Member

annevk commented May 3, 2018

The way this works is with "cloning steps". The HTML Standard https://html.spec.whatwg.org/ uses that hook for the elements you mention. We could possibly add a note here to indicate where this hook is used and possibly discourage others from using it, but I think the status quo is okay as well.

@bes-internal
Copy link
Author

I do not understand what you said. How does this solve my problem? I need the guy from this bug (and all other browsers) to see the exact instructions for copying the internal state of node

@annevk
Copy link
Member

annevk commented May 3, 2018

Well, ideally it would have helped you understand how the standard is not vague and that it in fact only copies internal state for a select set of elements (not select iirc). I don't think we want to expand that and at this point it would probably break folks relying on it not copying such state.

@bes-internal
Copy link
Author

From spec:

HTML defines cloning steps for script and input elements.

The cloning steps for input elements must propagate the value, dirty value flag, checkedness, and dirty checkedness flag from the node being cloned to the copy.

The cloning steps for textarea elements must propagate the raw value and dirty value flag from the node being cloned to the copy.

  1. You do not think that about the select element simply forgot? Because there is no logic why the actual value of the select element must be ignored. Do you agree with this statement?

  2. In your answer you are guided only by backward compatibility? Is backward compatibility superior to broken logic? How do you think the cloning function should work? It must produce an indent copy. Do you agree with this statement?

  3. In any description of the cloneNode function there is no note that the value of the select will not be copied. Because this is a bug in the behavior of the function. And just those who encountered this have written an extra code, rather than went to check with the standard and fix them. Do you agree with this statement?

I think the status quo is okay as well

Why?

@bes-internal bes-internal changed the title Determine spec of copying the internal state of node when "clone a node" Define cloning steps for an select element May 4, 2018
@annevk
Copy link
Member

annevk commented May 4, 2018

I disagree with your statements. There's a lot of internal state that is not copied over by cloneNode(), e.g., <canvas>'s bitmap, <a>'s URL, and <input type=file>'s files.

I strongly suspect it's copied over for input and textarea due to implementation bugs that were copied over by other browsers.

And yes, backwards compatibility is very important. I encourage you to read https://www.w3.org/TR/html-design-principles/.

@bes-internal
Copy link
Author

There's a lot of internal state that is not copied

Well this is good list to start work on it

I strongly suspect it's copied over for input and textarea due to implementation bugs that were copied over by other browsers.

sorry, there is an opinion that you write the specification as a description of the facts of the implementation history rather than good interface

@annevk
Copy link
Member

annevk commented May 4, 2018

Again, see the principles above, not all past mistakes can be fixed. The web platform has many such warts.

@bes-internal
Copy link
Author

It is sad. Close.

@studdugie
Copy link

studdugie commented Nov 28, 2018

I'm adding my voice to the silent chorus of voices who think it's worth breaking backward compatibility to remove this "wart" from the web platform. And I'm adding it now because I've been working with the DOM for over a decade and I've HATED it ... until recently.

Programming against the DOM today is a vastly superior experience than its ever been and I'm grateful that some of you decided that the ease of use consideration of an API matters and have thus made significant improvements to it. And then a couple days ago I write some code with the reasonable expectation that the selected option would be retained in the clone. That expectation was violated when today I got a bug report from the testing group. Now remember, I know the DOM and I know that this happens, but I forgot, because I'm human and in recent years the DOM has been reasonable, and the expectation is also reasonable. So if someone with my experience forgets, consider new web developers who are just learning the DOM.

I'm not of the opinion that breaking backwards compatibility for this specific issue is an apocalyptic event so I hope those who have the power to "fix" it will. But I could be wrong so I'm going to go out and stock up on canned goods and jerky just in case 😸

@bes-internal
Copy link
Author

Most depressing is that no one suggested how to get around the backward compatibility problem. Has the development mechanism not been working over the years of work? I remember the ideas on which this working group ascended - mummy of W3C. Now we will need to create that new to move on?

The guy from the whatwg had to come and say: hey, this is indeed an inaccuracy now we will fix it!
Maybe it's time to do node.cloneNode([deep = false], andSelectToo) or maybe node.cloneNodeReallyAll() ...

@domenic
Copy link
Member

domenic commented Nov 29, 2018

If someone creates a library which clones select state too, and it becomes of a similar level of popularity as cloneNode, that would be a great signal that we should reconsider this. At this point we are weighing three web developers who want to write less code, against the cost of propogating a legacy mistake throughout more of the platform.

A tree-cloning function that also copies a few small pieces of state if the nodes of the tree have certain names is not good design. (That's the legacy mistake I refer to.) And you're right that if we were to find out that this was a widespread need, we'd want to do it via a different function, which wasn't focused around cloning the tree structure like cloneNode is, and instead is focused around cloning the state. But we simply do not have evidence that enough developers are running into this, to make it important to add a sugar function to the web platform, to save them writing some code. And no amount of GitHub comments will really get us there; the best path is to show wide adoption of a library.

So hopefully the next steps here are clearer now!

@bes-internal
Copy link
Author

bes-internal commented Nov 29, 2018

Not a single popular site for developer (for example https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode) says about this features ("a lot of internal state that is not copied over by cloneNode()"). Now the threshold of entry into the development is very low and most do not even face this error. Because is not hello world difficult. Or they use a library where someone was not too lazy to write a little more code, unless of course he had tested his code enough to find out about this issue.

becomes of a similar level of popularity as cloneNode

How do you collect statistics? Or should someone open "cloneNodeReallyAll" fan club?

At this point we are weighing three web developers who want to write less code

In no case. I just want everything to meet the expected behavior or be documented if it is not. Do you have anything against it?

the best path is to show wide adoption of a library

What I have to prove, that fixed polyfill of cloneNone is gained popularity?
Not everything in IT world should work according to such plan. There are rarely used features and capabilities that someone should take care of and do this dirty work.

BUT in the same time
doc

WTF? I do not know this story, but then obviously someone does not bother about backward compatibility at all and your excuses about cloneNode() seem like bullshit!

@annevk
Copy link
Member

annevk commented Nov 30, 2018

@bes-internal there's no need to be rude, please read https://whatwg.org/code-of-conduct.

@studdugie
Copy link

studdugie commented Nov 30, 2018

@domenic My comment said nothing about writing less code. What my comment is fundamentally about is that I am of the opinion that the DOM should be intuitive and free of surprises. And the cloneNode behavior is not because of how it interacts with <select>

Additionally I'm just going to point out that the backwards incompatibility bludgeon that you and others like to wield when it suits you has been thoroughly debunked by @bes-internal's comment, profanity notwithstanding.

The reason I commented on this thread in the first place is because I tripped over the cloneNode behavior again this week and because of the ECMAScript working group. A few years ago I watched a video from some developer conference where someone from the ECMAScript working group pleaded with the audience of developers to get involved with the people and groups that produce the specs for the technology that they use everyday. So after years of thinking that spec groups were filled with tone deaf pompous [expletive here] and thus not worth the effort and the fact that the W3C proved me right, I decided to try to change my mind and listen to the ECMAScript guy and engage. I'm telling you this story because it's one possible explanation of why this issue isn't popular. In other words, most developers are not going to join the conversation about making a better web platform. But I'm trying to. And changing the cloneNode behavior is one small thing in a HUGE platform that can improve the DOM because at a minimum it would mean that the DOM has one less sharp edge.

@annevk
Copy link
Member

annevk commented Nov 30, 2018

To be clear, it hasn't been debunked. Backwards compatibility with a single implementation is not a thing standards typically care for. You need to look at where all implementations are at a given point in time to be able to judge whether a breaking change can be made.

Also, @domenic rightly observes that if this were a common pain point the evidence would be in libraries working around it. Libraries with reasonable adoption working around real or perceived shortcomings in standards has great value in the standardization process and can help us prioritize what needs to be tackled next.

@bes-internal
Copy link
Author

Let's see what is being done in libraries. Take this. Оne of those that did a lot in due time to show that standards need to be changed. https://api.jquery.com/clone/
(jquery src code of clone) :

Note: For performance reasons, the dynamic state of certain form elements (e.g., user data typed into textarea and user selections made to a select) is not copied to the cloned elements. When cloning input elements, the dynamic state of the element (e.g., user data typed into text inputs and user selections made to a checkbox) is retained in the cloned elements.

Hmm, see related bug. https://bugs.jquery.com/ticket/1294 :

Changed 11 years ago by brandon
The fix for this is to expensive for the core and has been removed in 1.2. The workaround is simple. Just copy the selectedIndex from the original.

The library would copy the state, but refer to performance. At least he understands that this is important and documented this.

Other voices
https://stackoverflow.com/questions/742810/clone-isnt-cloning-select-values (viewed | 31,738 times)
https://bugs.jquery.com/ticket/10550#comment:6
https://stackoverflow.com/questions/17274081/javascript-jquery-clone-not-working-in-dropdown-list
https://stackoverflow.com/questions/7450032/clone-a-row-containing-selects-and-clone-selects-values
https://stackoverflow.com/questions/44983149/javascript-clone-node-is-not-copying-all-values-from-cloned-to-new-object
Polymer/polymer#2112
https://stackoverflow.com/questions/3776270/jquery-clone-doesnt-copy-select-dom-properties

P.S.
Maybe backward compatibility is not relevant here such great importance? Anyway everyone expects this behavior and copy the state. So if the native function does it right away, then nothing will change.

@dmethvin
Copy link

dmethvin commented Dec 1, 2018

If someone creates a library which clones select state too, and it becomes of a similar level of popularity as cloneNode, that would be a great signal that we should reconsider this.

jQuery tried to fix some of these inconsistencies in the IE8 era but gave up on it because it's incredibly expensive to traverse two arbitrarily large cloned DOM trees to fix things after the fact. It's less of a burden at the app level (if you know you're cloning a specific set of form elements) but as a library we don't know that in advance so we have to do it for every clone operation.

At the point that jQuery documentation was written, you can see there were more exceptions. IE8 in particular cloned almost no state. As far as I can tell today, every modern browser clones the state of <input> and <textarea>.

For <textarea> I think the cloning behavior change started in June 2015 with Chrome 43. According to Chrome bug 487352 the copying of <textarea>'s dynamic value was an accident and considered to be a bug. Then in September 2016 the same discrepancy was revived in an old Firefox ticket.

The discussion in whatwg/html#1233 is a good timeline. As far as I can tell, nobody has reported a bug anywhere against the new behavior, although the previous non-copying behavior had been reported as a bug several times against browsers and jQuery, see jquery/jquery#3115 . (Note that ticket was about both <textarea> and <select> elements.)

A tree-cloning function that also copies a few small pieces of state if the nodes of the tree have certain names is not good design. (That's the legacy mistake I refer to.)

This is soooooo true! No form elements should have ever cloned state IMO. I think it started with checkboxes in the distant past and spread from there. The only thing worse than cloning state on all form elements is cloning it on some because the result is tickets like this one.

@annevk
Copy link
Member

annevk commented Dec 3, 2018

That's an interesting piece of feedback. Perhaps there should be a clean clone operation that doesn't copy state, ever. Perhaps worth discussing in a new issue?

@bes-internal
Copy link
Author

A tree-cloning function that also copies a few small pieces of state if the nodes of the tree have certain names is not good design. (That's the legacy mistake I refer to.)

This is soooooo true! No form elements should have ever cloned state IMO.

Could you describe in more detail why or give examples of usage without cloning state?

Perhaps there should be a clean clone operation that doesn't copy state, ever

What is the meaning to separate state and tree?

Why the state is considered in this case separately but not just as a set of object properties (correct if I misused the definition. I mean the opposite of element attributes)?

@annevk
Copy link
Member

annevk commented Dec 4, 2018

State is effectively private to the object (sometimes with public accessors), whereas the clone operation ideally only copies the public aspects of it (and does mostly, see <img>, <details>, <canvas>, etc.).

@blackirishmec
Copy link

I have created a function to extend jQuery's built in ".clone()" function, to create a deep copy a set of matched elements with the dynamic state of all form elements copied to the cloned elements.

Here is a link to the repo: https://github.com/blackirishmec/jq-deepest-copy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

6 participants