visibilityjs 1.1.0 → 1.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7a9ba4d047ee0acc40d0d22d42616c46bd4bfb51
4
- data.tar.gz: f663938cead70fd0e1059d7a8f0183712f55e77e
3
+ metadata.gz: 67bc18a7e786dbc5e14e5c26e95f4afea84b89c9
4
+ data.tar.gz: 6a747d0bbac0a17f58bb2f468a671b99ff7fd5c4
5
5
  SHA512:
6
- metadata.gz: b4ffa46278c837e7aeae670815bde746294c3c52c6ab900677aa4077efaf57bdf1565855903684bc3327d2b51d3b183834d6939fabb4cc73a5ce86e06aff6022
7
- data.tar.gz: c55f49573bc8cf75db252692e4a57f2d4d7385f2b409fa72c0c40fa0b3148b8d9c4d992270d7b6e972bfcdeb1351a07ebc774c89aac96f2a7e42249555b59e78
6
+ metadata.gz: 475e0c05d111b930c38e6adb18c566a962819702d8f26e1e5a629a73e4b45cb044ac47c29815bb50fee151f9f58ff1969eb7503497bb3e5e4be33d767631f632
7
+ data.tar.gz: 0037c05474dde93f3bb1fa7fbb14d9d6d3e2a74b290ce25ad67512f9c1fb66cd8d50a51bc02132a1ed1b71e30bbf9b2719b7a3a0706cf3125c90f82154a3d000
@@ -1,3 +1,11 @@
1
+ ### 1.2.0 “Discoverer 5, spy”
2
+ * Allow to use in CommonJS.
3
+ * Release npm package.
4
+ * Reduce library size to 10 %.
5
+ * Allow to use latest version from master in Ruby Bundler.
6
+ * Method `hidden()` now always return boolean.
7
+ * Change repository URL to `github.com/ai/visibilityjs`.
8
+
1
9
  ## 1.1.0 “Explorer 6, photo”
2
10
  * Prevent to run timer often, that it’s interval, when visibility was changed.
3
11
  * Allow to install by Bower package manager.
@@ -8,7 +16,7 @@
8
16
  * Remove jQuery.Chrono integration.
9
17
  * Remove outdated Firefox prefix.
10
18
 
11
- ## 0.6.2 “Pioneer 4, american sun
19
+ ## 0.6.2 “Pioneer 4, American Sun
12
20
  * Decrease files size (by compressible code and UnglifyJS 2).
13
21
  * Remove unnecessary vendor prefixes from fallback.
14
22
 
@@ -17,7 +25,7 @@
17
25
 
18
26
  ## 0.6 “Luna 1, Mechta”
19
27
  * Methods onVisible and afterPrerendering return listener ID (by mcfedr).
20
- * Fix documentation (by Erwann Mest).
28
+ * Fix documentation (by Erwänn Mest).
21
29
 
22
30
  ## 0.5 “SCORE, communication”
23
31
  * Split library to core and timers modules.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Visibility.js
2
2
 
3
- <img align="right" width="100" src="http://ai.github.io/visibility.js/logo.svg" title="Visibility.js logo by Eugenia Tuchapets">
3
+ <img align="right" width="100" src="http://ai.github.io/visibilityjs/logo.svg" title="Visibility.js logo by Eugenia Tuchapets">
4
4
 
5
5
  Visibility.js is a wrapper for the [Page Visibility API]. It hides vendor prefixes and adds high level functions.
6
6
 
@@ -292,7 +292,7 @@ Add to your site:
292
292
  ### Other
293
293
 
294
294
  If you need just a files, you can take already minified packages from
