Webcomponents: How should autofill work for inputs generated inside shadow roots

Created on 22 Sep 2016  路  25Comments  路  Source: WICG/webcomponents

I'm currently trying to build a form using custom elements, where each custom element generates an <input /> inside the custom element shadow root.

Something like this:

<form>
  <my-input>
    <!-- shadow root -->
      <input type="text" name="fname" id="fname" />
  </my-input>
  <my-input>
    <!-- shadow root -->
      <input type="text" name="lname" id="lname" />
  </my-input>
  <my-input>
    <!-- shadow root -->
      <input type="text" name="email" id="email" />
  </my-input>
  <input type="submit" value="submit" />
</form>

The above example doesn't seem to trigger autofill behaviour (i.e. loading the first name, last name, email from the browser profile).

Is there a recommended way of building custom element form inputs with shadow DOM while retaining autofill behaviour?

codepen

I've raised a Chrome issue for this with an example codepen (you'll need to view that in Chrome canary), but I'm not 100% sure yet whether this is a feature or drawback in shadow DOM.

P.S. the above code example wouldn't submit any values but hopefully https://github.com/w3c/webcomponents/issues/187 will fix that

shadow-dom

Most helpful comment

For the record, I have re-opened the Chrome issue, https://bugs.chromium.org/p/chromium/issues/detail?id=649162.

All 25 comments

The example is working as expected, as form elements inside shadow root do not participate in form submission for <form> outside shadow root.

@TakayoshiKochi are there any workarounds to make fields within a shadow root participate in the form? I've seen https://github.com/w3c/webcomponents/issues/187. I'm assuming that's the issue for resolving the happy path for this, but is there any way where we can get this to work now? This is a pretty important problem for us.

Yeah, #187 will be the solution for this problem, but until it is specified and implemented, I'm afraid we do not have a straightforward solution for this. What I can come up with is to hook form submission via onsubmit event handler and collect values from those custom elements, then add <input type=hidden> fields etc. to pass those data to the form. It seems modifying the form fields in onsubmit event handler is expected to work. But for making autofill to work, I have no idea... form= attribute (for association with the outer form) for each input element in shadow wouldn't work, as the form name lookup is restricted within the same node tree.

I can confirm that if you submit form fields in the light DOM with the same name as those in the shadow DOM that the ones in the shadow will suggest the values that were submitted. Unfortunately the ones in the shadow still don't receive autofill stuff from information the browser has collected from other forms being submitted.

We've come up with a potential way of auto-adding light DOM nodes, but this isn't perfect because we're mutating the DOM and need to be compatible with virtual DOM libraries. What we might be able to do from here if they blow that away (I don't think they should) is fake childNodes to make it think there isn't anything to mess with. cc @bengummer

Let me close this. It looks there is no action items which can be done immediately.

@hayatoito I think there is a good action item remaining here, which is to update https://html.spec.whatwg.org/multipage/forms.html#autofill to either spec Chrome's behavior (only autofill if in a document tree) or to specifically mention that it suffices for the element to be connected.

Can we reopen?

I don't think Chrome's behavior is desirable in the long term. It's totally reasonable for input element to appear within its own shadow tree in the world of componetized web form controls. However, autofill is a browser feature which is kind of beyond the scope of HTML spec to specify exactly how it should work. e.g. Safari uses a bunch of heuristics to determine which form control elements are associated together. If anything, we can just add a non-normative note recommending either behavior but I don't think we can spec anything with MUST.

I believe the problem with a different behavior is that it would be based on names, whereas for ids at least we kind of try to not "leak" them out of the shadow tree. I don't know if this is really a leak though...

I believe the problem with a different behavior is that it would be based on names

I don't know what you're referring here. Safari certainly doesn't use just name content attribute for autofilling. If you're talking about submission, then that needs to be spec'ed separately independently of autofill.

I think I am a bit confused. The spec section I linked to was about "autofill" via the autocomplete="" attribute. But the OP's post just uses name="", and from what I recall browsers use that to restore form data. But then @TakayoshiKochi started talking about form _submission_, which seems unrelated to any kind of autofilling or restoration...

