EPA-WG/custom-element

SRC attribute for DCE

Opened this issue · 4 comments

Use cases:

  • <custom-element tag="dce-internal" src="#template1"> - reference the template in page DOM
  • <custom-element src="#template2"></custom-element> - inline instantiation, no tag
  • <custom-element tag="dce-external" src="toc.html"> - external file
  • <custom-element tag="dce-hash" src="../index.html#shared-template"> - html template by ID in external file
  • <custom-element tag="dce-hash" src="../index.html#svg1" > - html with SVG collection
  • <custom-element tag="dce-hash" src="../index.xhtml#xsl1" > - xhtml/xml with embedded templates lib
  • <custom-element tag="dce-hash" src="embed-1.html" > - external file with embedding of another external DCE
  • own import maps
  • deep external files with own import maps
  • local template as a "loading..." or fallback for remote , error handling following slotted-element

template content type

the content from remote server can be used as is in case the content is a pure XSLT. In this case all dependencies are resolved by XSLT engine. *

A relative path for xsl:include/@href or xsl:import/@href is resolved against the directory of the XSLT file that does the including or importing.

import maps

For HTML it has to be converted into XSLT first ( as inline DCE template ) with path resolution relative to imported file URL.

The path resolution has to be importmaps aware.

if (HTMLScriptElement.supports('importmap')) {
  // The importmap feature is supported.
}

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap

encapsulated import maps.

The standard does not support locally scoped maps. But in DCE if the imported HTML module has it, the context root(DCE) would be able to resolve URLs accounting as global as local import maps.

Life cycle

in-page template

Same as embedded template case. Just instead of declaration payload, the template is taken by ID.

  • the xsltString getter exposes assembled from XSLT document template to be used in constructor and by utility API in dev tools. The getter pattern delays the actual load and CPU consumption to the moment when DCE instance created.
  • XSLTProcessor cached in DCE declaration and exposed as getter

DCE instance

  • initialize DAL in instance.xml
  • DCE instance constructor synchronously loads XSLT document , saving in cache
  • transform() performs initial UI state
  • applySlices() initializes the business logic leading to series of transforms
  • the functional components updating the data triggering the applySlices() cycle ^^
  • cache can be discarded once all renders completed and all state updates are final

external template

when src is presented and points to external document:

  • , DCE declaration constructor initializes remote template load
  • DCE instance constructor subscribes for template changes notification
  • same init cycle as in-page template. Inline declaration payload serves as a template for loading state until remote template available
  • on declaration template change notification run transform() and applySlices() sequence to initialize new template cycle

external template fallback, error handler

The inline template would be used to render the DCE instance before the remote template loaded and XSLTProcessor created.
Once the error happen during the load or creating the XSLTProcessor , the template data slice would be adjusted with the error and all DCE instances would receive the template change notification which would lead to trigger the transformation cycle.

If the inline template has the template.error handling, it would render the matching UI or ignore the error completely leaving the fallback UI.

default loading error appearance

DCE out of the box would display the template-error slot with debug info warning which would include the URL and potential error cause. The content can be overridden by providing custom template-error slot either on DCE declaration or on DCE instance level (samples TBD). The error suppressing can be done on DCE declaration payload level which would account the template/error data slice.

external template loading sequence

  • embedded connectedCallback() checks src attribute. When not defined, templateRootS is getTemplateChildren(this, this.children)
  • external, local. Otherwise if #localHash, templateRootS is getTemplateChildren( $( getContextRoot(this), localHash) ) with context root tried recursively up to document level
  • external by URL
    • dom = await xhrTemplate(src)
      • xhr.responseXML || create('div', xhr.responseText )
    • cache[ src ] = dom
    • if urlhash templateRootS is $( dom, urlhash ).map( resolveTemplateNode )
    • else templateRoot is getTemplateChildren( dom, [dom] )

Once templateRootS available, there are 3 choices:

  • xslt - used as is ( ?? when multiple )
  • html/svg/mathML - injected into generated XSL attributes section.
  • template content children - - injected into generated XSL attributes section.

🤔 External template content. Take the whole, root element or children?

  • xslt doc - whole. (Change the slots later though)
  • SVG image, MathML - inject root node
  • HTML, XHTML doc. Root node extracted out of document. The root can be needed optionally. html root is not injectable, but is it toxic?