1 | import React from 'react'
|
2 |
|
3 | export const StyleMapContext = React.createContext({})
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | export const checkAndWriteIntoHead = (styleMap = {}) => {
|
10 | if (typeof styleMap !== 'object') return
|
11 | Object.keys(styleMap).forEach(wrapper => {
|
12 | const style = styleMap[wrapper]
|
13 | if (style.count > 0) {
|
14 |
|
15 | if (!document.getElementById(wrapper)) {
|
16 | const styleTag = document.createElement('style')
|
17 | styleTag.innerHTML = style.css
|
18 | styleTag.setAttribute('id', wrapper)
|
19 | document.getElementsByTagName('head')[0].appendChild(styleTag)
|
20 | }
|
21 | } else {
|
22 |
|
23 | if (document.getElementById(wrapper)) {
|
24 | document.getElementById(wrapper).remove()
|
25 | }
|
26 | }
|
27 | })
|
28 | }
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 | export const append = (styleMap = {}, style) => {
|
36 | if (Array.isArray(style))
|
37 | return style.forEach(theStyle => append(styleMap, theStyle))
|
38 |
|
39 | if (typeof style !== 'object') return
|
40 |
|
41 | if (!styleMap[style.wrapper]) {
|
42 | styleMap[style.wrapper] = {
|
43 | css: style.css,
|
44 | count: 1
|
45 | }
|
46 | } else {
|
47 | styleMap[style.wrapper].count++
|
48 | }
|
49 |
|
50 | if (__CLIENT__) {
|
51 | checkAndWriteIntoHead(styleMap)
|
52 | }
|
53 | }
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 | export const remove = (styleMap = {}, style) => {
|
61 | if (Array.isArray(style))
|
62 | return style.forEach(theStyle => remove(theStyle))
|
63 |
|
64 | if (typeof style !== 'object') return
|
65 |
|
66 | if (styleMap[style.wrapper]) {
|
67 | styleMap[style.wrapper].count--
|
68 | }
|
69 | }
|
70 |
|
71 | const idDivStylesContainer = '__KOOT_ISOMORPHIC_STYLES_CONTAINER__'
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 | export const parseHtmlForStyles = (html) => {
|
79 | const matches = html.match(new RegExp(`<div id="${idDivStylesContainer}">(.+)</div>`, 'm'))
|
80 | return {
|
81 | html: html.substr(0, matches.index),
|
82 | htmlStyles: matches[1]
|
83 | }
|
84 | }
|
85 |
|
86 |
|
87 |
|
88 |
|
89 | export class StylesContainer extends React.Component {
|
90 | static contextType = StyleMapContext
|
91 | render() {
|
92 | return (
|
93 | <div
|
94 | id={idDivStylesContainer}
|
95 | dangerouslySetInnerHTML={{
|
96 | __html: Object.keys(this.context)
|
97 | .filter(id => !!this.context[id].css)
|
98 | .map(id => `<style id="${id}">${this.context[id].css}</style>`)
|
99 | .join('')
|
100 | }}
|
101 | />
|
102 | )
|
103 | }
|
104 | }
|