css3-mediaqueries-rails 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6338c0cdd175c964b5afefeeeb26f784e122cf66
4
+ data.tar.gz: 7f6ae21aec326fb99f15b70c9bb853b640496105
5
+ SHA512:
6
+ metadata.gz: ef4e5838e7d715a2ed24f5ea6faa31f3d6ef01fade0449d06aa92266184bd338a37cce84b65d9880d91c31cd9cf57d996fff35aff4bf7c7e9e010d2a85402009
7
+ data.tar.gz: a05cf0effecc634e34fa0f77cfc3f284e5fc504fea80fe7dd051a2aeb24dcfe71bd4413eead0548969ad6ffef1c3a4c1663ce11cb5186b400fb573006725a100
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in css3-mediaqueries-rails.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Yuri Zubov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,47 @@
1
+ # css3-mediaqueries
2
+
3
+ The [css3-mediaqueries](https://github.com/i0result/css3-mediaqueries-rails) gem simply
4
+ provides the [css3-mediaqueries](https://code.google.com/p/css3-mediaqueries-js/) javascript
5
+ libraries in a rails engine.
6
+
7
+ Supports Rails 3.1 and up. The files will be added to the asset pipeline.
8
+
9
+ You have the option of including `css3-mediaqueries.js`.
10
+
11
+
12
+ ## Installation
13
+
14
+ Add the gem to your Gemfile:
15
+
16
+ gem 'css3-mediaqueries-rails'
17
+
18
+ And run:
19
+
20
+ bundle install
21
+
22
+
23
+ ## Usage
24
+
25
+ Since you probably want to only include this when serving IE 8 and below, place
26
+ the include in a conditional comment within the `<head>` section of your layout:
27
+
28
+ #### Erb:
29
+
30
+ <!--[if lt IE 9]>
31
+ <%= javascript_include_tag 'css3-mediaqueries' %>
32
+ <![endif]-->
33
+
34
+ #### Haml:
35
+
36
+ /[if lt IE 9]
37
+ = javascript_include_tag 'css3-mediaqueries'
38
+
39
+
40
+ ## Contributing
41
+
42
+ 1. Fork it
43
+ 2. Clone it `git clone http://github.com/path/to/your/fork`
44
+ 3. Create your feature branch `git checkout -b my-new-feature`
45
+ 4. Commit your changes `git commit -am 'Add some feature`
46
+ 5. Push to the branch `git push origin my-new-feature`
47
+ 6. Create new pull request through Github
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,19 @@
1
+ require File.expand_path('../lib/css3-mediaqueries/rails/version', __FILE__)
2
+
3
+ # Describe your gem and declare its dependencies:
4
+ Gem::Specification.new do |spec|
5
+ spec.name = 'css3-mediaqueries-rails'
6
+ spec.version = Css3Mediaqueries::Rails::VERSION
7
+ spec.authors = ['Yuri Zubov']
8
+ spec.email = ['I0Result86@gmail.com']
9
+ spec.homepage = 'https://github.com/I0Result/css3-mediaqueries-rails'
10
+ spec.summary = 'Add css3-mediaqueries to the rails asset pipeline'
11
+ spec.description = 'This gem adds css3-mediaqueries.js to the rails asset pipeline.'
12
+ spec.license = 'MIT'
13
+ spec.files = `git ls-files`.split($/)
14
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
15
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
16
+ spec.require_paths = ['lib']
17
+ spec.add_dependency 'railties', '>= 3.0'
18
+ spec.add_development_dependency 'bundler', '>= 1.0'
19
+ end
@@ -0,0 +1,15 @@
1
+ module Css3Mediaqueries
2
+ module Rails
3
+ end
4
+ end
5
+
6
+ require 'css3-mediaqueries/rails/version'
7
+
8
+ case ::Rails.version.to_s
9
+ when /^4/
10
+ require 'css3-mediaqueries/rails/engine'
11
+ when /^3\.[12]/
12
+ require 'css3-mediaqueries/rails/engine3'
13
+ when /^3\.[0]/
14
+ require 'css3-mediaqueries/rails/railtie'
15
+ end
@@ -0,0 +1,9 @@
1
+ module Css3Mediaqueries
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ config.assets.precompile += %w(
5
+ css3-mediaqueries.js
6
+ )
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Css3Mediaqueries
2
+ module Rails
3
+ class Engine3 < ::Rails::Engine
4
+ initializer 'css3-mediaqueries.assets.precompile', :group => :all do |app|
5
+ app.config.assets.precompile += %w(
6
+ css3-mediaqueries.js
7
+ )
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ module Css3Mediaqueries
2
+ module Rails
3
+ class Railtie < ::Rails::Railtie
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Css3Mediaqueries
2
+ module Rails
3
+ VERSION = '1.0.0'
4
+ end
5
+ end
@@ -0,0 +1,1104 @@
1
+ /*
2
+ css3-mediaqueries.js - CSS Helper and CSS3 Media Queries Enabler
3
+
4
+ author: Wouter van der Graaf <wouter at dynora nl>
5
+ version: 1.0 (20110330)
6
+ license: MIT
7
+ website: http://code.google.com/p/css3-mediaqueries-js/
8
+
9
+ W3C spec: http://www.w3.org/TR/css3-mediaqueries/
10
+
11
+ Note: use of embedded <style> is not recommended when using media queries, because IE has no way of returning the raw literal css text from a <style> element.
12
+ */
13
+
14
+
15
+ // true prototypal inheritance (http://javascript.crockford.com/prototypal.html)
16
+ if (typeof Object.create !== 'function') {
17
+ Object.create = function (o) {
18
+ function F() {}
19
+ F.prototype = o;
20
+ return new F();
21
+ };
22
+ }
23
+
24
+
25
+ // user agent sniffing shortcuts
26
+ var ua = {
27
+ toString: function () {
28
+ return navigator.userAgent;
29
+ },
30
+ test: function (s) {
31
+ return this.toString().toLowerCase().indexOf(s.toLowerCase()) > -1;
32
+ }
33
+ };
34
+ ua.version = (ua.toString().toLowerCase().match(/[\s\S]+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1];
35
+ ua.webkit = ua.test('webkit');
36
+ ua.gecko = ua.test('gecko') && !ua.webkit;
37
+ ua.opera = ua.test('opera');
38
+ ua.ie = ua.test('msie') && !ua.opera;
39
+ ua.ie6 = ua.ie && document.compatMode && typeof document.documentElement.style.maxHeight === 'undefined';
40
+ ua.ie7 = ua.ie && document.documentElement && typeof document.documentElement.style.maxHeight !== 'undefined' && typeof XDomainRequest === 'undefined';
41
+ ua.ie8 = ua.ie && typeof XDomainRequest !== 'undefined';
42
+
43
+
44
+
45
+ // initialize when DOM content is loaded
46
+ var domReady = function () {
47
+ var fns = [];
48
+ var init = function () {
49
+ if (!arguments.callee.done) { // run init functions once
50
+ arguments.callee.done = true;
51
+ for (var i = 0; i < fns.length; i++) {
52
+ fns[i]();
53
+ }
54
+ }
55
+ };
56
+
57
+ // listeners for different browsers
58
+ if (document.addEventListener) {
59
+ document.addEventListener('DOMContentLoaded', init, false);
60
+ }
61
+ if (ua.ie) {
62
+ (function () {
63
+ try {
64
+ // throws errors until after ondocumentready
65
+ document.documentElement.doScroll('left');
66
+ }
67
+ catch (e) {
68
+ setTimeout(arguments.callee, 50);
69
+ return;
70
+ }
71
+ // no errors, fire
72
+ init();
73
+ })();
74
+ // trying to always fire before onload
75
+ document.onreadystatechange = function () {
76
+ if (document.readyState === 'complete') {
77
+ document.onreadystatechange = null;
78
+ init();
79
+ }
80
+ };
81
+ }
82
+ if (ua.webkit && document.readyState) {
83
+ (function () {
84
+ if (document.readyState !== 'loading') {
85
+ init();
86
+ }
87
+ else {
88
+ setTimeout(arguments.callee, 10);
89
+ }
90
+ })();
91
+ }
92
+ window.onload = init; // fallback
93
+
94
+ return function (fn) { // add fn to init functions
95
+ if (typeof fn === 'function') {
96
+ fns[fns.length] = fn;
97
+ }
98
+ return fn;
99
+ };
100
+ }();
101
+
102
+
103
+
104
+ // helper library for parsing css to objects
105
+ var cssHelper = function () {
106
+
107
+ var regExp = {
108
+ BLOCKS: /[^\s{;][^{;]*\{(?:[^{}]*\{[^{}]*\}[^{}]*|[^{}]*)*\}/g,
109
+ BLOCKS_INSIDE: /[^\s{][^{]*\{[^{}]*\}/g,
110
+ DECLARATIONS: /[a-zA-Z\-]+[^;]*:[^;]+;/g,
111
+ RELATIVE_URLS: /url\(['"]?([^\/\)'"][^:\)'"]+)['"]?\)/g,
112
+ // strip whitespace and comments, @import is evil
113
+ REDUNDANT_COMPONENTS: /(?:\/\*([^*\\\\]|\*(?!\/))+\*\/|@import[^;]+;)/g,
114
+ REDUNDANT_WHITESPACE: /\s*(,|:|;|\{|\})\s*/g,
115
+ WHITESPACE_IN_PARENTHESES: /\(\s*(\S*)\s*\)/g,
116
+ MORE_WHITESPACE: /\s{2,}/g,
117
+ FINAL_SEMICOLONS: /;\}/g,
118
+ NOT_WHITESPACE: /\S+/g
119
+ };
120
+
121
+ var parsed, parsing = false;
122
+
123
+ var waiting = [];
124
+ var wait = function (fn) {
125
+ if (typeof fn === 'function') {
126
+ waiting[waiting.length] = fn;
127
+ }
128
+ };
129
+ var ready = function () {
130
+ for (var i = 0; i < waiting.length; i++) {
131
+ waiting[i](parsed);
132
+ }
133
+ };
134
+ var events = {};
135
+ var broadcast = function (n, v) {
136
+ if (events[n]) {
137
+ var listeners = events[n].listeners;
138
+ if (listeners) {
139
+ for (var i = 0; i < listeners.length; i++) {
140
+ listeners[i](v);
141
+ }
142
+ }
143
+ }
144
+ };
145
+
146
+ var requestText = function (url, fnSuccess, fnFailure) {
147
+ if (ua.ie && !window.XMLHttpRequest) {
148
+ window.XMLHttpRequest = function () {
149
+ return new ActiveXObject('Microsoft.XMLHTTP');
150
+ };
151
+ }
152
+ if (!XMLHttpRequest) {
153
+ return '';
154
+ }
155
+ var r = new XMLHttpRequest();
156
+ try {
157
+ r.open('get', url, true);
158
+ r.setRequestHeader('X_REQUESTED_WITH', 'XMLHttpRequest');
159
+ }
160
+ catch (e) {
161
+ fnFailure();
162
+ return;
163
+ }
164
+ var done = false;
165
+ setTimeout(function () {
166
+ done = true;
167
+ }, 5000);
168
+ document.documentElement.style.cursor = 'progress';
169
+ r.onreadystatechange = function () {
170
+ if (r.readyState === 4 && !done) {
171
+ if (!r.status && location.protocol === 'file:' ||
172
+ (r.status >= 200 && r.status < 300) ||
173
+ r.status === 304 ||
174
+ navigator.userAgent.indexOf('Safari') > -1 && typeof r.status === 'undefined') {
175
+ fnSuccess(r.responseText);
176
+ }
177
+ else {
178
+ fnFailure();
179
+ }
180
+ document.documentElement.style.cursor = '';
181
+ r = null; // avoid memory leaks
182
+ }
183
+ };
184
+ r.send('');
185
+ };
186
+
187
+ var sanitize = function (text) {
188
+ text = text.replace(regExp.REDUNDANT_COMPONENTS, '');
189
+ text = text.replace(regExp.REDUNDANT_WHITESPACE, '$1');
190
+ text = text.replace(regExp.WHITESPACE_IN_PARENTHESES, '($1)');
191
+ text = text.replace(regExp.MORE_WHITESPACE, ' ');
192
+ text = text.replace(regExp.FINAL_SEMICOLONS, '}'); // optional final semicolons
193
+ return text;
194
+ };
195
+
196
+ var objects = {
197
+ stylesheet: function (el) {
198
+ var o = {};
199
+ var amqs = [], mqls = [], rs = [], rsw = [];
200
+ var s = el.cssHelperText;
201
+
202
+ // add attribute media queries
203
+ var attr = el.getAttribute('media');
204
+ if (attr) {
205
+ var qts = attr.toLowerCase().split(',')
206
+ }
207
+ else {
208
+ var qts = ['all'] // imply 'all'
209
+ }
210
+ for (var i = 0; i < qts.length; i++) {
211
+ amqs[amqs.length] = objects.mediaQuery(qts[i], o);
212
+ }
213
+
214
+ // add media query lists and rules (top down order)
215
+ var blocks = s.match(regExp.BLOCKS); // @charset is not a block
216
+ if (blocks !== null) {
217
+ for (var i = 0; i < blocks.length; i++) {
218
+ if (blocks[i].substring(0, 7) === '@media ') { // media query (list)
219
+ var mql = objects.mediaQueryList(blocks[i], o);
220
+ rs = rs.concat(mql.getRules());
221
+ mqls[mqls.length] = mql;
222
+ }
223
+ else { // regular rule set, page context (@page) or font description (@font-face)
224
+ rs[rs.length] = rsw[rsw.length] = objects.rule(blocks[i], o, null);
225
+ }
226
+ }
227
+ }
228
+
229
+ o.element = el;
230
+ o.getCssText = function () {
231
+ return s;
232
+ };
233
+ o.getAttrMediaQueries = function () {
234
+ return amqs;
235
+ };
236
+ o.getMediaQueryLists = function () {
237
+ return mqls;
238
+ };
239
+ o.getRules = function () {
240
+ return rs;
241
+ };
242
+ o.getRulesWithoutMQ = function () {
243
+ return rsw;
244
+ };
245
+ return o;
246
+ },
247
+
248
+ mediaQueryList: function (s, stsh) {
249
+ var o = {};
250
+ var idx = s.indexOf('{');
251
+ var lt = s.substring(0, idx);
252
+ s = s.substring(idx + 1, s.length - 1);
253
+ var mqs = [], rs = [];
254
+
255
+ // add media queries
256
+ var qts = lt.toLowerCase().substring(7).split(',');
257
+ for (var i = 0; i < qts.length; i++) { // parse each media query
258
+ mqs[mqs.length] = objects.mediaQuery(qts[i], o);
259
+ }
260
+
261
+ // add rule sets
262
+ var rts = s.match(regExp.BLOCKS_INSIDE);
263
+ if (rts !== null) {
264
+ for (i = 0; i < rts.length; i++) {
265
+ rs[rs.length] = objects.rule(rts[i], stsh, o);
266
+ }
267
+ }
268
+
269
+ o.type = 'mediaQueryList';
270
+ o.getMediaQueries = function () {
271
+ return mqs;
272
+ };
273
+ o.getRules = function () {
274
+ return rs;
275
+ };
276
+ o.getListText = function () {
277
+ return lt;
278
+ };
279
+ o.getCssText = function () {
280
+ return s;
281
+ };
282
+ return o;
283
+ },
284
+
285
+ mediaQuery: function (s, listOrSheet) {
286
+ s = s || '';
287
+ var mql, stsh;
288
+ if (listOrSheet.type === 'mediaQueryList') {
289
+ mql = listOrSheet;
290
+ }
291
+ else {
292
+ stsh = listOrSheet;
293
+ }
294
+ var not = false, type;
295
+ var expr = [];
296
+ var valid = true;
297
+ var tokens = s.match(regExp.NOT_WHITESPACE);
298
+
299
+
300
+
301
+ for (var i = 0; i < tokens.length; i++) {
302
+ var token = tokens[i];
303
+ if (!type && (token === 'not' || token === 'only')) { // 'not' and 'only' keywords
304
+ // keyword 'only' does nothing, as if it was not present
305
+ if (token === 'not') {
306
+ not = true;
307
+ }
308
+ }
309
+ else if (!type) { // media type
310
+ type = token;
311
+ }
312
+ else if (token.charAt(0) === '(') { // media feature expression
313
+ var pair = token.substring(1, token.length - 1).split(':');
314
+ expr[expr.length] = {
315
+ mediaFeature: pair[0],
316
+ value: pair[1] || null
317
+ };
318
+ }
319
+ }
320
+
321
+ return {
322
+ getQueryText: function () {
323
+ return s;
324
+ },
325
+ getAttrStyleSheet: function () {
326
+ return stsh || null;
327
+ },
328
+ getList: function () {
329
+ return mql || null;
330
+ },
331
+ getValid: function () {
332
+ return valid;
333
+ },
334
+ getNot: function () {
335
+ return not;
336
+ },
337
+ getMediaType: function () {
338
+ return type;
339
+ },
340
+ getExpressions: function () {
341
+ return expr;
342
+ }
343
+ };
344
+ },
345
+
346
+ rule: function (s, stsh, mql) {
347
+ var o = {};
348
+ var idx = s.indexOf('{');
349
+ var st = s.substring(0, idx);
350
+ var ss = st.split(',');
351
+ var ds = [];
352
+ var dts = s.substring(idx + 1, s.length - 1).split(';');
353
+ for (var i = 0; i < dts.length; i++) {
354
+ ds[ds.length] = objects.declaration(dts[i], o);
355
+ }
356
+
357
+ o.getStylesheet = function () {
358
+ return stsh || null;
359
+ };
360
+ o.getMediaQueryList = function () {
361
+ return mql || null;
362
+ };
363
+ o.getSelectors = function () {
364
+ return ss;
365
+ };
366
+ o.getSelectorText = function () {
367
+ return st;
368
+ };
369
+ o.getDeclarations = function () {
370
+ return ds;
371
+ };
372
+ o.getPropertyValue = function (n) {
373
+ for (var i = 0; i < ds.length; i++) {
374
+ if (ds[i].getProperty() === n) {
375
+ return ds[i].getValue();
376
+ }
377
+ }
378
+ return null;
379
+ };
380
+ return o;
381
+ },
382
+
383
+ declaration: function (s, r) {
384
+ var idx = s.indexOf(':');
385
+ var p = s.substring(0, idx);
386
+ var v = s.substring(idx + 1);
387
+ return {
388
+ getRule: function () {
389
+ return r || null;
390
+ },
391
+ getProperty: function () {
392
+ return p;
393
+ },
394
+ getValue: function () {
395
+ return v;
396
+ }
397
+ };
398
+ }
399
+ };
400
+
401
+ var parseText = function (el) {
402
+ if (typeof el.cssHelperText !== 'string') {
403
+ return;
404
+ }
405
+ var o = {
406
+ stylesheet: null,
407
+ mediaQueryLists: [],
408
+ rules: [],
409
+ selectors: {},
410
+ declarations: [],
411
+ properties: {}
412
+ };
413
+
414
+ // build stylesheet object
415
+ var stsh = o.stylesheet = objects.stylesheet(el);
416
+
417
+ // collect media query lists
418
+ var mqls = o.mediaQueryLists = stsh.getMediaQueryLists();
419
+
420
+ // collect all rules
421
+ var ors = o.rules = stsh.getRules();
422
+
423
+ // collect all selectors
424
+ var oss = o.selectors;
425
+ var collectSelectors = function (r) {
426
+ var ss = r.getSelectors();
427
+ for (var i = 0; i < ss.length; i++) {
428
+ var n = ss[i];
429
+ if (!oss[n]) {
430
+ oss[n] = [];
431
+ }
432
+ oss[n][oss[n].length] = r;
433
+ }
434
+ };
435
+ for (i = 0; i < ors.length; i++) {
436
+ collectSelectors(ors[i]);
437
+ }
438
+
439
+ // collect all declarations
440
+ var ods = o.declarations;
441
+ for (i = 0; i < ors.length; i++) {
442
+ ods = o.declarations = ods.concat(ors[i].getDeclarations());
443
+ }
444
+
445
+ // collect all properties
446
+ var ops = o.properties;
447
+ for (i = 0; i < ods.length; i++) {
448
+ var n = ods[i].getProperty();
449
+ if (!ops[n]) {
450
+ ops[n] = [];
451
+ }
452
+ ops[n][ops[n].length] = ods[i];
453
+ }
454
+
455
+ el.cssHelperParsed = o;
456
+ parsed[parsed.length] = el;
457
+ return o;
458
+ };
459
+
460
+ var parseEmbedded = function (el, s) {
461
+ return;
462
+ // This function doesn't work because of a bug in IE, where innerHTML gives us parsed css instead of raw literal.
463
+ el.cssHelperText = sanitize(s || el.innerHTML);
464
+ return parseText(el);
465
+ };
466
+
467
+ var parse = function () {
468
+ parsing = true;
469
+ parsed = [];
470
+ var linked = [];
471
+ var finish = function () {
472
+ for (var i = 0; i < linked.length; i++) {
473
+ parseText(linked[i]);
474
+ }
475
+ var styles = document.getElementsByTagName('style');
476
+ for (i = 0; i < styles.length; i++) {
477
+ parseEmbedded(styles[i]);
478
+ }
479
+ parsing = false;
480
+ ready();
481
+ };
482
+ var links = document.getElementsByTagName('link');
483
+ for (var i = 0; i < links.length; i++) {
484
+ var link = links[i];
485
+ if (link.getAttribute('rel').indexOf('style') > -1 && link.href && link.href.length !== 0 && !link.disabled) {
486
+ linked[linked.length] = link;
487
+ }
488
+ }
489
+ if (linked.length > 0) {
490
+ var c = 0;
491
+ var checkForFinish = function () {
492
+ c++;
493
+ if (c === linked.length) { // parse in right order, so after last link is read
494
+ finish();
495
+ }
496
+ };
497
+ var processLink = function (link) {
498
+ var href = link.href;
499
+ requestText(href, function (text) {
500
+ // fix url's
501
+ text = sanitize(text).replace(regExp.RELATIVE_URLS, 'url(' + href.substring(0, href.lastIndexOf('/')) + '/$1)');
502
+ link.cssHelperText = text;
503
+ checkForFinish();
504
+ }, checkForFinish);
505
+ };
506
+ for (i = 0; i < linked.length; i++) {
507
+ processLink(linked[i]);
508
+ }
509
+ }
510
+ else {
511
+ finish();
512
+ }
513
+ };
514
+
515
+ var types = {
516
+ stylesheets: 'array',
517
+ mediaQueryLists: 'array',
518
+ rules: 'array',
519
+ selectors: 'object',
520
+ declarations: 'array',
521
+ properties: 'object'
522
+ };
523
+
524
+ var collections = {
525
+ stylesheets: null,
526
+ mediaQueryLists: null,
527
+ rules: null,
528
+ selectors: null,
529
+ declarations: null,
530
+ properties: null
531
+ };
532
+
533
+ var addToCollection = function (name, v) {
534
+ if (collections[name] !== null) {
535
+ if (types[name] === 'array') {
536
+ return (collections[name] = collections[name].concat(v));
537
+ }
538
+ else {
539
+ var c = collections[name];
540
+ for (var n in v) {
541
+ if (v.hasOwnProperty(n)) {
542
+ if (!c[n]) {
543
+ c[n] = v[n];
544
+ }
545
+ else {
546
+ c[n] = c[n].concat(v[n]);
547
+ }
548
+ }
549
+ }
550
+ return c;
551
+ }
552
+ }
553
+ };
554
+
555
+ var collect = function (name) {
556
+ collections[name] = (types[name] === 'array') ? [] : {};
557
+ for (var i = 0; i < parsed.length; i++) {
558
+ var pname = name === 'stylesheets' ? 'stylesheet' : name; // the exception
559
+ addToCollection(name, parsed[i].cssHelperParsed[pname]);
560
+ }
561
+ return collections[name];
562
+ };
563
+
564
+ // viewport size
565
+ var getViewportSize = function (d) {
566
+ if (typeof window.innerWidth != 'undefined') {
567
+ return window['inner' + d];
568
+ }
569
+ else if (typeof document.documentElement !== 'undefined'
570
+ && typeof document.documentElement.clientWidth !== 'undefined'
571
+ && document.documentElement.clientWidth != 0) {
572
+ return document.documentElement['client' + d];
573
+ }
574
+ };
575
+
576
+ // public static functions
577
+ return {
578
+ addStyle: function (s, mediaTypes, process) {
579
+ var el = document.createElement('style');
580
+ el.setAttribute('type', 'text/css');
581
+ if (mediaTypes && mediaTypes.length > 0) {
582
+ el.setAttribute('media', mediaTypes.join(','));
583
+ }
584
+ document.getElementsByTagName('head')[0].appendChild(el);
585
+ if (el.styleSheet) { // IE
586
+ el.styleSheet.cssText = s;
587
+ }
588
+ else {
589
+ el.appendChild(document.createTextNode(s));
590
+ }
591
+ el.addedWithCssHelper = true;
592
+ if (typeof process === 'undefined' || process === true) {
593
+ cssHelper.parsed(function (parsed) {
594
+ var o = parseEmbedded(el, s);
595
+ for (var n in o) {
596
+ if (o.hasOwnProperty(n)) {
597
+ addToCollection(n, o[n]);
598
+ }
599
+ }
600
+ broadcast('newStyleParsed', el);
601
+ });
602
+ }
603
+ else {
604
+ el.parsingDisallowed = true;
605
+ }
606
+ return el;
607
+ },
608
+
609
+ removeStyle: function (el) {
610
+ return el.parentNode.removeChild(el);
611
+ },
612
+
613
+ parsed: function (fn) {
614
+ if (parsing) {
615
+ wait(fn);
616
+ }
617
+ else {
618
+ if (typeof parsed !== 'undefined') {
619
+ if (typeof fn === 'function') {
620
+ fn(parsed);
621
+ }
622
+ }
623
+ else {
624
+ wait(fn);
625
+ parse();
626
+ }
627
+ }
628
+ },
629
+
630
+ stylesheets: function (fn) {
631
+ cssHelper.parsed(function (parsed) {
632
+ fn(collections.stylesheets || collect('stylesheets'));
633
+ });
634
+ },
635
+
636
+ mediaQueryLists: function (fn) {
637
+ cssHelper.parsed(function (parsed) {
638
+ fn(collections.mediaQueryLists || collect('mediaQueryLists'));
639
+ });
640
+ },
641
+
642
+ rules: function (fn) {
643
+ cssHelper.parsed(function (parsed) {
644
+ fn(collections.rules || collect('rules'));
645
+ });
646
+ },
647
+
648
+ selectors: function (fn) {
649
+ cssHelper.parsed(function (parsed) {
650
+ fn(collections.selectors || collect('selectors'));
651
+ });
652
+ },
653
+
654
+ declarations: function (fn) {
655
+ cssHelper.parsed(function (parsed) {
656
+ fn(collections.declarations || collect('declarations'));
657
+ });
658
+ },
659
+
660
+ properties: function (fn) {
661
+ cssHelper.parsed(function (parsed) {
662
+ fn(collections.properties || collect('properties'));
663
+ });
664
+ },
665
+
666
+ broadcast: broadcast,
667
+
668
+ addListener: function (n, fn) { // in case n is 'styleadd': added function is called everytime style is added and parsed
669
+ if (typeof fn === 'function') {
670
+ if (!events[n]) {
671
+ events[n] = {
672
+ listeners: []
673
+ };
674
+ }
675
+ events[n].listeners[events[n].listeners.length] = fn;
676
+ }
677
+ },
678
+
679
+ removeListener: function (n, fn) {
680
+ if (typeof fn === 'function' && events[n]) {
681
+ var ls = events[n].listeners;
682
+ for (var i = 0; i < ls.length; i++) {
683
+ if (ls[i] === fn) {
684
+ ls.splice(i, 1);
685
+ i -= 1;
686
+ }
687
+ }
688
+ }
689
+ },
690
+
691
+ getViewportWidth: function () {
692
+ return getViewportSize('Width');
693
+ },
694
+
695
+ getViewportHeight: function () {
696
+ return getViewportSize('Height');
697
+ }
698
+ };
699
+ }();
700
+
701
+
702
+
703
+ // function to test and apply parsed media queries against browser capabilities
704
+ domReady(function enableCssMediaQueries() {
705
+ var meter;
706
+
707
+ var regExp = {
708
+ LENGTH_UNIT: /[0-9]+(em|ex|px|in|cm|mm|pt|pc)$/,
709
+ RESOLUTION_UNIT: /[0-9]+(dpi|dpcm)$/,
710
+ ASPECT_RATIO: /^[0-9]+\/[0-9]+$/,
711
+ ABSOLUTE_VALUE: /^[0-9]*(\.[0-9]+)*$/
712
+ };
713
+
714
+ var styles = [];
715
+
716
+ var nativeSupport = function () {
717
+ // check support for media queries
718
+ var id = 'css3-mediaqueries-test';
719
+ var el = document.createElement('div');
720
+ el.id = id;
721
+ var style = cssHelper.addStyle('@media all and (width) { #' + id +
722
+ ' { width: 1px !important; } }', [], false); // false means don't parse this temp style
723
+ document.body.appendChild(el);
724
+ var ret = el.offsetWidth === 1;
725
+ style.parentNode.removeChild(style);
726
+ el.parentNode.removeChild(el);
727
+ nativeSupport = function () {
728
+ return ret;
729
+ };
730
+ return ret;
731
+ };
732
+
733
+ var createMeter = function () { // create measuring element
734
+ meter = document.createElement('div');
735
+ meter.style.cssText = 'position:absolute;top:-9999em;left:-9999em;' +
736
+ 'margin:0;border:none;padding:0;width:1em;font-size:1em;'; // cssText is needed for IE, works for the others
737
+ document.body.appendChild(meter);
738
+ // meter must have browser default font size of 16px
739
+ if (meter.offsetWidth !== 16) {
740
+ meter.style.fontSize = 16 / meter.offsetWidth + 'em';
741
+ }
742
+ meter.style.width = '';
743
+ };
744
+
745
+ var measure = function (value) {
746
+ meter.style.width = value;
747
+ var amount = meter.offsetWidth;
748
+ meter.style.width = '';
749
+ return amount;
750
+ };
751
+
752
+ var testMediaFeature = function (feature, value) {
753
+ // non-testable features: monochrome|min-monochrome|max-monochrome|scan|grid
754
+ var l = feature.length;
755
+ var min = (feature.substring(0, 4) === 'min-');
756
+ var max = (!min && feature.substring(0, 4) === 'max-');
757
+
758
+ if (value !== null) { // determine value type and parse to usable amount
759
+ var valueType;
760
+ var amount;
761
+ if (regExp.LENGTH_UNIT.exec(value)) {
762
+ valueType = 'length';
763
+ amount = measure(value);
764
+ }
765
+ else if (regExp.RESOLUTION_UNIT.exec(value)) {
766
+ valueType = 'resolution';
767
+ amount = parseInt(value, 10);
768
+ var unit = value.substring((amount + '').length);
769
+ }
770
+ else if (regExp.ASPECT_RATIO.exec(value)) {
771
+ valueType = 'aspect-ratio';
772
+ amount = value.split('/');
773
+ }
774
+ else if (regExp.ABSOLUTE_VALUE) {
775
+ valueType = 'absolute';
776
+ amount = value;
777
+ }
778
+ else {
779
+ valueType = 'unknown';
780
+ }
781
+ }
782
+
783
+ var width, height;
784
+ if ('device-width' === feature.substring(l - 12, l)) { // screen width
785
+ width = screen.width;
786
+ if (value !== null) {
787
+ if (valueType === 'length') {
788
+ return ((min && width >= amount) || (max && width < amount) || (!min && !max && width === amount));
789
+ }
790
+ else {
791
+ return false;
792
+ }
793
+ }
794
+ else { // test width without value
795
+ return width > 0;
796
+ }
797
+ }
798
+ else if ('device-height' === feature.substring(l - 13, l)) { // screen height
799
+ height = screen.height;
800
+ if (value !== null) {
801
+ if (valueType === 'length') {
802
+ return ((min && height >= amount) || (max && height < amount) || (!min && !max && height === amount));
803
+ }
804
+ else {
805
+ return false;
806
+ }
807
+ }
808
+ else { // test height without value
809
+ return height > 0;
810
+ }
811
+ }
812
+ else if ('width' === feature.substring(l - 5, l)) { // viewport width
813
+ width = document.documentElement.clientWidth || document.body.clientWidth; // the latter for IE quirks mode
814
+ if (value !== null) {
815
+ if (valueType === 'length') {
816
+ return ((min && width >= amount) || (max && width < amount) || (!min && !max && width === amount));
817
+ }
818
+ else {
819
+ return false;
820
+ }
821
+ }
822
+ else { // test width without value
823
+ return width > 0;
824
+ }
825
+ }
826
+ else if ('height' === feature.substring(l - 6, l)) { // viewport height
827
+ height = document.documentElement.clientHeight || document.body.clientHeight; // the latter for IE quirks mode
828
+ if (value !== null) {
829
+ if (valueType === 'length') {
830
+ return ((min && height >= amount) || (max && height < amount) || (!min && !max && height === amount));
831
+ }
832
+ else {
833
+ return false;
834
+ }
835
+ }
836
+ else { // test height without value
837
+ return height > 0;
838
+ }
839
+ }
840
+ else if ('device-aspect-ratio' === feature.substring(l - 19, l)) { // screen aspect ratio
841
+ return valueType === 'aspect-ratio' && screen.width * amount[1] === screen.height * amount[0];
842
+ }
843
+ else if ('color-index' === feature.substring(l - 11, l)) { // number of colors
844
+ var colors = Math.pow(2, screen.colorDepth);
845
+ if (value !== null) {
846
+ if (valueType === 'absolute') {
847
+ return ((min && colors >= amount) || (max && colors < amount) || (!min && !max && colors === amount));
848
+ }
849
+ else {
850
+ return false;
851
+ }
852
+ }
853
+ else { // test height without value
854
+ return colors > 0;
855
+ }
856
+ }
857
+ else if ('color' === feature.substring(l - 5, l)) { // bits per color component
858
+ var color = screen.colorDepth;
859
+ if (value !== null) {
860
+ if (valueType === 'absolute') {
861
+ return ((min && color >= amount) || (max && color < amount) || (!min && !max && color === amount));
862
+ }
863
+ else {
864
+ return false;
865
+ }
866
+ }
867
+ else { // test height without value
868
+ return color > 0;
869
+ }
870
+ }
871
+ else if ('resolution' === feature.substring(l - 10, l)) {
872
+ var res;
873
+ if (unit === 'dpcm') {
874
+ res = measure('1cm');
875
+ }
876
+ else {
877
+ res = measure('1in');
878
+ }
879
+ if (value !== null) {
880
+ if (valueType === 'resolution') {
881
+ return ((min && res >= amount) || (max && res < amount) || (!min && !max && res === amount));
882
+ }
883
+ else {
884
+ return false;
885
+ }
886
+ }
887
+ else { // test height without value
888
+ return res > 0;
889
+ }
890
+ }
891
+ else {
892
+ return false;
893
+ }
894
+ };
895
+
896
+ var testMediaQuery = function (mq) {
897
+ var test = mq.getValid();
898
+ var expressions = mq.getExpressions();
899
+ var l = expressions.length;
900
+ if (l > 0) {
901
+ for (var i = 0; i < l && test; i++) {
902
+ test = testMediaFeature(expressions[i].mediaFeature, expressions[i].value);
903
+ }
904
+ var not = mq.getNot();
905
+ return (test && !not || not && !test);
906
+ }
907
+ return test;
908
+ };
909
+
910
+ var testMediaQueryList = function (mql, ts) {
911
+ // ts is null or an array with any media type but 'all'.
912
+ var mqs = mql.getMediaQueries();
913
+ var t = {};
914
+ for (var i = 0; i < mqs.length; i++) {
915
+ var type = mqs[i].getMediaType();
916
+ if (mqs[i].getExpressions().length === 0) {
917
+ continue;
918
+ // TODO: Browser check! Assuming old browsers do apply the bare media types, even in a list with media queries.
919
+ }
920
+ var typeAllowed = true;
921
+ if (type !== 'all' && ts && ts.length > 0) {
922
+ typeAllowed = false;
923
+ for (var j = 0; j < ts.length; j++) {
924
+ if (ts[j] === type) {
925
+ typeAllowed = true;
926
+ }
927
+ }
928
+ }
929
+ if (typeAllowed && testMediaQuery(mqs[i])) {
930
+ t[type] = true;
931
+ }
932
+ }
933
+ var s = [], c = 0;
934
+ for (var n in t) {
935
+ if (t.hasOwnProperty(n)) {
936
+ if (c > 0) {
937
+ s[c++] = ',';
938
+ }
939
+ s[c++] = n;
940
+ }
941
+ }
942
+ if (s.length > 0) {
943
+ styles[styles.length] = cssHelper.addStyle('@media ' + s.join('') + '{' + mql.getCssText() + '}', ts, false);
944
+ }
945
+ };
946
+
947
+ var testMediaQueryLists = function (mqls, ts) {
948
+ for (var i = 0; i < mqls.length; i++) {
949
+ testMediaQueryList(mqls[i], ts);
950
+ }
951
+ };
952
+
953
+ var testStylesheet = function (stsh) {
954
+ var amqs = stsh.getAttrMediaQueries();
955
+ var allPassed = false;
956
+ var t = {};
957
+ for (var i = 0; i < amqs.length; i++) {
958
+ if (testMediaQuery(amqs[i])) {
959
+ t[amqs[i].getMediaType()] = amqs[i].getExpressions().length > 0;
960
+ }
961
+ }
962
+ var ts = [], tswe = [];
963
+ for (var n in t) {
964
+ if (t.hasOwnProperty(n)) {
965
+ ts[ts.length] = n;
966
+ if (t[n]) {
967
+ tswe[tswe.length] = n
968
+ }
969
+ if (n === 'all') {
970
+ allPassed = true;
971
+ }
972
+ }
973
+ }
974
+ if (tswe.length > 0) { // types with query expressions that passed the test
975
+ styles[styles.length] = cssHelper.addStyle(stsh.getCssText(), tswe, false);
976
+ }
977
+ var mqls = stsh.getMediaQueryLists();
978
+ if (allPassed) {
979
+ // If 'all' in media attribute passed the test, then test all @media types in linked CSS and create style with those types.
980
+ testMediaQueryLists(mqls);
981
+ }
982
+ else {
983
+ // Or else, test only media attribute types that passed the test and also 'all'.
984
+ // For positive '@media all', create style with attribute types that passed their test.
985
+ testMediaQueryLists(mqls, ts);
986
+ }
987
+ };
988
+
989
+ var testStylesheets = function (stshs) {
990
+ for (var i = 0; i < stshs.length; i++) {
991
+ testStylesheet(stshs[i]);
992
+ }
993
+ if (ua.ie) {
994
+ // force repaint in IE
995
+ document.documentElement.style.display = 'block';
996
+ setTimeout(function () {
997
+ document.documentElement.style.display = '';
998
+ }, 0);
999
+ // delay broadcast somewhat for IE
1000
+ setTimeout(function () {
1001
+ cssHelper.broadcast('cssMediaQueriesTested');
1002
+ }, 100);
1003
+ }
1004
+ else {
1005
+ cssHelper.broadcast('cssMediaQueriesTested');
1006
+ }
1007
+ };
1008
+
1009
+ var test = function () {
1010
+ for (var i = 0; i < styles.length; i++) {
1011
+ cssHelper.removeStyle(styles[i]);
1012
+ }
1013
+ styles = [];
1014
+ cssHelper.stylesheets(testStylesheets);
1015
+ };
1016
+
1017
+ var scrollbarWidth = 0;
1018
+ var checkForResize = function () {
1019
+ var cvpw = cssHelper.getViewportWidth();
1020
+ var cvph = cssHelper.getViewportHeight();
1021
+
1022
+ // determine scrollbar width in IE, see resizeHandler
1023
+ if (ua.ie) {
1024
+ var el = document.createElement('div');
1025
+ el.style.position = 'absolute';
1026
+ el.style.top = '-9999em';
1027
+ el.style.overflow = 'scroll';
1028
+ document.body.appendChild(el);
1029
+ scrollbarWidth = el.offsetWidth - el.clientWidth;
1030
+ document.body.removeChild(el);
1031
+ }
1032
+
1033
+ var timer;
1034
+ var resizeHandler = function () {
1035
+ var vpw = cssHelper.getViewportWidth();
1036
+ var vph = cssHelper.getViewportHeight();
1037
+ // check whether vp size has really changed, because IE also triggers resize event when body size changes
1038
+ // 20px allowance to accomodate short appearance of scrollbars in IE in some cases
1039
+ if (Math.abs(vpw - cvpw) > scrollbarWidth || Math.abs(vph - cvph) > scrollbarWidth) {
1040
+ cvpw = vpw;
1041
+ cvph = vph;
1042
+ clearTimeout(timer);
1043
+ timer = setTimeout(function () {
1044
+ if (!nativeSupport()) {
1045
+ test();
1046
+ }
1047
+ else {
1048
+ cssHelper.broadcast('cssMediaQueriesTested');
1049
+ }
1050
+ }, 500);
1051
+ }
1052
+ };
1053
+
1054
+ window.onresize = function () {
1055
+ var x = window.onresize || function () {}; // save original
1056
+ return function () {
1057
+ x();
1058
+ resizeHandler();
1059
+ };
1060
+ }();
1061
+ };
1062
+
1063
+ // prevent jumping of layout by hiding everything before painting <body>
1064
+ var docEl = document.documentElement;
1065
+ docEl.style.marginLeft = '-32767px';
1066
+
1067
+ // make sure it comes back after a while
1068
+ setTimeout(function () {
1069
+ docEl.style.marginLeft = '';
1070
+ }, 5000);
1071
+
1072
+ return function () {
1073
+ if (!nativeSupport()) { // if browser doesn't support media queries
1074
+ cssHelper.addListener('newStyleParsed', function (el) {
1075
+ testStylesheet(el.cssHelperParsed.stylesheet);
1076
+ });
1077
+ // return visibility after media queries are tested
1078
+ cssHelper.addListener('cssMediaQueriesTested', function () {
1079
+ // force repaint in IE by changing width
1080
+ if (ua.ie) {
1081
+ docEl.style.width = '1px';
1082
+ }
1083
+ setTimeout(function () {
1084
+ docEl.style.width = ''; // undo width
1085
+ docEl.style.marginLeft = ''; // undo hide
1086
+ }, 0);
1087
+ // remove this listener to prevent following execution
1088
+ cssHelper.removeListener('cssMediaQueriesTested', arguments.callee);
1089
+ });
1090
+ createMeter();
1091
+ test();
1092
+ }
1093
+ else {
1094
+ docEl.style.marginLeft = ''; // undo visibility hidden
1095
+ }
1096
+ checkForResize();
1097
+ };
1098
+ }());
1099
+
1100
+
1101
+ // bonus: hotfix for IE6 SP1 (bug KB823727)
1102
+ try {
1103
+ document.execCommand('BackgroundImageCache', false, true);
1104
+ } catch (e) {}
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: css3-mediaqueries-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Yuri Zubov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: railties
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ description: This gem adds css3-mediaqueries.js to the rails asset pipeline.
42
+ email:
43
+ - I0Result86@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - Gemfile
49
+ - LICENSE
50
+ - README.md
51
+ - Rakefile
52
+ - css3-mediaqueries-rails.gemspec
53
+ - lib/css3-mediaqueries-rails.rb
54
+ - lib/css3-mediaqueries/rails/engine.rb
55
+ - lib/css3-mediaqueries/rails/engine3.rb
56
+ - lib/css3-mediaqueries/rails/railtie.rb
57
+ - lib/css3-mediaqueries/rails/version.rb
58
+ - vendor/assets/javascripts/css3-mediaqueries.js
59
+ homepage: https://github.com/I0Result/css3-mediaqueries-rails
60
+ licenses:
61
+ - MIT
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 2.2.2
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: Add css3-mediaqueries to the rails asset pipeline
83
+ test_files: []