I guess we need clearer test cases. Maybe the OP's issue is just a UI issue and not something observable from JS.

Yeah, I think what @bengummer is taking about (at least in https://github.com/w3c/webcomponents/issues/572#issue-178490097) is autofill UI in Chrome.

Here is a quick demo: https://jsbin.com/puhipimudo/edit?html,output

I cannot reproduce @bengummer's issue with just name="" because I cannot get that to trigger any autofill UI. But with autocomplete="" I can see the problem, where shadow DOM stops the Chrome autofill UI from working.

I guess I still think it might be valuable to clarify autocomplete="" UI behavior in the spec, since the whole autocomplete="" feature is about UI anyway. Personally I think it should not matter whether it's in shadow DOM (i.e. I think Chrome's current behavior is wrong). Note that there is no <form> so form association is not really the issue.

Yeah, the problem filed here is that Chrome does not fill a <input> field when another <input > field is filled by a user, if each <input> element is assigned to a slot in different tree scope, as far as I can read.

It sounds a problem of Blink's UI because all <input> elements are in the same tree scope, at least. Autocomplete should work in this case, IMO.

Ah, my understanding is incorrect.
According to http://s.codepen.io/bgummeratlassian/debug/Egkarq, each <input> is in different tree scopes.
In this case, I am not surprised that autofilling does not work in Blink. I guess Blink fills other <input> elements only if they are in the same tree scope.

It looks Blink does not support autofilling across tree scopes.

I guess we do not have any opinion about: "Should autofill work across shadow dom boundaries? or not?".
I do not have any strong opinion. This is a typical situation where "encapsulation vs ergonomics" comes.

We believe autofill should work across shadow boundaries. Otherwise, people with lousy idea of security can disable autofill by putting each input element into its own shadow tree. This is precisely why modern browsers ignore autocomplete="off". See https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion#The_autocomplete_attribute_and_login_fields

I see. Ah, I have a concern about it. We do not support <form> and <input> elements in different tree scopes yet.

Given that, auto-filling an <input> element in a different tree scope might be confusing for users?
They are not in the same collection of form-associated elements. I meant they are not submitted together.

They are not in the same collection of form-associated elements. I meant they are not submitted together.

That really depends on what scripts are doing. Even today, there are many input elements that are not wrapped in a form element but still function as a login form.

Okay. As long as we are aware of this kind of contradiction, it might be okay to support autofill across shadow dom boundaries.

That implies that we will support autofill across different collections of form-associated elements even if they all are in the same node tree.

e.g. a document tree has two <form>s. Every <input> elements are auto-filled, regardless of the <form> they are in.

Is that okay?

I'm confused what autofill has to do with forms at all. Many inputs are in no form. They still get autofilled, as my example shows. So it doesn't matter what collection of form associated elements an input belongs to. That's completely irrelevant for autofill, as far as I can tell. I don't see any contradiction.

Many inputs are in no form. They still get autofilled, as my example shows. So it doesn't matter what collection of form associated elements an input belongs to.

Right. Modern browsers don鈥檛 just use form element to group input elements as there are many websites that actively try to circumvent browser鈥檚 autofill feature, and allowing such a simple omission to disable the autofill would let those adversaries to accomplish just that.

I got it. Thank you for explaining! My understanding about autofill was wrong. Sorry for the confusion.
I am +1 for autofill working wherever input elements are in.

As far as I can read from https://html.spec.whatwg.org/multipage/forms.html#autofill, it looks the spec does not say that input elements must be in a document tree. We do not have to update the spec, right?

If my understanding is correct, let me close this issue, and re-open Blink's issue to fix the Blink's behavior.

I guess we don't have to update the spec, it's true. But I think it might be good to clarify anyway. Let me open a PR to do so.

For the record, I have re-opened the Chrome issue, https://bugs.chromium.org/p/chromium/issues/detail?id=649162.

Was this page helpful?
0 / 5 - 0 ratings