1
- ; ( function ( ) {
1
+ ;
2
+ ( function ( ) {
2
3
/**
3
4
*
4
5
* @type {Function }
5
6
* @constructor
6
7
*/
7
- var ElementQueries = this . ElementQueries = function ( ) {
8
- /**
9
- * Adds a listener to the over/under-flow event.
10
- *
11
- * @param {HTMLElement } element
12
- * @param {Function } callback
13
- */
14
- function addResizeListener ( element , callback ) {
15
- if ( window . OverflowEvent ) {
16
- //webkit
17
- element . addEventListener ( 'overflowchanged' , function ( e ) {
18
- callback . call ( this , e ) ;
19
- } ) ;
20
- } else {
21
- element . addEventListener ( 'overflow' , function ( e ) {
22
- callback . call ( this , e ) ;
23
- } ) ;
24
- element . addEventListener ( 'underflow' , function ( e ) {
25
- callback . call ( this , e ) ;
26
- } ) ;
27
- }
28
- }
29
-
30
- /**
31
- *
32
- * @constructor
33
- */
34
- function EventQueue ( ) {
35
- this . q = [ ] ;
36
- this . add = function ( ev ) {
37
- this . q . push ( ev ) ;
38
- } ;
39
-
40
- var i , j ;
41
- this . call = function ( ) {
42
- for ( i = 0 , j = this . q . length ; i < j ; i ++ ) {
43
- this . q [ i ] . call ( ) ;
44
- }
45
- } ;
46
- }
47
-
48
- /**
49
- * @param {HTMLElement } element
50
- * @param {String } prop
51
- * @returns {String|Integer }
52
- */
53
- function getComputedStyle ( element , prop ) {
54
- if ( element . currentStyle ) {
55
- return element . currentStyle ( prop ) ;
56
- } else if ( window . getComputedStyle ) {
57
- return window . getComputedStyle ( element , null ) . getPropertyValue ( prop ) ;
58
- } else {
59
- return element . style [ prop ] ;
60
- }
61
-
62
- }
63
- /**
64
- *
65
- * @param {HTMLElement } element
66
- * @param {Function } resized
67
- */
68
- function attachResizeEvent ( element , resized ) {
69
- if ( ! element . resizedAttached ) {
70
- element . resizedAttached = new EventQueue ( ) ;
71
- element . resizedAttached . add ( resized ) ;
72
- } else if ( element . resizedAttached ) {
73
- element . resizedAttached . add ( resized ) ;
74
- return ;
75
- }
76
-
77
- if ( element . onresize ) {
78
- //internet explorer
79
- if ( element . attachEvent ) {
80
- element . attachEvent ( 'onresize' , element . resizedAttached . call ) ;
81
- } else if ( element . addEventListener ) {
82
- element . addEventListener ( 'resize' , element . resizedAttached . call ) ;
83
- }
84
- } else {
85
- var myResized = function ( ) {
86
- if ( setupSensor ( ) ) {
87
- element . resizedAttached . call ( ) ;
88
- }
89
- }
90
- element . resizeSensor = document . createElement ( 'div' ) ;
91
- element . resizeSensor . className = 'resize-sensor' ;
92
- var style =
93
- 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: -1;' ;
94
- element . resizeSensor . style . cssText = style ;
95
- element . resizeSensor . innerHTML =
96
- '<div class="resize-sensor-overflow" style="' + style + '">' +
97
- '<div></div>' +
98
- '</div>' +
99
- '<div class="resize-sensor-underflow" style="' + style + '">' +
100
- '<div></div>' +
101
- '</div>' ;
102
- element . appendChild ( element . resizeSensor ) ;
103
-
104
- if ( 'absolute' !== getComputedStyle ( element , 'position' ) ) {
105
- element . style . position = 'relative' ;
106
- }
107
-
108
- var x = 0 ,
109
- y = 0 ,
110
- firstStyle = element . resizeSensor . firstElementChild . firstChild . style ,
111
- lastStyle = element . resizeSensor . lastElementChild . firstChild . style ;
112
-
113
- function setupSensor ( ) {
114
- var change = false ,
115
- width = element . resizeSensor . offsetWidth ,
116
- height = element . resizeSensor . offsetHeight ;
117
-
118
- if ( x != width ) {
119
- firstStyle . width = width - 1 + 'px' ;
120
- lastStyle . width = width + 1 + 'px' ;
121
- change = true ;
122
- x = width ;
123
- }
124
- if ( y != height ) {
125
- firstStyle . height = height - 1 + 'px' ;
126
- lastStyle . height = height + 1 + 'px' ;
127
- change = true ;
128
- y = height ;
129
- }
130
- return change ;
131
- }
132
- setupSensor ( ) ;
133
- addResizeListener ( element . resizeSensor , myResized ) ;
134
- addResizeListener ( element . resizeSensor . firstElementChild , myResized ) ;
135
- addResizeListener ( element . resizeSensor . lastElementChild , myResized ) ;
136
- }
137
- }
138
-
8
+ var ElementQueries = this . ElementQueries = function ( ) {
139
9
/**
140
10
*
141
11
* @param element
162
32
var units = value . replace ( / [ 0 - 9 ] * / , '' ) ;
163
33
value = parseFloat ( value ) ;
164
34
switch ( units ) {
165
- case "px" : return value ;
166
- case "em" : return value * getEmSize ( element ) ;
167
- case "rem" : return value * getEmSize ( ) ;
35
+ case "px" :
36
+ return value ;
37
+ case "em" :
38
+ return value * getEmSize ( element ) ;
39
+ case "rem" :
40
+ return value * getEmSize ( ) ;
168
41
// Viewport units!
169
42
// According to http://quirksmode.org/mobile/tableViewport.html
170
43
// documentElement.clientWidth/Height gets us the most reliable info
171
- case "vw" : return value * document . documentElement . clientWidth / 100 ;
172
- case "vh" : return value * document . documentElement . clientHeight / 100 ;
44
+ case "vw" :
45
+ return value * document . documentElement . clientWidth / 100 ;
46
+ case "vh" :
47
+ return value * document . documentElement . clientHeight / 100 ;
173
48
case "vmin" :
174
49
case "vmax" :
175
50
var vw = document . documentElement . clientWidth / 100 ;
176
51
var vh = document . documentElement . clientHeight / 100 ;
177
52
var chooser = Math [ units === "vmin" ? "min" : "max" ] ;
178
53
return value * chooser ( vw , vh ) ;
179
- default : return value ;
54
+ default :
55
+ return value ;
180
56
// for now, not supporting physical units (since they are just a set number of px)
181
57
// or ex/ch (getting accurate measurements is hard)
182
58
}
187
63
* @param {HTMLElement } element
188
64
* @constructor
189
65
*/
190
- function SetupInformation ( element ) {
66
+ function SetupInformation ( element ) {
191
67
this . element = element ;
192
68
this . options = [ ] ;
193
69
var i , j , option , width = 0 , height = 0 , value , actualValue , attrValues , attrValue , attrName ;
206
82
*/
207
83
this . call = function ( ) {
208
84
// extract current dimensions
209
- width = this . element . offsetWidth ;
85
+ width = this . element . offsetWidth ;
210
86
height = this . element . offsetHeight ;
211
87
212
88
attrValues = { } ;
213
89
214
- for ( i = 0 , j = this . options . length ; i < j ; i ++ ) {
90
+ for ( i = 0 , j = this . options . length ; i < j ; i ++ ) {
215
91
option = this . options [ i ] ;
216
- value = convertToPx ( this . element , option . value ) ;
92
+ value = convertToPx ( this . element , option . value ) ;
217
93
218
94
actualValue = option . property == 'width' ? width : height ;
219
- attrName = option . mode + '-' + option . property ;
220
- attrValue = '' ;
95
+ attrName = option . mode + '-' + option . property ;
96
+ attrValue = '' ;
221
97
222
98
if ( option . mode == 'min' && actualValue >= value ) {
223
99
attrValue += ' ' + option . value ;
251
127
} else {
252
128
element . elementQueriesSetupInformation = new SetupInformation ( element ) ;
253
129
element . elementQueriesSetupInformation . addOption ( options ) ;
254
- attachResizeEvent ( element , function ( ) {
130
+ new ResizeSensor ( element , function ( ) {
255
131
element . elementQueriesSetupInformation . call ( ) ;
256
132
} ) ;
257
133
}
276
152
}
277
153
278
154
var regex = / , * ( [ ^ , ] * ) \[ [ \s \t ] * ( m i n | m a x ) - ( w i d t h | h e i g h t ) [ \s \t ] * [ ~ $ \^ ] ? = [ \s \t ] * " ( [ ^ " ] * ) " [ \s \t ] * ] / ;
155
+
279
156
/**
280
157
* @param {CssRule } rule
281
158
*/
292
169
function readRules ( rules ) {
293
170
var selector = '' ;
294
171
for ( var i = 0 , j = rules . length ; i < j ; i ++ ) {
295
- selector = rules [ i ] . selectorText ;
296
- if ( - 1 !== selector . indexOf ( 'min-width' ) || - 1 !== selector . indexOf ( 'max-width' ) ) {
297
- extractQuery ( rules [ i ] ) ;
298
- //todo, ie7-8 includes @imports in a rule, so extract it
172
+ if ( 1 === rules [ i ] . type ) {
173
+ selector = rules [ i ] . selectorText ;
174
+ if ( - 1 !== selector . indexOf ( 'min-width' ) || - 1 !== selector . indexOf ( 'max-width' ) ) {
175
+ extractQuery ( rules [ i ] ) ;
176
+ //todo, ie7-8 includes @imports in a rule, so extract it
177
+ }
299
178
}
300
179
}
301
180
}
302
181
303
182
/**
304
183
* Searches all css rules and setups the event listener to all elements with element query rules..
305
184
*/
306
- this . init = function ( ) {
185
+ this . init = function ( ) {
307
186
for ( var i = 0 , j = document . styleSheets . length ; i < j ; i ++ ) {
308
187
readRules ( document . styleSheets [ i ] . cssRules || document . styleSheets [ i ] . rules ) ;
309
188
}
310
189
}
311
190
}
312
191
313
- function init ( ) {
192
+ function init ( ) {
314
193
new ElementQueries ( ) . init ( ) ;
315
194
}
316
195
317
- if ( window . addEventListener ) {
318
- window . addEventListener ( 'load' , init , false ) ;
196
+ if ( window . addEventListener ) {
197
+ window . addEventListener ( 'load' , init , false ) ;
319
198
} else {
320
- window . attachEvent ( 'onload' , init ) ;
199
+ window . attachEvent ( 'onload' , init ) ;
321
200
}
322
201
323
202
} ) ( ) ;
0 commit comments