-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathreprocss.js
More file actions
executable file
·235 lines (148 loc) · 5.92 KB
/
Copy pathreprocss.js
File metadata and controls
executable file
·235 lines (148 loc) · 5.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*
# reproCSS
## version 0.0.10
reproCSS is a flexible CSS reprocessor that uses `<style>` tags and a `process=""` attribute.
You can add the CSS you want reprocss.js to apply to your HTML in `<style>` tags with the following values on the `process` attribute:
- `none` means no reprocessing
- `once` means process immediately and never again
- `auto` runs every `resize`, `input`, and `click` event on window
- any space-separated list of JS events you wish to listen for
<style process="none"></style>
<style process="once"></style>
<style process="auto"></style>
<style process="touchstart scroll"></style>
If you are using reproCSS with custom events, you may also optionally use a `selector` attribute specify a list of one or more CSS selectors you would like to add event listeners for. If no `selector` attribute is found all custom events will be applied to window.
<style process="click" selector="#any, .css, [selector]"></style>
To evaluate JavaScript inside the CSS as it's being reprocessed by `reprocss.js` you can use the `${}` interpolation syntax. The following `<style>` tag would always ensure the `<div>` in this example was half of the window's height:
<style process="auto">
div {
height: calc(${innerHeight}px / 2);
}
</style>
When the browser is 1000px tall the `${innerHeight}` in our CSS will be output as `500`, leading to the following output:
<style process="auto">
div {
height: calc(500px / 2);
}
</style>
Currently this plugin only supports `<style>` tags, but it may be possible to support CSS loaded via `<link>` with a similar technique.
- https://github.com/tomhodgins/reprocss
Author: Tommy Hodgins
License: MIT
*/
// Uses Node, AMD or browser globals to create a module
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD: Register as an anonymous module
define([], factory)
} else if (typeof module === 'object' && module.exports) {
// Node: Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node
module.exports = factory()
} else {
// Browser globals (root is window)
root.reprocss = factory()
}
}(this, function(e) {
var reprocss = {}
reprocss.count = 0
reprocss.style = []
reprocss.load = function() {
// Find all <style process=""> tags in document
var tag = document.querySelectorAll('style[process]')
for (var i=0; i < tag.length; i++) {
// Mark tag with data-reprocss="" attribute and current tag count
tag[i].setAttribute('data-reprocss', reprocss.count)
// Increment tag count
reprocss.count++
reprocss.process(tag[i])
}
}
reprocss.process = function(tag) {
// Save original CSS code in the reprocss.style array
reprocss.style.push(tag.innerHTML)
// Remove current tag contents
tag.innerHTML = null
var trigger = tag.getAttribute('process')
var number = tag.getAttribute('data-reprocss')
switch (trigger) {
// process="none"
case "none":
// Populate tag with original CSS code
tag.innerHTML = reprocss.style[number]
break
// process="once"
case "once":
// Populate tag immediately with evaluated CSS code
reprocss.apply(number)
break
// process="auto"
case "auto":
// Populate tag immediately with evaluated CSS code
reprocss.apply(number)
// Listen on window resize
window.addEventListener('resize', function() {
reprocss.apply(number)
})
// Listen on window input
window.addEventListener('input', function() {
reprocss.apply(number)
})
// Listen on window click
window.addEventListener('click', function() {
reprocss.apply(number)
})
break
// For any other process="" values
default:
// Turn space-separated lists into an array
var triggers = trigger.split(' ')
var selectorAttr = tag.getAttribute('selector')
// if selector="" attribute has a value
if (selectorAttr) {
// split the value of selector="" into an array of selectors
var selector = selectorAttr.split(',')
// For each selector
for (var j=0; j < selector.length; j++) {
// Find all tags in document that match
var element = document.querySelectorAll(selector[j])
for (var k=0; k < element.length; k++) {
for (var l=0; l < triggers.length; l++) {
// Add a new event listener to window for that event
element[k].addEventListener(triggers[l], function() {
reprocss.apply(number)
})
}
}
}
// if no selector="" attribute found we apply events to window
} else {
// Populate tag immediately with evaluated CSS code
reprocss.apply(number)
// For each custom event we find
Array.from(triggers, function(event) {
// Add a new event listener to window for that event
window.addEventListener(event, function() {
reprocss.apply(number)
})
})
}
break
}
}
reprocss.apply = function(number) {
// Locate the corresponding `<style>` tag in DOM
var tag = document.querySelectorAll('style[data-reprocss]')[number]
// Evaluate CSS code for this tag
var css = reprocss.style[number].replace(/\$\{([^\}]*)\}/g, function(string, match) {
var func = new Function('return ' + match)
return func()
})
// Populate `<style>` tag with evaluated CSS
tag.innerHTML = css
}
// Start reprocss when document is loaded
document.addEventListener('DOMContentLoaded', reprocss.load())
return reprocss
}))