Encapsulation and defaulting to open vs closed (was Re: Shadow DOM Encapsulation)

On Feb 6, 2014, at 2:10 PM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:

> 
> The decision to do the JS side of Shadow DOM this way was made over a
> year ago.  Here's the relevant thread for the decision:
> <http://lists.w3.org/Archives/Public/public-webapps/2012OctDec/thread.html#msg312>
> (it's rather long) and a bug tracking it
> <https://www.w3.org/Bugs/Public/show_bug.cgi?id=19562>.
> 
> Note that there were good arguments made for adopting either a
> private-by-default or private-by-choice model, but we eventually went
> with a public-by-default model instead.

I think it should be made clear that "we" means the Chrome team and the Shadow DOM spec editors, and not the Web Apps WG as a whole. I don't think we ever actually reached consensus on this, and in particular, Shadow DOM currently does not even offer the option to have stronger encapsulation.[1]

The ^ and ^^ operators double down on this. They would render a flag to not expose the shadow dom directly toothless, since you could always use querySelector or styling to get at the Shadow DOM internals.

I understand that Google folks largely agree amongst themselves that they only want "weak" encapsulation - Type 1 in the typology I posted here several years ago: <http://lists.w3.org/Archives/Public/public-webapps/2011AprJun/1364.html>.

I don't think anyone has ever countered my arguments for why Type 2 encapsulation is valuable. Yet years after my feedback, the Web Components family of specs continues to not support it, and to be designed so it's not even possible to support it.

I think that is a bad design direction. I am ok with there being such a thing as a "public mode" where components get only Type 1 encapsulation. However, I strongly feel that Type 2 should also be offered. I also feel that Type 2 should be the default, because defaulting to open has frequently turned out to be a mistake that has been hard to correct in the Web Platform. Some examples of "open" decisions that are by default problematic:

- Exposing all properties of the "window" object in the global scope and visible to all JavaScript functions.
- Allowing webpages to embed cross-domain subresources (including scripts) freely
- Allowing SSL pages to embed non-SSL resources
- Allowing a page to embed a page from another site in an iframe without its permission
- Allowing the frame namespace of any window to be visible in all other windows

Since then, we had to do a lot of design and engineering to come up with ES6 Modules, CORS, HSTS, X-Frame-Options, etc to try to overcome these problems, or just made breaking changes that risked compatibility.

I have a hard time thinking of cases where defaulting to closed was a mistake, but I believe in all such cases, adding an option to be more open was not a problem. For example, opting into cross-site XHR through CORS is a much more robust solution than opting out of enframing via X-Frame-Options.

I continue to believe that Type 1 encapsulation is insufficient for a robust component model, and providing only Type 1 and not Type 2 is a major mistake. Editors of the Web Components specifications have consistently ignored this feedback for years, but I don't think we should take that to imply agreement with the approach.

Regards,
Maciej


[1]  In fact, the original agreement on the thread was to support both "public" and "private", in the sense that components could fully expose their shadow innards or not, and then the default could be decided. Dmitri even agreed to add support for a flag to decide this, but never did: <http://lists.w3.org/Archives/Public/public-webapps/2012OctDec/0612.html>.

Received on Thursday, 6 February 2014 23:06:56 UTC