media-queries-callbacks 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
19
+ .idea/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in MediaQueriesCallbacks.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Vik Ewoods
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'MediaQueriesCallbacks/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'media-queries-callbacks'
8
+ gem.version = MediaQueriesCallbacks::VERSION
9
+ gem.authors = ['Vik Ewoods']
10
+ gem.email = ['me@vikewoods.com']
11
+ gem.description = %q{Awesome Media Queries in JavaScript}
12
+ gem.summary = %q{Media Queries Callbacks is a lightweight, pure javascript library (with no dependencies) for programmatically responding to media queries.}
13
+ gem.homepage = 'http://vikewoods.com/rails/media-queries'
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+ end
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ ##Full Details
2
+
3
+ Visit the [enquire.js project page](http://wickynilliams.github.com/enquire.js/) for full details of the API.
4
+
5
+ ##Quick Start
6
+
7
+ The main method you will be dealing with is `register`. It's basic signature is as follows:
8
+
9
+ ```javascript
10
+ enquire.register(query /* string */, handler /* object || array || function */);
11
+ ```
12
+
13
+ `query` is the CSS media query you wish to respond to, and `handler` is an object containing any logic to handle the query. An example of usage is as follows:
14
+
15
+ ```javascript
16
+ enquire.register("screen and (max-width:1000px)", {
17
+
18
+ match : function() {}, // REQUIRED
19
+ // Triggered when the media query transitions
20
+ // *from an unmatched to a matched state*
21
+
22
+ unmatch : function() {}, // OPTIONAL
23
+ // If supplied, triggered when the media query transitions
24
+ // *from a matched state to an unmatched state*.
25
+ // Also may be called when handler is unregistered (if destroy is not available)
26
+
27
+ setup : function() {}, // OPTIONAL
28
+ // If supplied, triggered once immediately upon registration of the handler
29
+
30
+ destroy : function() {}, // OPTIONAL
31
+ // If supplied, triggered when handler is unregistered. Place cleanup code here
32
+
33
+ deferSetup : true // OPTIONAL, defaults to false
34
+ // If set to true, defers execution the setup function
35
+ // until the media query is first matched. still triggered just once
36
+ }).fire();
37
+ ```
38
+
39
+
40
+ ## Installation
41
+
42
+ Add this line to your application's Gemfile:
43
+
44
+ gem 'media-queries-callbacks'
45
+
46
+ And then execute:
47
+
48
+ $ bundle
49
+
50
+ Or install it yourself as:
51
+
52
+ $ gem install media-queries-callbacks
53
+
54
+ ## Usage
55
+
56
+ TODO: Write usage instructions here
57
+
58
+ ## Contributing
59
+
60
+ 1. Fork it
61
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
62
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
63
+ 4. Push to the branch (`git push origin my-new-feature`)
64
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,6 @@
1
+ module MediaQueriesCallbacks
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module MediaQueriesCallbacks
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,3 @@
1
+ if defined? Rails && Rails::VERSION::MAJOR == 3 && Rails::VERSION::MINOR >= 1
2
+ require 'MediaQueriesCallbacks/engine'
3
+ end
@@ -0,0 +1,395 @@
1
+ // enquire.js v1.5.6 - Awesome Media Queries in JavaScript
2
+ // Copyright (c) 2013 Nick Williams - http://wicky.nillia.ms/enquire.js
3
+ // License: MIT (http://www.opensource.org/licenses/mit-license.php)
4
+
5
+
6
+ window.enquire = (function(matchMedia) {
7
+
8
+ "use strict";
9
+
10
+ /**
11
+ * Helper function for iterating over a collection
12
+ *
13
+ * @param collection
14
+ * @param fn
15
+ */
16
+ function each(collection, fn) {
17
+ var i = 0,
18
+ length = collection.length,
19
+ cont;
20
+
21
+ for(i; i < length; i++) {
22
+ cont = fn(collection[i], i);
23
+ if(cont === false) {
24
+ break; //allow early exit
25
+ }
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Helper function for determining whether target object is an array
31
+ *
32
+ * @param target the object under test
33
+ * @return {Boolean} true if array, false otherwise
34
+ */
35
+ function isArray(target) {
36
+ return Object.prototype.toString.apply(target) === "[object Array]";
37
+ }
38
+
39
+ /**
40
+ * Helper function for determining whether target object is a function
41
+ *
42
+ * @param target the object under test
43
+ * @return {Boolean} true if function, false otherwise
44
+ */
45
+ function isFunction(target) {
46
+ return typeof target === "function";
47
+ }
48
+
49
+ /**
50
+ * Delegate to handle a media query being matched and unmatched.
51
+ *
52
+ * @param {object} options
53
+ * @param {function} options.match callback for when the media query is matched
54
+ * @param {function} [options.unmatch] callback for when the media query is unmatched
55
+ * @param {function} [options.setup] one-time callback triggered the first time a query is matched
56
+ * @param {boolean} [options.deferSetup=false] should the setup callback be run immediately, rather than first time query is matched?
57
+ * @constructor
58
+ */
59
+ function QueryHandler(options) {
60
+ this.initialised = false;
61
+ this.options = options;
62
+
63
+ if(!options.deferSetup) {
64
+ this.setup();
65
+ }
66
+ }
67
+ QueryHandler.prototype = {
68
+
69
+ /**
70
+ * coordinates setup of the handler
71
+ *
72
+ * @function
73
+ */
74
+ setup : function(e) {
75
+ if(this.options.setup){
76
+ this.options.setup(e);
77
+ }
78
+ this.initialised = true;
79
+ },
80
+
81
+ /**
82
+ * coordinates setup and triggering of the handler
83
+ *
84
+ * @function
85
+ * @param [e] the browser event which triggered a match
86
+ */
87
+ on : function(e) {
88
+ if(!this.initialised){
89
+ this.setup(e);
90
+ }
91
+ this.options.match(e);
92
+ },
93
+
94
+ /**
95
+ * coordinates the unmatch event for the handler
96
+ *
97
+ * @function
98
+ * @param [e] the browser event which triggered a match
99
+ */
100
+ off : function(e) {
101
+ if(this.options.unmatch){
102
+ this.options.unmatch(e);
103
+ }
104
+ },
105
+
106
+ /**
107
+ * called when a handler is to be destroyed.
108
+ * delegates to the destroy or unmatch callbacks, depending on availability.
109
+ *
110
+ * @function
111
+ */
112
+ destroy : function() {
113
+ if(this.options.destroy) {
114
+ this.options.destroy();
115
+ }
116
+ else {
117
+ this.off();
118
+ }
119
+ },
120
+
121
+ /**
122
+ * determines equality by reference.
123
+ * if object is supplied compare options, if function, compare match callback
124
+ *
125
+ * @function
126
+ * @param {object || function} [target] the target for comparison
127
+ */
128
+ equals : function(target) {
129
+ return this.options === target || this.options.match === target;
130
+ }
131
+
132
+ };
133
+ /**
134
+ * Represents a single media query, manages it's state and registered handlers for this query
135
+ *
136
+ * @constructor
137
+ * @param {string} query the media query string
138
+ * @param {boolean} [isUnconditional=false] whether the media query should run regardless of whether the conditions are met. Primarily for helping older browsers deal with mobile-first design
139
+ */
140
+ function MediaQuery(query, isUnconditional) {
141
+ this.query = query;
142
+ this.isUnconditional = isUnconditional;
143
+
144
+ this.handlers = [];
145
+ this.matched = false;
146
+ }
147
+ MediaQuery.prototype = {
148
+
149
+ /**
150
+ * tests whether this media query is currently matching
151
+ *
152
+ * @function
153
+ * @returns {boolean} true if match, false otherwise
154
+ */
155
+ matchMedia : function() {
156
+ return matchMedia(this.query).matches;
157
+ },
158
+
159
+ /**
160
+ * add a handler for this query, triggering if already active
161
+ *
162
+ * @function
163
+ * @param {object} handler
164
+ * @param {function} handler.match callback for when query is activated
165
+ * @param {function} [handler.unmatch] callback for when query is deactivated
166
+ * @param {function} [handler.setup] callback for immediate execution when a query handler is registered
167
+ * @param {boolean} [handler.deferSetup=false] should the setup callback be deferred until the first time the handler is matched?
168
+ * @param {boolean} [turnOn=false] should the handler be turned on if the query is matching?
169
+ */
170
+ addHandler : function(handler, turnOn) {
171
+ var qh = new QueryHandler(handler);
172
+ this.handlers.push(qh);
173
+
174
+ turnOn && this.matched && qh.on();
175
+ },
176
+
177
+ /**
178
+ * removes the given handler from the collection, and calls it's destroy methods
179
+ *
180
+ * @function
181
+ * @param {object || function} handler the handler to remove
182
+ */
183
+ removeHandler : function(handler) {
184
+ var handlers = this.handlers;
185
+ each(handlers, function(h, i) {
186
+ if(h.equals(handler)) {
187
+ h.destroy();
188
+ return !handlers.splice(i,1); //remove from array and exit each early
189
+ }
190
+ });
191
+ },
192
+
193
+ /*
194
+ * assesses the query, turning on all handlers if it matches, turning them off if it doesn't match
195
+ *
196
+ * @function
197
+ */
198
+ assess : function(e) {
199
+ if(this.matchMedia() || this.isUnconditional) {
200
+ this.match(e);
201
+ }
202
+ else {
203
+ this.unmatch(e);
204
+ }
205
+ },
206
+
207
+ /**
208
+ * activates a query.
209
+ * callbacks are fired only if the query is currently unmatched
210
+ *
211
+ * @function
212
+ * @param {Event} [e] browser event if triggered as the result of a browser event
213
+ */
214
+ match : function(e) {
215
+ if(this.matched) {
216
+ return; //already on
217
+ }
218
+
219
+ each(this.handlers, function(handler) {
220
+ handler.on(e);
221
+ });
222
+ this.matched = true;
223
+ },
224
+
225
+ /**
226
+ * deactivates a query.
227
+ * callbacks are fired only if the query is currently matched
228
+ *
229
+ * @function
230
+ * @param {Event} [e] browser event if triggered as the result of a browser event
231
+ */
232
+ unmatch : function(e) {
233
+ if(!this.matched) {
234
+ return; //already off
235
+ }
236
+
237
+ each(this.handlers, function(handler){
238
+ handler.off(e);
239
+ });
240
+ this.matched = false;
241
+ }
242
+ };
243
+ /**
244
+ * Allows for reigstration of query handlers.
245
+ * Manages the query handler's state and is responsible for wiring up browser events
246
+ *
247
+ * @constructor
248
+ */
249
+ function MediaQueryDispatch () {
250
+ if(!matchMedia) {
251
+ throw new Error('matchMedia is required');
252
+ }
253
+
254
+ var capabilityTest = new MediaQuery('only all');
255
+ this.queries = {};
256
+ this.listening = false;
257
+ this.browserIsIncapable = !capabilityTest.matchMedia();
258
+ }
259
+
260
+ MediaQueryDispatch.prototype = {
261
+
262
+ /**
263
+ * Registers a handler for the given media query
264
+ *
265
+ * @function
266
+ * @param {string} q the media query
267
+ * @param {object || Array || Function} options either a single query handler object, a function, or an array of query handlers
268
+ * @param {function} options.match fired when query matched
269
+ * @param {function} [options.unmatch] fired when a query is no longer matched
270
+ * @param {function} [options.setup] fired when handler first triggered
271
+ * @param {boolean} [options.deferSetup=false] whether setup should be run immediately or deferred until query is first matched
272
+ * @param {boolean} [shouldDegrade=false] whether this particular media query should always run on incapable browsers
273
+ */
274
+ register : function(q, options, shouldDegrade) {
275
+ var queries = this.queries,
276
+ isUnconditional = shouldDegrade && this.browserIsIncapable,
277
+ listening = this.listening;
278
+
279
+ if(!queries.hasOwnProperty(q)) {
280
+ queries[q] = new MediaQuery(q, isUnconditional);
281
+
282
+ this.listening && queries[q].assess();
283
+ }
284
+
285
+ //normalise to object
286
+ if(isFunction(options)) {
287
+ options = {
288
+ match : options
289
+ };
290
+ }
291
+ //normalise to array
292
+ if(!isArray(options)) {
293
+ options = [options];
294
+ }
295
+ each(options, function(handler) {
296
+ queries[q].addHandler(handler, listening);
297
+ });
298
+
299
+ return this;
300
+ },
301
+
302
+ /**
303
+ * unregisters a query and all it's handlers, or a specific handler for a query
304
+ *
305
+ * @function
306
+ * @param {string} q the media query to target
307
+ * @param {object || function} [handler] specific handler to unregister
308
+ */
309
+ unregister : function(q, handler) {
310
+ var queries = this.queries;
311
+
312
+ if(!queries.hasOwnProperty(q)) {
313
+ return this;
314
+ }
315
+
316
+ if(!handler) {
317
+ each(this.queries[q].handlers, function(handler) {
318
+ handler.destroy();
319
+ });
320
+ delete queries[q];
321
+ }
322
+ else {
323
+ queries[q].removeHandler(handler);
324
+ }
325
+
326
+ return this;
327
+ },
328
+
329
+ /**
330
+ * Tests all media queries and calls relevant methods depending whether
331
+ * transitioning from unmatched->matched or matched->unmatched
332
+ *
333
+ * @function
334
+ * @param {Event} [e] if fired as a result of a browser event,
335
+ * an event can be supplied to propagate to the various media query handlers
336
+ */
337
+ fire : function(e) {
338
+ var queries = this.queries,
339
+ mediaQuery;
340
+
341
+ for(mediaQuery in queries) {
342
+ if(queries.hasOwnProperty(mediaQuery)) {
343
+ queries[mediaQuery].assess(e);
344
+ }
345
+ }
346
+ return this;
347
+ },
348
+
349
+ /**
350
+ * sets up listeners for resize and orientation events
351
+ *
352
+ * @function
353
+ * @param {int} [timeout=500] the time (in milliseconds) after which the queries should be handled
354
+ */
355
+ listen : function(timeout) {
356
+ var self = this;
357
+
358
+ timeout = timeout || 500;
359
+
360
+ //creates closure for separate timed events
361
+ function wireFire(event) {
362
+ var timer;
363
+
364
+ window.addEventListener(event, function(e) {
365
+ timer && clearTimeout(timer);
366
+
367
+ timer = setTimeout(function() {
368
+ self.fire(e);
369
+ }, timeout);
370
+ }, false);
371
+ }
372
+
373
+ //prevent multiple event handlers
374
+ if(this.listening) {
375
+ return this;
376
+ }
377
+
378
+ // any browser that doesn't implement this
379
+ // will not have media query support
380
+ if(window.addEventListener) {
381
+ wireFire('resize');
382
+ wireFire('orientationChange');
383
+ }
384
+
385
+ self.fire();
386
+ this.listening = true;
387
+
388
+ return this;
389
+ }
390
+ };
391
+
392
+
393
+ return new MediaQueryDispatch();
394
+
395
+ }(window.matchMedia));
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: media-queries-callbacks
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Vik Ewoods
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-07 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Awesome Media Queries in JavaScript
15
+ email:
16
+ - me@vikewoods.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - Gemfile
23
+ - LICENSE.txt
24
+ - MediaQueriesCallbacks.gemspec
25
+ - README.md
26
+ - Rakefile
27
+ - lib/MediaQueriesCallbacks.rb
28
+ - lib/MediaQueriesCallbacks/engine.rb
29
+ - lib/MediaQueriesCallbacks/version.rb
30
+ - vendor/assets/javascripts/enquire.js
31
+ homepage: http://vikewoods.com/rails/media-queries
32
+ licenses: []
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubyforge_project:
51
+ rubygems_version: 1.8.25
52
+ signing_key:
53
+ specification_version: 3
54
+ summary: Media Queries Callbacks is a lightweight, pure javascript library (with no
55
+ dependencies) for programmatically responding to media queries.
56
+ test_files: []
57
+ has_rdoc: