Skip to content

Commit

Permalink
fix(ie11): improved css vars polyfill
Browse files Browse the repository at this point in the history
- dynamically added <style>
- data-no-csshim to skip polyfill
- fixed webpack integration
  • Loading branch information
manucorporat committed Sep 27, 2019
1 parent 35d61a4 commit 5e4a0f9
Show file tree
Hide file tree
Showing 12 changed files with 61 additions and 34 deletions.
3 changes: 0 additions & 3 deletions src/client/client-style.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import * as d from '../declarations';
import { win } from './client-window';
import { BUILD } from '@build-conditionals';

export const styles: d.StyleMap = /*@__PURE__*/ new Map();
export const cssVarShim: d.CssVarSim = BUILD.cssVarShim ? /*@__PURE__*/ (() => (win as any).__stencil_cssshim)() : false;
17 changes: 13 additions & 4 deletions src/client/import-shims.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import * as d from '../declarations';
import { NAMESPACE } from '@build-conditionals';
import { doc, win } from './client-window';
import { BUILD, NAMESPACE } from '@build-conditionals';
import { doc, plt, win } from './client-window';
import { getDynamicImportFunction } from '@utils';

export const patchEsm = () => {
// @ts-ignore
if (!(win.CSS && win.CSS.supports && win.CSS.supports('color', 'var(--c)'))) {
if (BUILD.cssVarShim && !(win.CSS && win.CSS.supports && win.CSS.supports('color', 'var(--c)'))) {
// @ts-ignore
return import('./polyfills/css-shim.js');
return import('./polyfills/css-shim.js').then(() => {
plt.$cssShim$ = (win as any).__stencil_cssshim;
if (plt.$cssShim$) {
return plt.$cssShim$.initShim();
}
});
}
return Promise.resolve();
};

export const patchBrowser = async (): Promise<d.CustomElementsDefineOptions> => {
if (BUILD.cssVarShim) {
plt.$cssShim$ = (win as any).__stencil_cssshim;
}

// @ts-ignore
const importMeta = import.meta.url;
const regex = new RegExp(`\/${NAMESPACE}(\\.esm)?\\.js($|\\?|#)`);
Expand Down
23 changes: 16 additions & 7 deletions src/client/polyfills/css-shim/custom-style.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { addGlobalLink, loadDocument } from './load-link-styles';
import { addGlobalLink, loadDocument, startWatcher } from './load-link-styles';
import { executeTemplate } from './template';
import { CSSScope } from './interfaces';
import { addGlobalStyle, parseCSS, reScope, updateGlobalScopes } from './scope';
Expand All @@ -12,18 +12,25 @@ export class CustomStyle {

private globalScopes: CSSScope[] = [];
private scopesMap = new Map<string, CSSScope>();
private didInit = false;

constructor(
private win: Window,
private doc: Document,
) {}

initShim() {
return new Promise(resolve => {
this.win.requestAnimationFrame(() => {
loadDocument(this.doc, this.globalScopes).then(() => resolve());
if (this.didInit) {
return Promise.resolve();
} else {
this.didInit = true;
return new Promise(resolve => {
this.win.requestAnimationFrame(() => {
startWatcher(this.doc, this.globalScopes);
loadDocument(this.doc, this.globalScopes).then(() => resolve());
});
});
});
}
}

addLink(linkEl: HTMLLinkElement) {
Expand All @@ -33,8 +40,9 @@ export class CustomStyle {
}

addGlobalStyle(styleEl: HTMLStyleElement) {
addGlobalStyle(this.globalScopes, styleEl);
this.updateGlobal();
if (addGlobalStyle(this.globalScopes, styleEl)) {
this.updateGlobal();
}
}

createHostStyle(
Expand All @@ -48,6 +56,7 @@ export class CustomStyle {
}
const baseScope = this.registerHostTemplate(cssText, cssScopeId, isScoped);
const styleEl = this.doc.createElement('style');
styleEl.setAttribute('data-styles', '');

if (!baseScope.usesCssVars) {
// This component does not use (read) css variables
Expand Down
21 changes: 15 additions & 6 deletions src/client/polyfills/css-shim/load-link-styles.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
import { CSSScope } from './interfaces';
import { addGlobalStyle } from './scope';
import { addGlobalStyle, updateGlobalScopes } from './scope';

export function loadDocument(doc: Document, globalScopes: CSSScope[]) {
loadDocumentStyles(doc, globalScopes);
return loadDocumentLinks(doc, globalScopes);
}

export function startWatcher(doc: Document, globalScopes: CSSScope[]) {
const mutation = new MutationObserver(() => {
if (loadDocumentStyles(doc, globalScopes)) {
updateGlobalScopes(globalScopes);
}
});
mutation.observe(document.head, { childList: true });
}

export function loadDocumentLinks(doc: Document, globalScopes: CSSScope[]) {
const promises: Promise<any>[] = [];

const linkElms = doc.querySelectorAll('link[rel="stylesheet"][href]');
const linkElms = doc.querySelectorAll('link[rel="stylesheet"][href]:not([data-no-shim])');
for (let i = 0; i < linkElms.length; i++) {
promises.push(addGlobalLink(doc, globalScopes, linkElms[i] as HTMLLinkElement));
}
return Promise.all(promises);
}

export function loadDocumentStyles(doc: Document, globalScopes: CSSScope[]) {
const styleElms = doc.querySelectorAll('style:not([data-styles])') as NodeListOf<HTMLStyleElement>;
for (let i = 0; i < styleElms.length; i++) {
addGlobalStyle(globalScopes, styleElms[i]);
}
const styleElms = Array.from(doc.querySelectorAll('style:not([data-styles]):not([data-no-shim])')) as HTMLStyleElement[];
return styleElms
.map(style => addGlobalStyle(globalScopes, style))
.some(Boolean);
}

export function addGlobalLink(doc: Document, globalScopes: CSSScope[], linkElm: HTMLLinkElement) {
Expand Down
4 changes: 4 additions & 0 deletions src/client/polyfills/css-shim/scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@ export function parseCSS(original: string): CSSScope {
}

export function addGlobalStyle(globalScopes: CSSScope[], styleEl: HTMLStyleElement) {
if (globalScopes.some(css => css.styleEl === styleEl)) {
return false;
}
const css = parseCSS(styleEl.textContent);
css.styleEl = styleEl;
globalScopes.push(css);
return true;
}

export function updateGlobalScopes(scopes: CSSScope[]) {
Expand Down
3 changes: 0 additions & 3 deletions src/client/polyfills/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,5 @@ export function applyPolyfills() {
) {
promises.push(import('./core-js.js'));
}
if (!(win.CSS && win.CSS.supports && win.CSS.supports('color', 'var(--c)'))) {
promises.push(import('./css-shim.js'));
}
return Promise.all(promises);
}
2 changes: 1 addition & 1 deletion src/compiler/app-core/optimize-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export async function optimizeModule(config: d.Config, compilerCtx: d.CompilerCt
opts.compress.passes = 3;
opts.compress.global_defs = {
supportsListenerOptions: true,
cssVarShim: false
'plt.$cssShim$': false
};
opts.compress.pure_funcs = ['getHostRef', ...opts.compress.pure_funcs];
}
Expand Down
2 changes: 2 additions & 0 deletions src/declarations/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ComponentInterface } from './component-interfaces';
import { HostElement } from './host-element';
import { RenderNode } from './render';
import { VNode } from './vdom';
import { CssVarSim } from './css-var-shim';


export type LazyBundlesRuntimeData = LazyBundleRuntimeData[];
Expand Down Expand Up @@ -109,6 +110,7 @@ export interface PlatformRuntime {
ael: (el: EventTarget, eventName: string, listener: EventListenerOrEventListenerObject, options: boolean | AddEventListenerOptions) => void;
rel: (el: EventTarget, eventName: string, listener: EventListenerOrEventListenerObject, options: boolean | AddEventListenerOptions) => void;
$orgLocNodes$?: Map<string, RenderNode>;
$cssShim$?: CssVarSim;
}

export type RefMap = WeakMap<any, HostRef>;
Expand Down
1 change: 0 additions & 1 deletion src/hydrate/platform/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ export const Build: d.UserBuildConditionals = {
};

export const styles: d.StyleMap = new Map();
export const cssVarShim: d.CssVarSim = false as any;

export { bootstrapHydrate } from './bootstrap-hydrate';

Expand Down
6 changes: 3 additions & 3 deletions src/runtime/disconnected-callback.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as d from '../declarations';
import { BUILD } from '@build-conditionals';
import { cssVarShim, getHostRef, plt } from '@platform';
import { getHostRef, plt } from '@platform';
import { PLATFORM_FLAGS } from './runtime-constants';
import { safeCall } from './update-component';

Expand All @@ -18,8 +18,8 @@ export const disconnectedCallback = (elm: d.HostElement) => {
}

// clear CSS var-shim tracking
if (cssVarShim) {
cssVarShim.removeHost(elm);
if (BUILD.cssVarShim && plt.$cssShim$) {
plt.$cssShim$.removeHost(elm);
}

if (BUILD.lazyLoad && BUILD.disconnectedCallback) {
Expand Down
7 changes: 4 additions & 3 deletions src/runtime/styles.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as d from '../declarations';
import { BUILD } from '@build-conditionals';
import { CMP_FLAGS } from '@utils';
import { cssVarShim, doc, styles, supportsConstructibleStylesheets, supportsShadowDom } from '@platform';
import { doc, plt, styles, supportsConstructibleStylesheets, supportsShadowDom } from '@platform';
import { HYDRATE_ID, NODE_TYPE } from './runtime-constants';


Expand Down Expand Up @@ -45,8 +45,8 @@ export const addStyle = (styleContainerNode: any, cmpMeta: d.ComponentRuntimeMet
styleElm.innerHTML = style;

} else {
if (cssVarShim) {
styleElm = cssVarShim.createHostStyle(hostElm, scopeId, style, !!(cmpMeta.$flags$ & CMP_FLAGS.needsScopedEncapsulation));
if (BUILD.cssVarShim && plt.$cssShim$) {
styleElm = plt.$cssShim$.createHostStyle(hostElm, scopeId, style, !!(cmpMeta.$flags$ & CMP_FLAGS.needsScopedEncapsulation));
const newScopeId = (styleElm as any)['s-sc'];
if (newScopeId) {
scopeId = newScopeId;
Expand All @@ -59,6 +59,7 @@ export const addStyle = (styleContainerNode: any, cmpMeta: d.ComponentRuntimeMet

} else {
styleElm = doc.createElement('style');
styleElm.setAttribute('data-styles', '');
styleElm.innerHTML = style;
}

Expand Down
6 changes: 3 additions & 3 deletions src/runtime/update-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as d from '../declarations';
import { attachStyles } from './styles';
import { BUILD } from '@build-conditionals';
import { CMP_FLAGS, HOST_FLAGS } from '@utils';
import { consoleError, cssVarShim, doc, getHostRef, plt, writeTask } from '@platform';
import { consoleError, doc, getHostRef, plt, writeTask } from '@platform';
import { HYDRATED_CLASS, PLATFORM_FLAGS } from './runtime-constants';
import { renderVdom } from './vdom/vdom-render';

Expand Down Expand Up @@ -90,8 +90,8 @@ const updateComponent = (elm: d.RenderNode, hostRef: d.HostRef, cmpMeta: d.Compo
elm.textContent = (BUILD.allRenderFn) ? instance.render() : (instance.render && instance.render());
}
}
if (cssVarShim) {
cssVarShim.updateHost(elm);
if (BUILD.cssVarShim && plt.$cssShim$) {
plt.$cssShim$.updateHost(elm);
}

if (BUILD.hydrateServerSide) {
Expand Down

0 comments on commit 5e4a0f9

Please sign in to comment.