Created
August 8, 2017 23:56
-
-
Save zanzamar/6b8cfd292346fb7237500238c1828a47 to your computer and use it in GitHub Desktop.
styletron-client-monkey-patch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* global document */ | |
/** | |
* Customize our own version of styletron until we get a P/R request imported: | |
* | |
* This monkey patches styletron to enable namespacing/wrapping the generated CSS classes from styletron. The generated | |
* class on the html element stays the same. | |
* | |
* ie: `<div class="a" />` has a classname written to the `<style />` of `.WRAP_CLASS a { ... }` | |
* | |
* Usage: | |
* const styletron = Styletron( | |
* document.getElementsByClassName('_styletron_hydrate_'), | |
* { selectorPrefix: '.WRAP-CLASS' } | |
* ); | |
* | |
* https://github.com/rtsao/styletron/pull/160 | |
*/ | |
import Styletron from 'styletron-client'; | |
import StyletronCore from 'styletron-core'; | |
function initialize(elements, options = {}) { | |
Styletron.prototype.injectDeclaration = injectDeclaration; | |
const styletron = new Styletron(elements, options); | |
styletron.selectorPrefix = options.selectorPrefix; | |
return styletron; | |
} | |
/** | |
* customized injectDeclaration | |
* | |
* Override styletron function | |
*/ | |
function injectDeclaration(decl) { | |
const oldCount = this.uniqueCount; | |
const className = StyletronCore.prototype.injectDeclaration.call(this, decl); | |
if (oldCount !== this.uniqueCount) { | |
const rule = declarationToRule(className, decl, this.selectorPrefix); | |
let sheet; | |
if (decl.media) { | |
if (!this.mediaSheets[decl.media]) { | |
const mediaSheet = document.createElement('style'); | |
mediaSheet.media = decl.media; | |
this.mediaSheets[decl.media] = mediaSheet; | |
this.mainSheet.parentNode.appendChild(mediaSheet); | |
} | |
sheet = this.mediaSheets[decl.media].sheet; | |
} else { | |
sheet = this.mainSheet.sheet; | |
} | |
sheet.insertRule(rule, sheet.cssRules.length); | |
} | |
return className; | |
} | |
/* | |
* Injection helpers | |
* | |
* Override styletron function | |
*/ | |
function declarationToRule(className, ref, selectorPrefix) { | |
const prop = ref.prop; | |
const val = ref.val; | |
const pseudo = ref.pseudo; | |
const decl = `${prop}:${val}`; | |
let selector = `${selectorPrefix ? `${selectorPrefix} ` : ''}.${className}`; | |
if (pseudo) { | |
selector += pseudo; | |
} | |
return `${selector}{${decl}}`; | |
} | |
export default initialize; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment