@emotion/sheet
Advanced tools
Comparing version 0.2.0 to 0.6.0
{ | ||
"name": "@emotion/sheet", | ||
"version": "0.2.0", | ||
"version": "0.6.0", | ||
"description": "emotion's stylesheet", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.cjs.js", |
147
src/index.js
@@ -34,2 +34,3 @@ // @flow | ||
// this weirdness brought to you by firefox | ||
/* istanbul ignore next */ | ||
for (let i = 0; i < document.styleSheets.length; i++) { | ||
@@ -43,119 +44,73 @@ if (document.styleSheets[i].ownerNode === tag) { | ||
type Options = { nonce?: string, key?: string, container?: HTMLElement } | ||
function makeStyleTag(opts: Options): HTMLStyleElement { | ||
let tag = document.createElement('style') | ||
tag.type = 'text/css' | ||
tag.setAttribute('data-emotion', opts.key || '') | ||
if (opts.nonce !== undefined) { | ||
tag.setAttribute('nonce', opts.nonce) | ||
} | ||
tag.appendChild(document.createTextNode('')) | ||
// $FlowFixMe | ||
;(opts.container !== undefined ? opts.container : document.head).appendChild( | ||
tag | ||
) | ||
return tag | ||
export type Options = { | ||
nonce?: string, | ||
key?: string, | ||
container?: HTMLElement, | ||
speedy?: boolean, | ||
maxLength?: number | ||
} | ||
export class DynamicStyleSheet { | ||
injected: boolean | ||
opts: Options | ||
ctr: number | ||
injected: boolean | ||
tag: HTMLStyleElement | ||
sheet: CSSStyleSheet | ||
constructor(options: Options) { | ||
this.ctr = 0 | ||
this.opts = options | ||
} | ||
inject() { | ||
if (process.env.NODE_ENV !== 'production' && this.tag !== undefined) { | ||
throw new Error('This stylesheet has already been injected') | ||
} | ||
this.tag = makeStyleTag(this.opts) | ||
this.sheet = sheetForTag(this.tag) | ||
} | ||
insertRules(rules: Array<string>) { | ||
this.removeRules() | ||
rules.forEach(this.insert, this) | ||
} | ||
insert(rule: string) { | ||
try { | ||
this.sheet.insertRule(rule, this.ctr) | ||
this.ctr++ | ||
} catch (e) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
console.warn(`Invalid Rule: "${rule}"`, e) | ||
} | ||
} | ||
} | ||
removeRules() { | ||
if (this.ctr !== 0) { | ||
while (this.ctr--) { | ||
this.sheet.deleteRule(this.ctr) | ||
} | ||
this.ctr = 0 | ||
} | ||
} | ||
flush() { | ||
// $FlowFixMe | ||
this.tag.parentNode.removeChild(this.tag) | ||
this.ctr = 0 | ||
// $FlowFixMe | ||
this.tag = undefined | ||
// $FlowFixMe | ||
this.sheet = undefined | ||
} | ||
} | ||
export class StyleSheet { | ||
injected: boolean | ||
isSpeedy: boolean | ||
ctr: number | ||
tags: HTMLStyleElement[] | ||
opts: Options | ||
constructor(options: Options) { | ||
this.isSpeedy = process.env.NODE_ENV === 'production' // the big drawback here is that the css won't be editable in devtools | ||
container: HTMLElement | ||
maxLength: number | ||
key: string | void | ||
nonce: string | void | ||
constructor(options: Options | void) { | ||
if (options === undefined) options = {} | ||
this.isSpeedy = | ||
options.speedy === undefined | ||
? process.env.NODE_ENV === 'production' | ||
: options.speedy | ||
// maxLength is how many rules we have per style tag, it's 65000 in speedy mode | ||
// because that's the upper limit in IE 10 TODO: make sure that is actually correct | ||
// it's 1 in dev because we insert source maps that map a single rule to a location | ||
// and you can only have one source map per style tag | ||
this.maxLength = options.maxLength || this.isSpeedy ? 65000 : 1 | ||
this.tags = [] | ||
this.ctr = 0 | ||
this.opts = options | ||
this.nonce = options.nonce | ||
// key is the value of the data-emotion attribute, it's used to identify different sheets | ||
this.key = options.key | ||
// $FlowFixMe | ||
this.container = | ||
options.container || | ||
(typeof document !== 'undefined' ? document.head : null) | ||
} | ||
inject() { | ||
if (this.injected) { | ||
throw new Error('already injected!') | ||
insert(rule: string) { | ||
if (this.ctr % this.maxLength === 0) { | ||
this._insertStyleTag() | ||
} | ||
const tag = this.tags[this.tags.length - 1] | ||
if (this.isSpeedy) { | ||
this.tags[0] = makeStyleTag(this.opts) | ||
} | ||
this.injected = true | ||
} | ||
speedy(bool: boolean) { | ||
if (this.ctr !== 0) { | ||
// cannot change speedy mode after inserting any rule to sheet. Either call speedy(${bool}) earlier in your app, or call flush() before speedy(${bool}) | ||
throw new Error(`cannot change speedy now`) | ||
} | ||
this.isSpeedy = !!bool | ||
} | ||
insert(rule: string, sourceMap?: string) { | ||
// this is the ultrafast version, works across browsers | ||
if (this.isSpeedy) { | ||
const tag = this.tags[this.tags.length - 1] | ||
const sheet = sheetForTag(tag) | ||
try { | ||
// this is the ultrafast version, works across browsers | ||
// the big drawback is that the css won't be editable in devtools | ||
sheet.insertRule(rule, sheet.cssRules.length) | ||
} catch (e) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
console.warn('illegal rule', rule) // eslint-disable-line no-console | ||
console.warn( | ||
`There was a problem inserting the following rule: "${rule}"`, | ||
e | ||
) | ||
} | ||
} | ||
} else { | ||
const tag = makeStyleTag(this.opts) | ||
this.tags.push(tag) | ||
tag.appendChild(document.createTextNode(rule + (sourceMap || ''))) | ||
tag.appendChild(document.createTextNode(rule)) | ||
} | ||
this.ctr++ | ||
if (this.ctr % 65000 === 0) { | ||
this.tags.push(makeStyleTag(this.opts)) | ||
} | ||
_insertStyleTag() { | ||
let tag = document.createElement('style') | ||
tag.setAttribute('data-emotion', this.key || '') | ||
if (this.nonce !== undefined) { | ||
tag.setAttribute('nonce', this.nonce) | ||
} | ||
tag.appendChild(document.createTextNode('')) | ||
this.container.appendChild(tag) | ||
this.tags.push(tag) | ||
} | ||
@@ -167,5 +122,3 @@ flush() { | ||
this.ctr = 0 | ||
// todo - look for remnants in document.styleSheets | ||
this.injected = false | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
31083
9
0
84
425