visibilityjs 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
- })();