fbshipit-source-id: b6fc29740c6875d2e78953b8a7123890a67930f2 Co-authored-by: Sebastian McKenzie <sebmck@fb.com> Co-authored-by: John Knox <jknox@fb.com> Co-authored-by: Emil Sjölander <emilsj@fb.com> Co-authored-by: Pritesh Nandgaonkar <prit91@fb.com>
93 lines
1.9 KiB
JavaScript
93 lines
1.9 KiB
JavaScript
/**
|
|
* Copyright 2018-present Facebook.
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
* @format
|
|
*/
|
|
|
|
const invariant = require('invariant');
|
|
|
|
function makeStyleTag(): HTMLStyleElement {
|
|
const tag = document.createElement('style');
|
|
tag.type = 'text/css';
|
|
tag.appendChild(document.createTextNode(''));
|
|
|
|
const {head} = document;
|
|
invariant(head, 'expected head');
|
|
head.appendChild(tag);
|
|
|
|
return tag;
|
|
}
|
|
|
|
export class StyleSheet {
|
|
constructor(isSpeedy?: boolean) {
|
|
this.injected = false;
|
|
this.isSpeedy = Boolean(isSpeedy);
|
|
|
|
this.flush();
|
|
this.inject();
|
|
}
|
|
|
|
ruleIndexes: Array<string>;
|
|
injected: boolean;
|
|
isSpeedy: boolean;
|
|
tag: HTMLStyleElement;
|
|
|
|
getRuleCount(): number {
|
|
return this.ruleIndexes.length;
|
|
}
|
|
|
|
flush() {
|
|
this.ruleIndexes = [];
|
|
if (this.tag) {
|
|
this.tag.innerHTML = '';
|
|
}
|
|
}
|
|
|
|
inject() {
|
|
if (this.injected) {
|
|
throw new Error('already injected stylesheet!');
|
|
}
|
|
|
|
this.tag = makeStyleTag();
|
|
this.injected = true;
|
|
}
|
|
|
|
delete(key: string) {
|
|
const index = this.ruleIndexes.indexOf(key);
|
|
if (index < 0) {
|
|
// TODO maybe error
|
|
return;
|
|
}
|
|
|
|
this.ruleIndexes.splice(index, 1);
|
|
|
|
const tag = this.tag;
|
|
if (this.isSpeedy) {
|
|
const sheet = tag.sheet;
|
|
invariant(sheet, 'expected sheet');
|
|
|
|
// $FlowFixMe: sheet is actually CSSStylesheet
|
|
sheet.deleteRule(index);
|
|
} else {
|
|
tag.removeChild(tag.childNodes[index + 1]);
|
|
}
|
|
}
|
|
|
|
insert(key: string, rule: string) {
|
|
const tag = this.tag;
|
|
|
|
if (this.isSpeedy) {
|
|
const sheet = tag.sheet;
|
|
invariant(sheet, 'expected sheet');
|
|
|
|
// $FlowFixMe: sheet is actually CSSStylesheet
|
|
sheet.insertRule(rule, sheet.cssRules.length);
|
|
} else {
|
|
tag.appendChild(document.createTextNode(rule));
|
|
}
|
|
|
|
this.ruleIndexes.push(key);
|
|
}
|
|
}
|