css3-mediaqueries-rails 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []