302 lines
14 KiB
JavaScript
302 lines
14 KiB
JavaScript
|
define(["require", "exports", "tslib", "./shadowConfig"], function (require, exports, tslib_1, shadowConfig_1) {
|
||
|
"use strict";
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
exports.Stylesheet = exports.STYLESHEET_SETTING = exports.InjectionMode = void 0;
|
||
|
exports.InjectionMode = {
|
||
|
/**
|
||
|
* Avoids style injection, use getRules() to read the styles.
|
||
|
*/
|
||
|
none: 0,
|
||
|
/**
|
||
|
* Inserts rules using the insertRule api.
|
||
|
*/
|
||
|
insertNode: 1,
|
||
|
/**
|
||
|
* Appends rules using appendChild.
|
||
|
*/
|
||
|
appendChild: 2,
|
||
|
};
|
||
|
exports.STYLESHEET_SETTING = '__stylesheet__';
|
||
|
/**
|
||
|
* MSIE 11 doesn't cascade styles based on DOM ordering, but rather on the order that each style node
|
||
|
* is created. As such, to maintain consistent priority, IE11 should reuse a single style node.
|
||
|
*/
|
||
|
var REUSE_STYLE_NODE = typeof navigator !== 'undefined' && /rv:11.0/.test(navigator.userAgent);
|
||
|
var _global = {};
|
||
|
// Grab window.
|
||
|
try {
|
||
|
// Why the cast?
|
||
|
// if compiled/type checked in same program with `@fluentui/font-icons-mdl2` which extends `Window` on global
|
||
|
// ( check packages/font-icons-mdl2/src/index.ts ) the definitions don't match! Thus the need of this extra assertion
|
||
|
_global = (window || {});
|
||
|
}
|
||
|
catch (_a) {
|
||
|
/* leave as blank object */
|
||
|
}
|
||
|
var _stylesheet;
|
||
|
/**
|
||
|
* Represents the state of styles registered in the page. Abstracts
|
||
|
* the surface for adding styles to the stylesheet, exposes helpers
|
||
|
* for reading the styles registered in server rendered scenarios.
|
||
|
*
|
||
|
* @public
|
||
|
*/
|
||
|
var Stylesheet = /** @class */ (function () {
|
||
|
function Stylesheet(config, serializedStylesheet) {
|
||
|
var _a, _b, _c, _d, _e, _f;
|
||
|
this._rules = [];
|
||
|
this._preservedRules = [];
|
||
|
this._counter = 0;
|
||
|
this._keyToClassName = {};
|
||
|
this._onInsertRuleCallbacks = [];
|
||
|
this._onResetCallbacks = [];
|
||
|
this._classNameToArgs = {};
|
||
|
// If there is no document we won't have an element to inject into.
|
||
|
this._config = tslib_1.__assign({ injectionMode: typeof document === 'undefined' ? exports.InjectionMode.none : exports.InjectionMode.insertNode, defaultPrefix: 'css', namespace: undefined, cspSettings: undefined }, config);
|
||
|
this._classNameToArgs = (_a = serializedStylesheet === null || serializedStylesheet === void 0 ? void 0 : serializedStylesheet.classNameToArgs) !== null && _a !== void 0 ? _a : this._classNameToArgs;
|
||
|
this._counter = (_b = serializedStylesheet === null || serializedStylesheet === void 0 ? void 0 : serializedStylesheet.counter) !== null && _b !== void 0 ? _b : this._counter;
|
||
|
this._keyToClassName = (_d = (_c = this._config.classNameCache) !== null && _c !== void 0 ? _c : serializedStylesheet === null || serializedStylesheet === void 0 ? void 0 : serializedStylesheet.keyToClassName) !== null && _d !== void 0 ? _d : this._keyToClassName;
|
||
|
this._preservedRules = (_e = serializedStylesheet === null || serializedStylesheet === void 0 ? void 0 : serializedStylesheet.preservedRules) !== null && _e !== void 0 ? _e : this._preservedRules;
|
||
|
this._rules = (_f = serializedStylesheet === null || serializedStylesheet === void 0 ? void 0 : serializedStylesheet.rules) !== null && _f !== void 0 ? _f : this._rules;
|
||
|
}
|
||
|
/**
|
||
|
* Gets the singleton instance.
|
||
|
*/
|
||
|
Stylesheet.getInstance = function (shadowConfig) {
|
||
|
_stylesheet = _global[exports.STYLESHEET_SETTING];
|
||
|
if (_global[shadowConfig_1.SHADOW_DOM_STYLESHEET_SETTING]) {
|
||
|
return _global[shadowConfig_1.SHADOW_DOM_STYLESHEET_SETTING].getInstance(shadowConfig);
|
||
|
}
|
||
|
if (!_stylesheet || (_stylesheet._lastStyleElement && _stylesheet._lastStyleElement.ownerDocument !== document)) {
|
||
|
var fabricConfig = (_global === null || _global === void 0 ? void 0 : _global.FabricConfig) || {};
|
||
|
var stylesheet = new Stylesheet(fabricConfig.mergeStyles, fabricConfig.serializedStylesheet);
|
||
|
_stylesheet = stylesheet;
|
||
|
_global[exports.STYLESHEET_SETTING] = stylesheet;
|
||
|
}
|
||
|
return _stylesheet;
|
||
|
};
|
||
|
/**
|
||
|
* Serializes the Stylesheet instance into a format which allows rehydration on creation.
|
||
|
* @returns string representation of `ISerializedStylesheet` interface.
|
||
|
*/
|
||
|
Stylesheet.prototype.serialize = function () {
|
||
|
return JSON.stringify({
|
||
|
classNameToArgs: this._classNameToArgs,
|
||
|
counter: this._counter,
|
||
|
keyToClassName: this._keyToClassName,
|
||
|
preservedRules: this._preservedRules,
|
||
|
rules: this._rules,
|
||
|
});
|
||
|
};
|
||
|
/**
|
||
|
* Configures the stylesheet.
|
||
|
*/
|
||
|
Stylesheet.prototype.setConfig = function (config) {
|
||
|
this._config = tslib_1.__assign(tslib_1.__assign({}, this._config), config);
|
||
|
};
|
||
|
/**
|
||
|
* Configures a reset callback.
|
||
|
*
|
||
|
* @param callback - A callback which will be called when the Stylesheet is reset.
|
||
|
* @returns function which when called un-registers provided callback.
|
||
|
*/
|
||
|
Stylesheet.prototype.onReset = function (callback) {
|
||
|
var _this = this;
|
||
|
this._onResetCallbacks.push(callback);
|
||
|
return function () {
|
||
|
_this._onResetCallbacks = _this._onResetCallbacks.filter(function (cb) { return cb !== callback; });
|
||
|
};
|
||
|
};
|
||
|
/**
|
||
|
* Configures an insert rule callback.
|
||
|
*
|
||
|
* @param callback - A callback which will be called when a rule is inserted.
|
||
|
* @returns function which when called un-registers provided callback.
|
||
|
*/
|
||
|
Stylesheet.prototype.onInsertRule = function (callback) {
|
||
|
var _this = this;
|
||
|
this._onInsertRuleCallbacks.push(callback);
|
||
|
return function () {
|
||
|
_this._onInsertRuleCallbacks = _this._onInsertRuleCallbacks.filter(function (cb) { return cb !== callback; });
|
||
|
};
|
||
|
};
|
||
|
/**
|
||
|
* Generates a unique classname.
|
||
|
*
|
||
|
* @param displayName - Optional value to use as a prefix.
|
||
|
*/
|
||
|
Stylesheet.prototype.getClassName = function (displayName) {
|
||
|
var namespace = this._config.namespace;
|
||
|
var prefix = displayName || this._config.defaultPrefix;
|
||
|
return "".concat(namespace ? namespace + '-' : '').concat(prefix, "-").concat(this._counter++);
|
||
|
};
|
||
|
/**
|
||
|
* Used internally to cache information about a class which was
|
||
|
* registered with the stylesheet.
|
||
|
*/
|
||
|
Stylesheet.prototype.cacheClassName = function (className, key, args, rules) {
|
||
|
this._keyToClassName[this._getCacheKey(key)] = className;
|
||
|
this._classNameToArgs[className] = {
|
||
|
args: args,
|
||
|
rules: rules,
|
||
|
};
|
||
|
};
|
||
|
/**
|
||
|
* Gets the appropriate classname given a key which was previously
|
||
|
* registered using cacheClassName.
|
||
|
*/
|
||
|
Stylesheet.prototype.classNameFromKey = function (key) {
|
||
|
return this._keyToClassName[this._getCacheKey(key)];
|
||
|
};
|
||
|
/**
|
||
|
* Gets all classnames cache with the stylesheet.
|
||
|
*/
|
||
|
Stylesheet.prototype.getClassNameCache = function () {
|
||
|
return this._keyToClassName;
|
||
|
};
|
||
|
/**
|
||
|
* Gets the arguments associated with a given classname which was
|
||
|
* previously registered using cacheClassName.
|
||
|
*/
|
||
|
Stylesheet.prototype.argsFromClassName = function (className) {
|
||
|
var entry = this._classNameToArgs[className];
|
||
|
return entry && entry.args;
|
||
|
};
|
||
|
/**
|
||
|
* Gets the rules associated with a given classname which was
|
||
|
* previously registered using cacheClassName.
|
||
|
*/
|
||
|
Stylesheet.prototype.insertedRulesFromClassName = function (className) {
|
||
|
var entry = this._classNameToArgs[className];
|
||
|
return entry && entry.rules;
|
||
|
};
|
||
|
/**
|
||
|
* Inserts a css rule into the stylesheet.
|
||
|
* @param preserve - Preserves the rule beyond a reset boundary.
|
||
|
*/
|
||
|
Stylesheet.prototype.insertRule = function (rule, preserve, stylesheetKey) {
|
||
|
if (stylesheetKey === void 0) { stylesheetKey = shadowConfig_1.GLOBAL_STYLESHEET_KEY; }
|
||
|
var injectionMode = this._config.injectionMode;
|
||
|
var element = injectionMode !== exports.InjectionMode.none ? this._getStyleElement() : undefined;
|
||
|
if (preserve) {
|
||
|
this._preservedRules.push(rule);
|
||
|
}
|
||
|
if (element) {
|
||
|
switch (injectionMode) {
|
||
|
case exports.InjectionMode.insertNode:
|
||
|
this._insertRuleIntoSheet(element.sheet, rule);
|
||
|
break;
|
||
|
case exports.InjectionMode.appendChild:
|
||
|
element.appendChild(document.createTextNode(rule));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
this._rules.push(rule);
|
||
|
}
|
||
|
// eslint-disable-next-line deprecation/deprecation
|
||
|
if (this._config.onInsertRule) {
|
||
|
// eslint-disable-next-line deprecation/deprecation
|
||
|
this._config.onInsertRule(rule);
|
||
|
}
|
||
|
this._onInsertRuleCallbacks.forEach(function (callback) {
|
||
|
return callback({ key: stylesheetKey, sheet: (element ? element.sheet : undefined), rule: rule });
|
||
|
});
|
||
|
};
|
||
|
/**
|
||
|
* Gets all rules registered with the stylesheet; only valid when
|
||
|
* using InsertionMode.none.
|
||
|
*/
|
||
|
Stylesheet.prototype.getRules = function (includePreservedRules) {
|
||
|
return (includePreservedRules ? this._preservedRules.join('') : '') + this._rules.join('');
|
||
|
};
|
||
|
/**
|
||
|
* Resets the internal state of the stylesheet. Only used in server
|
||
|
* rendered scenarios where we're using InsertionMode.none.
|
||
|
*/
|
||
|
Stylesheet.prototype.reset = function () {
|
||
|
this._rules = [];
|
||
|
this._counter = 0;
|
||
|
this._classNameToArgs = {};
|
||
|
this._keyToClassName = {};
|
||
|
this._onResetCallbacks.forEach(function (callback) { return callback(); });
|
||
|
};
|
||
|
// Forces the regeneration of incoming styles without totally resetting the stylesheet.
|
||
|
Stylesheet.prototype.resetKeys = function () {
|
||
|
this._keyToClassName = {};
|
||
|
};
|
||
|
Stylesheet.prototype._createStyleElement = function () {
|
||
|
var _a;
|
||
|
var doc = ((_a = this._config.window) === null || _a === void 0 ? void 0 : _a.document) || document;
|
||
|
var head = doc.head;
|
||
|
var styleElement = doc.createElement('style');
|
||
|
var nodeToInsertBefore = null;
|
||
|
styleElement.setAttribute('data-merge-styles', 'true');
|
||
|
var cspSettings = this._config.cspSettings;
|
||
|
if (cspSettings) {
|
||
|
if (cspSettings.nonce) {
|
||
|
styleElement.setAttribute('nonce', cspSettings.nonce);
|
||
|
}
|
||
|
}
|
||
|
if (this._lastStyleElement) {
|
||
|
// If the `nextElementSibling` is null, then the insertBefore will act as a regular append.
|
||
|
// https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore#Syntax
|
||
|
nodeToInsertBefore = this._lastStyleElement.nextElementSibling;
|
||
|
}
|
||
|
else {
|
||
|
var placeholderStyleTag = this._findPlaceholderStyleTag();
|
||
|
if (placeholderStyleTag) {
|
||
|
nodeToInsertBefore = placeholderStyleTag.nextElementSibling;
|
||
|
}
|
||
|
else {
|
||
|
nodeToInsertBefore = head.childNodes[0];
|
||
|
}
|
||
|
}
|
||
|
head.insertBefore(styleElement, head.contains(nodeToInsertBefore) ? nodeToInsertBefore : null);
|
||
|
this._lastStyleElement = styleElement;
|
||
|
return styleElement;
|
||
|
};
|
||
|
Stylesheet.prototype._insertRuleIntoSheet = function (sheet, rule) {
|
||
|
if (!sheet) {
|
||
|
return false;
|
||
|
}
|
||
|
try {
|
||
|
sheet.insertRule(rule, sheet.cssRules.length);
|
||
|
return true;
|
||
|
}
|
||
|
catch (e) {
|
||
|
// 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.
|
||
|
}
|
||
|
return false;
|
||
|
};
|
||
|
Stylesheet.prototype._getCacheKey = function (key) {
|
||
|
return key;
|
||
|
};
|
||
|
Stylesheet.prototype._getStyleElement = function () {
|
||
|
var _this = this;
|
||
|
if (!this._styleElement) {
|
||
|
this._styleElement = this._createStyleElement();
|
||
|
if (!REUSE_STYLE_NODE) {
|
||
|
// Reset the style element on the next frame.
|
||
|
var win = this._config.window || window;
|
||
|
win.requestAnimationFrame(function () {
|
||
|
_this._styleElement = undefined;
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
return this._styleElement;
|
||
|
};
|
||
|
Stylesheet.prototype._findPlaceholderStyleTag = function () {
|
||
|
var head = document.head;
|
||
|
if (head) {
|
||
|
return head.querySelector('style[data-merge-styles]');
|
||
|
}
|
||
|
return null;
|
||
|
};
|
||
|
return Stylesheet;
|
||
|
}());
|
||
|
exports.Stylesheet = Stylesheet;
|
||
|
});
|
||
|
//# sourceMappingURL=Stylesheet.js.map
|