From 492279f16b517e3604cb788ca306505c1ff5ea87 Mon Sep 17 00:00:00 2001 From: David Zearing Date: Tue, 24 Apr 2018 09:50:59 -0700 Subject: [PATCH 1/3] Updating how style elements are injected (to preserve the location in head in which they're inserted.) --- packages/merge-styles/src/Stylesheet.ts | 71 +++++++++++++------------ 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/packages/merge-styles/src/Stylesheet.ts b/packages/merge-styles/src/Stylesheet.ts index c3b1a87a52ee6..3cbb1ab4519df 100644 --- a/packages/merge-styles/src/Stylesheet.ts +++ b/packages/merge-styles/src/Stylesheet.ts @@ -50,6 +50,7 @@ let _stylesheet: Stylesheet; * @public */ export class Stylesheet { + private _lastStyleElement?: HTMLStyleElement; private _styleElement?: HTMLStyleElement; private _rules: string[] = []; private _config: IStyleSheetConfig; @@ -158,28 +159,28 @@ export class Stylesheet { public insertRule( rule: string ): void { - const element = this._getElement(); - const injectionMode = element ? this._config.injectionMode : InjectionMode.none; - - switch (injectionMode) { - case InjectionMode.insertNode: - const { sheet } = element!; - - try { - // tslint:disable-next-line:no-any - (sheet as any).insertRule(rule, (sheet as any).cssRules.length); - } catch (e) { - /* no-op on errors */ - } - break; - - case InjectionMode.appendChild: - _createStyleElement(rule); - break; - - default: - this._rules.push(rule); - break; + const { injectionMode } = this._config; + const element = injectionMode !== InjectionMode.none ? this._getStyleElement() : undefined; + + if (element) { + switch (this._config.injectionMode) { + case InjectionMode.insertNode: + const { sheet } = element!; + + try { + // tslint:disable-next-line:no-any + (sheet as any).insertRule(rule, (sheet as any).cssRules.length); + } catch (e) { + /* no-op on errors */ + } + break; + + case InjectionMode.appendChild: + element.appendChild(document.createTextNode(rule)); + break; + } + } else { + this._rules.push(rule); } if (this._config.onInsertRule) { @@ -212,9 +213,9 @@ export class Stylesheet { this._keyToClassName = {}; } - private _getElement(): HTMLStyleElement | undefined { + private _getStyleElement(): HTMLStyleElement | undefined { if (!this._styleElement && typeof document !== 'undefined') { - this._styleElement = _createStyleElement(); + this._styleElement = this._createStyleElement(); // Reset the style element on the next frame. window.requestAnimationFrame(() => { @@ -223,17 +224,21 @@ export class Stylesheet { } return this._styleElement; } -} -function _createStyleElement(content?: string): HTMLStyleElement { - const styleElement = document.createElement('style'); + private _createStyleElement(): HTMLStyleElement { + const styleElement = document.createElement('style'); + + styleElement.setAttribute('data-merge-styles', 'true'); + styleElement.type = 'text/css'; + + if (this._lastStyleElement && this._lastStyleElement.nextElementSibling) { + document.head.insertBefore(styleElement, this._lastStyleElement.nextElementSibling); + } else { + document.head.appendChild(styleElement); + } + this._lastStyleElement = styleElement; - styleElement.setAttribute('data-merge-styles', 'true'); - styleElement.type = 'text/css'; - if (content) { - styleElement.appendChild(document.createTextNode(content)); + return styleElement; } - document.head.appendChild(styleElement); - return styleElement; } \ No newline at end of file From 342b02aec85f657ab5c0e168bd629d011eaceec6 Mon Sep 17 00:00:00 2001 From: David Zearing Date: Tue, 24 Apr 2018 09:59:53 -0700 Subject: [PATCH 2/3] adding change file --- .../merge-styles-order_2018-04-24-16-59.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@uifabric/merge-styles/merge-styles-order_2018-04-24-16-59.json diff --git a/common/changes/@uifabric/merge-styles/merge-styles-order_2018-04-24-16-59.json b/common/changes/@uifabric/merge-styles/merge-styles-order_2018-04-24-16-59.json new file mode 100644 index 0000000000000..59eca511c07b0 --- /dev/null +++ b/common/changes/@uifabric/merge-styles/merge-styles-order_2018-04-24-16-59.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@uifabric/merge-styles", + "comment": "merge-styles: `style` elements which are created on the fly now \"bunch\" together, avoiding unpredictability in specificity.", + "type": "patch" + } + ], + "packageName": "@uifabric/merge-styles", + "email": "dzearing@microsoft.com" +} \ No newline at end of file From 9f2885d2b47b98d85faa016df0462b057aca108b Mon Sep 17 00:00:00 2001 From: David Zearing Date: Tue, 24 Apr 2018 19:19:57 -0700 Subject: [PATCH 3/3] Adding nit fixes. --- packages/merge-styles/src/Stylesheet.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/merge-styles/src/Stylesheet.ts b/packages/merge-styles/src/Stylesheet.ts index 3cbb1ab4519df..f86b551edd5c9 100644 --- a/packages/merge-styles/src/Stylesheet.ts +++ b/packages/merge-styles/src/Stylesheet.ts @@ -168,10 +168,11 @@ export class Stylesheet { const { sheet } = element!; try { - // tslint:disable-next-line:no-any - (sheet as any).insertRule(rule, (sheet as any).cssRules.length); + (sheet as CSSStyleSheet).insertRule(rule, (sheet as CSSStyleSheet).cssRules.length); } catch (e) { - /* no-op on errors */ + // The browser will throw exceptions on unsupported rules (such as a moz prefix in webkit.) + // We need to swallow the exceptions for this scenario, otherwise we'd need to filter + // which could be slower and bulkier. } break;