Browse Source
* remove unused styles by diffing styles * update README * fix tests * use a polyfill for Object.entriesadd-plugins-support
Naoyuki Kanezawa
8 years ago
committed by
GitHub
12 changed files with 155 additions and 60 deletions
@ -1 +0,0 @@ |
|||||
module.exports = require('./dist/inject') |
|
@ -1,32 +0,0 @@ |
|||||
// Ours
|
|
||||
import memory from './memory' |
|
||||
|
|
||||
const isBrowser = typeof window !== 'undefined' |
|
||||
const tags = {} |
|
||||
|
|
||||
export default function inject(id, css) { |
|
||||
if (isBrowser) { |
|
||||
// if the tag is already present we ignore it!
|
|
||||
if (!tags[id]) { |
|
||||
const el = makeStyleTag(css) |
|
||||
|
|
||||
tags[id] = el |
|
||||
memory[id] = el |
|
||||
} |
|
||||
} else { |
|
||||
memory[id] = css |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
function makeStyleTag(str) { |
|
||||
// based on implementation by glamor
|
|
||||
const tag = document.createElement('style') |
|
||||
|
|
||||
tag.type = 'text/css' |
|
||||
tag.appendChild(document.createTextNode(str)) |
|
||||
|
|
||||
const head = document.head || document.getElementsByTagName('head')[0] |
|
||||
head.appendChild(tag) |
|
||||
|
|
||||
return tag |
|
||||
} |
|
@ -0,0 +1,56 @@ |
|||||
|
import entries from 'object.entries' |
||||
|
import memory from './memory' |
||||
|
|
||||
|
const {hasOwnProperty} = Object.prototype |
||||
|
const tags = {} |
||||
|
let prevStyles = {} |
||||
|
|
||||
|
export default typeof window === 'undefined' ? renderOnServer : renderOnClient |
||||
|
|
||||
|
function renderOnServer(components) { |
||||
|
for (const {props} of components) { |
||||
|
memory[props['data-jsx']] = props.css |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function renderOnClient(components) { |
||||
|
const styles = {} |
||||
|
for (const c of components) { |
||||
|
styles[c.props['data-jsx']] = c |
||||
|
} |
||||
|
|
||||
|
patch(diff(prevStyles, styles)) |
||||
|
|
||||
|
prevStyles = styles |
||||
|
} |
||||
|
|
||||
|
function diff(a, b) { |
||||
|
const added = entries(b).filter(([k]) => !hasOwnProperty.call(a, k)) |
||||
|
const removed = entries(a).filter(([k]) => !hasOwnProperty.call(b, k)) |
||||
|
return [added, removed] |
||||
|
} |
||||
|
|
||||
|
function patch([added, removed]) { |
||||
|
for (const [id, c] of added) { |
||||
|
tags[id] = makeStyleTag(c.props.css) |
||||
|
} |
||||
|
|
||||
|
for (const [id] of removed) { |
||||
|
const t = tags[id] |
||||
|
delete tags[id] |
||||
|
t.parentNode.removeChild(t) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function makeStyleTag(str) { |
||||
|
// based on implementation by glamor
|
||||
|
const tag = document.createElement('style') |
||||
|
|
||||
|
tag.type = 'text/css' |
||||
|
tag.appendChild(document.createTextNode(str)) |
||||
|
|
||||
|
const head = document.head || document.getElementsByTagName('head')[0] |
||||
|
head.appendChild(tag) |
||||
|
|
||||
|
return tag |
||||
|
} |
@ -0,0 +1,47 @@ |
|||||
|
import {Component} from 'react' |
||||
|
import render from './render' |
||||
|
|
||||
|
export default class extends Component { |
||||
|
componentWillMount() { |
||||
|
mount(this) |
||||
|
} |
||||
|
|
||||
|
componentWillUnmount() { |
||||
|
unmount(this) |
||||
|
} |
||||
|
|
||||
|
render() { |
||||
|
return null |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const components = [] |
||||
|
const update = typeof window === 'undefined' ? doRender : updateOnClient |
||||
|
let requestId |
||||
|
|
||||
|
function mount(component) { |
||||
|
components.push(component) |
||||
|
update() |
||||
|
} |
||||
|
|
||||
|
function unmount(component) { |
||||
|
const i = components.indexOf(component) |
||||
|
if (i < 0) { |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
components.splice(i, 1) |
||||
|
update() |
||||
|
} |
||||
|
|
||||
|
function updateOnClient() { |
||||
|
window.cancelAnimationFrame(requestId) |
||||
|
requestId = window.requestAnimationFrame(() => { |
||||
|
requestId = null |
||||
|
doRender() |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
function doRender() { |
||||
|
render(components) |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
module.exports = require('./dist/style') |
Loading…
Reference in new issue