Important: starcounter-include
component was designed for Starcounter 2 family and no longer supported in Starcounter 3. There will be no further development or improvements.
<starcounter-include>
is a custom element that lets you load partial HTML views into your Starcounter page, it uses
<imported-template>
- You can take full control over loaded<script>
s and<link rel="import">
s. Thanks to HTML Imports - caching, script execution, etc. is completely native.
You can use Shadow DOM v1 features to apply Document Fragment with custom HTML composition and slots to tune the presentation of HTML Elements given by the partial HTML view. It lets you blend and apply your desired look & feel to elements given by your and even other apps - which were mixed due to Starcounter mappings.
For more details see articles:
- "HTML partials/includes WebComponents-way" - How partials work,
- "Unobtrusive styling and composing 3rd party HTML content" - How to style them with Shadow DOM,
- "Layout compositions for HTML partials" - How to use styles in Starcounter
<starcounter-include>
recognizes 4 kinds of HTML compositions:
- Fallback composition - a single
<style>:host{display: block;}</style><slot></slot>
to display all things from light DOM in case no composition was provided - Default composition - composition (or multiple concatenated compositions) found in the partial HTML view (
<template is="declarative-shadow-dom">
part) - Parent composition - composition found in the parent HTML view (content of
<starcounter-include ...><template is="declarative-shadow-dom" presentation="parent">
). It's used to enforce by parent view a given composition for any kind of elements. - Custom composition - stored composition provided in JSON by BlendingProvider
- Temporary composition - explicit composition set directly in the shadow root of
starcounter-include
(for example by Chrome DevTools or<starcounter-layout-html-editor>
in BlendingEditor)
If you have /app/sub/page/path.html:
<template>
<h1>Hello {{username}}</h1>
</template>
and merged/blended JSON view-model
SubPageViewModel = {
App: {
username: "World"
Html: "/app/sub/page/path.html"
}
}
You can put it on screen with
<starcounter-include view-model="{{ SubPageViewModel }}"></starcounter-include>
To produce
<h1>Hello World</h1>
<starcounter-layout-html-editor>
- editor for Document Fragments
- Applies two-way databinding, even for nested asynchronously loaded
<polymer-element>
s, - Multiple (concatenated) templates per partial HTML view,
- Polymer's
<template>
features (binding, repeat, if, etc.), - HTML Imports features:
- Sends request for template only once (HTML Import's caching),
- Supports
<script>, <link>, <style>
tags to be executed once, - Supports
<script>, <style>
tags per template instance, - Easy way to attach presentation expressed in declarative Shadow DOM,
- Blocks rendering of Shadow DOM until
<link rel="stylesheet">
s are loaded, unless loaded asynchronously (see below).
You can read more on Blendable Web Apps in Starcounter docs
- https://docs.starcounter.io/guides/blendable-web-apps/html-views
- https://docs.starcounter.io/guides/blendable-web-apps/view-composing
- It should be W3C compliant Document body,
- It should contain at least one
<template>
tag in root node.
- View-model contains
Html
property with path to file (:construction:, or just inline markup).
Starcounter has it already pre-installed, under /sys/starcounter-include/starcounter-include.html
, but if you want to use it separately as well.
Install the component using Bower:
$ bower install starcounter-include --save
Or download as ZIP.
-
Import Web Components' polyfill (if needed):
<script src="bower_components/webcomponentsjs/webcomponents-lite.js"></script>
-
Import Custom Element:
<link rel="import" href="bower_components/starcounter-include/starcounter-include.html">
-
Start using it!
<starcounter-include view-model="{{ViewModel}}"></starcounter-include>
or without mustache-style data-binding:
document.querySelector("starcounter-include").viewModel = ViewModel;
or with inline JSON:
<starcounter-include view-model="{"Html": "/path/to/file.html", "some": "data"}"></starcounter-include>
Attribute | Options | Default | Description |
---|---|---|---|
partial |
JSON | Set to provide partial JSON view-model. It's also a partial property. |
|
partial-id |
String | Read-only attribute that represents PartialID fetched from partial JSON. It's also a partialId property. |
|
view-model |
JSON | Alias for partial |
|
composition |
String | Read-only attribute that reflects currently used composition kind |
Property | Options | Default | Description |
---|---|---|---|
partial |
Object | Object containing partial JSON view-model, bindable with Polymer | |
partialId |
String | Partial Id used to identify partial, usually it's fetched from partial.{compositionProvider}.PartialId . |
|
viewModel |
Object | Alias for partial |
|
compositionProvider |
String | CompositionProvider_0 |
Key/app name of composition provider. could be overwritten per instance scInclude.compositionProvider or globally by changing the prototype, like: customElements.get('starcounter-include').prototype.compositionProvider = 'CustomProvider_7' |
Name | Detail | Description |
---|---|---|
starcounter-include-composition-saved |
String stored composition | Triggered once composition is saved |
partial-changed |
Object {value: storedComposition, path: 'partial.{compositionProvider}.Composition'} |
Polymer notification protocol compliant event to notify about partial.{compositionProvider}.Composition change, triggered once composition is saved. |
view-model-changed |
Object {value: storedComposition, path: 'viewModel.{compositionProvider}.Composition'} |
Polymer notification protocol compliant event to notify about partial.{compositionProvider}.Composition change, triggered once composition is saved. |
presentation-loaded |
none | When all links from a stamped presentation finished loading (with success or failure). |
To mimic native behavior of markup for Declarative Shadow DOM and to avoid FOUC the element will "block rendering" until all <link rel="stylesheet">
s are loaded or throw an error.
You can opt-out by using the same technique you can use to asynchronously load the stylesheet into a static document:
<link rel="preload" href="/path/to/styles.css" as="style" onload="this.rel='stylesheet'">
The blocked rendering is achieved by setting visibility: hidden
on shadow host - <strcounter-include>
element.
- start mock server and simple dev static files server
npm run serve
- open local browser at
127.0.0.1:8081/components/starcounter-include/test/
In browsers with Shadow DOM polyfilled using ShadyDOM and ShadyCSS, styles may still leak. This seems to be related to the limitation in the polyfill and its API.
- it does not cover Vanilla JS custom elements automatically and API does not provide sufficient methods to cover our case,
- shadow roots provided without template (compositions from DB) and different for every instance of the element seems not to be covered by polyfill at all,
- style scoping methods that transform HTML markup seems to be broken when element is being upgraded. ShadyCSS is going to be refactored soon, so we prefer to wait with heavy workarounds.
Please prepare your selectors more carefully. Feel free to report issues with your specific use-cases. We will try to provide a solution that works now, and make sure we will eventually cover them in a nice way.
For detailed changelog, check Releases.
MIT