element-internals-polyfill icon indicating copy to clipboard operation
element-internals-polyfill copied to clipboard

form.elements still not polyfilled

Open aigan opened this issue 2 years ago • 9 comments

As a workaround I added form._elements = initSet in order to get the elements from the internal set. Better than nothing.

aigan avatar Aug 30 '21 14:08 aigan

Yeah, unfortunately form.elements (which is an HTMLFormControlsCollection[]) isn't mutable by the user. I'm more than happy to consider solutions, but don't have a really good idea how to implement that behavior right now.

calebdwilliams avatar Sep 12 '21 18:09 calebdwilliams

When elements this.attachInternals() does this provide the details needed to lookup elements from the form.elements getter (with this.localName perhaps?) and return a similarly behaving collection when called? As in the getter is substituted somehow. This is from my brief look at the prototype getter in Safari which I successfully overwrote where $0 was a form element reference in the devtools:

Object.defineProperty($0.constructor.prototype, 'elements', {get: function(){ return [...this.__elements, ...this.querySelectorAll('custom-element1, custom-element2, ...')]; }})

drafted a solution in PR #50 [since closed]

working solution for form.elements against a demo in the default branch here: https://github.com/jimmont/element-internals-polyfill/ https://jimmont.github.io/element-internals-polyfill/

also continuing on through some related issues

jimmont avatar Oct 20 '21 14:10 jimmont

@jimmont would you be interested in adding this via PR? This could be globalized by using the formsMap object. If not, I'll take a stab at it soon.

calebdwilliams avatar Dec 23 '21 17:12 calebdwilliams

OK, I'm finally getting around to this one, I have a CodePen with a start for this, but I don't have the sorting algorithm quite right. I'll work on it as I have time and the mental bandwidth, but this is moving in the right direction. If anyone wants to help out with this, I'd still appreciate it, just let me know.

calebdwilliams avatar Jan 08 '22 22:01 calebdwilliams

Hey Caleb, curious if you could give an estimated progress update on this? I've been heavily relying on form.elements in my app not realizing that breaks on Safari :( Just trying to figure out if I should come up with a temporary solution but if this is nearing release I'll just wait for it. Awesome work on this polyfill, form associated elements are so useful!

joezappie avatar May 07 '22 05:05 joezappie

I might be able to add something soon. I’d also gladly accept a pull request @jrj2211

calebdwilliams avatar May 08 '22 18:05 calebdwilliams

I'm taking a look at this and might be able to provide a PR. Seems like what's needed for your code pen is just to finish up the elements getter? Fixing the sorting and returning an object that mimics HTMLCollection?

joezappie avatar May 11 '22 23:05 joezappie

@jrj2211 yeah, that’s basically it. You might check the scoped registry polyfill. I did something similar there you might be able to pull from.

calebdwilliams avatar May 12 '22 01:05 calebdwilliams

@calebdwilliams I don't have much experience with TS and not sure exactly where this should go in the source code but here's an updated code pen:

https://codepen.io/jrj2211/pen/WNMGvaN?editors=1011

It now sorts properly. Not sure if you have any objections on using recursion but my "compare" function does call itself to check if there are multiple poly filled elements that are before the next native element.

Untitled-1

Blue is native elements and green is the polyfilled array pointer. 2 and 3 are before 4 so both those need to be added before moving to the next native element.

I also now sort the polyfilledElements array as I think that's the more performant option rather than nested loops. That was I think your main issue with how you were trying to do it before. The way polyfilledElements just happens to get initialized puts four before three. Since you where just incrementing a pointer to access that list, three would always then come after four.

There is also a for loop to add any remaining polyfilled elements that come after the last native element.

I also provided a class HTMLFormInternalsCollection (feel free to rename) which from what I can tell mimics an HTMLCollection. It lets you access by index or name, or by the getters item(x) or namedItem(name). It also provides an iterator so you can loop it normally. I don't think theres anything else missing for that except the fact that its not a live list. Could cache the result and update the list everytime a polyfill element is added but I'm not sure how youd keep it live with the native form.elements.

Hope this helps.

joezappie avatar May 12 '22 05:05 joezappie