Skip to content

Commit

Permalink
refactor: remove placeholder span from shadow root (#503)
Browse files Browse the repository at this point in the history
  • Loading branch information
vladitasev authored Jun 7, 2019
1 parent 5709e31 commit 4003029
Show file tree
Hide file tree
Showing 71 changed files with 353 additions and 361 deletions.
56 changes: 34 additions & 22 deletions packages/base/src/CSS.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,56 @@
import { getTheme } from "./Configuration.js";
import { getEffectiveStyle } from "./Theming.js";
import { injectWebComponentStyle } from "./theming/StyleInjection.js";

const styleMap = new Map();

const createStyleElement = css => {
// Create a local <style> tag for the real shadow DOM
const style = document.createElement("style");
style.innerHTML = css;
return style;
};

const createConstructableStyleSheet = css => {
const elementStyleSheet = new CSSStyleSheet();
elementStyleSheet.replaceSync(css);
return elementStyleSheet;
/**
* Creates the needed CSS for a web component class in the head tag
* Note: IE11, Edge
* @param ElementClass
*/
const createHeadStyle = ElementClass => {
const tag = ElementClass.getMetadata().getTag();
const cssContent = getEffectiveStyle(ElementClass);
injectWebComponentStyle(tag, cssContent);
};

const _createStyle = (tagName, styleContent) => {
/**
* Returns (and caches) a constructable style sheet for a web component class
* Note: Chrome
* @param ElementClass
* @returns {*}
*/
const getConstructableStyle = ElementClass => {
const tagName = ElementClass.getMetadata().getTag();
const styleContent = getEffectiveStyle(ElementClass);
const theme = getTheme();
const key = theme + tagName;
if (styleMap.has(key)) {
return styleMap.get(key);
}

let style;
if (document.adoptedStyleSheets) {
style = createConstructableStyleSheet(styleContent);
} else {
style = createStyleElement(styleContent);
}
const style = new CSSStyleSheet();
style.replaceSync(styleContent);

styleMap.set(key, style);
return style;
};

const createStyle = ElementClass => {
const tagName = ElementClass.getMetadata().getTag();
/**
* Returns the CSS to be injected inside a web component shadow root, or undefined if not needed
* Note: FF, Safari
* @param ElementClass
* @returns {string}
*/
const getShadowRootStyle = ElementClass => {
if (document.adoptedStyleSheets || window.ShadyDOM) {
return;
}

const styleContent = getEffectiveStyle(ElementClass);
return _createStyle(tagName, styleContent);
return styleContent;
};

// eslint-disable-next-line
export { createStyle };
export { createHeadStyle, getConstructableStyle, getShadowRootStyle};
12 changes: 8 additions & 4 deletions packages/base/src/Renderer.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import LitRenderer from "./renderer/LitRenderer.js";
import { getShadowRootStyle } from "./CSS.js";

const RendererImpl = LitRenderer;

class Renderer {
static render(element) {
const root = element._getRoot();
const renderer = Object.getPrototypeOf(element).constructor.renderer.render;
const renderResult = renderer(element);
const root = element.shadowRoot;
const { render } = Object.getPrototypeOf(element).constructor.renderer;
const renderResult = render(element);

RendererImpl.render(renderResult, root, { eventContext: element });
// For browsers that do not support constructable style sheets (and not using the polyfill)
const styleToPrepend = getShadowRootStyle(element.constructor);

RendererImpl.render(renderResult, root, element, styleToPrepend);
}
}

Expand Down
22 changes: 11 additions & 11 deletions packages/base/src/UI5Element.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { getWCNoConflict, getCompactSize } from "./Configuration.js";
import DOMObserver from "./compatibility/DOMObserver.js";
import ShadowDOM from "./compatibility/ShadowDOM.js";
import UI5ElementMetadata from "./UI5ElementMetadata.js";
import Integer from "./types/Integer.js";
import Renderer from "./Renderer.js";
import RenderScheduler from "./RenderScheduler.js";
import { createStyle } from "./CSS.js";
import { getConstructableStyle, createHeadStyle } from "./CSS.js";
import { attachThemeChange } from "./Theming.js";

const metadata = {
Expand Down Expand Up @@ -44,7 +43,7 @@ class UI5Element extends HTMLElement {
// polyfill theme handling is in head styles directly
return;
}
const newStyle = createStyle(this.constructor);
const newStyle = getConstructableStyle(this.constructor);
if (document.adoptedStyleSheets) {
this.shadowRoot.adoptedStyleSheets = [newStyle];
} else {
Expand All @@ -69,11 +68,15 @@ class UI5Element extends HTMLElement {
}

this.attachShadow({ mode: "open" });
const shadowDOM = await ShadowDOM.prepareShadowDOM(this.constructor);
this.shadowRoot.appendChild(shadowDOM);

// IE11, Edge
if (window.ShadyDOM) {
createHeadStyle(this.constructor);
}

// Chrome
if (document.adoptedStyleSheets) {
const style = createStyle(this.constructor);
const style = getConstructableStyle(this.constructor);
this.shadowRoot.adoptedStyleSheets = [style];
}
}
Expand Down Expand Up @@ -467,17 +470,14 @@ class UI5Element extends HTMLElement {
return;
}

return this._getRoot().children[0];
return this.shadowRoot.children.length === 1
? this.shadowRoot.children[0] : this.shadowRoot.children[1];
}

_waitForDomRef() {
return this._domRefReadyPromise;
}

_getRoot() {
return this.shadowRoot.querySelector("[data-sap-ui-wc-root]");
}

getFocusDomRef() {
const domRef = this.getDomRef();
if (domRef) {
Expand Down
102 changes: 0 additions & 102 deletions packages/base/src/compatibility/ShadowDOM.js

This file was deleted.

16 changes: 13 additions & 3 deletions packages/base/src/renderer/LitRenderer.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { render } from "lit-html";
import { html, render } from "lit-html";

class LitRenderer {
static render(renderResult, domNode, options) {
render(renderResult, domNode, options);
/**
* Renders "templateResult" by replacing the content of "domNode", and optionally prepends a style tag containing "styles"
* @param templateResult - lit template result object
* @param domNode - the node whose content will be replaced
* @param eventContext - the context of events, bound via the template
* @param styles - if given, will be prepended in a style tag
*/
static render(templateResult, domNode, eventContext, styles) {
if (styles) {
templateResult = html`<style data-ui5-shadow-root-styles>${styles}</style>${templateResult}`;
}
render(templateResult, domNode, { eventContext });
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/main/src/Button.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
aria-disabled="{{ariaDisabled}}"
data-sap-focus-ref
{{> ariaPressed}}
dir="{{rtl}}"
>
{{#if icon}}
<ui5-icon
Expand Down
7 changes: 7 additions & 0 deletions packages/main/src/Button.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import UI5Element from "@ui5/webcomponents-base/src/UI5Element.js";
import Bootstrap from "@ui5/webcomponents-base/src/Bootstrap.js";
import { isSpace, isEnter } from "@ui5/webcomponents-base/src/events/PseudoEvents.js";
import { getCompactSize } from "@ui5/webcomponents-base/src/Configuration.js";
import getEffectiveRTL from "@ui5/webcomponents-base/src/util/getEffectiveRTL.js";
import ButtonType from "./types/ButtonType.js";
import ButtonRenderer from "./build/compiled/ButtonRenderer.lit.js";
import Icon from "./Icon.js";
Expand Down Expand Up @@ -252,6 +254,7 @@ class Button extends UI5Element {
sapMBtnDisabled: this.disabled,
sapMBtnIconEnd: this.iconEnd,
[`sapMBtn${this.type}`]: true,
sapUiSizeCompact: getCompactSize(),
},
icon: {
sapWCIconInButton: true,
Expand All @@ -266,6 +269,10 @@ class Button extends UI5Element {
return this.disabled ? "true" : undefined;
}

get rtl() {
return getEffectiveRTL() ? "rtl" : undefined;
}

static async define(...params) {
await Icon.define();

Expand Down
4 changes: 3 additions & 1 deletion packages/main/src/CalendarHeader.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<div
class="{{classes.main}}">
class="{{classes.main}}"
dir="{{rtl}}"
>

<ui5-icon id="{{_id}}-btnPrev"
class="{{classes.buttons}}"
Expand Down
7 changes: 7 additions & 0 deletions packages/main/src/CalendarHeader.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import UI5Element from "@ui5/webcomponents-base/src/UI5Element.js";
import Bootstrap from "@ui5/webcomponents-base/src/Bootstrap.js";
import { isSpace, isEnter } from "@ui5/webcomponents-base/src/events/PseudoEvents.js";
import { getCompactSize } from "@ui5/webcomponents-base/src/Configuration.js";
import getEffectiveRTL from "@ui5/webcomponents-base/src/util/getEffectiveRTL.js";
import Button from "./Button.js";
import ButtonType from "./types/ButtonType.js";
import CalendarHeaderRenderer from "./build/compiled/CalendarHeaderRenderer.lit.js";
Expand Down Expand Up @@ -123,6 +125,7 @@ class CalendarHeader extends UI5Element {
return {
main: {
sapWCCalHead: true,
sapUiSizeCompact: getCompactSize(),
},
buttons: {
sapWCCalHeadArrowButton: true,
Expand All @@ -134,6 +137,10 @@ class CalendarHeader extends UI5Element {
};
}

get rtl() {
return getEffectiveRTL() ? "rtl" : undefined;
}

static async define(...params) {
await Button.define();

Expand Down
5 changes: 4 additions & 1 deletion packages/main/src/Card.hbs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<div class="{{classes.main}}">
<div
class="{{classes.main}}"
dir="{{rtl}}"
>
<header class="{{classes.header}}"
@click="{{_headerClick}}"
@keydown="{{_headerKeydown}}"
Expand Down
5 changes: 5 additions & 0 deletions packages/main/src/Card.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import UI5Element from "@ui5/webcomponents-base/src/UI5Element.js";
import Bootstrap from "@ui5/webcomponents-base/src/Bootstrap.js";
import { isIconURI } from "@ui5/webcomponents-base/src/IconPool.js";
import { isSpace, isEnter } from "@ui5/webcomponents-base/src/events/PseudoEvents.js";
import getEffectiveRTL from "@ui5/webcomponents-base/src/util/getEffectiveRTL.js";
import CardRenderer from "./build/compiled/CardRenderer.lit.js";
import Icon from "./Icon.js";

Expand Down Expand Up @@ -184,6 +185,10 @@ class Card extends UI5Element {
this.fireEvent("headerPress");
}
}

get rtl() {
return getEffectiveRTL() ? "rtl" : undefined;
}
}

Bootstrap.boot().then(_ => {
Expand Down
4 changes: 3 additions & 1 deletion packages/main/src/CheckBox.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
aria-checked="{{checked}}"
aria-readonly="{{ariaReadonly}}"
aria-disabled="{{ariaDisabled}}"
tabindex="{{tabIndex}}">
tabindex="{{tabIndex}}"
dir="{{rtl}}"
>
<div id="{{_id}}-CbBg" class="{{classes.inner}}">
<input id="{{_id}}-CB" type='checkbox' ?checked="{{checked}}" ?readonly="{{readonly}}" ?disabled="{{disabled}}" data-sap-no-tab-ref/>
</div>
Expand Down
Loading

0 comments on commit 4003029

Please sign in to comment.