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 +4 -4
- data/ChangeLog.md +10 -2
- data/README.md +2 -2
- data/lib/{assets/javascripts/visibility.core.js → visibility.core.js} +37 -77
- data/lib/{assets/javascripts/visibility.fallback.js → visibility.fallback.js} +8 -8
- data/lib/visibility.js +4 -0
- data/lib/{assets/javascripts/visibility.timers.js → visibility.timers.js} +50 -55
- data/lib/visibilityjs.rb +9 -0
- metadata +9 -9
- data/lib/assets/javascripts/visibility.js +0 -390
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67bc18a7e786dbc5e14e5c26e95f4afea84b89c9
|
4
|
+
data.tar.gz: 6a747d0bbac0a17f58bb2f468a671b99ff7fd5c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 475e0c05d111b930c38e6adb18c566a962819702d8f26e1e5a629a73e4b45cb044ac47c29815bb50fee151f9f58ff1969eb7503497bb3e5e4be33d767631f632
|
7
|
+
data.tar.gz: 0037c05474dde93f3bb1fa7fbb14d9d6d3e2a74b290ce25ad67512f9c1fb66cd8d50a51bc02132a1ed1b71e30bbf9b2719b7a3a0706cf3125c90f82154a3d000
|
data/ChangeLog.md
CHANGED
@@ -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,
|
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
|
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/
|
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/
|
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 (
|
1
|
+
;(function (global) {
|
2
2
|
"use strict";
|
3
3
|
|
4
|
-
var
|
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 =
|
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
|
-
|
24
|
+
var support = self.isSupported();
|
25
|
+
if ( !support || !self.hidden() ) {
|
27
26
|
callback();
|
28
|
-
return
|
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
|
-
|
59
|
-
var number =
|
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
|
-
|
87
|
+
var support = self.isSupported();
|
88
|
+
var prerender = 'prerender';
|
89
|
+
|
90
|
+
if ( !support || prerender != self.state() ) {
|
89
91
|
callback();
|
90
|
-
return
|
92
|
+
return support;
|
91
93
|
}
|
92
94
|
|
93
95
|
var listener = self.change(function (e, state) {
|
94
|
-
if (
|
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.
|
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.
|
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
|
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:
|
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.
|
163
|
+
if ( self._init ) {
|
212
164
|
return;
|
213
165
|
}
|
214
|
-
|
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(
|
173
|
+
self._change.apply(self, arguments);
|
217
174
|
};
|
218
175
|
if ( self._doc.addEventListener ) {
|
219
|
-
self._doc.addEventListener(event, listener
|
176
|
+
self._doc.addEventListener(event, listener);
|
220
177
|
} else {
|
221
178
|
self._doc.attachEvent(event, listener);
|
222
179
|
}
|
223
|
-
self.
|
224
|
-
self._wasHidden = self.hidden();
|
180
|
+
self._init = true;
|
225
181
|
}
|
226
182
|
|
227
183
|
};
|
228
184
|
|
229
|
-
|
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
|
37
|
+
var onFocus = function () {
|
38
38
|
document.hidden = false;
|
39
39
|
document.visibilityState = 'visible';
|
40
40
|
fireEvent();
|
41
41
|
};
|
42
|
-
var
|
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',
|
50
|
-
window.addEventListener('blur',
|
49
|
+
window.addEventListener('focus', onFocus, true);
|
50
|
+
window.addEventListener('blur', onBlur, true);
|
51
51
|
} else {
|
52
|
-
document.attachEvent('onfocusin',
|
53
|
-
document.attachEvent('onfocusout',
|
52
|
+
document.attachEvent('onfocusin', onFocus);
|
53
|
+
document.attachEvent('onfocusout', onBlur);
|
54
54
|
}
|
55
|
-
})();
|
55
|
+
})(document);
|
data/lib/visibility.js
ADDED
@@ -1,13 +1,9 @@
|
|
1
|
-
;(function () {
|
1
|
+
;(function (window) {
|
2
2
|
"use strict";
|
3
3
|
|
4
|
-
var
|
5
|
-
return ('undefined' != typeof(variable));
|
6
|
-
};
|
4
|
+
var lastTimer = -1;
|
7
5
|
|
8
|
-
var
|
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
|
36
|
-
|
31
|
+
Visibility.every = function (interval, hiddenInterval, callback) {
|
32
|
+
Visibility._time();
|
37
33
|
|
38
|
-
if ( !
|
34
|
+
if ( !callback ) {
|
39
35
|
callback = hiddenInterval;
|
40
36
|
hiddenInterval = null;
|
41
37
|
}
|
42
38
|
|
43
|
-
|
44
|
-
var number =
|
39
|
+
lastTimer += 1;
|
40
|
+
var number = lastTimer;
|
45
41
|
|
46
|
-
|
42
|
+
Visibility._timers[number] = {
|
47
43
|
visible: interval,
|
48
44
|
hidden: hiddenInterval,
|
49
45
|
callback: callback
|
50
46
|
};
|
51
|
-
|
47
|
+
Visibility._run(number, false);
|
52
48
|
|
53
|
-
if (
|
54
|
-
|
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
|
68
|
-
|
69
|
-
if ( !defined(timer) ) {
|
63
|
+
Visibility.stop = function(id) {
|
64
|
+
if ( !Visibility._timers[id] ) {
|
70
65
|
return false;
|
71
66
|
}
|
72
|
-
|
73
|
-
delete
|
74
|
-
return
|
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
|
88
|
-
if (
|
76
|
+
Visibility._time = function () {
|
77
|
+
if ( Visibility._timed ) {
|
89
78
|
return;
|
90
79
|
}
|
91
|
-
|
80
|
+
Visibility._timed = true;
|
81
|
+
Visibility._wasHidden = Visibility.hidden();
|
92
82
|
|
93
|
-
|
94
|
-
|
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
|
95
|
+
Visibility._run = function (id, runNow) {
|
105
96
|
var interval,
|
106
|
-
timer =
|
107
|
-
|
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
|
142
|
-
var timer =
|
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
|
151
|
-
var isHidden =
|
152
|
-
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
|
156
|
-
|
157
|
-
|
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
|
-
|
165
|
-
|
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);
|
data/lib/visibilityjs.rb
CHANGED
@@ -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.
|
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
|
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/
|
43
|
-
- lib/
|
44
|
-
- lib/
|
45
|
-
- lib/
|
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/
|
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.
|
67
|
+
rubygems_version: 2.2.2
|
68
68
|
signing_key:
|
69
69
|
specification_version: 4
|
70
|
-
summary:
|
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
|
-
})();
|