-
Notifications
You must be signed in to change notification settings - Fork 376
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Why do we really need hyphens? #658
Comments
We already have a unifying module that does all that. it is called HTML.
Hence the still mostly unresolved (at least for my problem space)
discussions about HTML imports and modules and so on. I'm afraid i don't
have solutions though -- we work around this using thing like Vue and our
own internally developed workflows and libraries. There are several
staunchly entrenched combatants in these discussions unfortunately. We are
working around them until they reach consensus.
I hope folk go easy with the "everybody" part though. :) I personally don't
HATE the hyphens but this is really a namespace issue at the core. We came
out of the gate with this having to make a list of exceptions to the
allowed names. What we really need (and others smarter/deeper in
implementation of the spec than me) are ways to name things locally in any
way we chose.
…On Fri, Aug 25, 2017 at 13:10 Joseph Orbegoso Pea ***@***.***> wrote:
I know this has already been discussed.
But I think the web moves too slow for this to really be a problem.
Many frameworks already allow this.
For example, the new and highly popular Vue <http://vuejs.org> allows
names without hyphens.
Everyone LOVES it.
------------------------------
What the web needs is perhaps to stop, and think about these new component
models in a different way. For example, here's a proposal: the Unity
Component Spec
<https://github.com/TheLarkInn/unity-component-specification>.
We simply just need a way to write components in a way where we can easily
associate behaviors with any tag name. For example, if we want to define
what <foo> means inside our component, let's be able to do that.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#658>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/AGYGJxsKnJkbFdocwWzEvLYoV76OKk-eks5sbwAFgaJpZM4PC7rw>
.
|
I hate the hyphens in custom element name. Then we can use the different But now, I needs to change the url of |
Hyphens are needed to dustunguish custom elements from mistyped stuff like |
Maybe what the web needs is an official component model that works on top of DOM (like Vue, React, etc), not in the DOM (Custom Elements are part of DOM, not on top of it). Suppose we had something like a way to use selectors to associate components with DOM elements, officially, without creating anything that extends HTMLElement. Maybe this is a good use-case for the Or perhaps we just need an official declarative way of doing what jQuery has been doing for years. F.e. F.e., let's take a div, and let's assign many behaviors to it: <div is="foo bar baz">
...
</div> components.define('foo', class Foo {...})
components.define('bar', class Bar {...})
components.define('baz', class Baz {...}) Which would simply play nicely along the current Custom Elements. Of course, logic in components could clash, as with any sort of programming. So some care would need to be taken. Defined components might have lifecycle hooks similar to Custom Elements. Components' is not the element, it is just the instance of the component, and perhaps the constructor received the target element as an argument. I'm just trying to throw some ideas out there so we can overcome limitations (f.e. naming with hyphens). While we're thinking about it, we should also figure a way toocally name components, perhaps using shadow roots, so that root.components.define('foo', class Foo {...})
root.components.define('bar', class Bar {...})
root.components.define('baz', class Baz {...}, {
// limit elements it can be used on
allowedOn: ['div', 'p', '.some-class']
}) Just throwing ideas. We just need something more modular and easier to scope, so different components can name their parts anything they want (just like with Vue or React components). It would solve many problems in an official way. |
If typo is such as i have an old web application, it mostly used buildin element. if I can upgrade it without modify any code, it sounds so great. such as we can just use build in element to development our web application. then, enhance the experience by custom element. eg: development via |
Another idea: something like lit-html, but native; perhaps a template tag function that is native, and processes HTML strings to create dom-diffable components. The element/component names can be defined per-template. Throwing ideas out there. We don't necessarily need to be stick only with Custom Elements. |
@web-padawan At now, custom element named likes |
The above So maybe we just need something as powerful, yet declarative, but not using selectors so that it is completely clear what behaviors/components are being used explicitly. |
@baocang I mean that parser needs an explicit direction about whether the element can be upgraded later on (and thus should not be treated as unknown) or not. Please see the spec for upgrading definition. @trusktr condider the fact that user can disable JavaScript and DOM would still be rendered, see also explanation here. |
This is an existing problem that people tried to solve with the is="" attribute. But now that I think about it, this component is seems like a better alternative without the problem of the original (limited to only one class, and the class must extend the target element's native interface). |
@web-padawan I know about the spec. But why we can't config it in manfest or other way to tell browser we needs custom the buildin element? Why some thing jQuery can do, many developer can do, W3C can't? I can enhance the but with webcompoennts, I needs change and if i use some element likes If we have no way to change it, I will bear it. If we can change it,why don‘t do it? By the below reason, why W3C no way to define a custom element without javascript,
|
The thing is, Custom Element means you MUST extend a class. This isn't the same with jQuery, and this is the reason you are experiencing difficulty. The web may need a NON-extending form of components.
That's fine, that is also the graceful fallback behavior that users of the current is="" attribute want. They also don't need to extend elements, they just need to add functionality. (See that long thread). So I think this component is a good way to achieve that without the complications that the other long thread is about. A non-extending way to associate JS behavior is much simpler to implement, it is just attaching logic to some elements. We could also make it selector based: components.define('.nav-link', class {...}) But that might be too heavyweight, needing selectors to be fired on every DOM change. Maybe a native API that allows us to pass the same component classes to act in a NodeList would be great, and we'd be one more step closer to what jQuery has already proven over and over works, for the non-declarative folks: components.create(document.querySelectorAll('.nav-link'), 'foo')
// or similar using the defined component by name there. This imperatively adds And boom, we have an official way to augment any DOM without all those problems that seem to be related to extending and element's class in that other long thread. In many cases, we just need to manipulate an element, we do that actually need We can even pass it into all the lifecycle methods, and then allow people to create Singleton components where only one instance is made, and lifecycle hooks get passed the element to operate on: components.define('foo', class {
connectedCallback(el) {
// do something with the connected element.
}
}, {
singleton: true
}) This idea is much more desirable than the current is="" attribute! |
The concept is: we learn from jQuery and other libs, and we make official ways to enhance DOM without being required to extend specific elements. This component idea is interesting, because it would still be possible to make shadow-dom based components with them, without extending the manipulated elements. The nice thing about Vue and React, for example, is that virtual JavaScript components map to DOM output. That is an interesting concept, and I don't see why we can't also explore a native version of that. It doesn't have to be based on dom-diffing, for example see Turbine for a clean non-diff way of mapping state changes to DOM. |
Sorry, I took this issue slightly off topic by moving from naming to the component idea I described. I've made a new issue for the component idea here: #662 |
What @milieuChris said, this is really a namespace problem at the core and the technology that would allow us to "name things locally in any way we chose" was called XSLT (or XQuery or XProc to suit your needs). Developers didn't "want" this for various suspect reasons and without any such "response filter" mechanisms we are left to hardcoding our HTML directly in the output, reminding ourselves all this time that the "X" in these acronyms would stand for "extensible". It may not be the custom elements you want, but it is the custom elements we deserve and it is the custom elements we need: At least the resulting syntax is very explicit about the use magic it involves. There's no reason why a high level framework cannot be rigged to output See also #634 for plausible solution to hyphen-free components that doesn't reinvent the wheel. |
@wiredearp XSLT is very heavyweight from what I've seen of it, realistically I'd rather just a minimal tool for choosing names e.g.: <import src="./my-web-component.???" as="my-component-name" />
<!-- my-component-name would be strictly scoped to this document not
other documents (not even shadow roots) that way we can be certain
that there's never any name collisions
There'd probably be a `document.customElements.define` or something
like that for scoping elements to a specific document in this idea
-->
<my-component-name>...</my-component-name> With that sort've approach I don't see any reason you couldn't permit hyphen-less names as well (as long as they're document scoped): <import src="./my-progress-component.???" as="progress" />
<!--- The import would shadow the outer progress but only this document
can actually observe that, before upgrading it'd probably just appear
as a regular progress element
-->
<progress>My progress content</progress> Of course this idea has the wider issue that there's no canonical way to distribute a Custom Element (given that WebKit doesn't want to implement Maybe something like (yes this idea is basically just ES import/export in HTML instead): <template id="content">
<link rel="stylesheet" href="./fizz-buzz.css">
...
</template>
<!-- Basically just `<script type="module"` except that it's obviously
assigned extra meaning in the context of custom elements
-->
<script type="export">
export default class MyElement extends HTMLElement {
constructor() {
super()
// ... Clone template[id="content"].content etc here
}
}
</script>
<!-- And in another file -->
<import src="./my-element.html" as="foo" />
<foo></foo> This would arguably be even nicer with the proposed html modules from that issue e.g.: // component.js
import content from "./content.html" as DocumentFragment
// Given that Custom Elements *require* JavaScript to define them why
// not make that what's imported to register them:
export default class MyElement extends HTMLElement {
constructor() {
super()
const shadowRoot = this.attachShadow({ mode: 'open' })
}
} <import src="./component.js" as="my-component-name" />
// component.js would be `import`-ed then `document.customElements.define`
// would be called on the resulting module |
@Jamesernator fwiw we've been spiking some ideas around a single-file-component structure using |
From the Custom Elements spec: https://www.w3.org/TR/custom-elements/#valid-custom-element-name
|
IMHO the requirement of hyphenated names for custom elements is like requiring underscore-prefixed variable names in JavaScript in order to declare The convenience of hyphen-less elements greatly outweighs the down-the-road concern that some element with the same name will be introduced. I agree it's part of what makes Vue so easy-to-use and keeps templates concise. |
It's the same in JavaScript too. It's always been suggested to not use the global scope or directly access native prototypes. For instance, instead of adding |
If we had a way to scope element names, the problem could be solved. But I can't yet imagine how to polyfill a proposed solution, because the solution would have to somehow prevent the global |
I don't exactly what you mean by you want to scope custom elements. They already are in the sense that custom elements are only available if you define them in your document. Scoping them per-shadow root seems a bit overkill imo as custom elements seem like they were more designed for the main document but every developer is free to do as they please. Which wraps back to the hyphen issue. The web as it stands right now is all about forwards compatibility. The lack of hyphens in custom element names is simply a contract between the nice folks over at whatwg/html and us site developers that the tags they make and the tags we make are in a different space; thus ensuring a tag you make today isn't going to conflict with an official element added later on. |
I think there is a lot of use cases for Custom Elements, but defining all range of components in one namespace - is not good idea for large enterprize apps. I belive - the DOM is the better framework for web development, but it provides not all what we need - we need just native way for combining it all together and hide implementation in modules. Custom Elements should be local inside HTML module as local variables, functions and classes in JS modules to avoid name conflicts. |
@vitalydmitriev1970 your comment isn't really related to the hyphen issue as there are no namespaces in custom elements. As far as making custom elements more declarative, there is Polymer as well as the project you made and many more. |
@trusktr Just in response to a couple things from the other thread that are more relevant here.
The thing is it's more like variable reassignment given that if the tag already has a value it somehow has to be assigned. This isn't unique to global tags in document, even if a tag is part of the shadow DOM if behavior of the tag changes after the element has been filled then there's a period of standard DOM behavior.
And this is the thing I'm getting at is depending on the behavior of this new HTML Now detecting usage of this sort've thing is improving with browser efforts so it might be that WHATWG can just ask browser vendors to detect usage of a certain word if they want to add new tags so it might not be that risky in practice.
Trailing dashes are valid in custom element names so you can avoid cutting words by using ASIDE Most uses of custom elements I've seen don't bother to use custom attribute names and just use single words which risk clashing with future global attributes (e.g. ASIDE ASIDE Interesting vue even goes so far as to abuse technically invalid attribute names like |
Correct me if I'm wrong, but a vast majority of web applications consist of a single document. That argument there is like trying to convince React team to force everyone to globally register all components by name, per document, which would result in a huge storm of frustrated developers. We need scoping inside a single application, and because most applications consist of a single document, we need scoping inside of documents, and shadow roots are the obvious unit of encapsulation for that (for all other Web Component encapsulation).
That's not going to happen in shadow roots. Once a scoped name is defined in a shadow root, introducing a new native builtin will do absolutely nothing because the root's definition of the element will continue to be the same, because it shadows the outer scope. This is the same in just about all programming languages.
The simple good practice of defining the element names before rendering the DOM content would be useful here. There's possible ways to solve it for everyone: Maybe overrides can only be defined before any such elements exist in the root, otherwise a helpful error can be thrown, and the |
I'm going to close this since hyphen-less names were considered and rejected as they would conflict with future built-in element names. And a unified scheme that both built-in elements and custom elements could use was also considered, but nobody could figure out how to make it work. |
You could still have that contract and allow custom elements without hyphens. Anyone who wants the safety of the contract would use hyphens, and anyone who wants to take their chances could do without them. But let's consider what the worst thing is that could happen: if I introduce (for example) a |
I'm no expert, but it seems that enabling custom elements to override built-ins could be a security problem. |
A builtin element becoming another underived element underfoot (as opposed to upgrading to a more-derived custom element that still has the same native brand/slots) doesn’t seem plausible or desirable. The number of new HTML behaviors that would need to be defined and implemented to account for the states this would make possible which hadn’t been before seems enormous. Despite the low value of most such possible states for users and developers, if they become possible at all, they must have defined behavior. For example, what happens when a builtin ceases to be that builtin during script execution when...
Even in non-upgrade cases, consider all the implications for parsing if a script could have previously redefined:
Also, ECMAScript objects branded with cross-realm slots cannot suddenly stop having those slots. While technically it wouldn’t violate a language-level invariant, it is an invariant-in-practice for all branded intrinsic and host objects and must remain so. I too yearn for hyphenlessness but I think the right call was made :) |
This is the whole problem. I should be able to build off of html as a format, and have those extensions be first class, not some weird tacked on thing. They are custom elements from the BROWSERS point of view, not the documents point of view. All the good things about HTML come from it being a semantic data format. Sometimes I need more semantics than the built-in set, and I should be able to add a tag to represent those, with a semantic name. The JS custom element thing is just display logic. And view should be written to conform to the model not the other way around. I suggest the "nice folks over at whatwg/html" put the elements they make in a namespace, and let me have the default one. |
If you have no description of how the ability to override tags is a security risk, then how can anyone take your claim seriously? Do you think that all custom tags are a security risk? Why would custom tags with no hyphens suddenly create a risk? |
Let's get rid of the hyphen madness, it's so ugly, and makes coding a chore. If the argument is that new tags can be added in the future, I don't really care as my own definitions will take precedence. I should be able to do it if I want. I also want to be able to extend or completely replace native elements. If I want to make my own |
Or better question: why aren't we thinking of ways to allow any tag name inside some form of encapsulation of a component? Today we have Vue setting the example. It was React yesterday.
I know this has already been discussed.
Many frameworks already allow this.
For example, the new and highly popular Vue allows names without hyphens.
Everyone LOVES it.
What the web needs is perhaps to stop, and think about these new component models in a different way. For example, here's a proposal: the Unity Component Spec.
We simply just need a way to write components in a way where we can easily associate behaviors with any tag name. For example, if we want to define what
<foo>
means inside our component, let's be able to do that.The text was updated successfully, but these errors were encountered: