Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/shared/js/idletimer.js
diff options
context:
space:
mode:
Diffstat (limited to 'shared/js/idletimer.js')
-rw-r--r--shared/js/idletimer.js127
1 files changed, 127 insertions, 0 deletions
diff --git a/shared/js/idletimer.js b/shared/js/idletimer.js
new file mode 100644
index 0000000..5c42384
--- /dev/null
+++ b/shared/js/idletimer.js
@@ -0,0 +1,127 @@
+/*
+ This file implements window.setIdleTimeout() and
+ window.clearIdleTimeout(). They look like setTimeout() except the
+ setIdleTimeout() function takes two callbacks:
+
+ setIdleTimeout(idleCallback, activeCallback, ms):
+ idleCallback will fire after specific microsecond of idle.
+ The time it takes will calculated from the time
+ setIdleTimeout() is called and resets as user interacts.
+
+ activeCallback will fire when the first user action *after*
+ idleCallback fires
+
+ returns id.
+
+ clearIdleTimeout(id):
+ takes the id returns from setIdleTimeout() and cancels it.
+
+*/
+
+// Wrap everything into a closure so we will not expose idleTimerRegistry
+
+'use strict';
+
+(function idleTimerAsAIdleObserverWrapper(win) {
+
+ // stuff the 0th element so id is always a truey value
+ var idleTimerRegistry = [undefined];
+
+ // setIdleTimeout()
+ win.setIdleTimeout = function setIdleTimeout(idleCallback,
+ activeCallback,
+ ms) {
+ var startTimestamp = Date.now();
+ var idleFired = false;
+
+ var idleTimer = {
+ timer: undefined,
+ resetStartTimestamp: function resetStartTimestamp() {
+ startTimestamp = Date.now();
+ }
+ };
+
+ // If the system unix time changes, we would need to update
+ // the number we kept in startTimestamp, or bad things will happen.
+ window.addEventListener('moztimechange', idleTimer.resetStartTimestamp);
+
+ // Create an idle observer with a very short time as
+ // we are not interested in when onidle fires (since it's inaccuate),
+ // instead, we need to know when onactive callback calls.
+ idleTimer.observer = {
+ onidle: function observerReportIdle() {
+ // Once the onidle fires, the next user action will trigger
+ // onactive.
+
+ // The time it takes for onidle to fire need to be subtracted from
+ // the real time we are going to set to setTimeout()
+ var time = (ms - (Date.now() - startTimestamp));
+
+ // Let's start the real count down and wait for that.
+ idleTimer.timer = setTimeout(function idled() {
+ // remove the timer
+ idleTimer.timer = undefined;
+
+ // set idleFired to true
+ idleFired = true;
+
+ // fire the real idleCallback
+ idleCallback();
+ }, time);
+ },
+ onactive: function observerReportActive() {
+ // Remove the timer set by onidle
+ if (idleTimer.timer) {
+ clearTimeout(idleTimer.timer);
+ idleTimer.timer = undefined;
+ }
+
+ // Reset the timestamp; the next real count down should start
+ // from the time onactive fires
+ startTimestamp = Date.now();
+
+ // If idleCallback is not called yet,
+ // we should not trigger activeCallback here
+ if (!idleFired)
+ return;
+
+ // fire the real activeCallback
+ activeCallback();
+
+ // reset the flag
+ idleFired = false;
+
+ // After a short time, onidle will fire again.
+ // timer will be registered there again.
+ },
+ time: 1
+ };
+
+ // Register the idleObserver
+ navigator.addIdleObserver(idleTimer.observer);
+
+ // Push the idleTimer object to the registry
+ idleTimerRegistry.push(idleTimer);
+
+ // return the id so people can do clearIdleTimeout();
+ return (idleTimerRegistry.length - 1);
+ };
+
+ // clearIdleTimeout()
+ win.clearIdleTimeout = function clearIdleTimeout(id) {
+ if (!idleTimerRegistry[id])
+ return;
+
+ // Get the idleTimer object and remove it from registry
+ var idleTimer = idleTimerRegistry[id];
+ idleTimerRegistry[id] = undefined;
+
+ // Properly clean it up, make sure we will never heard from
+ // those callbacks ever again.
+ navigator.removeIdleObserver(idleTimer.observer);
+ window.removeEventListener('moztimechange', idleTimer.resetStartTimestamp);
+ if (idleTimer.timer)
+ clearTimeout(idleTimer.timer);
+ };
+
+})(this);