Newer
Older
import {AdapterLitElement} from './src/adapter-lit-element';
export default class DBPLitElement extends AdapterLitElement {
Bekerle, Patrizio
committed
constructor() {
super();
this.htmlOverrides = '';
this._localTemplateSlotsImported = false;
this._globalSlotsContainer = null;
this._globalTemplateSlotsImported = false;
this._renderDone = false;
Bekerle, Patrizio
committed
}
static get properties() {
return {
...super.properties,
htmlOverrides: {type: String, attribute: 'html-overrides'},
Bekerle, Patrizio
committed
};
disconnectedCallback() {
super.disconnectedCallback();
if (this._globalSlotsContainer !== null) {
this._globalSlotsContainer.remove();
}
}
Bekerle, Patrizio
committed
_(selector) {
return this.shadowRoot === null
? this.querySelector(selector)
: this.shadowRoot.querySelector(selector);
Bekerle, Patrizio
committed
}
_a(selector) {
return this.shadowRoot === null
? this.querySelectorAll(selector)
: this.shadowRoot.querySelectorAll(selector);
}
firstUpdated() {
super.firstUpdated();
this._renderDone = true;
this._importTemplateSlots();
}
Bekerle, Patrizio
committed
update(changedProperties) {
changedProperties.forEach((oldValue, propName) => {
switch (propName) {
this._importTemplateSlots();
break;
}
});
super.update(changedProperties);
Bekerle, Patrizio
committed
}
/**
Bekerle, Patrizio
committed
* Transforms all global override templates or named template slots in the light DOM to named div slots
* on the first render.
* Global overrides will replace all existing slotted elements with the same slot name.
*/
if (!this._renderDone) {
Bekerle, Patrizio
committed
return;
}
this._importLocalTemplateSlots();
this._importGlobalTemplateSlots();
}
Bekerle, Patrizio
committed
_importLocalTemplateSlots() {
return;
}
// Now extract slots from templates contained in the light dom
let lightTemplateSlots = this.querySelectorAll(':scope > template[slot]:not([slot=""]');
// create a slot div container to put in the cloned template content
const divElem = document.createElement('div');
divElem.slot = templateElem.getAttribute('slot');
divElem.appendChild(templateElem.content.cloneNode(true));
Bekerle, Patrizio
committed
// remove the old template
templateElem.remove();
// put the slot div container with the cloned template in the light DOM
this.appendChild(divElem);
}
this._localTemplateSlotsImported = true;
}
_importGlobalTemplateSlots() {
if (this.htmlOverrides === '' || this._globalTemplateSlotsImported) {
return;
}
Bekerle, Patrizio
committed
// First add global override templates as light dom slots
let globalOverrideTemplateElem = document.querySelector('template#' + this.htmlOverrides);
if (globalOverrideTemplateElem !== null) {
// we need to clone the element so we can access the content
const overrideTemplateElemClone = globalOverrideTemplateElem.content.cloneNode(true);
const templateOverrideElem = overrideTemplateElemClone.querySelector(
'template#' + this.tagName.toLowerCase()
);
if (templateOverrideElem !== null) {
const templateOverrideElemClone = templateOverrideElem.content.cloneNode(true);
// Find all slots which are direct children (somehow :scope doesn't work here so check parentNode)
let globalTemplateSlots = [];
for (let e of templateOverrideElemClone.querySelectorAll('[slot]:not([slot=""]')) {
if (e.parentNode === templateOverrideElemClone) {
globalTemplateSlots.push(e);
}
Bekerle, Patrizio
committed
}
// Global overrides will replace local ones.
// Either normal slotted elements or the ones we create from templates.
for (let elm of this.querySelectorAll('[slot="' + slotElem.slot + '"]')) {
elm.remove();
}
}
// Create a dummy node and add it to the the same shadow root the templates are from
// By adding it into the template we have the nice side effect that it is not visible
globalOverrideTemplateElem.append(container);
this._globalSlotsContainer = container;
container.appendChild(slotElem);
}
// Now move the slots into the light dom of the target.
// The parent node in the other shadow root has to stay around for this to work
while (container.childNodes.length) {
this.appendChild(container.removeChild(container.childNodes[0]));
}
Bekerle, Patrizio
committed
}
}
this._globalTemplateSlotsImported = true;
}