mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Simple prefetch functionality (ifvisible.js)
config: [labs] allow_prefetch
This commit is contained in:
parent
b7e135a553
commit
38672e1672
18 changed files with 988 additions and 28 deletions
13
vendors/ifvisible/.jshintrc
vendored
Normal file
13
vendors/ifvisible/.jshintrc
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"boss": true,
|
||||
"undef": false,
|
||||
"white": false,
|
||||
"eqeqeq": false,
|
||||
"browser": true,
|
||||
"devel": true,
|
||||
"bitwise": false,
|
||||
"quotmark": false,
|
||||
"camelcase": false,
|
||||
"strict": false,
|
||||
"trailing": true
|
||||
}
|
||||
102
vendors/ifvisible/README.md
vendored
Normal file
102
vendors/ifvisible/README.md
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
ifvisible.js
|
||||
------------
|
||||
|
||||
Crosbrowser & lightweight way to check if user is looking at the page or interacting with it.
|
||||
|
||||
#### Check out the [Demo](http://serkanyersen.github.com/ifvisible.js/demo.html) or read below for code example or Check [Annotated Sorce](http://serkanyersen.github.com/ifvisible.js/docs/ifvisible.html)
|
||||
|
||||
|
||||
## Installation
|
||||
From Bower
|
||||
```
|
||||
bower install ifvisible
|
||||
```
|
||||
|
||||
For Meteor
|
||||
```
|
||||
mrt add ifvisible
|
||||
```
|
||||
> meteor package is provided by [@frozeman](https://github.com/frozeman/meteor-ifvisible.js) via [Atmosphere](https://atmosphere.meteor.com/package/ifvisible)
|
||||
|
||||
## Examples
|
||||
|
||||
```javascript
|
||||
|
||||
// If page is visible right now
|
||||
if( ifvisible.now() ){
|
||||
// Display pop-up
|
||||
openPopUp();
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Handle tab switch or browser minimize states
|
||||
|
||||
```javascript
|
||||
|
||||
ifvisible.on("blur", function(){
|
||||
// example code here..
|
||||
animations.pause();
|
||||
});
|
||||
|
||||
ifvisible.on("focus", function(){
|
||||
// resume all animations
|
||||
animations.resume();
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
ifvisible.js can handle activity states too, such as being IDLE or ACTIVE on the page
|
||||
|
||||
```javascript
|
||||
|
||||
ifvisible.on("idle", function(){
|
||||
// Stop auto updating the live data
|
||||
stream.pause();
|
||||
});
|
||||
|
||||
ifvisible.on("wakeup", function(){
|
||||
// go back updating data
|
||||
stream.resume();
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
Default idle duration is 60 seconds but you can change it with `setIdleDuration` method
|
||||
|
||||
```javascript
|
||||
|
||||
ifvisible.setIdleDuration(120); // Page will become idle after 120 seconds
|
||||
|
||||
```
|
||||
|
||||
You can manually trigger status events by calling them directly or you can set events with their names by giving first argument as a callback
|
||||
|
||||
```javascript
|
||||
|
||||
ifvisible.idle(); // will put page in a idle status
|
||||
|
||||
ifvisible.idle(function(){
|
||||
// This code will work when page goes into idle status
|
||||
});
|
||||
|
||||
// other methods are
|
||||
ifvisible.blur();
|
||||
ifvisible.focus();
|
||||
ifvisible.idle();
|
||||
ifvisible.wakeup();
|
||||
|
||||
```
|
||||
|
||||
You can set your smart intervals with ifvisible.js, if user is IDLE or not seeing the page the interval will automatically stop itself
|
||||
|
||||
```javascript
|
||||
|
||||
// If page is visible run this function on every half seconds
|
||||
ifvisible.onEvery(0.5, function(){
|
||||
// Do an animation on the logo only when page is visible
|
||||
animateLogo();
|
||||
|
||||
});
|
||||
|
||||
```
|
||||
5
vendors/ifvisible/component.json
vendored
Normal file
5
vendors/ifvisible/component.json
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "ifvisible.js",
|
||||
"version": "1.0.0",
|
||||
"main": "./src/ifvisible.js"
|
||||
}
|
||||
2
vendors/ifvisible/ifvisible.min.js
vendored
Normal file
2
vendors/ifvisible/ifvisible.min.js
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/*!ifvisible.js v1.0.0 (c) 2013 Serkan Yersen | MIT */
|
||||
(function(){"use strict";var a,b,c,d,e,f,g,h,i,j,k,l,m,n;i={},c=document,k=!1,l="active",g=6e4,f=!1,b=function(){var a,b,c,d,e,f;return a=function(){return(65536*(1+Math.random())|0).toString(16).substring(1)},e=function(){return a()+a()+"-"+a()+"-"+a()+"-"+a()+"-"+a()+a()+a()},f={},c="__ceGUID",b=function(a,b,d){return a[c]=void 0,a[c]||(a[c]="ifvisible.object.event.identifier"),f[a[c]]||(f[a[c]]={}),f[a[c]][b]||(f[a[c]][b]=[]),f[a[c]][b].push(d)},d=function(a,b,d){var e,g,h,i,j;if(a[c]&&f[a[c]]&&f[a[c]][b]){for(i=f[a[c]][b],j=[],g=0,h=i.length;h>g;g++)e=i[g],j.push(e(d||{}));return j}},{add:b,fire:d}}(),a=function(){var a;return a=!1,function(b,c,d){return a||(a=b.addEventListener?function(a,b,c){return a.addEventListener(b,c,!1)}:b.attachEvent?function(a,b,c){return a.attachEvent("on"+b,c,!1)}:function(a,b,c){return a["on"+b]=c}),a(b,c,d)}}(),d=function(a,b){var d;return c.createEventObject?a.fireEvent("on"+b,d):(d=c.createEvent("HTMLEvents"),d.initEvent(b,!0,!0),!a.dispatchEvent(d))},h=function(){var a,b,d,e,f;for(e=void 0,f=3,d=c.createElement("div"),a=d.getElementsByTagName("i"),b=function(){return d.innerHTML="<!--[if gt IE "+ ++f+"]><i></i><![endif]-->",a[0]};b(););return f>4?f:e}(),e=!1,n=void 0,"undefined"!=typeof c.hidden?(e="hidden",n="visibilitychange"):"undefined"!=typeof c.mozHidden?(e="mozHidden",n="mozvisibilitychange"):"undefined"!=typeof c.msHidden?(e="msHidden",n="msvisibilitychange"):"undefined"!=typeof c.webkitHidden&&(e="webkitHidden",n="webkitvisibilitychange"),m=function(){var b,d;return b=!1,d=function(){return clearTimeout(b),"active"!==l&&i.wakeup(),f=+new Date,b=setTimeout(function(){return"active"===l?i.idle():void 0},g)},d(),a(c,"mousemove",d),a(c,"keyup",d),a(window,"scroll",d),i.focus(d)},j=function(){var b;return k?!0:(e===!1?(b="blur",9>h&&(b="focusout"),a(window,b,function(){return i.blur()}),a(window,"focus",function(){return i.focus()})):a(c,n,function(){return c[e]?i.blur():i.focus()},!1),k=!0,m())},i={setIdleDuration:function(a){return g=1e3*a},getIdleDuration:function(){return g},getIdleInfo:function(){var a,b;return a=+new Date,b={},"idle"===l?(b.isIdle=!0,b.idleFor=a-f,b.timeLeft=0,b.timeLeftPer=100):(b.isIdle=!1,b.idleFor=a-f,b.timeLeft=f+g-a,b.timeLeftPer=(100-100*b.timeLeft/g).toFixed(2)),b},focus:function(a){return"function"==typeof a?this.on("focus",a):(l="active",b.fire(this,"focus"),b.fire(this,"wakeup"),b.fire(this,"statusChanged",{status:l}))},blur:function(a){return"function"==typeof a?this.on("blur",a):(l="hidden",b.fire(this,"blur"),b.fire(this,"idle"),b.fire(this,"statusChanged",{status:l}))},idle:function(a){return"function"==typeof a?this.on("idle",a):(l="idle",b.fire(this,"idle"),b.fire(this,"statusChanged",{status:l}))},wakeup:function(a){return"function"==typeof a?this.on("wakeup",a):(l="active",b.fire(this,"wakeup"),b.fire(this,"statusChanged",{status:l}))},on:function(a,c){return j(),b.add(this,a,c)},onEvery:function(a,b){var c;return j(),c=setInterval(function(){return"active"===l?b():void 0},1e3*a),{stop:function(){return clearInterval(c)},code:c,callback:b}},now:function(){return j(),"active"===l}},"function"==typeof define&&define.amd?define(function(){return i}):window.ifvisible=i}).call(this);
|
||||
417
vendors/ifvisible/src/ifvisible.coffee
vendored
Normal file
417
vendors/ifvisible/src/ifvisible.coffee
vendored
Normal file
|
|
@ -0,0 +1,417 @@
|
|||
# # Ifvisible.js
|
||||
# By Serkan Yersen - http://serkanyersen.github.com/ifvisible.js/
|
||||
|
||||
|
||||
###Copyright (c) 2013 Serkan Yersen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.###
|
||||
|
||||
# Use strict rules for proper coding
|
||||
"use strict"
|
||||
|
||||
# Export Object
|
||||
# ```
|
||||
# @type {Object}
|
||||
# ```
|
||||
ifvisible = {}
|
||||
|
||||
# document element
|
||||
# ```
|
||||
# @type {Document Object}
|
||||
# ```
|
||||
doc = document
|
||||
|
||||
# flag to prevent multiple initializations
|
||||
# ```
|
||||
# @type {Boolean}`
|
||||
# ```
|
||||
initialized = false
|
||||
|
||||
# Current status, may contain `active`, `idle`, `hidden`
|
||||
# ```
|
||||
# @type {String}`
|
||||
# ```
|
||||
status = "active"
|
||||
|
||||
# Time to wait when setting page to idle
|
||||
# ```
|
||||
# @type {Number} in miliseconds
|
||||
# ```
|
||||
idleTime = 60000
|
||||
|
||||
# To track how many time left to become IDLE I need to know
|
||||
# when we started keeping the time
|
||||
# ```
|
||||
# @type {Number} in miliseconds
|
||||
# ```
|
||||
idleStartedTime = false
|
||||
|
||||
# ## Custome Event Handler
|
||||
|
||||
# Handle Custom Object events
|
||||
# ```
|
||||
# @return {Object} add and fire methods to handle custom events
|
||||
# ```
|
||||
customEvent = (->
|
||||
# Create a synthetic GUID
|
||||
S4 = ->
|
||||
(((1+Math.random())*0x10000)|0).toString(16).substring(1)
|
||||
guid = ->
|
||||
(S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4())
|
||||
|
||||
# Event listeners
|
||||
# ```
|
||||
# @type {Object}
|
||||
# ```
|
||||
listeners = {}
|
||||
|
||||
# Name of the custom GUID property
|
||||
# ```
|
||||
# @type {String}
|
||||
# ```
|
||||
cgid = '__ceGUID'
|
||||
|
||||
# Add a custom event to a given object
|
||||
# ```
|
||||
# @param {Object} obj Object to add custom events
|
||||
# @param {string} event name of the custom event
|
||||
# @param {Function} callback callback function to run when
|
||||
# event is fired
|
||||
# ```
|
||||
addCustomEvent = (obj, event, callback)->
|
||||
# Extent Objects with custom event GUID so that it will be hidden
|
||||
obj[cgid] = `undefined` # it was using prototype before but diabled
|
||||
# We were using GUID here but it's disabled to keep events object in scope
|
||||
obj[cgid] = "ifvisible.object.event.identifier" unless obj[cgid]
|
||||
# create a place for event
|
||||
listeners[obj[cgid]] = {} unless listeners[obj[cgid]]
|
||||
listeners[obj[cgid]][event] = [] unless listeners[obj[cgid]][event]
|
||||
# add event
|
||||
listeners[obj[cgid]][event].push(callback)
|
||||
|
||||
# Trigger the custom event on given object
|
||||
# ```
|
||||
# @param {Object} obj Object to trigger the event
|
||||
# @param {string} event name of the event to trigger
|
||||
# @param {object} memo a custom argument to send
|
||||
# triggered event
|
||||
# ```
|
||||
fireCustomEvent = (obj, event, memo)->
|
||||
if obj[cgid] and listeners[obj[cgid]] and listeners[obj[cgid]][event]
|
||||
ev memo or {} for ev in listeners[obj[cgid]][event]
|
||||
|
||||
# export methods to use
|
||||
add: addCustomEvent
|
||||
fire: fireCustomEvent
|
||||
)()
|
||||
|
||||
# ## Regular Event Handlers
|
||||
|
||||
# CrossBrowser event attachement
|
||||
# ```
|
||||
# @param {DomElement} el Dom Element to attach the event
|
||||
# @param {string} ev name of the event with on prefix
|
||||
# @param {Function} fn callback function to run when event
|
||||
# is fired
|
||||
# ```
|
||||
addEvent = (->
|
||||
setListener = false
|
||||
# return an anonmous function with the correct version of set listener
|
||||
(el, ev, fn)->
|
||||
if not setListener
|
||||
if el.addEventListener
|
||||
setListener = (el, ev, fn) ->
|
||||
el.addEventListener(ev, fn, false)
|
||||
else if el.attachEvent
|
||||
setListener = (el, ev, fn) ->
|
||||
el.attachEvent('on' + ev, fn, false)
|
||||
else
|
||||
setListener = (el, ev, fn) ->
|
||||
el['on' + ev] = fn
|
||||
setListener(el, ev, fn)
|
||||
)()
|
||||
|
||||
# Trigger any HTML events
|
||||
# ```
|
||||
# @param {DomElement} element Dom Element to trigger
|
||||
# events on
|
||||
# @param {string} event event name to trigger
|
||||
# @return {boolean} if dispached or not
|
||||
# ```
|
||||
fireEvent = (element, event) ->
|
||||
if doc.createEventObject
|
||||
element.fireEvent('on'+event,evt)
|
||||
else
|
||||
evt = doc.createEvent('HTMLEvents')
|
||||
evt.initEvent(event, true, true)
|
||||
not element.dispatchEvent(evt)
|
||||
|
||||
# ## IE Detection
|
||||
|
||||
# Get the IE version
|
||||
# ```
|
||||
# @return {Number|Undefined} version number of IE or undefined
|
||||
# ```
|
||||
ie = (->
|
||||
undef = undefined
|
||||
v = 3
|
||||
div = doc.createElement("div")
|
||||
all = div.getElementsByTagName("i")
|
||||
|
||||
check = ->
|
||||
return ((div.innerHTML = "<!--[if gt IE " + (++v) +
|
||||
"]><i></i><![endif]-->"); all[0])
|
||||
|
||||
while check()
|
||||
continue
|
||||
|
||||
(if v > 4 then v else undef)
|
||||
)()
|
||||
|
||||
# ## Get HTML5 visibility api for current browser
|
||||
|
||||
# Set the name of the hidden property and the change event for visibility checks
|
||||
hidden = false
|
||||
visibilityChange = undefined
|
||||
# Standarts
|
||||
if typeof doc.hidden isnt "undefined"
|
||||
hidden = "hidden"
|
||||
visibilityChange = "visibilitychange"
|
||||
# For Gecko browsers
|
||||
else if typeof doc.mozHidden isnt "undefined"
|
||||
hidden = "mozHidden"
|
||||
visibilityChange = "mozvisibilitychange"
|
||||
# For MSIE
|
||||
else if typeof doc.msHidden isnt "undefined"
|
||||
hidden = "msHidden"
|
||||
visibilityChange = "msvisibilitychange"
|
||||
# For Webkit browsers
|
||||
else if typeof doc.webkitHidden isnt "undefined"
|
||||
hidden = "webkitHidden"
|
||||
visibilityChange = "webkitvisibilitychange"
|
||||
|
||||
|
||||
# Track if the page is idle or not
|
||||
trackIdleStatus = ->
|
||||
timer = false
|
||||
wakeUp = ->
|
||||
clearTimeout timer
|
||||
ifvisible.wakeup() if status isnt "active"
|
||||
idleStartedTime = +(new Date())
|
||||
timer = setTimeout(->
|
||||
ifvisible.idle() if status is "active"
|
||||
, idleTime)
|
||||
|
||||
# Call once so that it can set page to idle without doing anything
|
||||
wakeUp()
|
||||
addEvent doc, "mousemove", wakeUp
|
||||
addEvent doc, "keyup", wakeUp
|
||||
addEvent window, "scroll", wakeUp
|
||||
# If page got focus but noinput activity was recorded
|
||||
ifvisible.focus wakeUp
|
||||
|
||||
# ## Initialize the module
|
||||
|
||||
# constructor
|
||||
init = ->
|
||||
return true if initialized
|
||||
|
||||
# If hidden is false the use the legacy methods
|
||||
if hidden is false
|
||||
blur = "blur"
|
||||
blur = "focusout" if ie < 9
|
||||
addEvent window, blur, ->
|
||||
ifvisible.blur()
|
||||
|
||||
addEvent window, "focus", ->
|
||||
ifvisible.focus()
|
||||
|
||||
else
|
||||
|
||||
# add HTML5 visibility events
|
||||
addEvent doc, visibilityChange, ->
|
||||
if doc[hidden]
|
||||
ifvisible.blur()
|
||||
else
|
||||
ifvisible.focus()
|
||||
, false
|
||||
initialized = true
|
||||
|
||||
#Set method to be initialized
|
||||
trackIdleStatus()
|
||||
|
||||
# ## Exports
|
||||
|
||||
# Methods to be exported
|
||||
# ```
|
||||
# @type {Object}
|
||||
# ```
|
||||
ifvisible =
|
||||
|
||||
# Change idle timeout value.
|
||||
# ```
|
||||
# @param {Number} seconds a number in seconds such as: 10 or 0.5
|
||||
# ```
|
||||
setIdleDuration: (seconds) ->
|
||||
idleTime = seconds * 1000
|
||||
|
||||
|
||||
# Get idle timeout value.
|
||||
getIdleDuration: ->
|
||||
idleTime
|
||||
|
||||
|
||||
# Get information about user being idle.
|
||||
# ```
|
||||
# @return {Object} An object contining information about idle status
|
||||
# ```
|
||||
# Informations is as following
|
||||
# ```
|
||||
# isIdle: [current idle status true/false]
|
||||
# idleFor: [how long the user was idle
|
||||
# in milliseconds]
|
||||
# timeLeft: [How long does it take to become
|
||||
# idle in milliseconds]
|
||||
# timeLeftPer: [How long does it take to become
|
||||
# idle in percentage]
|
||||
# ```
|
||||
getIdleInfo: ->
|
||||
now = +(new Date())
|
||||
res = {}
|
||||
if status is "idle"
|
||||
res.isIdle = true
|
||||
res.idleFor = now - idleStartedTime
|
||||
res.timeLeft = 0
|
||||
res.timeLeftPer = 100
|
||||
else
|
||||
res.isIdle = false
|
||||
res.idleFor = now - idleStartedTime
|
||||
res.timeLeft = (idleStartedTime + idleTime) - now
|
||||
res.timeLeftPer = (100 - (res.timeLeft * 100 / idleTime)).toFixed(2)
|
||||
res
|
||||
|
||||
|
||||
# When User Opens the page,
|
||||
# ```
|
||||
# @note: User may not be looking at it directly
|
||||
# ```
|
||||
focus: (callback) ->
|
||||
|
||||
# if first argument is a callback then set an event
|
||||
return @on("focus", callback) if typeof callback is "function"
|
||||
# else trigger event
|
||||
status = "active"
|
||||
customEvent.fire this, "focus"
|
||||
customEvent.fire this, "wakeup" # When focused page will woke up too.
|
||||
customEvent.fire this, "statusChanged", { status: status }
|
||||
|
||||
|
||||
# When User swicthes tabs or minimizes the window
|
||||
# ```
|
||||
# @note: this may trigger when iframes are selected
|
||||
# ```
|
||||
blur: (callback) ->
|
||||
|
||||
# if first argument is a callback then set an event
|
||||
return @on("blur", callback) if typeof callback is "function"
|
||||
# else trigger event
|
||||
status = "hidden"
|
||||
customEvent.fire this, "blur"
|
||||
customEvent.fire this, "idle" # When blurred page is idle too
|
||||
customEvent.fire this, "statusChanged", { status: status }
|
||||
|
||||
|
||||
# When page is focused but user is doing nothing on the page
|
||||
idle: (callback) ->
|
||||
|
||||
# if first argument is a callback then set an event
|
||||
return @on("idle", callback) if typeof callback is "function"
|
||||
# else trigger event
|
||||
status = "idle"
|
||||
customEvent.fire this, "idle"
|
||||
customEvent.fire this, "statusChanged", { status: status }
|
||||
|
||||
|
||||
# When user started to make interactions on the page such as:
|
||||
# `mousemove`, `click`, `keypress`, `scroll`
|
||||
# This will be called when page has focus too
|
||||
wakeup: (callback) ->
|
||||
|
||||
# if first argument is a callback then set an event
|
||||
return @on("wakeup", callback) if typeof callback is "function"
|
||||
# else trigger event
|
||||
status = "active"
|
||||
customEvent.fire this, "wakeup"
|
||||
customEvent.fire this, "statusChanged", { status: status }
|
||||
|
||||
|
||||
|
||||
# Set an event to ifvisible object
|
||||
# ```
|
||||
# @param {string} name Event name such as focus,
|
||||
# idle, blur, wakeup
|
||||
# @param {Function} callback callback function to call
|
||||
# when event is fired
|
||||
# @return {object} an object with a stop method
|
||||
# to unbid this event
|
||||
# ```
|
||||
on: (name, callback) ->
|
||||
init() # Auto init on first call
|
||||
customEvent.add this, name, callback
|
||||
|
||||
|
||||
# if page is visible then run given code in given seconds of intervals
|
||||
# ```
|
||||
# @param {float} seconds seconds to run interval
|
||||
# @param {Function} callback callback function to run
|
||||
# ```
|
||||
onEvery: (seconds, callback) ->
|
||||
# Auto init on first call
|
||||
init()
|
||||
t = setInterval(->
|
||||
callback() if status is "active"
|
||||
, seconds * 1000)
|
||||
|
||||
# return methods
|
||||
stop: ->
|
||||
clearInterval t
|
||||
|
||||
code: t
|
||||
callback: callback
|
||||
|
||||
|
||||
# `ifvisible.now()` return if the page is visible right now?
|
||||
# ```
|
||||
# @return {boolean} true if page is visible
|
||||
# ```
|
||||
now: ->
|
||||
# Auto init on first call
|
||||
init()
|
||||
status is "active"
|
||||
|
||||
|
||||
# If there is a **Require JS** kind of library use it othervise
|
||||
# place it on the `window`
|
||||
if typeof define is "function" and define.amd
|
||||
define ->
|
||||
ifvisible
|
||||
|
||||
else
|
||||
window.ifvisible = ifvisible
|
||||
|
||||
# compile code: `coffee -wcm ifvisible.coffee`
|
||||
315
vendors/ifvisible/src/ifvisible.js
vendored
Normal file
315
vendors/ifvisible/src/ifvisible.js
vendored
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
// Generated by CoffeeScript 1.6.2
|
||||
/*Copyright (c) 2013 Serkan Yersen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
var addEvent, customEvent, doc, fireEvent, hidden, idleStartedTime, idleTime, ie, ifvisible, init, initialized, status, trackIdleStatus, visibilityChange;
|
||||
|
||||
ifvisible = {};
|
||||
|
||||
doc = document;
|
||||
|
||||
initialized = false;
|
||||
|
||||
status = "active";
|
||||
|
||||
idleTime = 60000;
|
||||
|
||||
idleStartedTime = false;
|
||||
|
||||
customEvent = (function() {
|
||||
var S4, addCustomEvent, cgid, fireCustomEvent, guid, listeners;
|
||||
|
||||
S4 = function() {
|
||||
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
|
||||
};
|
||||
guid = function() {
|
||||
return S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4();
|
||||
};
|
||||
listeners = {};
|
||||
cgid = '__ceGUID';
|
||||
addCustomEvent = function(obj, event, callback) {
|
||||
obj[cgid] = undefined;
|
||||
if (!obj[cgid]) {
|
||||
obj[cgid] = "ifvisible.object.event.identifier";
|
||||
}
|
||||
if (!listeners[obj[cgid]]) {
|
||||
listeners[obj[cgid]] = {};
|
||||
}
|
||||
if (!listeners[obj[cgid]][event]) {
|
||||
listeners[obj[cgid]][event] = [];
|
||||
}
|
||||
return listeners[obj[cgid]][event].push(callback);
|
||||
};
|
||||
fireCustomEvent = function(obj, event, memo) {
|
||||
var ev, _i, _len, _ref, _results;
|
||||
|
||||
if (obj[cgid] && listeners[obj[cgid]] && listeners[obj[cgid]][event]) {
|
||||
_ref = listeners[obj[cgid]][event];
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
ev = _ref[_i];
|
||||
_results.push(ev(memo || {}));
|
||||
}
|
||||
return _results;
|
||||
}
|
||||
};
|
||||
return {
|
||||
add: addCustomEvent,
|
||||
fire: fireCustomEvent
|
||||
};
|
||||
})();
|
||||
|
||||
addEvent = (function() {
|
||||
var setListener;
|
||||
|
||||
setListener = false;
|
||||
return function(el, ev, fn) {
|
||||
if (!setListener) {
|
||||
if (el.addEventListener) {
|
||||
setListener = function(el, ev, fn) {
|
||||
return el.addEventListener(ev, fn, false);
|
||||
};
|
||||
} else if (el.attachEvent) {
|
||||
setListener = function(el, ev, fn) {
|
||||
return el.attachEvent('on' + ev, fn, false);
|
||||
};
|
||||
} else {
|
||||
setListener = function(el, ev, fn) {
|
||||
return el['on' + ev] = fn;
|
||||
};
|
||||
}
|
||||
}
|
||||
return setListener(el, ev, fn);
|
||||
};
|
||||
})();
|
||||
|
||||
fireEvent = function(element, event) {
|
||||
var evt;
|
||||
|
||||
if (doc.createEventObject) {
|
||||
return element.fireEvent('on' + event, evt);
|
||||
} else {
|
||||
evt = doc.createEvent('HTMLEvents');
|
||||
evt.initEvent(event, true, true);
|
||||
return !element.dispatchEvent(evt);
|
||||
}
|
||||
};
|
||||
|
||||
ie = (function() {
|
||||
var all, check, div, undef, v;
|
||||
|
||||
undef = void 0;
|
||||
v = 3;
|
||||
div = doc.createElement("div");
|
||||
all = div.getElementsByTagName("i");
|
||||
check = function() {
|
||||
return (div.innerHTML = "<!--[if gt IE " + (++v) + "]><i></i><![endif]-->", all[0]);
|
||||
};
|
||||
while (check()) {
|
||||
continue;
|
||||
}
|
||||
if (v > 4) {
|
||||
return v;
|
||||
} else {
|
||||
return undef;
|
||||
}
|
||||
})();
|
||||
|
||||
hidden = false;
|
||||
|
||||
visibilityChange = void 0;
|
||||
|
||||
if (typeof doc.hidden !== "undefined") {
|
||||
hidden = "hidden";
|
||||
visibilityChange = "visibilitychange";
|
||||
} else if (typeof doc.mozHidden !== "undefined") {
|
||||
hidden = "mozHidden";
|
||||
visibilityChange = "mozvisibilitychange";
|
||||
} else if (typeof doc.msHidden !== "undefined") {
|
||||
hidden = "msHidden";
|
||||
visibilityChange = "msvisibilitychange";
|
||||
} else if (typeof doc.webkitHidden !== "undefined") {
|
||||
hidden = "webkitHidden";
|
||||
visibilityChange = "webkitvisibilitychange";
|
||||
}
|
||||
|
||||
trackIdleStatus = function() {
|
||||
var timer, wakeUp;
|
||||
|
||||
timer = false;
|
||||
wakeUp = function() {
|
||||
clearTimeout(timer);
|
||||
if (status !== "active") {
|
||||
ifvisible.wakeup();
|
||||
}
|
||||
idleStartedTime = +(new Date());
|
||||
return timer = setTimeout(function() {
|
||||
if (status === "active") {
|
||||
return ifvisible.idle();
|
||||
}
|
||||
}, idleTime);
|
||||
};
|
||||
wakeUp();
|
||||
addEvent(doc, "mousemove", wakeUp);
|
||||
addEvent(doc, "keyup", wakeUp);
|
||||
addEvent(window, "scroll", wakeUp);
|
||||
return ifvisible.focus(wakeUp);
|
||||
};
|
||||
|
||||
init = function() {
|
||||
var blur;
|
||||
|
||||
if (initialized) {
|
||||
return true;
|
||||
}
|
||||
if (hidden === false) {
|
||||
blur = "blur";
|
||||
if (ie < 9) {
|
||||
blur = "focusout";
|
||||
}
|
||||
addEvent(window, blur, function() {
|
||||
return ifvisible.blur();
|
||||
});
|
||||
addEvent(window, "focus", function() {
|
||||
return ifvisible.focus();
|
||||
});
|
||||
} else {
|
||||
addEvent(doc, visibilityChange, function() {
|
||||
if (doc[hidden]) {
|
||||
return ifvisible.blur();
|
||||
} else {
|
||||
return ifvisible.focus();
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
initialized = true;
|
||||
return trackIdleStatus();
|
||||
};
|
||||
|
||||
ifvisible = {
|
||||
setIdleDuration: function(seconds) {
|
||||
return idleTime = seconds * 1000;
|
||||
},
|
||||
getIdleDuration: function() {
|
||||
return idleTime;
|
||||
},
|
||||
getIdleInfo: function() {
|
||||
var now, res;
|
||||
|
||||
now = +(new Date());
|
||||
res = {};
|
||||
if (status === "idle") {
|
||||
res.isIdle = true;
|
||||
res.idleFor = now - idleStartedTime;
|
||||
res.timeLeft = 0;
|
||||
res.timeLeftPer = 100;
|
||||
} else {
|
||||
res.isIdle = false;
|
||||
res.idleFor = now - idleStartedTime;
|
||||
res.timeLeft = (idleStartedTime + idleTime) - now;
|
||||
res.timeLeftPer = (100 - (res.timeLeft * 100 / idleTime)).toFixed(2);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
focus: function(callback) {
|
||||
if (typeof callback === "function") {
|
||||
return this.on("focus", callback);
|
||||
}
|
||||
status = "active";
|
||||
customEvent.fire(this, "focus");
|
||||
customEvent.fire(this, "wakeup");
|
||||
return customEvent.fire(this, "statusChanged", {
|
||||
status: status
|
||||
});
|
||||
},
|
||||
blur: function(callback) {
|
||||
if (typeof callback === "function") {
|
||||
return this.on("blur", callback);
|
||||
}
|
||||
status = "hidden";
|
||||
customEvent.fire(this, "blur");
|
||||
customEvent.fire(this, "idle");
|
||||
return customEvent.fire(this, "statusChanged", {
|
||||
status: status
|
||||
});
|
||||
},
|
||||
idle: function(callback) {
|
||||
if (typeof callback === "function") {
|
||||
return this.on("idle", callback);
|
||||
}
|
||||
status = "idle";
|
||||
customEvent.fire(this, "idle");
|
||||
return customEvent.fire(this, "statusChanged", {
|
||||
status: status
|
||||
});
|
||||
},
|
||||
wakeup: function(callback) {
|
||||
if (typeof callback === "function") {
|
||||
return this.on("wakeup", callback);
|
||||
}
|
||||
status = "active";
|
||||
customEvent.fire(this, "wakeup");
|
||||
return customEvent.fire(this, "statusChanged", {
|
||||
status: status
|
||||
});
|
||||
},
|
||||
on: function(name, callback) {
|
||||
init();
|
||||
return customEvent.add(this, name, callback);
|
||||
},
|
||||
onEvery: function(seconds, callback) {
|
||||
var t;
|
||||
|
||||
init();
|
||||
t = setInterval(function() {
|
||||
if (status === "active") {
|
||||
return callback();
|
||||
}
|
||||
}, seconds * 1000);
|
||||
return {
|
||||
stop: function() {
|
||||
return clearInterval(t);
|
||||
},
|
||||
code: t,
|
||||
callback: callback
|
||||
};
|
||||
},
|
||||
now: function() {
|
||||
init();
|
||||
return status === "active";
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define(function() {
|
||||
return ifvisible;
|
||||
});
|
||||
} else {
|
||||
window.ifvisible = ifvisible;
|
||||
}
|
||||
|
||||
}).call(this);
|
||||
|
||||
/*
|
||||
//@ sourceMappingURL=ifvisible.map
|
||||
*/
|
||||
10
vendors/ifvisible/src/ifvisible.map
vendored
Normal file
10
vendors/ifvisible/src/ifvisible.map
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue