[Proposal]: Symbol namespacing of attributes

#1

XML has a way of namespacing tags. The idea was applied, somewhat unsuccessfully, to html. HTML5 kind of nixed it (I think). I’m not aware of why it was nixed, so perhaps I’m missing some of the lessons learned. But I think we should give it another try:

Proposal:

Just like with import maps, be able to place a script tag in the head part of an html document:

<html>
   <head>
   <script type="module">
     import {mySymbol} from 'my-library/myLib.js';
     window.registerAttributePrefix('foo', mySymbol);
   </script>
  </head>
  <body>
      <button id="myButton" foo-bar="hello">My Button</button>
     <script type="module">
        import {mySymbol} from 'my-library/myLib.js';
        console.log(myButton.getAttribute(mySymbol, "bar")); 
        // "hello"
        myButton.setAttribute(mySymbol, "bar", "goodbye");
     </script>
  </body>

</html>
#2

Could you describe what’s going on in the code example? Can the foo-bar attribute only be read/set from JavaScript if you have access to mySymbol? What’s the use case for this?

#3

Yes, that’s correct, @simevidas. It allows for “private” attributes, which can only be accessed if you know the symbol. I realized after posting, that there are a number of other functions that would need to change, including mutation observers, and observedAttributes with custom elements. How styling would work is another question (I guess styling would need to ignore these attributes, unless css could reference symbols somehow?).

This proposal is meant to provide a way of reconciling the reality that many widely used libraries (angular and AMP, for example) are using non standard attributes, and that data-* is a bit clunky and won’t by itself resolve name spacing conflicts if different libraries used together (it just guarantees no conflicts with future browser supported attributes).

Other discussion can be found here and here and here

#4

This may be a stupid question, but how private is it? A web page’s JavaScript code is public. Anyone can find the line

import {mySymbol} from 'my-library/myLib.js';

and copy-paste it into their own code to read/write a library’s attributes.


Also, what happens if a library registers the foo prefix, but then another library tries to use the same prefix without providing the correct symbol? In other words, what happens in the case of a name collision?

#5

Definitely not a stupid question – my wording was sloppy – private is too strong a word. And I think actually a better analogy would be the way you can do this in JavaScript:

import { export as alias } from "module-name";

I guess I have enough faith in library authors that if they go out of their way to use the same symbol, that they want to convey that they are adding a plug-in (or whatever) into the ecosystem of the library that created the symbol.

If two libraries happen to crash upon the same default prefix of “foo”, that is precisely the problem this hopes to fix.

If a web application is consuming both libraries, this would allow the web application to distinguish between the two by giving them different prefix aliases in the header. I.e.

<html>
   <head>
   <script type="module">
     import {mySymbol} from 'my-library/myLib.js';
     import {yourSymbol} from 'your-library/yourLib.js';
     window.registerAttributePrefix('foo-mylib', mySymbol);
     window.registerAttributePrefix('foo-yourib', yourSymbol);
   </script>
  </head>
  <body>
   <button foo-mylib-bar="hello" foo-yourlib-bar="goodbye">My button is your button</button>
  </body>
</html>

One addendum I’m thinking is that libraries could provide their default prefix (‘foo’), which would be ignored if the symbol was previously registered with a different prefix). So you would only need this when there is a conflict between libraries.

Another addendum would be to allow ShadowDOM realms to define their own symbol-attribute mapping, somehow.