- From: Jonas Sicking <jonas@sicking.cc>
- Date: Thu, 20 Feb 2014 14:39:30 -0800
- To: Webapps WG <public-webapps@w3.org>
- Cc: W3C TAG <www-tag@w3.org>
On Thu, Feb 20, 2014 at 2:09 PM, Edward O'Connor <eoconnor@apple.com> wrote: > +public-webapps, -www-tag in replies to avoid cross-posting > > Hi, > > Domenic wrote, to www-tag: > >> [C]an shadow DOM be used to explain existing elements, like <video> or >> <input type="range">, in terms of a lower-level primitive? >> >> As of now, it seems like it cannot, for two reasons: >> >> 1. Native elements have extra capabilities which are not granted by >> shadow DOM, or by custom elements. For example, they can participate >> in form submission. > > Authors need to be able to participate in form submission, but this is > independent of Custom Elements. > > Web applications often maintain state in JS objects that have no direct > DOM representation. Such applications may want such state to be > submittable. > > Existing form elements map one field name to many values. People often > build custom controls precisely because those controls hold more > complex values that would be better represented as many names to many > values. Subclassing existing form elements don't get you this. > > And inheriting from HTMLInputElement is insane (not because inheriting > is insane, but because HTMLInputElement is insane), so that's not really > how we want author-defined objects to become submittable. > > Given the above I don't think we should try to solve the "how authors > can participate in form submission" problem by enabling the subclassing > of existing form elements. Instead, we should define a protocol > implementable by any JS object, which allows that JS object to expose > names and values to the form validation and submission processes. > > Something like this: > > function Point(x, y) { > this.x = x; > this.y = y; > } > Point.prototype.formData = function() { > return { > "x": this.x, > "y": this.y > }; > } > > var theForm = document.querySelector("#my-form"); > > var p = new Point(4,2); > > theForm.addParticipant(p); > theForm.submit(); > > This is obviously a super hand-wavy strawman and would need to be > fleshed out. Thoughts? Something like this seems awesome! I like that the .addParticipant function can enable random JS objects to participate in submission. A couple of comments though: I'm not sure if we should return a dictionary or an array. Keep in mind that a form control can have multiple values. This is something used by both <input multiple> and <select multiple>. Also keep in mind that order matters as many servers are sensitive to order. So we could either do `return { x: [5, 6, 7] }` where enumeration order determines submission order, or we could do `return [["x", 5], ["x", 6], ["x", 7]]`. Or, given that normally a single form control only has a single name and 0 to many values, we could do `return { name: "x", value: [5, 6, 7] }`. The other thing is that it would be great if elements that wanted to participate in submission didn't have to manually call addParticipant. This could be done by having the <form> element attempt check for a .formData property on any descendant that was added, and add any elements that has such a property as a participant automatically. We could even make the built-in form controls like <input> and <select> have a .formData() function which returns data in whatever format we decide is the right one. This way custom elements could very easily and automatically participate in submission by simply declaring a .formData property. The only tricky part is that form.controls is a live array. I don't see a way of making form.controls contain custom elements without synchronously running getters whenever an element is added as a descendant of a <form>, which is not something we want to do. But live arrays are evil anyway so we can probably just ignore integration with that and instead add a form.getParticipants() function which returns a non-live array of all participants. / Jonas
Received on Thursday, 20 February 2014 22:40:28 UTC