295
- [github.com/ai/visibility.js/releases](https://github.com/ai/visibility.js/releases).
295
+ [github.com/ai/visibilityjs/releases](https://github.com/ai/visibilityjs/releases).
296
296
 
297
297
  ## Contributing
298
298
 
@@ -1,15 +1,13 @@
1
- ;(function (undefined) {
1
+ ;(function (global) {
2
2
  "use strict";
3
3
 
4
- var defined = function (variable) {
5
- return (variable != undefined);
6
- };
4
+ var lastId = -1;
7
5
 
8
6
  // Visibility.js allow you to know, that your web page is in the background
9
7
  // tab and thus not visible to the user. This library is wrap under
10
8
  // Page Visibility API. It fix problems with different vendor prefixes and
11
9
  // add high-level useful functions.
12
- var self = window.Visibility = {
10
+ var self = {
13
11
 
14
12
  // Call callback only when page become to visible for user or
15
13
  // call it now if page is visible now or Page Visibility API
@@ -23,9 +21,10 @@
23
21
  // startIntroAnimation();
24
22
  // });
25
23
  onVisible: function (callback) {
26
- if ( !self.isSupported() || !self.hidden() ) {
24
+ var support = self.isSupported();
25
+ if ( !support || !self.hidden() ) {
27
26
  callback();
28
- return self.isSupported();
27
+ return support;
29
28
  }
30
29
 
31
30
  var listener = self.change(function (e, state) {
@@ -55,8 +54,8 @@
55
54
  if ( !self.isSupported() ) {
56
55
  return false;
57
56
  }
58
- self._lastId += 1;
59
- var number = self._lastId;
57
+ lastId += 1;
58
+ var number = lastId;
60
59
  self._callbacks[number] = callback;
61
60
  self._listen();
62
61
  return number;
@@ -85,13 +84,16 @@
85
84
  // Statistics.countVisitor();
86
85
  // });
87
86
  afterPrerendering: function (callback) {
88
- if ( !self.isSupported() || 'prerender' != self.state() ) {
87
+ var support = self.isSupported();
88
+ var prerender = 'prerender';
89
+
90
+ if ( !support || prerender != self.state() ) {
89
91
  callback();
90
- return self.isSupported();
92
+ return support;
91
93
  }
92
94
 
93
95
  var listener = self.change(function (e, state) {
94
- if ( 'prerender' != state ) {
96
+ if ( prerender != state ) {
95
97
  self.unbind(listener);
96
98
  callback();
97
99
  }
@@ -107,7 +109,7 @@
107
109
  //
108
110
  // It is just proxy to `document.hidden`, but use vendor prefix.
109
111
  hidden: function () {
110
- return self._prop('hidden', false);
112
+ return !!(self._doc.hidden || self._doc.webkitHidden);
111
113
  },
112
114
 
113
115
  // Return visibility state: 'visible', 'hidden' or 'prerender'.
@@ -123,7 +125,9 @@
123
125
  // It is just proxy to `document.visibilityState`, but use
124
126
  // vendor prefix.
125
127
  state: function () {
126
- return self._prop('visibilityState', 'visible');
128
+ return self._doc.visibilityState ||
129
+ self._doc.webkitVisibilityState ||
130
+ 'visible';
127
131
  },
128
132
 
129
133
  // Return true if browser support Page Visibility API.
@@ -135,66 +139,16 @@
135
139
  // });
136
140
  // }
137
141
  isSupported: function () {
138
- return defined(self._prefix());
142
+ return !!(self._doc.visibilityState ||
143
+ self._doc.webkitVisibilityState);
139
144
  },
140
145
 
141
146
  // Link to document object to change it in tests.
142
- _doc: window.document,
143
-
144
- // Vendor prefix cached by `_prefix` function.
145
- _cached: null,
146
-
147
- // Is listener for `visibilitychange` event is already added
148
- // by `_listen` method.
149
- _enable: false,
150
-
151
- // Last timer number.
152
- _lastId: -1,
147
+ _doc: document || {},
153
148
 
154
149
  // Callbacks from `change` method, that wait visibility changes.
155
150
  _callbacks: { },
156
151
 
157
- // Variable to check hidden-visible state changes.
158
- _wasHidden: false,
159
-
160
- // Initialize variables on page loading.
161
- _init: function () {
162
- self._wasHidden = self.hidden();
163
- },
164
-
165
- // Detect vendor prefix and return it.
166
- _prefix: function () {
167
- if ( null !== self._cached ) {
168
- return self._cached;
169
- }
170
- if ( defined(self._doc.visibilityState) ) {
171
- return self._cached = '';
172
- }
173
- if ( defined(self._doc.webkitVisibilityState) ) {
174
- return self._cached = 'webkit';
175
- }
176
- },
177
-
178
- // Return property name with vendor prefix.
179
- _name: function (name) {
180
- var prefix = self._prefix();
181
- if ( '' == prefix ) {
182
- return name;
183
- } else {
184
- return prefix +
185
- name.substr(0, 1).toUpperCase() + name.substr(1);
186
- }
187
- },
188
-
189
- // Return document’s property value with name with vendor prefix.
190
- // If API is not support, it will retun `unsupported` value.
191
- _prop: function (name, unsupported) {
192
- if ( !self.isSupported() ) {
193
- return unsupported;
194
- }
195
- return self._doc[self._name(name)];
196
- },
197
-
198
152
  // Listener for `visibilitychange` event.
199
153
  _change: function(event) {
200
154
  var state = self.state();
@@ -202,30 +156,36 @@
202
156
  for ( var i in self._callbacks ) {
203
157
  self._callbacks[i].call(self._doc, event, state);
204
158
  }
205
-
206
- self._wasHidden = self.hidden();
207
159
  },
208
160
 
209
161
  // Set listener for `visibilitychange` event.
210
162
  _listen: function () {
211
- if ( self._enable ) {
163
+ if ( self._init ) {
212
164
  return;
213
165
  }
214
- var event = self._prefix() + 'visibilitychange';
166
+
167
+ var event = 'visibilitychange';
168
+ if ( self._doc.webkitVisibilityState ) {
169
+ event = 'webkit' + event;
170
+ }
171
+
215
172
  var listener = function () {
216
- self._change.apply(Visibility, arguments);
173
+ self._change.apply(self, arguments);
217
174
  };
218
175
  if ( self._doc.addEventListener ) {
219
- self._doc.addEventListener(event, listener, false);
176
+ self._doc.addEventListener(event, listener);
220
177
  } else {
221
178
  self._doc.attachEvent(event, listener);
222
179
  }
223
- self._enable = true;
224
- self._wasHidden = self.hidden();
180
+ self._init = true;
225
181
  }
226
182
 
227
183
  };
228
184
 
229
- self._init();
185
+ if ( typeof(module) != 'undefined' && module.exports ) {
186
+ module.exports = self;
187
+ } else {
188
+ global.Visibility = self;
189
+ }
230
190
 
231
- })();
191
+ })(this);
@@ -8,7 +8,7 @@
8
8
  //
9
9
  // For Firefox 5–9 it will be better to use MozVisibility hack without
10
10
  // this issue. See <https://github.com/private-face/mozvisibility>.
11
- ;(function () {
11
+ ;(function (document) {
12
12
  "use strict";
13
13
 
14
14
  if ( document.visibilityState || document.webkitVisibilityState ) {
@@ -34,22 +34,22 @@
34
34
  }
35
35
  }
36
36
 
37
- var onfocus = function () {
37
+ var onFocus = function () {
38
38
  document.hidden = false;
39
39
  document.visibilityState = 'visible';
40
40
  fireEvent();
41
41
  };
42
- var onblur = function () {
42
+ var onBlur = function () {
43
43
  document.hidden = true;
44
44
  document.visibilityState = 'hidden';
45
45
  fireEvent();
46
46
  }
47
47
 
48
48
  if ( document.addEventListener ) {
49
- window.addEventListener('focus', onfocus, true);
50
- window.addEventListener('blur', onblur, true);
49
+ window.addEventListener('focus', onFocus, true);
50
+ window.addEventListener('blur', onBlur, true);
51
51
  } else {
52
- document.attachEvent('onfocusin', onfocus);
53
- document.attachEvent('onfocusout', onblur);
52
+ document.attachEvent('onfocusin', onFocus);
53
+ document.attachEvent('onfocusout', onBlur);
54
54
  }
55
- })();
55
+ })(document);
@@ -0,0 +1,4 @@
1
+ // File for Rails Assets Pipeline
2
+
3
+ //= require visibility.core
4
+ //= require visibility.timers
@@ -1,13 +1,9 @@
1
- ;(function () {
1
+ ;(function (window) {
2
2
  "use strict";
3
3
 
4
- var defined = function(variable) {
5
- return ('undefined' != typeof(variable));
6
- };
4
+ var lastTimer = -1;
7
5
 
8
- var self = Visibility;
9
-
10
- var timers = {
6
+ var install = function (Visibility) {
11
7
 
12
8
  // Run callback every `interval` milliseconds if page is visible and
13
9
  // every `hiddenInterval` milliseconds if page is hidden.
@@ -32,29 +28,29 @@
32
28
  // so don’t use it in `clearInterval`.
33
29
  //
34
30
  // On change state from hidden to visible timers will be execute.
35
- every: function (interval, hiddenInterval, callback) {
36
- self._time();
31
+ Visibility.every = function (interval, hiddenInterval, callback) {
32
+ Visibility._time();
37
33
 
38
- if ( !defined(callback) ) {
34
+ if ( !callback ) {
39
35
  callback = hiddenInterval;
40
36
  hiddenInterval = null;
41
37
  }
42
38
 
43
- self._lastTimer += 1;
44
- var number = self._lastTimer;
39
+ lastTimer += 1;
40
+ var number = lastTimer;
45
41
 
46
- self._timers[number] = {
42
+ Visibility._timers[number] = {
47
43
  visible: interval,
48
44
  hidden: hiddenInterval,
49
45
  callback: callback
50
46
  };
51
- self._run(number, false);
47
+ Visibility._run(number, false);
52
48
 
53
- if ( self.isSupported() ) {
54
- self._listen();
49
+ if ( Visibility.isSupported() ) {
50
+ Visibility._listen();
55
51
  }
56
52
  return number;
57
- },
53
+ };
58
54
 
59
55
  // Stop timer from `every` method by it ID (`every` method return it).
60
56
  //
@@ -64,36 +60,31 @@
64
60
  // $('.stopSlideshow').click(function () {
65
61
  // Visibility.stop(slideshow);
66
62
  // });
67
- stop: function(id) {
68
- var timer = self._timers[id]
69
- if ( !defined(timer) ) {
63
+ Visibility.stop = function(id) {
64
+ if ( !Visibility._timers[id] ) {
70
65
  return false;
71
66
  }
72
- self._stop(id);
73
- delete self._timers[id];
74
- return timer;
75
- },
76
-
77
- // Last timer number.
78
- _lastTimer: -1,
67
+ Visibility._stop(id);
68
+ delete Visibility._timers[id];
69
+ return true;
70
+ };
79
71
 
80
72
  // Callbacks and intervals added by `every` method.
81
- _timers: { },
82
-
83
- // Is setInterval method detected and listener is binded.
84
- _timed: false,
73
+ Visibility._timers = { };
85
74
 
86
75
  // Initialize variables on page loading.
87
- _time: function () {
88
- if ( self._timed ) {
76
+ Visibility._time = function () {
77
+ if ( Visibility._timed ) {
89
78
  return;
90
79
  }
91
- self._timed = true;
80
+ Visibility._timed = true;
81
+ Visibility._wasHidden = Visibility.hidden();
92
82
 
93
- self.change(function () {
94
- self._stopRun()
83
+ Visibility.change(function () {
84
+ Visibility._stopRun();
85
+ Visibility._wasHidden = Visibility.hidden();
95
86
  });
96
- },
87
+ };
97
88
 
98
89
  // Try to run timer from every method by it’s ID. It will be use
99
90
  // `interval` or `hiddenInterval` depending on visibility state.
@@ -101,10 +92,11 @@
101
92
  // it will not run timer.
102
93
  //
103
94
  // Argument `runNow` say, that timers must be execute now too.
104
- _run: function (id, runNow) {
95
+ Visibility._run = function (id, runNow) {
105
96
  var interval,
106
- timer = self._timers[id];
107
- if ( self.hidden() ) {
97
+ timer = Visibility._timers[id];
98
+
99
+ if ( Visibility.hidden() ) {
108
100
  if ( null === timer.hidden ) {
109
101
  return;
110
102
  }
@@ -135,34 +127,37 @@
135
127
  } else {
136
128
  timer.id = setInterval(runner, interval);
137
129
  }
138
- },
130
+ };
139
131
 
140
132
  // Stop timer from `every` method by it’s ID.
141
- _stop: function (id) {
142
- var timer = self._timers[id];
133
+ Visibility._stop = function (id) {
134
+ var timer = Visibility._timers[id];
143
135
  clearInterval(timer.id);
144
136
  clearTimeout(timer.delay);
145
137
  delete timer.id;
146
138
  delete timer.delay;
147
- },
139
+ };
148
140
 
149
141
  // Listener for `visibilitychange` event.
150
- _stopRun: function (event) {
151
- var isHidden = self.hidden(),
152
- wasHidden = self._wasHidden;
142
+ Visibility._stopRun = function (event) {
143
+ var isHidden = Visibility.hidden(),
144
+ wasHidden = Visibility._wasHidden;
153
145
 
154
146
  if ( (isHidden && !wasHidden) || (!isHidden && wasHidden) ) {
155
- for ( var i in self._timers ) {
156
- self._stop(i);
157
- self._run(i, !isHidden);
147
+ for ( var i in Visibility._timers ) {
148
+ Visibility._stop(i);
149
+ Visibility._run(i, !isHidden);
158
150
  }
159
151
  }
160
- }
152
+ };
161
153
 
162
- };
154
+ return Visibility;
155
+ }
163
156
 
164
- for ( var prop in timers ) {
165
- Visibility[prop] = timers[prop];
157
+ if ( typeof(module) != 'undefined' && module.exports ) {
158
+ module.exports = install(require('./visibility.core'));
159
+ } else {
160
+ install(window.Visibility)
166
161
  }
167
162
 
168
- })();
163
+ })(window);
@@ -1,8 +1,17 @@
1
1
  # Used only for Ruby on Rails gem to tell, that gem contain `lib/assets` with
2
2
  # visibility.js file.
3
3
  module VisibilityJs
4
+
5
+ # Add assets paths to standalone Sprockets environment.
6
+ def self.install(sprockets)
7
+ sprockets.append_path(Pathname(__FILE__).dirname)
8
+ end
9
+
4
10
  module Rails
5
11
  class Engine < ::Rails::Engine
12
+ initializer 'visibilityjs' do
13
+ VisibilityJs.install(::Rails.application.assets)
14
+ end
6
15
  end
7
16
  end
8
17
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: visibilityjs
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Sitnik
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-06 00:00:00.000000000 Z
11
+ date: 2014-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sprockets
@@ -39,12 +39,12 @@ files:
39
39
  - ChangeLog.md
40
40
  - LICENSE
41
41
  - README.md
42
- - lib/assets/javascripts/visibility.core.js
43
- - lib/assets/javascripts/visibility.fallback.js
44
- - lib/assets/javascripts/visibility.js
45
- - lib/assets/javascripts/visibility.timers.js
42
+ - lib/visibility.core.js
43
+ - lib/visibility.fallback.js
44
+ - lib/visibility.js
45
+ - lib/visibility.timers.js
46
46
  - lib/visibilityjs.rb
47
- homepage: https://github.com/ai/visibility.js
47
+ homepage: https://github.com/ai/visibilityjs
48
48
  licenses:
49
49
  - MIT
50
50
  metadata: {}
@@ -64,8 +64,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
64
  version: '0'
65
65
  requirements: []
66
66
  rubyforge_project:
67
- rubygems_version: 2.2.0
67
+ rubygems_version: 2.2.2
68
68
  signing_key:
69
69
  specification_version: 4
70
- summary: Visibility.js - a wrapper for the Page Visibility API.
70
+ summary: Wrapper for the Page Visibility API
71
71
  test_files: []
@@ -1,390 +0,0 @@
1
- ;(function (undefined) {
2
- "use strict";
3
-
4
- var defined = function (variable) {
5
- return (variable != undefined);
6
- };
7
-
8
- // Visibility.js allow you to know, that your web page is in the background
9
- // tab and thus not visible to the user. This library is wrap under
10
- // Page Visibility API. It fix problems with different vendor prefixes and
11
- // add high-level useful functions.
12
- var self = window.Visibility = {
13
-
14
- // Call callback only when page become to visible for user or
15
- // call it now if page is visible now or Page Visibility API
16
- // doesn’t supported.
17
- //
18
- // Return false if API isn’t supported, true if page is already visible
19
- // or listener ID (you can use it in `unbind` method) if page isn’t
20
- // visible now.
21
- //
22
- // Visibility.onVisible(function () {
23
- // startIntroAnimation();
24
- // });
25
- onVisible: function (callback) {
26
- if ( !self.isSupported() || !self.hidden() ) {
27
- callback();
28
- return self.isSupported();
29
- }
30
-
31
- var listener = self.change(function (e, state) {
32
- if ( !self.hidden() ) {
33
- self.unbind(listener);
34
- callback();
35
- }
36
- });
37
- return listener;
38
- },
39
-
40
- // Call callback when visibility will be changed. First argument for
41
- // callback will be original event object, second will be visibility
42
- // state name.
43
- //
44
- // Return listener ID to unbind listener by `unbind` method.
45
- //
46
- // If Page Visibility API doesn’t supported method will be return false
47
- // and callback never will be called.
48
- //
49
- // Visibility.change(function(e, state) {
50
- // Statistics.visibilityChange(state);
51
- // });
52
- //
53
- // It is just proxy to `visibilitychange` event, but use vendor prefix.
54
- change: function (callback) {
55
- if ( !self.isSupported() ) {
56
- return false;
57
- }
58
- self._lastId += 1;
59
- var number = self._lastId;
60
- self._callbacks[number] = callback;
61
- self._listen();
62
- return number;
63
- },
64
-
65
- // Remove `change` listener by it ID.
66
- //
67
- // var id = Visibility.change(function(e, state) {
68
- // firstChangeCallback();
69
- // Visibility.unbind(id);
70
- // });
71
- unbind: function (id) {
72
- delete self._callbacks[id];
73
- },
74
-
75
- // Call `callback` in any state, expect “prerender”. If current state
76
- // is “prerender” it will wait until state will be changed.
77
- // If Page Visibility API doesn’t supported, it will call `callback`
78
- // immediately.
79
- //
80
- // Return false if API isn’t supported, true if page is already after
81
- // prerendering or listener ID (you can use it in `unbind` method)
82
- // if page is prerended now.
83
- //
84
- // Visibility.afterPrerendering(function () {
85
- // Statistics.countVisitor();
86
- // });
87
- afterPrerendering: function (callback) {
88
- if ( !self.isSupported() || 'prerender' != self.state() ) {
89
- callback();
90
- return self.isSupported();
91
- }
92
-
93
- var listener = self.change(function (e, state) {
94
- if ( 'prerender' != state ) {
95
- self.unbind(listener);
96
- callback();
97
- }
98
- });
99
- return listener;
100
- },
101
-
102
- // Return true if page now isn’t visible to user.
103
- //
104
- // if ( !Visibility.hidden() ) {
105
- // VideoPlayer.play();
106
- // }
107
- //
108
- // It is just proxy to `document.hidden`, but use vendor prefix.
109
- hidden: function () {
110
- return self._prop('hidden', false);
111
- },
112
-
113
- // Return visibility state: 'visible', 'hidden' or 'prerender'.
114
- //
115
- // if ( 'prerender' == Visibility.state() ) {
116
- // Statistics.pageIsPrerendering();
117
- // }
118
- //
119
- // Don’t use `Visibility.state()` to detect, is page visible, because
120
- // visibility states can extend in next API versions.
121
- // Use more simpler and general `Visibility.hidden()` for this cases.
122
- //
123
- // It is just proxy to `document.visibilityState`, but use
124
- // vendor prefix.
125
- state: function () {
126
- return self._prop('visibilityState', 'visible');
127
- },
128
-
129
- // Return true if browser support Page Visibility API.
130
- //
131
- // if ( Visibility.isSupported() ) {
132
- // Statistics.startTrackingVisibility();
133
- // Visibility.change(function(e, state)) {
134
- // Statistics.trackVisibility(state);
135
- // });
136
- // }
137
- isSupported: function () {
138
- return defined(self._prefix());
139
- },
140
-
141
- // Link to document object to change it in tests.
142
- _doc: window.document,
143
-
144
- // Vendor prefix cached by `_prefix` function.
145
- _cached: null,
146
-
147
- // Is listener for `visibilitychange` event is already added
148
- // by `_listen` method.
149
- _enable: false,
150
-
151
- // Last timer number.
152
- _lastId: -1,
153
-
154
- // Callbacks from `change` method, that wait visibility changes.
155
- _callbacks: { },
156
-
157
- // Variable to check hidden-visible state changes.
158
- _wasHidden: false,
159
-
160
- // Initialize variables on page loading.
161
- _init: function () {
162
- self._wasHidden = self.hidden();
163
- },
164
-
165
- // Detect vendor prefix and return it.
166
- _prefix: function () {
167
- if ( null !== self._cached ) {
168
- return self._cached;
169
- }
170
- if ( defined(self._doc.visibilityState) ) {
171
- return self._cached = '';
172
- }
173
- if ( defined(self._doc.webkitVisibilityState) ) {
174
- return self._cached = 'webkit';
175
- }
176
- },
177
-
178
- // Return property name with vendor prefix.
179
- _name: function (name) {
180
- var prefix = self._prefix();
181
- if ( '' == prefix ) {
182
- return name;
183
- } else {
184
- return prefix +
185
- name.substr(0, 1).toUpperCase() + name.substr(1);
186
- }
187
- },
188
-
189
- // Return document’s property value with name with vendor prefix.
190
- // If API is not support, it will retun `unsupported` value.
191
- _prop: function (name, unsupported) {
192
- if ( !self.isSupported() ) {
193
- return unsupported;
194
- }
195
- return self._doc[self._name(name)];
196
- },
197
-
198
- // Listener for `visibilitychange` event.
199
- _change: function(event) {
200
- var state = self.state();
201
-
202
- for ( var i in self._callbacks ) {
203
- self._callbacks[i].call(self._doc, event, state);
204
- }
205
-
206
- self._wasHidden = self.hidden();
207
- },
208
-
209
- // Set listener for `visibilitychange` event.
210
- _listen: function () {
211
- if ( self._enable ) {
212
- return;
213
- }
214
- var event = self._prefix() + 'visibilitychange';
215
- var listener = function () {
216
- self._change.apply(Visibility, arguments);
217
- };
218
- if ( self._doc.addEventListener ) {
219
- self._doc.addEventListener(event, listener, false);
220
- } else {
221
- self._doc.attachEvent(event, listener);
222
- }
223
- self._enable = true;
224
- self._wasHidden = self.hidden();
225
- }
226
-
227
- };
228
-
229
- self._init();
230
-
231
-
232
- var timers = {
233
-
234
- // Run callback every `interval` milliseconds if page is visible and
235
- // every `hiddenInterval` milliseconds if page is hidden.
236
- //
237
- // Visibility.every(60 * 1000, 5 * 60 * 1000, function () {
238
- // checkNewMails();
239
- // });
240
- //
241
- // You can skip `hiddenInterval` and callback will be called only if
242
- // page is visible.
243
- //
244
- // Visibility.every(1000, function () {
245
- // updateCountdown();
246
- // });
247
- //
248
- // It is analog of `setInterval(callback, interval)` but use visibility
249
- // state.
250
- //
251
- // It return timer ID, that you can use in `Visibility.stop(id)` to stop
252
- // timer (`clearInterval` analog).
253
- // Warning: timer ID is different from interval ID from `setInterval`,
254
- // so don’t use it in `clearInterval`.
255
- //
256
- // On change state from hidden to visible timers will be execute.
257
- every: function (interval, hiddenInterval, callback) {
258
- self._time();
259
-
260
- if ( !defined(callback) ) {
261
- callback = hiddenInterval;
262
- hiddenInterval = null;
263
- }
264
-
265
- self._lastTimer += 1;
266
- var number = self._lastTimer;
267
-
268
- self._timers[number] = {
269
- visible: interval,
270
- hidden: hiddenInterval,
271
- callback: callback
272
- };
273
- self._run(number, false);
274
-
275
- if ( self.isSupported() ) {
276
- self._listen();
277
- }
278
- return number;
279
- },
280
-
281
- // Stop timer from `every` method by it ID (`every` method return it).
282
- //
283
- // slideshow = Visibility.every(5 * 1000, function () {
284
- // changeSlide();
285
- // });
286
- // $('.stopSlideshow').click(function () {
287
- // Visibility.stop(slideshow);
288
- // });
289
- stop: function(id) {
290
- var timer = self._timers[id]
291
- if ( !defined(timer) ) {
292
- return false;
293
- }
294
- self._stop(id);
295
- delete self._timers[id];
296
- return timer;
297
- },
298
-
299
- // Last timer number.
300
- _lastTimer: -1,
301
-
302
- // Callbacks and intervals added by `every` method.
303
- _timers: { },
304
-
305
- // Is setInterval method detected and listener is binded.
306
- _timed: false,
307
-
308
- // Initialize variables on page loading.
309
- _time: function () {
310
- if ( self._timed ) {
311
- return;
312
- }
313
- self._timed = true;
314
-
315
- self.change(function () {
316
- self._stopRun()
317
- });
318
- },
319
-
320
- // Try to run timer from every method by it’s ID. It will be use
321
- // `interval` or `hiddenInterval` depending on visibility state.
322
- // If page is hidden and `hiddenInterval` is null,
323
- // it will not run timer.
324
- //
325
- // Argument `runNow` say, that timers must be execute now too.
326
- _run: function (id, runNow) {
327
- var interval,
328
- timer = self._timers[id];
329
- if ( self.hidden() ) {
330
- if ( null === timer.hidden ) {
331
- return;
332
- }
333
- interval = timer.hidden;
334
- } else {
335
- interval = timer.visible;
336
- }
337
-
338
- var runner = function () {
339
- timer.last = new Date();
340
- timer.callback.call(window);
341
- }
342
-
343
- if ( runNow ) {
344
- var now = new Date();
345
- var last = now - timer.last ;
346
-
347
- if ( interval > last ) {
348
- timer.delay = setTimeout(function () {
349
- runner();
350
- timer.id = setInterval(runner, interval);
351
- }, interval - last);
352
- } else {
353
- runner();
354
- timer.id = setInterval(runner, interval);
355
- }
356
-
357
- } else {
358
- timer.id = setInterval(runner, interval);
359
- }
360
- },
361
-
362
- // Stop timer from `every` method by it’s ID.
363
- _stop: function (id) {
364
- var timer = self._timers[id];
365
- clearInterval(timer.id);
366
- clearTimeout(timer.delay);
367
- delete timer.id;
368
- delete timer.delay;
369
- },
370
-
371
- // Listener for `visibilitychange` event.
372
- _stopRun: function (event) {
373
- var isHidden = self.hidden(),
374
- wasHidden = self._wasHidden;
375
-
376
- if ( (isHidden && !wasHidden) || (!isHidden && wasHidden) ) {
377
- for ( var i in self._timers ) {
378
- self._stop(i);
379
- self._run(i, !isHidden);
380
- }
381
- }
382
- }
383
-
384
- };
385
-
386
- for ( var prop in timers ) {
387
- Visibility[prop] = timers[prop];
388
- }
389
-
390
- })();