visibilityjs 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,21 +1,3 @@
1
- /*
2
- * Copyright 2011 Andrey “A.I.” Sitnik <andrey@sitnik.ru>,
3
- * sponsored by Evil Martians.
4
- *
5
- * This program is free software: you can redistribute it and/or modify
6
- * it under the terms of the GNU Lesser General Public License as published by
7
- * the Free Software Foundation, either version 3 of the License, or
8
- * (at your option) any later version.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU Lesser General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU Lesser General Public License
16
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
- */
18
-
19
1
  ;(function (undefined) {
20
2
  "use strict";
21
3
 
@@ -73,10 +55,10 @@
73
55
  if ( !self.isSupported() ) {
74
56
  return false;
75
57
  }
76
- self._lastCallback += 1;
77
- var number = self._lastCallback;
58
+ self._lastId += 1;
59
+ var number = self._lastId;
78
60
  self._callbacks[number] = callback;
79
- self._setListener();
61
+ self._listen();
80
62
  return number;
81
63
  },
82
64
 
@@ -160,36 +142,36 @@
160
142
  _doc: window.document,
161
143
 
162
144
  // Vendor prefix cached by `_prefix` function.
163
- _chechedPrefix: null,
145
+ _cached: null,
164
146
 
165
147
  // Is listener for `visibilitychange` event is already added
166
- // by `_setListener` method.
167
- _listening: false,
148
+ // by `_listen` method.
149
+ _enable: false,
168
150
 
169
151
  // Last timer number.
170
- _lastCallback: -1,
152
+ _lastId: -1,
171
153
 
172
154
  // Callbacks from `change` method, that wait visibility changes.
173
155
  _callbacks: { },
174
156
 
175
157
  // Variable to check hidden-visible state changes.
176
- _hiddenBefore: false,
158
+ _wasHidden: false,
177
159
 
178
160
  // Initialize variables on page loading.
179
161
  _init: function () {
180
- self._hiddenBefore = self.hidden();
162
+ self._wasHidden = self.hidden();
181
163
  },
182
164
 
183
165
  // Detect vendor prefix and return it.
184
166
  _prefix: function () {
185
- if ( null !== self._chechedPrefix ) {
186
- return self._chechedPrefix;
167
+ if ( null !== self._cached ) {
168
+ return self._cached;
187
169
  }
188
170
  if ( defined(self._doc.visibilityState) ) {
189
- return self._chechedPrefix = '';
171
+ return self._cached = '';
190
172
  }
191
173
  if ( defined(self._doc.webkitVisibilityState) ) {
192
- return self._chechedPrefix = 'webkit';
174
+ return self._cached = 'webkit';
193
175
  }
194
176
  },
195
177
 
@@ -214,32 +196,32 @@
214
196
  },
215
197
 
216
198
  // Listener for `visibilitychange` event.
217
- _onChange: function(event) {
199
+ _change: function(event) {
218
200
  var state = self.state();
219
201
 
220
202
  for ( var i in self._callbacks ) {
221
203
  self._callbacks[i].call(self._doc, event, state);
222
204
  }
223
205
 
224
- self._hiddenBefore = self.hidden();
206
+ self._wasHidden = self.hidden();
225
207
  },
226
208
 
227
209
  // Set listener for `visibilitychange` event.
228
- _setListener: function () {
229
- if ( self._listening ) {
210
+ _listen: function () {
211
+ if ( self._enable ) {
230
212
  return;
231
213
  }
232
214
  var event = self._prefix() + 'visibilitychange';
233
215
  var listener = function () {
234
- self._onChange.apply(Visibility, arguments);
216
+ self._change.apply(Visibility, arguments);
235
217
  };
236
218
  if ( self._doc.addEventListener ) {
237
219
  self._doc.addEventListener(event, listener, false);
238
220
  } else {
239
221
  self._doc.attachEvent(event, listener);
240
222
  }
241
- self._listening = true;
242
- self._hiddenBefore = self.hidden();
223
+ self._enable = true;
224
+ self._wasHidden = self.hidden();
243
225
  }
244
226
 
245
227
  };
@@ -249,138 +231,155 @@
249
231
 
250
232
  var timers = {
251
233
 
252
- // Run callback every `interval` milliseconds if page is visible and
253
- // every `hiddenInterval` milliseconds if page is hidden.
254
- //
255
- // Visibility.every(60 * 1000, 5 * 60 * 1000, function () {
256
- // checkNewMails();
257
- // });
258
- //
259
- // You can skip `hiddenInterval` and callback will be called only if
260
- // page is visible.
261
- //
262
- // Visibility.every(1000, function () {
263
- // updateCountdown();
264
- // });
265
- //
266
- // It is analog of `setInterval(callback, interval)` but use visibility
267
- // state.
268
- //
269
- // It return timer ID, that you can use in `Visibility.stop(id)` to stop
270
- // timer (`clearInterval` analog).
271
- // Warning: timer ID is different from interval ID from `setInterval`,
272
- // so don’t use it in `clearInterval`.
273
- //
274
- // On change state from hidden to visible timers will be execute.
275
- every: function (interval, hiddenInterval, callback) {
276
- self._initTimers();
277
-
278
- if ( !defined(callback) ) {
279
- callback = hiddenInterval;
280
- hiddenInterval = null;
281
- }
282
- self._lastTimer += 1;
283
- var number = self._lastTimer;
284
- self._timers[number] = ({
285
- interval: interval,
286
- hiddenInterval: hiddenInterval,
287
- callback: callback
288
- });
289
- self._runTimer(number, false);
290
-
291
- if ( self.isSupported() ) {
292
- self._setListener();
293
- }
294
- return number;
295
- },
296
-
297
- // Stop timer from `every` method by it ID (`every` method return it).
298
- //
299
- // slideshow = Visibility.every(5 * 1000, function () {
300
- // changeSlide();
301
- // });
302
- // $('.stopSlideshow').click(function () {
303
- // Visibility.stop(slideshow);
304
- // });
305
- stop: function(id) {
306
- var timer = self._timers[id]
307
- if ( !defined(timer) ) {
308
- return false;
309
- }
310
- self._stopTimer(id);
311
- delete self._timers[id];
312
- return timer;
313
- },
314
-
315
- // Last timer number.
316
- _lastTimer: -1,
317
-
318
- // Callbacks and intervals added by `every` method.
319
- _timers: { },
320
-
321
- // Is setInterval method detected and listener is binded.
322
- _timersInitialized: false,
323
-
324
- // Initialize variables on page loading.
325
- _initTimers: function () {
326
- if ( self._timersInitialized ) {
327
- return;
328
- }
329
- self._timersInitialized = true;
330
-
331
- self.change(function () {
332
- self._timersStopRun()
333
- });
334
- },
335
-
336
- // Set interval by `setInterval`. Allow to change function for tests or
337
- // syntax sugar in `interval` arguments.
338
- _setInterval: function (callback, interval) {
339
- return setInterval(callback, interval);
340
- },
341
-
342
- // Try to run timer from every method by it’s ID. It will be use
343
- // `interval` or `hiddenInterval` depending on visibility state.
344
- // If page is hidden and `hiddenInterval` is null,
345
- // it will not run timer.
346
- //
347
- // Argument `now` say, that timers must be execute now too.
348
- _runTimer: function (id, now) {
349
- var interval,
350
- timer = self._timers[id];
351
- if ( self.hidden() ) {
352
- if ( null === timer.hiddenInterval ) {
353
- return;
354
- }
355
- interval = timer.hiddenInterval;
356
- } else {
357
- interval = timer.interval;
358
- }
359
- if ( now ) {
360
- timer.callback.call(window);
361
- }
362
- timer.id = self._setInterval(timer.callback, interval);
363
- },
364
-
365
- // Stop timer from `every` method by it’s ID.
366
- _stopTimer: function (id) {
367
- var timer = self._timers[id];
368
- clearInterval(timer.id);
369
- delete timer.id;
370
- },
371
-
372
- // Listener for `visibilitychange` event.
373
- _timersStopRun: function (event) {
374
- var isHidden = self.hidden(),
375
- hiddenBefore = self._hiddenBefore;
376
-
377
- if ( (isHidden && !hiddenBefore) || (!isHidden && hiddenBefore) ) {
378
- for ( var i in self._timers ) {
379
- self._stopTimer(i);
380
- self._runTimer(i, !isHidden);
381
- }
382
- }
383
- }
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
+ }
384
383
 
385
384
  };
386
385