Skip to content
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

[declarative-custom-elements] do we need DOM parts or any template mechanism in spec? #1090

Open
mildred opened this issue Dec 6, 2024 · 4 comments

Comments

@mildred
Copy link

mildred commented Dec 6, 2024

Thinking about declarative custom elements and playing with a load-file custom element that does load a file using the fetch API to create a shadow DOM root, I'm wondering if we absolutely need to have DOM parts, at least initially, for declarative custom elements.

My take on this is that you can have declarative custom elements without any form of templating:

  • the main document includes a custom elements declared in an inline template or in an external file that is taken as template content
  • when the custom elements is used, the template in put as it is as shadow root without any templating whatsoever
  • slots can be used for minimal templating needs
  • any inline script tag within the template is executed when the template is instanciated as a shadow root, this script can perform DOM transformations to adjust the markup on the context
  • the script can use the slotchange event to detect if the content of a slot is changed to adjust the DOM

Example using an import link idea:

<head>
  <link rel="custom-element" href="custom-element.html" />
</head>
<body>
  <custom-element>
    <span slot="data" data-title="Abc" data-code="123"></span>
  </custom-element>
</body>

and in custom-element.html:

<template element="custom-element">
  <div>
    <slot name="data"></slot><!-- display none on this seems to block slot filling -->
    <h1>This is custom element title <span class="title">unknown</span></h1>
    <p>Code is <span class="code">000</span></p>
    <script>
      (() => {
        let titleElem = document.currentScript.parentElement.querySelector('.title')
        let codeElem = document.currentScript.parentElement.querySelector('.code')
        let dataSlot = document.currentScript.parentElement.querySelector('slot[name=data]')

        dataSlot.addEventListener('slotchange', (e) => bindData())
        bindData()

        function bindData(){
          let dataset = dataSlot.assignedNodes()[0]?.dataset
          titleElem.textContent = dataset?.title
          codeElem.textContent = dataset?.code
        }
      })()
    </script>
  </div>
</template>

Here, vanilla javascript is used to perform templating, but any templating library can be used in the same way as long as the template respects standard HTML syntax.

DOM Parts can be used later to incrementally improve on this.

@mildred
Copy link
Author

mildred commented Dec 6, 2024

To answer some of #1009 questions:

  • Declaration

    • How are attributes and properties declared? do they need declaration?
    • How are styles declared? <link rel="stylesheet"> inline inside the template, it should be possible to inherit parent styles
    • Are registrations always global, or can they be scoped? scoped seems better to prevent grandchildren custom elements to conflict
  • Scripting

    • Do declarative custom elements run with JavaScript disabled? yes
    • Will HTML Modules be importable from HTML with JavaScript disabled? yes
    • What is the base class for a declarative custom element? Does it directly extend HTMLElement, or is there another class with shared behavior? The same way that custom elements are enhanced seems a good thing, just the shadow root would already be attached
    • Can a declarative custom element be enhanced with script? yes with standard customElements.define(...)
      • How is that script associated with the element? any <script> that is executed at the declaration time that used customElements.define(...)
      • Must the script be inline, or can it be bundled? both can work depending if the <script> tag has a src attribute
      • Can the script be loaded late? Is there an upgrade-like step when it does? yes, same as current custom elements
  • Lifecycle

    • How do elements detect changes to data? through events
    • When do element re-render? Synchronously or asynchronously? good question
  • Templates : templating is not performed by the user agent, all these concerns go away

  • Security

    • Do declarative custom elements introduce a script gadget vulnerability? use same rules as with existing HTML?
    • Is expression evaluation sanitized? no templating to evaluate simple functions, either javascript is disabled and minimum templating is available through slots, or javascript is enabled by policy and anything javascript can do is possible
    • for the rest, there is no data binding to worry about

@mildred
Copy link
Author

mildred commented Dec 6, 2024

As for templating, there are ways to perform templating without special markup, just in a declarative way using CSS selectors (or any kind of selector). See existing engines:

But the HTML spec does not need to define a specific templating engine.

@bahrus
Copy link

bahrus commented Dec 6, 2024

As for templating, there are ways to perform templating without special markup, just in a declarative way using CSS selectors (or any kind of selector).

There is additional discussion (and additional libraries that take that approach mentioned) in with issue 1035

@sashafirsov
Copy link

to have the DCE viable, it have to have sufficient functionality to build full blown web app. With data retrieval layer, fully functional template (variables, conditions, loops, etc.), interactivity with browser and user (events & APIs).

The "parts" is necessary peace of the data-template-logic triangle. In <custom-element> DCE impleentation parts exposed in template via {} and attribute value syntax.

The subject for part content as slots as different kind of data: attributes of DCE, payload, slots, data slice, etc.
The syntax for parts in <custom-element> is XPath, a native in browser selector across DOM. All data reflected via DOM, even if native can be JS object of API interface.

As for shadow or not, it can be left outside of DCE proposal, there are implementations in both. Shadowless version still has CSS scoping/insulation. The DCE concept gives insulation on logic and relations layer which makes shadow absolete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants