copy dari repo om Irfan
This commit is contained in:
+91
@@ -0,0 +1,91 @@
|
||||
####VERSION: 1.0.0
|
||||
####RELEASED: 03/10/2014
|
||||
####AUTHOR: TODD HORST
|
||||
-------
|
||||
|
||||
This is the first release I'm in charge of, and as such, I've made the project my own. Hopefully things work well, and we can
|
||||
keep this project evolving. Please feel free to submit requests for feature.
|
||||
|
||||
#####SRC
|
||||
|
||||
Fixed:
|
||||
* if users set idle=true and left startImmediately=true ( the default ), it would toggle incorrectly
|
||||
* opts references (changed to obj) in toggleIdleState
|
||||
* chaining on all functions
|
||||
* mousemove issues experienced in chrome & iOS7 #4
|
||||
* every time you called a function (say getElapsedTime), it would reset olddate, so you were getting elapsed from last getElapsedTime, not actual time from last state change
|
||||
* can now call functions on default binding ex $.idleTimer("pause");
|
||||
* can now call default binding with parameter $.idleTimer({idle:true});
|
||||
* destroy doesnt remove bindings user added, only internally bound events
|
||||
|
||||
Added:
|
||||
* reset, pause/resume #19
|
||||
* getRemainingTime, getLastActiveTime (supports autologout demo), isIdle (state of object)
|
||||
* internally documentation for obj keys
|
||||
* element, trigger event, and (copy of) object are parameters to raised idle/active event
|
||||
* `wheel` event. wheel is to replace DOMMouseScroll & mousewheel. We could remove DOMMouseScroll now as its technically not needed to support firefox n-1. mousewheel will stick around until we drop ie8.
|
||||
* `MSPointerDown` `MSPointerMove` events #22
|
||||
* ability to send only settings parameter
|
||||
|
||||
Update:
|
||||
* changed $().data() to jQuery.data() for speed
|
||||
* removed myelem in toggleIdleState and replaced with elem
|
||||
|
||||
|
||||
###Breaking Changes
|
||||
|
||||
NOTE:
|
||||
I realize these changes could upset some people. If you need something added back, please open a ticket. If its determined that
|
||||
these are necessary, I will be happy to put them back. They were removed to clean up the code or fix bugs. You can of course continue
|
||||
using the old version.
|
||||
|
||||
* Passing timeout AND settings is no longer valid. Example: `$( document ).idleTimer(3000, {idle:true});` Change to `$( document ).idleTimer({timeout:3000,idle:true});`
|
||||
* Using `$( document ).data("idleTimer");` returned a string. This is less ideal. Start using `$( document ).idleTimer("isIdle");`
|
||||
to get a boolean value of the current state of the element. If you need the string use:
|
||||
`var state = $( document ).idleTimer("isIdle") ? "idle" : "active"`
|
||||
* `Enabled` param has been removed. If needed dont initialize idleTimer until you need it. Previously there was no way to enable
|
||||
once it was disabled anyway, unless manually modifying the internal data. You may also want to look at reset (resets data/state without removing
|
||||
bindings) and pause (stops timer until resumed)
|
||||
* `StartImmediately` param has been removed. If you need to not have the timer start set `idle` setting to true. This was redundant and
|
||||
could cause a bug if users didn't flip both `idle` and `startImmediately`
|
||||
* Firefox lateness bug fix, Firefox has updated their implementation, so there is no need to have added code to support intended
|
||||
browsers. Besides I always look at elem instead of local instance on myelem now
|
||||
* Chrome "alert triggers event" bugfix, I believe Chrome has fixed this, if you still experience the issue let me know and I'll put it back
|
||||
but I was unable to reproduce this
|
||||
|
||||
|
||||
|
||||
###DEMO
|
||||
|
||||
* Updated jQuery to newest (1.11.0)
|
||||
* Remove jQuery UI (was used for dialog)
|
||||
* Added bootstrap and standard template
|
||||
* Added examples of all functions
|
||||
* Made clearer which log was for document/textarea idletimer
|
||||
* Stops event propagation on textarea
|
||||
* Shows default state according to obj idle value
|
||||
* Added demo for autologout (handles that fact that js gets paused when iOS app gets minimized)
|
||||
* Added demo with all autobinding
|
||||
|
||||
###README
|
||||
|
||||
* Link to demo
|
||||
* Document new functions
|
||||
* Document supported browsers
|
||||
* Document jQuery dependency
|
||||
* Document author history
|
||||
* Removed note about mixing `$.idleTimer` and `$( document ).idleTimer(...)`, related bugs have been fixed
|
||||
* General cleanup
|
||||
|
||||
###DIST
|
||||
|
||||
* Automated builds from travis
|
||||
* Grunt settings have been updated, so that it builds correctly
|
||||
* Tests added for new functions, admittedly Im still learning this
|
||||
* Tests only keydown. Need to test idleTimer not the browser events. Having them all in a loop was unpredictable.
|
||||
|
||||
###THOUGHTS
|
||||
|
||||
I thought about allowing users to send a callback function in, ala most jquery methods. However
|
||||
after researching and thinking the callbacks would be synchronous and events are async. So we
|
||||
will be sticking with the current method
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
# Contributing
|
||||
|
||||
## Important notes
|
||||
Please don't edit files in the `dist` subdirectory as they are generated via grunt. You'll find source code in the `src` subdirectory!
|
||||
|
||||
### Code style
|
||||
Regarding code style like indentation and whitespace, **follow the conventions you see used in the source already.**
|
||||
|
||||
### PhantomJS
|
||||
While grunt can run the included unit tests via [PhantomJS](http://phantomjs.org/), this shouldn't be considered a substitute for the real thing. Please be sure to test the `test/*.html` unit test file(s) in _actual_ browsers.
|
||||
|
||||
See the [Why does grunt complain that PhantomJS isn't installed?](https://github.com/gruntjs/grunt/blob/master/docs/faq.md#why-does-grunt-complain-that-phantomjs-isnt-installed) guide in the [Grunt FAQ](https://github.com/gruntjs/grunt/blob/master/docs/faq.md) for help with installing or troubleshooting PhantomJS.
|
||||
|
||||
## Modifying the code
|
||||
First, ensure that you have the latest [Node.js](http://nodejs.org/) and [npm](http://npmjs.org/) installed.
|
||||
|
||||
Test that grunt is installed globally by running `grunt --version` at the command-line. If grunt isn't installed globally, run `npm install -g grunt` to install the latest version. _You may need to run `sudo npm install -g grunt`._
|
||||
|
||||
_Note that in Windows, you may have to run `grunt.cmd` instead of `grunt`._
|
||||
|
||||
1. Fork and clone the repo.
|
||||
1. Run `npm install` to install all dependencies (including grunt).
|
||||
1. Run `grunt` to grunt this project.
|
||||
|
||||
Assuming that you don't see any red, you're ready to go. Just be sure to run `grunt` after making any changes, to ensure that nothing is broken.
|
||||
|
||||
## Submitting pull requests
|
||||
|
||||
1. Create a new branch, please don't work in your `master` branch directly.
|
||||
1. Add failing tests for the change you want to make. Run `grunt` to see the tests fail.
|
||||
1. Fix stuff.
|
||||
1. Run `grunt` to see if the tests pass. Repeat steps 2-4 until done.
|
||||
1. Open `test/*.html` unit test file(s) in actual browser to ensure tests pass everywhere.
|
||||
1. Update the documentation to reflect any changes.
|
||||
1. Push to your fork and submit a pull request.
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function(grunt) {
|
||||
|
||||
// Project configuration.
|
||||
grunt.initConfig({
|
||||
// Metadata.
|
||||
pkg: grunt.file.readJSON("idle-timer.jquery.json"),
|
||||
banner: "/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - " +
|
||||
"<%= grunt.template.today('yyyy-mm-dd') %>\n" +
|
||||
"<%= pkg.homepage ? '* ' + pkg.homepage + '\\n' : '' %>" +
|
||||
"* Copyright (c) <%= grunt.template.today('yyyy') %> <%= pkg.author.name %>;" +
|
||||
" Licensed <%= _.pluck(pkg.licenses, 'type').join(', ') %> */\n",
|
||||
minbanner: "/*! <%= pkg.title || pkg.name %> v<%= pkg.version %> <%= grunt.template.today('yyyy-mm-dd') %> | " +
|
||||
"<%= pkg.homepage ? pkg.homepage : '' %> | (c) <%= grunt.template.today('yyyy') %> <%= pkg.author.name %> | " +
|
||||
"Licensed <%= _.pluck(pkg.licenses, 'type').join(', ') %> */\n",
|
||||
// Task configuration.
|
||||
concat: {
|
||||
options: {
|
||||
banner: "<%= banner %>",
|
||||
stripBanners: true
|
||||
},
|
||||
dist: {
|
||||
files: [
|
||||
{
|
||||
src: ["src/<%= pkg.name %>.js"],
|
||||
dest: "dist/<%= pkg.name %>.js"
|
||||
},
|
||||
{
|
||||
src: ["src/<%= pkg.name %>.js"],
|
||||
dest: "dist/<%= pkg.name %>.<%= pkg.version %>.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
uglify: {
|
||||
options: {
|
||||
banner: "<%= minbanner %>"
|
||||
},
|
||||
dist: {
|
||||
files: [
|
||||
{
|
||||
src: "<%= concat.dist.files[0].dest %>",
|
||||
dest: "dist/<%= pkg.name %>.min.js"
|
||||
},
|
||||
{
|
||||
src: "<%= concat.dist.files[0].dest %>",
|
||||
dest: "dist/<%= pkg.name %>.<%= pkg.version %>.min.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
qunit: {
|
||||
options: {
|
||||
timeout: 30000,
|
||||
"--web-security": "no",
|
||||
coverage: {
|
||||
src: [ "src/<%= pkg.name %>.js" ],
|
||||
instrumentedFiles: "temp/",
|
||||
htmlReport: "build/report/coverage",
|
||||
lcovReport: "build/report/lcov",
|
||||
linesThresholdPct: 0
|
||||
}
|
||||
},
|
||||
files: ["test/**/*.html"]
|
||||
},
|
||||
coveralls: {
|
||||
options: {
|
||||
// dont fail if coveralls fails
|
||||
force: true
|
||||
},
|
||||
main_target: {
|
||||
src: "build/report/lcov/lcov.info"
|
||||
}
|
||||
},
|
||||
jshint: {
|
||||
gruntfile: {
|
||||
options: {
|
||||
jshintrc: ".jshintrc"
|
||||
},
|
||||
src: "Gruntfile.js"
|
||||
},
|
||||
src: {
|
||||
options: {
|
||||
jshintrc: "src/.jshintrc"
|
||||
},
|
||||
src: ["src/**/*.js"]
|
||||
},
|
||||
test: {
|
||||
options: {
|
||||
jshintrc: "test/.jshintrc"
|
||||
},
|
||||
src: ["test/**/*.js"]
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
gruntfile: {
|
||||
files: "<%= jshint.gruntfile.src %>",
|
||||
tasks: ["jshint:gruntfile"]
|
||||
},
|
||||
src: {
|
||||
files: "<%= jshint.src.src %>",
|
||||
tasks: ["jshint:src", "qunit"]
|
||||
},
|
||||
test: {
|
||||
files: "<%= jshint.test.src %>",
|
||||
tasks: ["jshint:test", "qunit"]
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// These plugins provide necessary tasks.
|
||||
grunt.loadNpmTasks("grunt-contrib-jshint");
|
||||
grunt.loadNpmTasks("grunt-coveralls");
|
||||
grunt.loadNpmTasks("grunt-qunit-istanbul");
|
||||
grunt.loadNpmTasks("grunt-contrib-concat");
|
||||
grunt.loadNpmTasks("grunt-contrib-uglify");
|
||||
grunt.loadNpmTasks("grunt-contrib-watch");
|
||||
|
||||
// Default task.
|
||||
grunt.registerTask("default", ["jshint", "qunit", "concat", "uglify"]);
|
||||
|
||||
};
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2013 Paul Irish
|
||||
|
||||
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.
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
jQuery Idle Timer Plugin
|
||||
========================
|
||||
|
||||
[](https://travis-ci.org/thorst/jquery-idletimer)
|
||||
[](https://david-dm.org/thorst/jquery-idletimer)
|
||||
[](https://david-dm.org/thorst/jquery-idletimer#info=devDependencies)
|
||||
[](https://coveralls.io/r/thorst/jquery-idletimer?branch=master)
|
||||
|
||||
Demo
|
||||
--------
|
||||
http://thorst.github.io/jquery-idletimer/index.html
|
||||
|
||||
Download
|
||||
--------
|
||||
* [Compressed ~3kb](https://raw.github.com/thorst/jquery-idletimer/master/dist/idle-timer.min.js)
|
||||
* [Uncompressed ~11kb](https://raw.github.com/thorst/jquery-idletimer/master/dist/idle-timer.js)
|
||||
|
||||
Purpose
|
||||
-------
|
||||
|
||||
Fires a custom event when the user is "idle". Idle is defined by not...
|
||||
|
||||
* moving the mouse
|
||||
* scrolling the mouse wheel
|
||||
* using the keyboard
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
There are two ways to instantiate. Either statically, or on an element. Element bound timers
|
||||
will only watch for events inside of them. You may just want page-level activity, in which
|
||||
case you may set up your timers on `document`, `document.documentElement`, and `document.body`.
|
||||
Instantiate returns jQuery for chaining.
|
||||
|
||||
```javascript
|
||||
|
||||
// binds to document - shorthand
|
||||
$.idleTimer();
|
||||
|
||||
// binds to document - explicit
|
||||
$( document ).idleTimer();
|
||||
|
||||
// bind to different element
|
||||
$( "#myTextArea" ).idleTimer();
|
||||
|
||||
```
|
||||
|
||||
You can configure the settings several ways
|
||||
|
||||
```javascript
|
||||
|
||||
// idleTimer() with all defaults
|
||||
$( document ).idleTimer( );
|
||||
|
||||
// idleTimer() takes an optional numeric argument that defines just the idle timeout
|
||||
// timeout is in milliseconds
|
||||
$( document ).idleTimer( 10000 );
|
||||
|
||||
// idleTimer() takes an optional object argument that defines any/all setting
|
||||
$( document ).idleTimer( {
|
||||
timeout:10000,
|
||||
idle:true
|
||||
});
|
||||
|
||||
/*
|
||||
* Here are the possible settings
|
||||
* you can omit any or all of them
|
||||
*/
|
||||
|
||||
// indicates if the user is idle
|
||||
idle [default:false]
|
||||
|
||||
// the timeout period
|
||||
timeout [default:30000]
|
||||
|
||||
// activity is any one of these events
|
||||
events [default:'mousemove keydown wheel DOMMouseScroll mousewheel mousedown touchstart touchmove MSPointerDown MSPointerMove']
|
||||
|
||||
```
|
||||
|
||||
When a users state changes a custom events get triggered. There are several parameters
|
||||
passed to your handler for you to use
|
||||
|
||||
```javascript
|
||||
|
||||
$( document ).on( "idle.idleTimer", function(event, elem, obj){
|
||||
// function you want to fire when the user goes idle
|
||||
});
|
||||
|
||||
$( document ).on( "active.idleTimer", function(event, elem, obj, triggerevent){
|
||||
// function you want to fire when the user becomes active again
|
||||
});
|
||||
|
||||
/*
|
||||
* Here are the arguments
|
||||
*/
|
||||
// event
|
||||
// will be either idle.idleTimer or active.idleTimer
|
||||
// use event.stopPropagation(); to stop element from bubbling up to document
|
||||
|
||||
// elem
|
||||
// is the element that the event was triggered on
|
||||
|
||||
// obj
|
||||
// is a copy of the internal data used by idleTimer
|
||||
|
||||
// triggerevent
|
||||
// is the initial event that triggered the element to become active
|
||||
// obviously for idle state this will be undefined
|
||||
|
||||
```
|
||||
|
||||
There are several methods to invoke
|
||||
|
||||
```javascript
|
||||
|
||||
// stop the timer, removes data, removes event bindings
|
||||
// to come back from this you will need to instantiate again
|
||||
// returns: jQuery
|
||||
$( document ).idleTimer("destroy");
|
||||
|
||||
// save remaining time, and stops the timer
|
||||
// returns: jQuery
|
||||
$( document ).idleTimer("pause");
|
||||
|
||||
// starts timer with remaining time
|
||||
// returns: jQuery
|
||||
$( document ).idleTimer("resume");
|
||||
|
||||
// restore initial idle state, and restart the timer
|
||||
// returns: jQuery
|
||||
$( document ).idleTimer("reset");
|
||||
|
||||
// get time left until idle, if idle return 0
|
||||
// returns: number
|
||||
$( document ).idleTimer("getRemainingTime");
|
||||
|
||||
// get time elapsed (in ms) since the user went idle/active
|
||||
// if idle, how have you been idle, if active, how long have you been active
|
||||
// returns: number
|
||||
$( document ).idleTimer("getElapsedTime");
|
||||
|
||||
// get time last active event fired
|
||||
// returns: number
|
||||
$( document ).idleTimer("getLastActiveTime");
|
||||
|
||||
// you can also query if it's "idle" or "active"
|
||||
// returns: bool
|
||||
$( document ).idleTimer("isIdle");
|
||||
|
||||
```
|
||||
|
||||
Pre-Req
|
||||
-------
|
||||
jQuery 1.7 (tested with 1.11.0)
|
||||
|
||||
Intended Browser Support
|
||||
-------
|
||||
####Desktop
|
||||
* >=IE8
|
||||
* Firefox n-1
|
||||
* Chrome n-1
|
||||
* Safari n
|
||||
|
||||
####Mobile
|
||||
* iOS n-1
|
||||
* Android (version?)
|
||||
* Windows Phone IEMobile/10.0
|
||||
|
||||
Links
|
||||
-------
|
||||
* [jQuery plugin repo listing](http://plugins.jquery.com/idle-timer/)
|
||||
* [cdn](http://cdnjs.com/libraries/jquery-idletimer/)
|
||||
* [nuget]() - coming soon
|
||||
* [Eric Hynds Idle Timeout plugin](https://github.com/ehynds/jquery-idle-timeout)
|
||||
(note we have similar functionality [here](http://thorst.github.io/jquery-idletimer/prod/demos/autologout.html))
|
||||
|
||||
Playground
|
||||
-------
|
||||
* [js fiddle](http://jsfiddle.net/thorst/2aGL4/4/)
|
||||
* [css deck](http://cssdeck.com/labs/sosoro3m)
|
||||
|
||||
Version History
|
||||
-------
|
||||
| Version | Author | Released | Links |
|
||||
| --------------------------------------- |-----------------| ---------- | ----------------------------- |
|
||||
| [1.0.0](https://raw.github.com/thorst/jquery-idletimer/master/dist/idle-timer.1.0.0.min.js) | Todd Horst | 03/10/2014 | [Change Log](CHANGELOG.md) - [Breaking Changes](CHANGELOG.md#breaking-changes) |
|
||||
| [0.9.3](https://raw.github.com/thorst/jquery-idletimer/master/dist/idle-timer.0.9.3.min.js) | Mike Sherov | 08/04/2013 |
|
||||
|
||||
|
||||
Author History
|
||||
-------
|
||||
* Nicholas C. Zakas (yui Version) [idleTimer Blog](http://www.nczonline.net/blog/2009/06/02/detecting-if-the-user-is-idle-with-javascript-and-yui-3/) | [Github Profile](https://github.com/nzakas) | [Github](https://github.com/nzakas/jstools/)
|
||||
* Paul Irish (initial jQuery Version) [idleTimer Blog](http://paulirish.com/2009/jquery-idletimer-plugin/) | [Github Profile](https://github.com/paulirish) | [Github](https://github.com/paulirish/jquery-idletimer/)
|
||||
* Mike Sherov (transfered from Paul) [Github Profile](https://github.com/mikesherov)
|
||||
* Todd Horst (transfered from Mike) [Github Profile](https://github.com/thorst)
|
||||
|
||||
Bug?
|
||||
-------
|
||||
Please create a [fiddle](http://jsfiddle.net/thorst/2aGL4/4/) and [submit a ticket](https://github.com/thorst/jquery-idletimer/issues/new)
|
||||
@@ -0,0 +1,187 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8' />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Jquery-idletimer : provides you a way to monitor user activity with a page." />
|
||||
<title>Jquery-idletimer</title>
|
||||
|
||||
<!-- jQuery and idleTimer -->
|
||||
<script type="text/javascript" src="//code.jquery.com/jquery-1.11.0.min.js"></script>
|
||||
<script type="text/javascript" src="../src/idle-timer.js"></script>
|
||||
|
||||
<!-- Bootstrap/respond (ie8) and moment -->
|
||||
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.js"></script>
|
||||
|
||||
<!-- Respond.js proxy on external server -->
|
||||
<link href="//netdna.bootstrapcdn.com/respond-proxy.html" id="respond-proxy" rel="respond-proxy" />
|
||||
<link href="respond.proxy.gif" id="respond-redirect" rel="respond-redirect" />
|
||||
<script src="respond.proxy.js"></script>
|
||||
<style>
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
body {
|
||||
margin-top: 40px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="index.html">Jquery-idletimer</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="index.html">Main Demo</a></li>
|
||||
<li><a href="defaultbinding.html">Default Binding</a></li>
|
||||
<li><a href="https://github.com/thorst/jquery-idletimer">Documentation</a></li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="https://github.com/thorst/jquery-idletimer/zipball/master">Zip</a></li>
|
||||
<li><a href="https://github.com/thorst/jquery-idletimer/tarball/master">Tar</a></li>
|
||||
<li><a href="https://github.com/thorst/jquery-idletimer">Github</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<h2>Concept</h2>
|
||||
<p>
|
||||
Wait 10 seconds, you will see a expiring warning. Wait 10 more seconds and you will see that you have been logged out.
|
||||
</p>
|
||||
<p>
|
||||
In the real world I forward them to the logout url, which intern fowards them to login screen, instead of showing the 2nd dialog.
|
||||
You can modify the session.logout function.
|
||||
</p>
|
||||
<p>
|
||||
We could use the active.idleTimer event to clearTimeout, however I prefer the user to explicitly say they want to keep the
|
||||
session open by clicking ok, not just moving the mouse on the screen.
|
||||
</p>
|
||||
<p>
|
||||
This demo takes into account when a mobile device closes the browser, and after the idle timeout expires, launches the browser again. Instead
|
||||
of displaying the warning, it will jump straight to the logged out dialog.
|
||||
</p>
|
||||
<p>
|
||||
For the sake of complete demo, I've included the code needed to call a keepalive url to keep the server side session valid.
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Session Expiration Warning</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>You've been inactive for a while. For your security, we'll log you out automatically. Click "Stay Online" to continue your session. </p>
|
||||
<p>Your session will expire in <span class="bold" id="sessionSecondsRemaining">120</span> seconds.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="extendSession" type="button" class="btn btn-default btn-success" data-dismiss="modal">Stay Online</button>
|
||||
<button id="logoutSession" type="button" class="btn btn-default" data-dismiss="modal">Logout</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="mdlLoggedOut" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">You have been logged out</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Your session has expired.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function ($) {
|
||||
var
|
||||
session = {
|
||||
//Logout Settings
|
||||
inactiveTimeout: 10000, //(ms) The time until we display a warning message
|
||||
warningTimeout: 10000, //(ms) The time until we log them out
|
||||
minWarning: 5000, //(ms) If they come back to page (on mobile), The minumum amount, before we just log them out
|
||||
warningStart: null, //Date time the warning was started
|
||||
warningTimer: null, //Timer running every second to countdown to logout
|
||||
logout: function () { //Logout function once warningTimeout has expired
|
||||
//window.location = settings.autologout.logouturl;
|
||||
$("#mdlLoggedOut").modal("show");
|
||||
},
|
||||
|
||||
//Keepalive Settings
|
||||
keepaliveTimer: null,
|
||||
keepaliveUrl: "",
|
||||
keepaliveInterval: 5000, //(ms) the interval to call said url
|
||||
keepAlive: function () {
|
||||
$.ajax({ url: session.keepaliveUrl });
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
$(document).on("idle.idleTimer", function (event, elem, obj) {
|
||||
//Get time when user was last active
|
||||
var
|
||||
diff = (+new Date()) - obj.lastActive - obj.timeout,
|
||||
warning = (+new Date()) - diff
|
||||
;
|
||||
|
||||
//On mobile js is paused, so see if this was triggered while we were sleeping
|
||||
if (diff >= session.warningTimeout || warning <= session.minWarning) {
|
||||
$("#mdlLoggedOut").modal("show");
|
||||
} else {
|
||||
//Show dialog, and note the time
|
||||
$('#sessionSecondsRemaining').html(Math.round((session.warningTimeout - diff) / 1000));
|
||||
$("#myModal").modal("show");
|
||||
session.warningStart = (+new Date()) - diff;
|
||||
|
||||
//Update counter downer every second
|
||||
session.warningTimer = setInterval(function () {
|
||||
var remaining = Math.round((session.warningTimeout / 1000) - (((+new Date()) - session.warningStart) / 1000));
|
||||
if (remaining >= 0) {
|
||||
$('#sessionSecondsRemaining').html(remaining);
|
||||
} else {
|
||||
session.logout();
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
});
|
||||
|
||||
// create a timer to keep server session alive, independent of idle timer
|
||||
session.keepaliveTimer = setInterval(function () {
|
||||
session.keepAlive();
|
||||
}, session.keepaliveInterval);
|
||||
|
||||
//User clicked ok to extend session
|
||||
$("#extendSession").click(function () {
|
||||
clearTimeout(session.warningTimer);
|
||||
});
|
||||
//User clicked logout
|
||||
$("#logoutSession").click(function () {
|
||||
session.logout();
|
||||
});
|
||||
|
||||
//Set up the timer, if inactive for 10 seconds log them out
|
||||
$(document).idleTimer(session.inactiveTimeout);
|
||||
})(jQuery);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,455 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset='utf-8' />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Jquery-idletimer : provides you a way to monitor user activity with a page." />
|
||||
<title>Jquery-idletimer</title>
|
||||
|
||||
<!-- jQuery and idleTimer -->
|
||||
<script type="text/javascript" src="//code.jquery.com/jquery-1.11.0.min.js"></script>
|
||||
<script type="text/javascript" src="../src/idle-timer.js"></script>
|
||||
|
||||
<!-- Bootstrap/respond (ie8) and moment -->
|
||||
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.js"></script>
|
||||
|
||||
<!-- Respond.js proxy on external server -->
|
||||
<link href="//netdna.bootstrapcdn.com/respond-proxy.html" id="respond-proxy" rel="respond-proxy" />
|
||||
<link href="respond.proxy.gif" id="respond-redirect" rel="respond-redirect" />
|
||||
<script src="respond.proxy.js"></script>
|
||||
<style>
|
||||
body {
|
||||
margin-top: 40px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 5px 6px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="index.html">Jquery-idletimer</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="index.html">Main Demo</a></li>
|
||||
<li><a href="autologout.html">Auto Logout</a></li>
|
||||
<li><a href="https://github.com/thorst/jquery-idletimer">Documentation</a></li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="https://github.com/thorst/jquery-idletimer/zipball/master">Zip</a></li>
|
||||
<li><a href="https://github.com/thorst/jquery-idletimer/tarball/master">Tar</a></li>
|
||||
<li><a href="https://github.com/thorst/jquery-idletimer">Github</a></li>
|
||||
</ul>
|
||||
</div> <!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<h2>Concept</h2>
|
||||
<p>Here we use default bindings. Instead of explicitly telling idleTimer which element to bind to, it assumes document.</p>
|
||||
<p>Some previous versions had issues mixing default binding with explicit calling on document.</p>
|
||||
<p>This should no longer be the case. To test I've added 2 sets of buttons to show that they can be mixed.</p>
|
||||
<p>The background color changes to show that it is returning a jQuery object</p>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h3>Document <small><span id="docTimeout"></span> second timeout</small></h3>
|
||||
<h4>default binding</h4>
|
||||
<div class="btn-group">
|
||||
<a href="#" id="btDefaultPause" class="btn btn-default btn-sm">Pause</a>
|
||||
<a href="#" id="btDefaultResume" class="btn btn-default btn-sm">Resume</a>
|
||||
<a href="#" id="btDefaultElapsed" class="btn btn-default btn-sm">Elapsed</a>
|
||||
<a href="#" id="btDefaultInit" class="btn btn-default btn-sm">Init</a>
|
||||
<a href="#" id="btDefaultDestroy" class="btn btn-default btn-sm">Destroy</a>
|
||||
|
||||
<a href="#" id="btDefaultReset" class="btn btn-default btn-sm">Reset</a>
|
||||
<a href="#" id="btDefaultLastActive" class="btn btn-default btn-sm">Last Active</a>
|
||||
<a href="#" id="btDefaultRemaining" class="btn btn-default btn-sm">Remaining</a>
|
||||
<a href="#" id="btDefaultState" class="btn btn-default btn-sm">State</a>
|
||||
</div>
|
||||
<h4>explicit binding</h4>
|
||||
<div class="btn-group">
|
||||
<a href="#" id="btExplicitPause" class="btn btn-default btn-sm">Pause</a>
|
||||
<a href="#" id="btExplicitResume" class="btn btn-default btn-sm">Resume</a>
|
||||
<a href="#" id="btExplicitElapsed" class="btn btn-default btn-sm">Elapsed</a>
|
||||
<a href="#" id="btExplicitInit" class="btn btn-default btn-sm">Init</a>
|
||||
<a href="#" id="btExplicitDestroy" class="btn btn-default btn-sm">Destroy</a>
|
||||
|
||||
<a href="#" id="btExplicitReset" class="btn btn-default btn-sm">Reset</a>
|
||||
<a href="#" id="btExplicitLastActive" class="btn btn-default btn-sm">Last Active</a>
|
||||
<a href="#" id="btExplicitRemaining" class="btn btn-default btn-sm">Remaining</a>
|
||||
<a href="#" id="btExplicitState" class="btn btn-default btn-sm">State</a>
|
||||
</div>
|
||||
<textarea rows="10" cols="30" id="docStatus" class="form-control"></textarea><br />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/*
|
||||
scrollToBottom plugin, chainable
|
||||
*/
|
||||
$.fn.scrollToBottom = function () {
|
||||
this.scrollTop(this[0].scrollHeight);
|
||||
return this;
|
||||
};
|
||||
var rndColor = function () {
|
||||
return '#' + Math.floor(Math.random() * 16777215).toString(16);
|
||||
}
|
||||
var
|
||||
docTimeout = 5000
|
||||
;
|
||||
</script>
|
||||
|
||||
<script>
|
||||
/*
|
||||
Code for document idle timer
|
||||
*/
|
||||
(function ($) {
|
||||
|
||||
// Display the actual timeout on the page
|
||||
$('#docTimeout').text(docTimeout / 1000);
|
||||
|
||||
//Clear old statuses
|
||||
$('#docStatus').val('');
|
||||
|
||||
//Handle idle event
|
||||
$(document).on("idle.idleTimer", function () {
|
||||
$("#docStatus")
|
||||
.val(function (i, v) {
|
||||
return v + "Idle @ " + new Date() + " \n";
|
||||
})
|
||||
.removeClass("alert-success")
|
||||
.addClass("alert-warning")
|
||||
.scrollToBottom();
|
||||
});
|
||||
|
||||
//Handle active event
|
||||
$(document).on("active.idleTimer", function () {
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Active @ " + new Date() + " \n";
|
||||
})
|
||||
.addClass("alert-success")
|
||||
.removeClass("alert-warning")
|
||||
.scrollToBottom();
|
||||
});
|
||||
|
||||
//Start timeout, passing no options
|
||||
//Same as $(document).idleTimer(docTimeout);
|
||||
$.idleTimer(docTimeout);
|
||||
|
||||
//For demo purposes, get initial state and style accordingly
|
||||
if ($.idleTimer("isIdle")) {
|
||||
$("#docStatus")
|
||||
.val(function (i, v) {
|
||||
return v + "Initial Idle @ " + new Date() + " \n";
|
||||
})
|
||||
.removeClass("alert-success")
|
||||
.addClass("alert-warning")
|
||||
.scrollToBottom();
|
||||
} else {
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Initial Active @ " + new Date() + " \n";
|
||||
})
|
||||
.addClass("alert-success")
|
||||
.removeClass("alert-warning")
|
||||
.scrollToBottom();
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function ($) {
|
||||
|
||||
/*
|
||||
Handle button events
|
||||
*/
|
||||
$("#btDefaultPause").click(function () {
|
||||
//pause
|
||||
$.idleTimer("pause").find("h2").css({ "background-color": rndColor() });
|
||||
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Paused @ " + new Date() + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btDefaultResume").click(function () {
|
||||
//resume
|
||||
$.idleTimer("resume").find("h2").css({ "background-color": rndColor() });
|
||||
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Resumed @ " + new Date() + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btDefaultElapsed").click(function () {
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Elapsed: " + $.idleTimer("getElapsedTime") + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btDefaultInit").click(function () {
|
||||
// for demo purposes show init with just object
|
||||
$.idleTimer({ timeout: docTimeout }).find("h2").css({ "background-color": rndColor() });
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Init: @ " + moment().format() + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
|
||||
//Apply classes for default state
|
||||
if ($.idleTimer("isIdle")) {
|
||||
$('#docStatus')
|
||||
.removeClass("alert-success")
|
||||
.addClass("alert-warning");
|
||||
} else {
|
||||
$('#docStatus')
|
||||
.addClass("alert-success")
|
||||
.removeClass("alert-warning");
|
||||
}
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btDefaultDestroy").click(function () {
|
||||
// console.log($.idleTimer("destroy"));
|
||||
$.idleTimer("destroy").find("h2").css({ "background-color": rndColor() });
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Destroyed: @ " + moment().format() + " \n";
|
||||
})
|
||||
.removeClass("alert-success")
|
||||
.removeClass("alert-warning")
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btDefaultReset").click(function () {
|
||||
|
||||
//Reset
|
||||
var s = $.idleTimer("reset").find("h2").css({ "background-color": rndColor() });
|
||||
|
||||
//Output
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Reset @ " + new Date() + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
|
||||
//Apply classes for default state
|
||||
var idle = $.idleTimer("isIdle");
|
||||
if (idle) {
|
||||
$('#docStatus')
|
||||
.removeClass("alert-success")
|
||||
.addClass("alert-warning");
|
||||
} else {
|
||||
$('#docStatus')
|
||||
.addClass("alert-success")
|
||||
.removeClass("alert-warning");
|
||||
}
|
||||
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btDefaultLastActive").click(function () {
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Last Active: " + $.idleTimer("getLastActiveTime") + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btDefaultRemaining").click(function () {
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Remaining: " + $.idleTimer("getRemainingTime") + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btDefaultState").click(function () {
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "State: " + ($.idleTimer("isIdle") ? "idle" : "active") + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function ($) {
|
||||
|
||||
/*
|
||||
Handle button events
|
||||
*/
|
||||
$("#btExplicitPause").click(function () {
|
||||
//pause
|
||||
$(document).idleTimer("pause").find("h2").css({ "background-color": rndColor() });
|
||||
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Paused @ " + new Date() + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btExplicitResume").click(function () {
|
||||
//resume
|
||||
$(document).idleTimer("resume").find("h2").css({ "background-color": rndColor() });
|
||||
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Resumed @ " + new Date() + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btExplicitElapsed").click(function () {
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Elapsed: " + $(document).idleTimer("getElapsedTime") + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btExplicitInit").click(function () {
|
||||
// for demo purposes show init with just object
|
||||
$.idleTimer({ timeout: docTimeout }).find("h2").css({ "background-color": rndColor() });
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Init: @ " + moment().format() + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
|
||||
//Apply classes for default state
|
||||
if ($(document).idleTimer("isIdle")) {
|
||||
$('#docStatus')
|
||||
.removeClass("alert-success")
|
||||
.addClass("alert-warning");
|
||||
} else {
|
||||
$('#docStatus')
|
||||
.addClass("alert-success")
|
||||
.removeClass("alert-warning");
|
||||
}
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btExplicitDestroy").click(function () {
|
||||
|
||||
$(document).idleTimer("destroy").find("h2").css({ "background-color": rndColor() });
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Destroyed: @ " + moment().format() + " \n";
|
||||
})
|
||||
.removeClass("alert-success")
|
||||
.removeClass("alert-warning")
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btExplicitReset").click(function () {
|
||||
|
||||
//Reset
|
||||
var s = $(document).idleTimer("reset").find("h2").css({ "background-color": rndColor() });
|
||||
|
||||
//Output
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Reset @ " + new Date() + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
|
||||
//Apply classes for default state
|
||||
var idle = $(document).idleTimer("isIdle");
|
||||
if (idle) {
|
||||
$('#docStatus')
|
||||
.removeClass("alert-success")
|
||||
.addClass("alert-warning");
|
||||
} else {
|
||||
$('#docStatus')
|
||||
.addClass("alert-success")
|
||||
.removeClass("alert-warning");
|
||||
}
|
||||
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btExplicitLastActive").click(function () {
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Last Active: " + $(document).idleTimer("getLastActiveTime") + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btExplicitRemaining").click(function () {
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Remaining: " + $(document).idleTimer("getRemainingTime") + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btExplicitState").click(function () {
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "State: " + ($(document).idleTimer("isIdle") ? "idle" : "active") + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
})(jQuery);
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
+388
@@ -0,0 +1,388 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8' />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="Jquery-idletimer : provides you a way to monitor user activity with a page." />
|
||||
<title>Jquery-idletimer</title>
|
||||
|
||||
<!-- jQuery and idleTimer -->
|
||||
<script type="text/javascript" src="//code.jquery.com/jquery-1.11.0.min.js"></script>
|
||||
<script type="text/javascript" src="../src/idle-timer.js"></script>
|
||||
|
||||
<!-- Bootstrap/respond (ie8) and moment -->
|
||||
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.js"></script>
|
||||
|
||||
<!-- Respond.js proxy on external server -->
|
||||
<link href="//netdna.bootstrapcdn.com/respond-proxy.html" id="respond-proxy" rel="respond-proxy" />
|
||||
<link href="respond.proxy.gif" id="respond-redirect" rel="respond-redirect" />
|
||||
<script src="respond.proxy.js"></script>
|
||||
<style>
|
||||
body {
|
||||
margin-top: 40px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 5px 6px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="index.html">Jquery-idletimer</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="autologout.html">Auto Logout</a></li>
|
||||
<li><a href="defaultbinding.html">Default Binding</a></li>
|
||||
<li><a href="https://github.com/thorst/jquery-idletimer">Documentation</a></li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="https://github.com/thorst/jquery-idletimer/zipball/master">Zip</a></li>
|
||||
<li><a href="https://github.com/thorst/jquery-idletimer/tarball/master">Tar</a></li>
|
||||
<li><a href="https://github.com/thorst/jquery-idletimer">Github</a></li>
|
||||
</ul>
|
||||
</div> <!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<h2>Concept</h2>
|
||||
<p>The idle timer is built on <a href="http://jquery.com/">jQuery</a> and provides two events: <code>idle.idleTimer</code> and <code>active.idleTimer</code>, which fire when the user's idle state has changed.</p>
|
||||
<p>When you move your mouse over the page or start typing, you're considered "active".</p>
|
||||
<p>On this page we have two idle timers. One for the entire document. Another for the text area on the right (or bottom if your on mobile).</p>
|
||||
<p>I use explicit instantiation here</p>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h3>Document <small><span id="docTimeout"></span> second timeout</small></h3>
|
||||
<div class="btn-group">
|
||||
<a href="#" id="btPause" class="btn btn-default btn-sm">Pause</a>
|
||||
<a href="#" id="btResume" class="btn btn-default btn-sm">Resume</a>
|
||||
<a href="#" id="btElapsed" class="btn btn-default btn-sm">Elapsed</a>
|
||||
<a href="#" id="btInit" class="btn btn-default btn-sm">Init</a>
|
||||
<a href="#" id="btDestroy" class="btn btn-default btn-sm">Destroy</a>
|
||||
</div>
|
||||
<textarea rows="10" cols="30" id="docStatus" class="form-control"></textarea><br />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h3>Element <small><span id="elTimeout"></span> second timeout</small></h3>
|
||||
<div class="btn-group">
|
||||
<a href="#" id="btReset" class="btn btn-default btn-sm">Reset</a>
|
||||
<a href="#" id="btLastActive" class="btn btn-default btn-sm">Last Active</a>
|
||||
<a href="#" id="btRemaining" class="btn btn-default btn-sm">Remaining</a>
|
||||
<a href="#" id="btState" class="btn btn-default btn-sm">State</a>
|
||||
</div>
|
||||
<textarea rows="10" cols="30" id="elStatus" class="form-control"></textarea><br />
|
||||
</div>
|
||||
</div>
|
||||
<h3>Dialogs</h3>
|
||||
<!-- Button trigger modal -->
|
||||
<button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
|
||||
Launch modal
|
||||
</button>
|
||||
<button id="alert" class="btn btn-primary btn-lg">
|
||||
Launch alert
|
||||
</button>
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
...
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
/*
|
||||
scrollToBottom plugin, chainable
|
||||
*/
|
||||
$.fn.scrollToBottom = function () {
|
||||
this.scrollTop(this[0].scrollHeight);
|
||||
return this;
|
||||
};
|
||||
/*
|
||||
click event for alert button
|
||||
*/
|
||||
(function ($) {
|
||||
//Display alert
|
||||
$("#alert").click(function () { alert("Hello!"); return false; });
|
||||
})(jQuery);
|
||||
|
||||
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
/*
|
||||
Code for document idle timer
|
||||
*/
|
||||
(function ($) {
|
||||
//Define default
|
||||
var
|
||||
docTimeout = 5000
|
||||
;
|
||||
|
||||
/*
|
||||
Handle raised idle/active events
|
||||
*/
|
||||
$(document).on("idle.idleTimer", function (event, elem, obj) {
|
||||
$("#docStatus")
|
||||
.val(function (i, v) {
|
||||
return v + "Idle @ " + moment().format() + " \n";
|
||||
})
|
||||
.removeClass("alert-success")
|
||||
.addClass("alert-warning")
|
||||
.scrollToBottom();
|
||||
});
|
||||
$(document).on("active.idleTimer", function (event, elem, obj, e) {
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Active [" + e.type + "] [" + e.target.nodeName + "] @ " + moment().format() + " \n";
|
||||
})
|
||||
.addClass("alert-success")
|
||||
.removeClass("alert-warning")
|
||||
.scrollToBottom();
|
||||
});
|
||||
|
||||
/*
|
||||
Handle button events
|
||||
*/
|
||||
$("#btPause").click(function () {
|
||||
$(document).idleTimer("pause");
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Paused @ " + moment().format() + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btResume").click(function () {
|
||||
$(document).idleTimer("resume");
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Resumed @ " + moment().format() + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btElapsed").click(function () {
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Elapsed (since becoming active): " + $(document).idleTimer("getElapsedTime") + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btDestroy").click(function () {
|
||||
$(document).idleTimer("destroy");
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Destroyed: @ " + moment().format() + " \n";
|
||||
})
|
||||
.removeClass("alert-success")
|
||||
.removeClass("alert-warning")
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btInit").click(function () {
|
||||
// for demo purposes show init with just object
|
||||
$(document).idleTimer({ timeout: docTimeout });
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Init: @ " + moment().format() + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
|
||||
//Apply classes for default state
|
||||
if ($(document).idleTimer("isIdle")) {
|
||||
$('#docStatus')
|
||||
.removeClass("alert-success")
|
||||
.addClass("alert-warning");
|
||||
} else {
|
||||
$('#docStatus')
|
||||
.addClass("alert-success")
|
||||
.removeClass("alert-warning");
|
||||
}
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
|
||||
//Clear old statuses
|
||||
$('#docStatus').val('');
|
||||
|
||||
//Start timeout, passing no options
|
||||
//Same as $.idleTimer(docTimeout, docOptions);
|
||||
$(document).idleTimer(docTimeout);
|
||||
|
||||
//For demo purposes, style based on initial state
|
||||
if ($(document).idleTimer("isIdle")) {
|
||||
$("#docStatus")
|
||||
.val(function (i, v) {
|
||||
return v + "Initial Idle State @ " + moment().format() + " \n";
|
||||
})
|
||||
.removeClass("alert-success")
|
||||
.addClass("alert-warning")
|
||||
.scrollToBottom();
|
||||
} else {
|
||||
$('#docStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Initial Active State @ " + moment().format() + " \n";
|
||||
})
|
||||
.addClass("alert-success")
|
||||
.removeClass("alert-warning")
|
||||
.scrollToBottom();
|
||||
}
|
||||
|
||||
|
||||
//For demo purposes, display the actual timeout on the page
|
||||
$('#docTimeout').text(docTimeout / 1000);
|
||||
|
||||
|
||||
})(jQuery);
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
/*
|
||||
Code for element idle timer
|
||||
*/
|
||||
(function ($) {
|
||||
//Define textarea settings
|
||||
var
|
||||
taTimeout = 3000
|
||||
;
|
||||
|
||||
/*
|
||||
Handle raised idle/active events
|
||||
*/
|
||||
$('#elStatus').on("idle.idleTimer", function (event, elem, obj) {
|
||||
//If you dont stop propagation it will bubble up to document event handler
|
||||
event.stopPropagation();
|
||||
|
||||
$('#elStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Idle @ " + moment().format() + " \n";
|
||||
})
|
||||
.removeClass("alert-success")
|
||||
.addClass("alert-warning")
|
||||
.scrollToBottom();
|
||||
|
||||
});
|
||||
$('#elStatus').on("active.idleTimer", function (event) {
|
||||
//If you dont stop propagation it will bubble up to document event handler
|
||||
event.stopPropagation();
|
||||
|
||||
$('#elStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Active @ " + moment().format() + " \n";
|
||||
})
|
||||
.addClass("alert-success")
|
||||
.removeClass("alert-warning")
|
||||
.scrollToBottom();
|
||||
});
|
||||
|
||||
/*
|
||||
Handle button events
|
||||
*/
|
||||
$("#btReset").click(function () {
|
||||
$('#elStatus')
|
||||
.idleTimer("reset")
|
||||
.val(function (i, v) {
|
||||
return v + "Reset @ " + moment().format() + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
|
||||
//Apply classes for default state
|
||||
if ($("#elStatus").idleTimer("isIdle")) {
|
||||
$('#elStatus')
|
||||
.removeClass("alert-success")
|
||||
.addClass("alert-warning");
|
||||
} else {
|
||||
$('#elStatus')
|
||||
.addClass("alert-success")
|
||||
.removeClass("alert-warning");
|
||||
}
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btRemaining").click(function () {
|
||||
$('#elStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Remaining: " + $("#elStatus").idleTimer("getRemainingTime") + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btLastActive").click(function () {
|
||||
$('#elStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "LastActive: " + $("#elStatus").idleTimer("getLastActiveTime") + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
$("#btState").click(function () {
|
||||
$('#elStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "State: " + ($("#elStatus").idleTimer("isIdle")? "idle":"active") + " \n";
|
||||
})
|
||||
.scrollToBottom();
|
||||
$(this).blur();
|
||||
return false;
|
||||
});
|
||||
|
||||
//Clear value if there was one cached & start time
|
||||
$('#elStatus').val('').idleTimer(taTimeout);
|
||||
|
||||
//For demo purposes, show initial state
|
||||
if ($("#elStatus").idleTimer("isIdle")) {
|
||||
$("#elStatus")
|
||||
.val(function (i, v) {
|
||||
return v + "Initial Idle @ " + moment().format() + " \n";
|
||||
})
|
||||
.removeClass("alert-success")
|
||||
.addClass("alert-warning")
|
||||
.scrollToBottom();
|
||||
} else {
|
||||
$('#elStatus')
|
||||
.val(function (i, v) {
|
||||
return v + "Initial Active @ " + moment().format() + " \n";
|
||||
})
|
||||
.addClass("alert-success")
|
||||
.removeClass("alert-warning")
|
||||
.scrollToBottom();
|
||||
}
|
||||
|
||||
// Display the actual timeout on the page
|
||||
$('#elTimeout').text(taTimeout / 1000);
|
||||
|
||||
})(jQuery);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 35 B |
@@ -0,0 +1,129 @@
|
||||
/*! Respond.js: min/max-width media query polyfill. Remote proxy (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */
|
||||
(function(win, doc, undefined){
|
||||
var docElem = doc.documentElement,
|
||||
proxyURL = doc.getElementById("respond-proxy").href,
|
||||
redirectURL = (doc.getElementById("respond-redirect") || location).href,
|
||||
baseElem = doc.getElementsByTagName("base")[0],
|
||||
urls = [],
|
||||
refNode;
|
||||
|
||||
function encode(url){
|
||||
return win.encodeURIComponent(url);
|
||||
}
|
||||
|
||||
function fakejax( url, callback ){
|
||||
|
||||
var iframe,
|
||||
AXO;
|
||||
|
||||
// All hail Google http://j.mp/iKMI19
|
||||
// Behold, an iframe proxy without annoying clicky noises.
|
||||
if ( "ActiveXObject" in win ) {
|
||||
AXO = new ActiveXObject( "htmlfile" );
|
||||
AXO.open();
|
||||
AXO.write( '<iframe id="x"></iframe>' );
|
||||
AXO.close();
|
||||
iframe = AXO.getElementById( "x" );
|
||||
} else {
|
||||
iframe = doc.createElement( "iframe" );
|
||||
iframe.style.cssText = "position:absolute;top:-99em";
|
||||
docElem.insertBefore(iframe, docElem.firstElementChild || docElem.firstChild );
|
||||
}
|
||||
|
||||
iframe.src = checkBaseURL(proxyURL) + "?url=" + encode(redirectURL) + "&css=" + encode(checkBaseURL(url));
|
||||
|
||||
function checkFrameName() {
|
||||
var cssText;
|
||||
|
||||
try {
|
||||
cssText = iframe.contentWindow.name;
|
||||
}
|
||||
catch (e) { }
|
||||
|
||||
if (cssText) {
|
||||
// We've got what we need. Stop the iframe from loading further content.
|
||||
iframe.src = "about:blank";
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
iframe = null;
|
||||
|
||||
|
||||
// Per http://j.mp/kn9EPh, not taking any chances. Flushing the ActiveXObject
|
||||
if (AXO) {
|
||||
AXO = null;
|
||||
|
||||
if (win.CollectGarbage) {
|
||||
win.CollectGarbage();
|
||||
}
|
||||
}
|
||||
|
||||
callback(cssText);
|
||||
}
|
||||
else{
|
||||
win.setTimeout(checkFrameName, 100);
|
||||
}
|
||||
}
|
||||
|
||||
win.setTimeout(checkFrameName, 500);
|
||||
}
|
||||
|
||||
// http://stackoverflow.com/a/472729
|
||||
function checkBaseURL(href) {
|
||||
var el = document.createElement('div'),
|
||||
escapedURL = href.split('&').join('&').
|
||||
split('<').join('<').
|
||||
split('"').join('"');
|
||||
|
||||
el.innerHTML = '<a href="' + escapedURL + '">x</a>';
|
||||
return el.firstChild.href;
|
||||
}
|
||||
|
||||
function checkRedirectURL() {
|
||||
// IE6 & IE7 don't build out absolute urls in <link /> attributes.
|
||||
// So respond.proxy.gif remains relative instead of http://example.com/respond.proxy.gif.
|
||||
// This trickery resolves that issue.
|
||||
if (~ !redirectURL.indexOf(location.host)) {
|
||||
|
||||
var fakeLink = doc.createElement("div");
|
||||
|
||||
fakeLink.innerHTML = '<a href="' + redirectURL + '"></a>';
|
||||
docElem.insertBefore(fakeLink, docElem.firstElementChild || docElem.firstChild );
|
||||
|
||||
// Grab the parsed URL from that dummy object
|
||||
redirectURL = fakeLink.firstChild.href;
|
||||
|
||||
// Clean up
|
||||
fakeLink.parentNode.removeChild(fakeLink);
|
||||
fakeLink = null;
|
||||
}
|
||||
}
|
||||
|
||||
function buildUrls(){
|
||||
var links = doc.getElementsByTagName( "link" );
|
||||
|
||||
for( var i = 0, linkl = links.length; i < linkl; i++ ){
|
||||
|
||||
var thislink = links[i],
|
||||
href = links[i].href,
|
||||
extreg = (/^([a-zA-Z:]*\/\/(www\.)?)/).test( href ),
|
||||
ext = (baseElem && !extreg) || extreg;
|
||||
|
||||
//make sure it's an external stylesheet
|
||||
if( thislink.rel.indexOf( "stylesheet" ) >= 0 && ext ){
|
||||
(function( link ){
|
||||
fakejax( href, function( css ){
|
||||
link.styleSheet.rawCssText = css;
|
||||
respond.update();
|
||||
} );
|
||||
})( thislink );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if( !respond.mediaQueriesSupported ){
|
||||
checkRedirectURL();
|
||||
buildUrls();
|
||||
}
|
||||
|
||||
})( window, document );
|
||||
@@ -0,0 +1,144 @@
|
||||
/*! Idle Timer - v0.9.2 - 2013-08-04
|
||||
* https://github.com/mikesherov/jquery-idletimer
|
||||
* Copyright (c) 2013 Paul Irish; Licensed MIT */
|
||||
( function( $ ) {
|
||||
|
||||
$.idleTimer = function( firstParam, elem, opts ) {
|
||||
|
||||
// defaults that are to be stored as instance props on the elem
|
||||
opts = $.extend( {
|
||||
startImmediately: true, //starts a timeout as soon as the timer is set up
|
||||
idle: false, //indicates if the user is idle
|
||||
enabled: true, //indicates if the idle timer is enabled
|
||||
timeout: 30000, //the amount of time (ms) before the user is considered idle
|
||||
events: "mousemove keydown DOMMouseScroll mousewheel mousedown touchstart touchmove" // activity is one of these events
|
||||
}, opts );
|
||||
|
||||
|
||||
elem = elem || document;
|
||||
|
||||
var jqElem = $( elem ),
|
||||
obj = jqElem.data("idleTimerObj") || {},
|
||||
|
||||
/* (intentionally not documented)
|
||||
* Toggles the idle state and fires an appropriate event.
|
||||
* @return {void}
|
||||
*/
|
||||
toggleIdleState = function( myelem ) {
|
||||
|
||||
// curse you, mozilla setTimeout lateness bug!
|
||||
if ( typeof myelem === "number" ) {
|
||||
myelem = undefined;
|
||||
}
|
||||
|
||||
var obj = $.data( myelem || elem, "idleTimerObj" );
|
||||
|
||||
//toggle the state
|
||||
obj.idle = !obj.idle;
|
||||
|
||||
// reset timeout
|
||||
var elapsed = ( +new Date() ) - obj.olddate;
|
||||
obj.olddate = +new Date();
|
||||
|
||||
// handle Chrome always triggering idle after js alert or comfirm popup
|
||||
if ( obj.idle && ( elapsed < opts.timeout ) ) {
|
||||
obj.idle = false;
|
||||
clearTimeout( $.idleTimer.tId );
|
||||
if ( opts.enabled ) {
|
||||
$.idleTimer.tId = setTimeout( toggleIdleState, opts.timeout );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// create a custom event, but first, store the new state on the element
|
||||
// and then append that string to a namespace
|
||||
var event = $.Event( $.data( elem, "idleTimer", obj.idle ? "idle" : "active" ) + ".idleTimer" );
|
||||
$( elem ).trigger( event );
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops the idle timer. This removes appropriate event handlers
|
||||
* and cancels any pending timeouts.
|
||||
* @return {void}
|
||||
* @method stop
|
||||
* @static
|
||||
*/
|
||||
stop = function( jqElem ) {
|
||||
|
||||
var obj = jqElem.data("idleTimerObj") || {};
|
||||
|
||||
//set to disabled
|
||||
obj.enabled = false;
|
||||
|
||||
//clear any pending timeouts
|
||||
clearTimeout( obj.tId );
|
||||
|
||||
//detach the event handlers
|
||||
jqElem.off(".idleTimer");
|
||||
};
|
||||
|
||||
obj.olddate = obj.olddate || +new Date();
|
||||
|
||||
if ( typeof firstParam === "number" ) {
|
||||
opts.timeout = firstParam;
|
||||
} else if ( firstParam === "destroy" ) {
|
||||
stop( jqElem );
|
||||
return this;
|
||||
} else if ( firstParam === "getElapsedTime" ) {
|
||||
return ( +new Date() ) - obj.olddate;
|
||||
}
|
||||
|
||||
|
||||
/* (intentionally not documented)
|
||||
* Handles a user event indicating that the user isn't idle.
|
||||
* @param {Event} event A DOM2-normalized event object.
|
||||
* @return {void}
|
||||
*/
|
||||
jqElem.on( $.trim( ( opts.events + " " ).split(" ").join(".idleTimer ") ), function() {
|
||||
var obj = $.data( this, "idleTimerObj" );
|
||||
|
||||
//clear any existing timeout
|
||||
clearTimeout( obj.tId );
|
||||
|
||||
//if the idle timer is enabled
|
||||
if ( obj.enabled ){
|
||||
//if it's idle, that means the user is no longer idle
|
||||
if ( obj.idle ){
|
||||
toggleIdleState( this );
|
||||
}
|
||||
|
||||
//set a new timeout
|
||||
obj.tId = setTimeout( toggleIdleState, obj.timeout );
|
||||
}
|
||||
});
|
||||
|
||||
obj.idle = opts.idle;
|
||||
obj.enabled = opts.enabled;
|
||||
obj.timeout = opts.timeout;
|
||||
|
||||
//set a timeout to toggle state. May wish to omit this in some situations
|
||||
if ( opts.startImmediately ) {
|
||||
obj.tId = setTimeout( toggleIdleState, obj.timeout );
|
||||
}
|
||||
|
||||
// assume the user is active for the first x seconds.
|
||||
jqElem.data( "idleTimer", "active" );
|
||||
|
||||
// store our instance on the object
|
||||
jqElem.data( "idleTimerObj", obj );
|
||||
};
|
||||
|
||||
$.fn.idleTimer = function( firstParam, opts ) {
|
||||
// Allow omission of opts for backward compatibility
|
||||
if ( !opts ) {
|
||||
opts = {};
|
||||
}
|
||||
|
||||
if ( this[0] ){
|
||||
return $.idleTimer( firstParam, this[0], opts );
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
})( jQuery );
|
||||
@@ -0,0 +1,4 @@
|
||||
/*! Idle Timer - v0.9.2 - 2013-08-04
|
||||
* https://github.com/mikesherov/jquery-idletimer
|
||||
* Copyright (c) 2013 Paul Irish; Licensed MIT */
|
||||
(function(e){e.idleTimer=function(t,i,d){d=e.extend({startImmediately:!0,idle:!1,enabled:!0,timeout:3e4,events:"mousemove keydown DOMMouseScroll mousewheel mousedown touchstart touchmove"},d),i=i||document;var l=e(i),a=l.data("idleTimerObj")||{},o=function(t){"number"==typeof t&&(t=void 0);var l=e.data(t||i,"idleTimerObj");l.idle=!l.idle;var a=+new Date-l.olddate;if(l.olddate=+new Date,l.idle&&d.timeout>a)return l.idle=!1,clearTimeout(e.idleTimer.tId),d.enabled&&(e.idleTimer.tId=setTimeout(o,d.timeout)),void 0;var m=e.Event(e.data(i,"idleTimer",l.idle?"idle":"active")+".idleTimer");e(i).trigger(m)},m=function(e){var t=e.data("idleTimerObj")||{};t.enabled=!1,clearTimeout(t.tId),e.off(".idleTimer")};if(a.olddate=a.olddate||+new Date,"number"==typeof t)d.timeout=t;else{if("destroy"===t)return m(l),this;if("getElapsedTime"===t)return+new Date-a.olddate}l.on(e.trim((d.events+" ").split(" ").join(".idleTimer ")),function(){var t=e.data(this,"idleTimerObj");clearTimeout(t.tId),t.enabled&&(t.idle&&o(this),t.tId=setTimeout(o,t.timeout))}),a.idle=d.idle,a.enabled=d.enabled,a.timeout=d.timeout,d.startImmediately&&(a.tId=setTimeout(o,a.timeout)),l.data("idleTimer","active"),l.data("idleTimerObj",a)},e.fn.idleTimer=function(t,i){return i||(i={}),this[0]?e.idleTimer(t,this[0],i):this}})(jQuery);
|
||||
@@ -0,0 +1,302 @@
|
||||
/*! Idle Timer - v1.0.0 - 2014-03-10
|
||||
* https://github.com/thorst/jquery-idletimer
|
||||
* Copyright (c) 2014 Paul Irish; Licensed MIT */
|
||||
/*
|
||||
mousewheel (deprecated) -> IE6.0, Chrome, Opera, Safari
|
||||
DOMMouseScroll (deprecated) -> Firefox 1.0
|
||||
wheel (standard) -> Chrome 31, Firefox 17, IE9, Firefox Mobile 17.0
|
||||
|
||||
//No need to use, use DOMMouseScroll
|
||||
MozMousePixelScroll -> Firefox 3.5, Firefox Mobile 1.0
|
||||
|
||||
//Events
|
||||
WheelEvent -> see wheel
|
||||
MouseWheelEvent -> see mousewheel
|
||||
MouseScrollEvent -> Firefox 3.5, Firefox Mobile 1.0
|
||||
*/
|
||||
(function ($) {
|
||||
|
||||
$.idleTimer = function (firstParam, elem) {
|
||||
var opts;
|
||||
if ( typeof firstParam === "object" ) {
|
||||
opts = firstParam;
|
||||
firstParam = null;
|
||||
} else if (typeof firstParam === "number") {
|
||||
opts = { timeout: firstParam };
|
||||
firstParam = null;
|
||||
}
|
||||
|
||||
// element to watch
|
||||
elem = elem || document;
|
||||
|
||||
// defaults that are to be stored as instance props on the elem
|
||||
opts = $.extend({
|
||||
idle: false, // indicates if the user is idle
|
||||
timeout: 30000, // the amount of time (ms) before the user is considered idle
|
||||
events: "mousemove keydown wheel DOMMouseScroll mousewheel mousedown touchstart touchmove MSPointerDown MSPointerMove" // define active events
|
||||
}, opts);
|
||||
|
||||
var jqElem = $(elem),
|
||||
obj = jqElem.data("idleTimerObj") || {},
|
||||
|
||||
/* (intentionally not documented)
|
||||
* Toggles the idle state and fires an appropriate event.
|
||||
* @return {void}
|
||||
*/
|
||||
toggleIdleState = function (e) {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// toggle the state
|
||||
obj.idle = !obj.idle;
|
||||
|
||||
// store toggle state date time
|
||||
obj.olddate = +new Date();
|
||||
|
||||
// create a custom event, with state and name space
|
||||
var event = $.Event((obj.idle ? "idle" : "active") + ".idleTimer");
|
||||
|
||||
// trigger event on object with elem and copy of obj
|
||||
$(elem).trigger(event, [elem, $.extend({}, obj), e]);
|
||||
},
|
||||
/**
|
||||
* Handle event triggers
|
||||
* @return {void}
|
||||
* @method event
|
||||
* @static
|
||||
*/
|
||||
handleEvent = function (e) {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// this is already paused, ignore events for now
|
||||
if (obj.remaining != null) { return; }
|
||||
|
||||
/*
|
||||
mousemove is kinda buggy, it can be triggered when it should be idle.
|
||||
Typically is happening between 115 - 150 milliseconds after idle triggered.
|
||||
@psyafter & @kaellis report "always triggered if using modal (jQuery ui, with overlay)"
|
||||
@thorst has similar issues on ios7 "after $.scrollTop() on text area"
|
||||
*/
|
||||
if (e.type === "mousemove") {
|
||||
// if coord are same, it didn't move
|
||||
if (e.pageX === obj.pageX && e.pageY === obj.pageY) {
|
||||
return;
|
||||
}
|
||||
// if coord don't exist how could it move
|
||||
if (typeof e.pageX === "undefined" && typeof e.pageY === "undefined") {
|
||||
return;
|
||||
}
|
||||
// under 200 ms is hard to do, and you would have to stop, as continuous activity will bypass this
|
||||
var elapsed = (+new Date()) - obj.olddate;
|
||||
if (elapsed < 200) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// clear any existing timeout
|
||||
clearTimeout(obj.tId);
|
||||
|
||||
// if the idle timer is enabled, flip
|
||||
if (obj.idle) {
|
||||
toggleIdleState(e);
|
||||
}
|
||||
|
||||
// store when user was last active
|
||||
obj.lastActive = +new Date();
|
||||
|
||||
// update mouse coord
|
||||
obj.pageX = e.pageX;
|
||||
obj.pageY = e.pageY;
|
||||
|
||||
// set a new timeout
|
||||
obj.tId = setTimeout(toggleIdleState, obj.timeout);
|
||||
|
||||
},
|
||||
/**
|
||||
* Restore initial settings and restart timer
|
||||
* @return {void}
|
||||
* @method reset
|
||||
* @static
|
||||
*/
|
||||
reset = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// reset settings
|
||||
obj.idle = obj.idleBackup;
|
||||
obj.olddate = +new Date();
|
||||
obj.lastActive = obj.olddate;
|
||||
obj.remaining = null;
|
||||
|
||||
// reset Timers
|
||||
clearTimeout(obj.tId);
|
||||
if (!obj.idle) {
|
||||
obj.tId = setTimeout(toggleIdleState, obj.timeout);
|
||||
}
|
||||
|
||||
},
|
||||
/**
|
||||
* Store remaining time, stop timer
|
||||
* You can pause from an idle OR active state
|
||||
* @return {void}
|
||||
* @method pause
|
||||
* @static
|
||||
*/
|
||||
pause = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// this is already paused
|
||||
if ( obj.remaining != null ) { return; }
|
||||
|
||||
// define how much is left on the timer
|
||||
obj.remaining = obj.timeout - ((+new Date()) - obj.olddate);
|
||||
|
||||
// clear any existing timeout
|
||||
clearTimeout(obj.tId);
|
||||
},
|
||||
/**
|
||||
* Start timer with remaining value
|
||||
* @return {void}
|
||||
* @method resume
|
||||
* @static
|
||||
*/
|
||||
resume = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// this isn't paused yet
|
||||
if ( obj.remaining == null ) { return; }
|
||||
|
||||
// start timer
|
||||
if ( !obj.idle ) {
|
||||
obj.tId = setTimeout(toggleIdleState, obj.remaining);
|
||||
}
|
||||
|
||||
// clear remaining
|
||||
obj.remaining = null;
|
||||
},
|
||||
/**
|
||||
* Stops the idle timer. This removes appropriate event handlers
|
||||
* and cancels any pending timeouts.
|
||||
* @return {void}
|
||||
* @method destroy
|
||||
* @static
|
||||
*/
|
||||
destroy = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
//clear any pending timeouts
|
||||
clearTimeout(obj.tId);
|
||||
|
||||
//Remove data
|
||||
jqElem.removeData("idleTimerObj");
|
||||
|
||||
//detach the event handlers
|
||||
jqElem.off("._idleTimer");
|
||||
},
|
||||
/**
|
||||
* Returns the time until becoming idle
|
||||
* @return {number}
|
||||
* @method remainingtime
|
||||
* @static
|
||||
*/
|
||||
remainingtime = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
//If idle there is no time remaining
|
||||
if ( obj.idle ) { return 0; }
|
||||
|
||||
//If its paused just return that
|
||||
if ( obj.remaining != null ) { return obj.remaining; }
|
||||
|
||||
//Determine remaining, if negative idle didn't finish flipping, just return 0
|
||||
var remaining = obj.timeout - ((+new Date()) - obj.lastActive);
|
||||
if (remaining < 0) { remaining = 0; }
|
||||
|
||||
//If this is paused return that number, else return current remaining
|
||||
return remaining;
|
||||
};
|
||||
|
||||
|
||||
// determine which function to call
|
||||
if (firstParam === null && typeof obj.idle !== "undefined") {
|
||||
// they think they want to init, but it already is, just reset
|
||||
reset();
|
||||
return jqElem;
|
||||
} else if (firstParam === null) {
|
||||
// they want to init
|
||||
} else if (firstParam !== null && typeof obj.idle === "undefined") {
|
||||
// they want to do something, but it isnt init
|
||||
// not sure the best way to handle this
|
||||
return false;
|
||||
} else if (firstParam === "destroy") {
|
||||
destroy();
|
||||
return jqElem;
|
||||
} else if (firstParam === "pause") {
|
||||
pause();
|
||||
return jqElem;
|
||||
} else if (firstParam === "resume") {
|
||||
resume();
|
||||
return jqElem;
|
||||
} else if (firstParam === "reset") {
|
||||
reset();
|
||||
return jqElem;
|
||||
} else if (firstParam === "getRemainingTime") {
|
||||
return remainingtime();
|
||||
} else if (firstParam === "getElapsedTime") {
|
||||
return (+new Date()) - obj.olddate;
|
||||
} else if (firstParam === "getLastActiveTime") {
|
||||
return obj.lastActive;
|
||||
} else if (firstParam === "isIdle") {
|
||||
return obj.idle;
|
||||
}
|
||||
|
||||
/* (intentionally not documented)
|
||||
* Handles a user event indicating that the user isn't idle. namespaced with internal idleTimer
|
||||
* @param {Event} event A DOM2-normalized event object.
|
||||
* @return {void}
|
||||
*/
|
||||
jqElem.on($.trim((opts.events + " ").split(" ").join("._idleTimer ")), function (e) {
|
||||
handleEvent(e);
|
||||
});
|
||||
|
||||
|
||||
// Internal Object Properties, This isn't all necessary, but we
|
||||
// explicitly define all keys here so we know what we are working with
|
||||
obj = $.extend({}, {
|
||||
olddate : +new Date(), // the last time state changed
|
||||
lastActive: +new Date(), // the last time timer was active
|
||||
idle : opts.idle, // current state
|
||||
idleBackup : opts.idle, // backup of idle parameter since it gets modified
|
||||
timeout : opts.timeout, // the interval to change state
|
||||
remaining : null, // how long until state changes
|
||||
tId : null, // the idle timer setTimeout
|
||||
pageX : null, // used to store the mouse coord
|
||||
pageY : null
|
||||
});
|
||||
|
||||
// set a timeout to toggle state. May wish to omit this in some situations
|
||||
if (!obj.idle) {
|
||||
obj.tId = setTimeout(toggleIdleState, obj.timeout);
|
||||
}
|
||||
|
||||
// store our instance on the object
|
||||
$.data(elem, "idleTimerObj", obj);
|
||||
|
||||
return jqElem;
|
||||
};
|
||||
|
||||
// This allows binding to element
|
||||
$.fn.idleTimer = function (firstParam) {
|
||||
if (this[0]) {
|
||||
return $.idleTimer(firstParam, this[0]);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,2 @@
|
||||
/*! Idle Timer v1.0.0 2014-03-10 | https://github.com/thorst/jquery-idletimer | (c) 2014 Paul Irish | Licensed MIT */
|
||||
!function(a){a.idleTimer=function(b,c){var d;"object"==typeof b?(d=b,b=null):"number"==typeof b&&(d={timeout:b},b=null),c=c||document,d=a.extend({idle:!1,timeout:3e4,events:"mousemove keydown wheel DOMMouseScroll mousewheel mousedown touchstart touchmove MSPointerDown MSPointerMove"},d);var e=a(c),f=e.data("idleTimerObj")||{},g=function(b){var d=a.data(c,"idleTimerObj")||{};d.idle=!d.idle,d.olddate=+new Date;var e=a.Event((d.idle?"idle":"active")+".idleTimer");a(c).trigger(e,[c,a.extend({},d),b])},h=function(b){var d=a.data(c,"idleTimerObj")||{};if(null==d.remaining){if("mousemove"===b.type){if(b.pageX===d.pageX&&b.pageY===d.pageY)return;if("undefined"==typeof b.pageX&&"undefined"==typeof b.pageY)return;var e=+new Date-d.olddate;if(200>e)return}clearTimeout(d.tId),d.idle&&g(b),d.lastActive=+new Date,d.pageX=b.pageX,d.pageY=b.pageY,d.tId=setTimeout(g,d.timeout)}},i=function(){var b=a.data(c,"idleTimerObj")||{};b.idle=b.idleBackup,b.olddate=+new Date,b.lastActive=b.olddate,b.remaining=null,clearTimeout(b.tId),b.idle||(b.tId=setTimeout(g,b.timeout))},j=function(){var b=a.data(c,"idleTimerObj")||{};null==b.remaining&&(b.remaining=b.timeout-(+new Date-b.olddate),clearTimeout(b.tId))},k=function(){var b=a.data(c,"idleTimerObj")||{};null!=b.remaining&&(b.idle||(b.tId=setTimeout(g,b.remaining)),b.remaining=null)},l=function(){var b=a.data(c,"idleTimerObj")||{};clearTimeout(b.tId),e.removeData("idleTimerObj"),e.off("._idleTimer")},m=function(){var b=a.data(c,"idleTimerObj")||{};if(b.idle)return 0;if(null!=b.remaining)return b.remaining;var d=b.timeout-(+new Date-b.lastActive);return 0>d&&(d=0),d};if(null===b&&"undefined"!=typeof f.idle)return i(),e;if(null===b);else{if(null!==b&&"undefined"==typeof f.idle)return!1;if("destroy"===b)return l(),e;if("pause"===b)return j(),e;if("resume"===b)return k(),e;if("reset"===b)return i(),e;if("getRemainingTime"===b)return m();if("getElapsedTime"===b)return+new Date-f.olddate;if("getLastActiveTime"===b)return f.lastActive;if("isIdle"===b)return f.idle}return e.on(a.trim((d.events+" ").split(" ").join("._idleTimer ")),function(a){h(a)}),f=a.extend({},{olddate:+new Date,lastActive:+new Date,idle:d.idle,idleBackup:d.idle,timeout:d.timeout,remaining:null,tId:null,pageX:null,pageY:null}),f.idle||(f.tId=setTimeout(g,f.timeout)),a.data(c,"idleTimerObj",f),e},a.fn.idleTimer=function(b){return this[0]?a.idleTimer(b,this[0]):this}}(jQuery);
|
||||
@@ -0,0 +1,302 @@
|
||||
/*! Idle Timer - v1.0.1 - 2014-03-21
|
||||
* https://github.com/thorst/jquery-idletimer
|
||||
* Copyright (c) 2014 Paul Irish; Licensed MIT */
|
||||
/*
|
||||
mousewheel (deprecated) -> IE6.0, Chrome, Opera, Safari
|
||||
DOMMouseScroll (deprecated) -> Firefox 1.0
|
||||
wheel (standard) -> Chrome 31, Firefox 17, IE9, Firefox Mobile 17.0
|
||||
|
||||
//No need to use, use DOMMouseScroll
|
||||
MozMousePixelScroll -> Firefox 3.5, Firefox Mobile 1.0
|
||||
|
||||
//Events
|
||||
WheelEvent -> see wheel
|
||||
MouseWheelEvent -> see mousewheel
|
||||
MouseScrollEvent -> Firefox 3.5, Firefox Mobile 1.0
|
||||
*/
|
||||
(function ($) {
|
||||
|
||||
$.idleTimer = function (firstParam, elem) {
|
||||
var opts;
|
||||
if ( typeof firstParam === "object" ) {
|
||||
opts = firstParam;
|
||||
firstParam = null;
|
||||
} else if (typeof firstParam === "number") {
|
||||
opts = { timeout: firstParam };
|
||||
firstParam = null;
|
||||
}
|
||||
|
||||
// element to watch
|
||||
elem = elem || document;
|
||||
|
||||
// defaults that are to be stored as instance props on the elem
|
||||
opts = $.extend({
|
||||
idle: false, // indicates if the user is idle
|
||||
timeout: 30000, // the amount of time (ms) before the user is considered idle
|
||||
events: "mousemove keydown wheel DOMMouseScroll mousewheel mousedown touchstart touchmove MSPointerDown MSPointerMove" // define active events
|
||||
}, opts);
|
||||
|
||||
var jqElem = $(elem),
|
||||
obj = jqElem.data("idleTimerObj") || {},
|
||||
|
||||
/* (intentionally not documented)
|
||||
* Toggles the idle state and fires an appropriate event.
|
||||
* @return {void}
|
||||
*/
|
||||
toggleIdleState = function (e) {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// toggle the state
|
||||
obj.idle = !obj.idle;
|
||||
|
||||
// store toggle state date time
|
||||
obj.olddate = +new Date();
|
||||
|
||||
// create a custom event, with state and name space
|
||||
var event = $.Event((obj.idle ? "idle" : "active") + ".idleTimer");
|
||||
|
||||
// trigger event on object with elem and copy of obj
|
||||
$(elem).trigger(event, [elem, $.extend({}, obj), e]);
|
||||
},
|
||||
/**
|
||||
* Handle event triggers
|
||||
* @return {void}
|
||||
* @method event
|
||||
* @static
|
||||
*/
|
||||
handleEvent = function (e) {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// this is already paused, ignore events for now
|
||||
if (obj.remaining != null) { return; }
|
||||
|
||||
/*
|
||||
mousemove is kinda buggy, it can be triggered when it should be idle.
|
||||
Typically is happening between 115 - 150 milliseconds after idle triggered.
|
||||
@psyafter & @kaellis report "always triggered if using modal (jQuery ui, with overlay)"
|
||||
@thorst has similar issues on ios7 "after $.scrollTop() on text area"
|
||||
*/
|
||||
if (e.type === "mousemove") {
|
||||
// if coord are same, it didn't move
|
||||
if (e.pageX === obj.pageX && e.pageY === obj.pageY) {
|
||||
return;
|
||||
}
|
||||
// if coord don't exist how could it move
|
||||
if (typeof e.pageX === "undefined" && typeof e.pageY === "undefined") {
|
||||
return;
|
||||
}
|
||||
// under 200 ms is hard to do, and you would have to stop, as continuous activity will bypass this
|
||||
var elapsed = (+new Date()) - obj.olddate;
|
||||
if (elapsed < 200) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// clear any existing timeout
|
||||
clearTimeout(obj.tId);
|
||||
|
||||
// if the idle timer is enabled, flip
|
||||
if (obj.idle) {
|
||||
toggleIdleState(e);
|
||||
}
|
||||
|
||||
// store when user was last active
|
||||
obj.lastActive = +new Date();
|
||||
|
||||
// update mouse coord
|
||||
obj.pageX = e.pageX;
|
||||
obj.pageY = e.pageY;
|
||||
|
||||
// set a new timeout
|
||||
obj.tId = setTimeout(toggleIdleState, obj.timeout);
|
||||
|
||||
},
|
||||
/**
|
||||
* Restore initial settings and restart timer
|
||||
* @return {void}
|
||||
* @method reset
|
||||
* @static
|
||||
*/
|
||||
reset = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// reset settings
|
||||
obj.idle = obj.idleBackup;
|
||||
obj.olddate = +new Date();
|
||||
obj.lastActive = obj.olddate;
|
||||
obj.remaining = null;
|
||||
|
||||
// reset Timers
|
||||
clearTimeout(obj.tId);
|
||||
if (!obj.idle) {
|
||||
obj.tId = setTimeout(toggleIdleState, obj.timeout);
|
||||
}
|
||||
|
||||
},
|
||||
/**
|
||||
* Store remaining time, stop timer
|
||||
* You can pause from an idle OR active state
|
||||
* @return {void}
|
||||
* @method pause
|
||||
* @static
|
||||
*/
|
||||
pause = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// this is already paused
|
||||
if ( obj.remaining != null ) { return; }
|
||||
|
||||
// define how much is left on the timer
|
||||
obj.remaining = obj.timeout - ((+new Date()) - obj.olddate);
|
||||
|
||||
// clear any existing timeout
|
||||
clearTimeout(obj.tId);
|
||||
},
|
||||
/**
|
||||
* Start timer with remaining value
|
||||
* @return {void}
|
||||
* @method resume
|
||||
* @static
|
||||
*/
|
||||
resume = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// this isn't paused yet
|
||||
if ( obj.remaining == null ) { return; }
|
||||
|
||||
// start timer
|
||||
if ( !obj.idle ) {
|
||||
obj.tId = setTimeout(toggleIdleState, obj.remaining);
|
||||
}
|
||||
|
||||
// clear remaining
|
||||
obj.remaining = null;
|
||||
},
|
||||
/**
|
||||
* Stops the idle timer. This removes appropriate event handlers
|
||||
* and cancels any pending timeouts.
|
||||
* @return {void}
|
||||
* @method destroy
|
||||
* @static
|
||||
*/
|
||||
destroy = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
//clear any pending timeouts
|
||||
clearTimeout(obj.tId);
|
||||
|
||||
//Remove data
|
||||
jqElem.removeData("idleTimerObj");
|
||||
|
||||
//detach the event handlers
|
||||
jqElem.off("._idleTimer");
|
||||
},
|
||||
/**
|
||||
* Returns the time until becoming idle
|
||||
* @return {number}
|
||||
* @method remainingtime
|
||||
* @static
|
||||
*/
|
||||
remainingtime = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
//If idle there is no time remaining
|
||||
if ( obj.idle ) { return 0; }
|
||||
|
||||
//If its paused just return that
|
||||
if ( obj.remaining != null ) { return obj.remaining; }
|
||||
|
||||
//Determine remaining, if negative idle didn't finish flipping, just return 0
|
||||
var remaining = obj.timeout - ((+new Date()) - obj.lastActive);
|
||||
if (remaining < 0) { remaining = 0; }
|
||||
|
||||
//If this is paused return that number, else return current remaining
|
||||
return remaining;
|
||||
};
|
||||
|
||||
|
||||
// determine which function to call
|
||||
if (firstParam === null && typeof obj.idle !== "undefined") {
|
||||
// they think they want to init, but it already is, just reset
|
||||
reset();
|
||||
return jqElem;
|
||||
} else if (firstParam === null) {
|
||||
// they want to init
|
||||
} else if (firstParam !== null && typeof obj.idle === "undefined") {
|
||||
// they want to do something, but it isnt init
|
||||
// not sure the best way to handle this
|
||||
return false;
|
||||
} else if (firstParam === "destroy") {
|
||||
destroy();
|
||||
return jqElem;
|
||||
} else if (firstParam === "pause") {
|
||||
pause();
|
||||
return jqElem;
|
||||
} else if (firstParam === "resume") {
|
||||
resume();
|
||||
return jqElem;
|
||||
} else if (firstParam === "reset") {
|
||||
reset();
|
||||
return jqElem;
|
||||
} else if (firstParam === "getRemainingTime") {
|
||||
return remainingtime();
|
||||
} else if (firstParam === "getElapsedTime") {
|
||||
return (+new Date()) - obj.olddate;
|
||||
} else if (firstParam === "getLastActiveTime") {
|
||||
return obj.lastActive;
|
||||
} else if (firstParam === "isIdle") {
|
||||
return obj.idle;
|
||||
}
|
||||
|
||||
/* (intentionally not documented)
|
||||
* Handles a user event indicating that the user isn't idle. namespaced with internal idleTimer
|
||||
* @param {Event} event A DOM2-normalized event object.
|
||||
* @return {void}
|
||||
*/
|
||||
jqElem.on($.trim((opts.events + " ").split(" ").join("._idleTimer ")), function (e) {
|
||||
handleEvent(e);
|
||||
});
|
||||
|
||||
|
||||
// Internal Object Properties, This isn't all necessary, but we
|
||||
// explicitly define all keys here so we know what we are working with
|
||||
obj = $.extend({}, {
|
||||
olddate : +new Date(), // the last time state changed
|
||||
lastActive: +new Date(), // the last time timer was active
|
||||
idle : opts.idle, // current state
|
||||
idleBackup : opts.idle, // backup of idle parameter since it gets modified
|
||||
timeout : opts.timeout, // the interval to change state
|
||||
remaining : null, // how long until state changes
|
||||
tId : null, // the idle timer setTimeout
|
||||
pageX : null, // used to store the mouse coord
|
||||
pageY : null
|
||||
});
|
||||
|
||||
// set a timeout to toggle state. May wish to omit this in some situations
|
||||
if (!obj.idle) {
|
||||
obj.tId = setTimeout(toggleIdleState, obj.timeout);
|
||||
}
|
||||
|
||||
// store our instance on the object
|
||||
$.data(elem, "idleTimerObj", obj);
|
||||
|
||||
return jqElem;
|
||||
};
|
||||
|
||||
// This allows binding to element
|
||||
$.fn.idleTimer = function (firstParam) {
|
||||
if (this[0]) {
|
||||
return $.idleTimer(firstParam, this[0]);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,2 @@
|
||||
/*! Idle Timer v1.0.1 2014-03-21 | https://github.com/thorst/jquery-idletimer | (c) 2014 Paul Irish | Licensed MIT */
|
||||
!function(a){a.idleTimer=function(b,c){var d;"object"==typeof b?(d=b,b=null):"number"==typeof b&&(d={timeout:b},b=null),c=c||document,d=a.extend({idle:!1,timeout:3e4,events:"mousemove keydown wheel DOMMouseScroll mousewheel mousedown touchstart touchmove MSPointerDown MSPointerMove"},d);var e=a(c),f=e.data("idleTimerObj")||{},g=function(b){var d=a.data(c,"idleTimerObj")||{};d.idle=!d.idle,d.olddate=+new Date;var e=a.Event((d.idle?"idle":"active")+".idleTimer");a(c).trigger(e,[c,a.extend({},d),b])},h=function(b){var d=a.data(c,"idleTimerObj")||{};if(null==d.remaining){if("mousemove"===b.type){if(b.pageX===d.pageX&&b.pageY===d.pageY)return;if("undefined"==typeof b.pageX&&"undefined"==typeof b.pageY)return;var e=+new Date-d.olddate;if(200>e)return}clearTimeout(d.tId),d.idle&&g(b),d.lastActive=+new Date,d.pageX=b.pageX,d.pageY=b.pageY,d.tId=setTimeout(g,d.timeout)}},i=function(){var b=a.data(c,"idleTimerObj")||{};b.idle=b.idleBackup,b.olddate=+new Date,b.lastActive=b.olddate,b.remaining=null,clearTimeout(b.tId),b.idle||(b.tId=setTimeout(g,b.timeout))},j=function(){var b=a.data(c,"idleTimerObj")||{};null==b.remaining&&(b.remaining=b.timeout-(+new Date-b.olddate),clearTimeout(b.tId))},k=function(){var b=a.data(c,"idleTimerObj")||{};null!=b.remaining&&(b.idle||(b.tId=setTimeout(g,b.remaining)),b.remaining=null)},l=function(){var b=a.data(c,"idleTimerObj")||{};clearTimeout(b.tId),e.removeData("idleTimerObj"),e.off("._idleTimer")},m=function(){var b=a.data(c,"idleTimerObj")||{};if(b.idle)return 0;if(null!=b.remaining)return b.remaining;var d=b.timeout-(+new Date-b.lastActive);return 0>d&&(d=0),d};if(null===b&&"undefined"!=typeof f.idle)return i(),e;if(null===b);else{if(null!==b&&"undefined"==typeof f.idle)return!1;if("destroy"===b)return l(),e;if("pause"===b)return j(),e;if("resume"===b)return k(),e;if("reset"===b)return i(),e;if("getRemainingTime"===b)return m();if("getElapsedTime"===b)return+new Date-f.olddate;if("getLastActiveTime"===b)return f.lastActive;if("isIdle"===b)return f.idle}return e.on(a.trim((d.events+" ").split(" ").join("._idleTimer ")),function(a){h(a)}),f=a.extend({},{olddate:+new Date,lastActive:+new Date,idle:d.idle,idleBackup:d.idle,timeout:d.timeout,remaining:null,tId:null,pageX:null,pageY:null}),f.idle||(f.tId=setTimeout(g,f.timeout)),a.data(c,"idleTimerObj",f),e},a.fn.idleTimer=function(b){return this[0]?a.idleTimer(b,this[0]):this}}(jQuery);
|
||||
+302
@@ -0,0 +1,302 @@
|
||||
/*! Idle Timer - v1.0.1 - 2014-03-21
|
||||
* https://github.com/thorst/jquery-idletimer
|
||||
* Copyright (c) 2014 Paul Irish; Licensed MIT */
|
||||
/*
|
||||
mousewheel (deprecated) -> IE6.0, Chrome, Opera, Safari
|
||||
DOMMouseScroll (deprecated) -> Firefox 1.0
|
||||
wheel (standard) -> Chrome 31, Firefox 17, IE9, Firefox Mobile 17.0
|
||||
|
||||
//No need to use, use DOMMouseScroll
|
||||
MozMousePixelScroll -> Firefox 3.5, Firefox Mobile 1.0
|
||||
|
||||
//Events
|
||||
WheelEvent -> see wheel
|
||||
MouseWheelEvent -> see mousewheel
|
||||
MouseScrollEvent -> Firefox 3.5, Firefox Mobile 1.0
|
||||
*/
|
||||
(function ($) {
|
||||
|
||||
$.idleTimer = function (firstParam, elem) {
|
||||
var opts;
|
||||
if ( typeof firstParam === "object" ) {
|
||||
opts = firstParam;
|
||||
firstParam = null;
|
||||
} else if (typeof firstParam === "number") {
|
||||
opts = { timeout: firstParam };
|
||||
firstParam = null;
|
||||
}
|
||||
|
||||
// element to watch
|
||||
elem = elem || document;
|
||||
|
||||
// defaults that are to be stored as instance props on the elem
|
||||
opts = $.extend({
|
||||
idle: false, // indicates if the user is idle
|
||||
timeout: 30000, // the amount of time (ms) before the user is considered idle
|
||||
events: "mousemove keydown wheel DOMMouseScroll mousewheel mousedown touchstart touchmove MSPointerDown MSPointerMove" // define active events
|
||||
}, opts);
|
||||
|
||||
var jqElem = $(elem),
|
||||
obj = jqElem.data("idleTimerObj") || {},
|
||||
|
||||
/* (intentionally not documented)
|
||||
* Toggles the idle state and fires an appropriate event.
|
||||
* @return {void}
|
||||
*/
|
||||
toggleIdleState = function (e) {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// toggle the state
|
||||
obj.idle = !obj.idle;
|
||||
|
||||
// store toggle state date time
|
||||
obj.olddate = +new Date();
|
||||
|
||||
// create a custom event, with state and name space
|
||||
var event = $.Event((obj.idle ? "idle" : "active") + ".idleTimer");
|
||||
|
||||
// trigger event on object with elem and copy of obj
|
||||
$(elem).trigger(event, [elem, $.extend({}, obj), e]);
|
||||
},
|
||||
/**
|
||||
* Handle event triggers
|
||||
* @return {void}
|
||||
* @method event
|
||||
* @static
|
||||
*/
|
||||
handleEvent = function (e) {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// this is already paused, ignore events for now
|
||||
if (obj.remaining != null) { return; }
|
||||
|
||||
/*
|
||||
mousemove is kinda buggy, it can be triggered when it should be idle.
|
||||
Typically is happening between 115 - 150 milliseconds after idle triggered.
|
||||
@psyafter & @kaellis report "always triggered if using modal (jQuery ui, with overlay)"
|
||||
@thorst has similar issues on ios7 "after $.scrollTop() on text area"
|
||||
*/
|
||||
if (e.type === "mousemove") {
|
||||
// if coord are same, it didn't move
|
||||
if (e.pageX === obj.pageX && e.pageY === obj.pageY) {
|
||||
return;
|
||||
}
|
||||
// if coord don't exist how could it move
|
||||
if (typeof e.pageX === "undefined" && typeof e.pageY === "undefined") {
|
||||
return;
|
||||
}
|
||||
// under 200 ms is hard to do, and you would have to stop, as continuous activity will bypass this
|
||||
var elapsed = (+new Date()) - obj.olddate;
|
||||
if (elapsed < 200) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// clear any existing timeout
|
||||
clearTimeout(obj.tId);
|
||||
|
||||
// if the idle timer is enabled, flip
|
||||
if (obj.idle) {
|
||||
toggleIdleState(e);
|
||||
}
|
||||
|
||||
// store when user was last active
|
||||
obj.lastActive = +new Date();
|
||||
|
||||
// update mouse coord
|
||||
obj.pageX = e.pageX;
|
||||
obj.pageY = e.pageY;
|
||||
|
||||
// set a new timeout
|
||||
obj.tId = setTimeout(toggleIdleState, obj.timeout);
|
||||
|
||||
},
|
||||
/**
|
||||
* Restore initial settings and restart timer
|
||||
* @return {void}
|
||||
* @method reset
|
||||
* @static
|
||||
*/
|
||||
reset = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// reset settings
|
||||
obj.idle = obj.idleBackup;
|
||||
obj.olddate = +new Date();
|
||||
obj.lastActive = obj.olddate;
|
||||
obj.remaining = null;
|
||||
|
||||
// reset Timers
|
||||
clearTimeout(obj.tId);
|
||||
if (!obj.idle) {
|
||||
obj.tId = setTimeout(toggleIdleState, obj.timeout);
|
||||
}
|
||||
|
||||
},
|
||||
/**
|
||||
* Store remaining time, stop timer
|
||||
* You can pause from an idle OR active state
|
||||
* @return {void}
|
||||
* @method pause
|
||||
* @static
|
||||
*/
|
||||
pause = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// this is already paused
|
||||
if ( obj.remaining != null ) { return; }
|
||||
|
||||
// define how much is left on the timer
|
||||
obj.remaining = obj.timeout - ((+new Date()) - obj.olddate);
|
||||
|
||||
// clear any existing timeout
|
||||
clearTimeout(obj.tId);
|
||||
},
|
||||
/**
|
||||
* Start timer with remaining value
|
||||
* @return {void}
|
||||
* @method resume
|
||||
* @static
|
||||
*/
|
||||
resume = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// this isn't paused yet
|
||||
if ( obj.remaining == null ) { return; }
|
||||
|
||||
// start timer
|
||||
if ( !obj.idle ) {
|
||||
obj.tId = setTimeout(toggleIdleState, obj.remaining);
|
||||
}
|
||||
|
||||
// clear remaining
|
||||
obj.remaining = null;
|
||||
},
|
||||
/**
|
||||
* Stops the idle timer. This removes appropriate event handlers
|
||||
* and cancels any pending timeouts.
|
||||
* @return {void}
|
||||
* @method destroy
|
||||
* @static
|
||||
*/
|
||||
destroy = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
//clear any pending timeouts
|
||||
clearTimeout(obj.tId);
|
||||
|
||||
//Remove data
|
||||
jqElem.removeData("idleTimerObj");
|
||||
|
||||
//detach the event handlers
|
||||
jqElem.off("._idleTimer");
|
||||
},
|
||||
/**
|
||||
* Returns the time until becoming idle
|
||||
* @return {number}
|
||||
* @method remainingtime
|
||||
* @static
|
||||
*/
|
||||
remainingtime = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
//If idle there is no time remaining
|
||||
if ( obj.idle ) { return 0; }
|
||||
|
||||
//If its paused just return that
|
||||
if ( obj.remaining != null ) { return obj.remaining; }
|
||||
|
||||
//Determine remaining, if negative idle didn't finish flipping, just return 0
|
||||
var remaining = obj.timeout - ((+new Date()) - obj.lastActive);
|
||||
if (remaining < 0) { remaining = 0; }
|
||||
|
||||
//If this is paused return that number, else return current remaining
|
||||
return remaining;
|
||||
};
|
||||
|
||||
|
||||
// determine which function to call
|
||||
if (firstParam === null && typeof obj.idle !== "undefined") {
|
||||
// they think they want to init, but it already is, just reset
|
||||
reset();
|
||||
return jqElem;
|
||||
} else if (firstParam === null) {
|
||||
// they want to init
|
||||
} else if (firstParam !== null && typeof obj.idle === "undefined") {
|
||||
// they want to do something, but it isnt init
|
||||
// not sure the best way to handle this
|
||||
return false;
|
||||
} else if (firstParam === "destroy") {
|
||||
destroy();
|
||||
return jqElem;
|
||||
} else if (firstParam === "pause") {
|
||||
pause();
|
||||
return jqElem;
|
||||
} else if (firstParam === "resume") {
|
||||
resume();
|
||||
return jqElem;
|
||||
} else if (firstParam === "reset") {
|
||||
reset();
|
||||
return jqElem;
|
||||
} else if (firstParam === "getRemainingTime") {
|
||||
return remainingtime();
|
||||
} else if (firstParam === "getElapsedTime") {
|
||||
return (+new Date()) - obj.olddate;
|
||||
} else if (firstParam === "getLastActiveTime") {
|
||||
return obj.lastActive;
|
||||
} else if (firstParam === "isIdle") {
|
||||
return obj.idle;
|
||||
}
|
||||
|
||||
/* (intentionally not documented)
|
||||
* Handles a user event indicating that the user isn't idle. namespaced with internal idleTimer
|
||||
* @param {Event} event A DOM2-normalized event object.
|
||||
* @return {void}
|
||||
*/
|
||||
jqElem.on($.trim((opts.events + " ").split(" ").join("._idleTimer ")), function (e) {
|
||||
handleEvent(e);
|
||||
});
|
||||
|
||||
|
||||
// Internal Object Properties, This isn't all necessary, but we
|
||||
// explicitly define all keys here so we know what we are working with
|
||||
obj = $.extend({}, {
|
||||
olddate : +new Date(), // the last time state changed
|
||||
lastActive: +new Date(), // the last time timer was active
|
||||
idle : opts.idle, // current state
|
||||
idleBackup : opts.idle, // backup of idle parameter since it gets modified
|
||||
timeout : opts.timeout, // the interval to change state
|
||||
remaining : null, // how long until state changes
|
||||
tId : null, // the idle timer setTimeout
|
||||
pageX : null, // used to store the mouse coord
|
||||
pageY : null
|
||||
});
|
||||
|
||||
// set a timeout to toggle state. May wish to omit this in some situations
|
||||
if (!obj.idle) {
|
||||
obj.tId = setTimeout(toggleIdleState, obj.timeout);
|
||||
}
|
||||
|
||||
// store our instance on the object
|
||||
$.data(elem, "idleTimerObj", obj);
|
||||
|
||||
return jqElem;
|
||||
};
|
||||
|
||||
// This allows binding to element
|
||||
$.fn.idleTimer = function (firstParam) {
|
||||
if (this[0]) {
|
||||
return $.idleTimer(firstParam, this[0]);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,2 @@
|
||||
/*! Idle Timer v1.0.1 2014-03-21 | https://github.com/thorst/jquery-idletimer | (c) 2014 Paul Irish | Licensed MIT */
|
||||
!function(a){a.idleTimer=function(b,c){var d;"object"==typeof b?(d=b,b=null):"number"==typeof b&&(d={timeout:b},b=null),c=c||document,d=a.extend({idle:!1,timeout:3e4,events:"mousemove keydown wheel DOMMouseScroll mousewheel mousedown touchstart touchmove MSPointerDown MSPointerMove"},d);var e=a(c),f=e.data("idleTimerObj")||{},g=function(b){var d=a.data(c,"idleTimerObj")||{};d.idle=!d.idle,d.olddate=+new Date;var e=a.Event((d.idle?"idle":"active")+".idleTimer");a(c).trigger(e,[c,a.extend({},d),b])},h=function(b){var d=a.data(c,"idleTimerObj")||{};if(null==d.remaining){if("mousemove"===b.type){if(b.pageX===d.pageX&&b.pageY===d.pageY)return;if("undefined"==typeof b.pageX&&"undefined"==typeof b.pageY)return;var e=+new Date-d.olddate;if(200>e)return}clearTimeout(d.tId),d.idle&&g(b),d.lastActive=+new Date,d.pageX=b.pageX,d.pageY=b.pageY,d.tId=setTimeout(g,d.timeout)}},i=function(){var b=a.data(c,"idleTimerObj")||{};b.idle=b.idleBackup,b.olddate=+new Date,b.lastActive=b.olddate,b.remaining=null,clearTimeout(b.tId),b.idle||(b.tId=setTimeout(g,b.timeout))},j=function(){var b=a.data(c,"idleTimerObj")||{};null==b.remaining&&(b.remaining=b.timeout-(+new Date-b.olddate),clearTimeout(b.tId))},k=function(){var b=a.data(c,"idleTimerObj")||{};null!=b.remaining&&(b.idle||(b.tId=setTimeout(g,b.remaining)),b.remaining=null)},l=function(){var b=a.data(c,"idleTimerObj")||{};clearTimeout(b.tId),e.removeData("idleTimerObj"),e.off("._idleTimer")},m=function(){var b=a.data(c,"idleTimerObj")||{};if(b.idle)return 0;if(null!=b.remaining)return b.remaining;var d=b.timeout-(+new Date-b.lastActive);return 0>d&&(d=0),d};if(null===b&&"undefined"!=typeof f.idle)return i(),e;if(null===b);else{if(null!==b&&"undefined"==typeof f.idle)return!1;if("destroy"===b)return l(),e;if("pause"===b)return j(),e;if("resume"===b)return k(),e;if("reset"===b)return i(),e;if("getRemainingTime"===b)return m();if("getElapsedTime"===b)return+new Date-f.olddate;if("getLastActiveTime"===b)return f.lastActive;if("isIdle"===b)return f.idle}return e.on(a.trim((d.events+" ").split(" ").join("._idleTimer ")),function(a){h(a)}),f=a.extend({},{olddate:+new Date,lastActive:+new Date,idle:d.idle,idleBackup:d.idle,timeout:d.timeout,remaining:null,tId:null,pageX:null,pageY:null}),f.idle||(f.tId=setTimeout(g,f.timeout)),a.data(c,"idleTimerObj",f),e},a.fn.idleTimer=function(b){return this[0]?a.idleTimer(b,this[0]):this}}(jQuery);
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "idle-timer",
|
||||
"title": "Idle Timer",
|
||||
"description": "provides you a way to monitor user activity with a page.",
|
||||
"version": "1.0.1",
|
||||
"homepage": "https://github.com/thorst/jquery-idletimer",
|
||||
"author": {
|
||||
"name": "Paul Irish",
|
||||
"email": "paul.irish@gmail.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Mike Sherov",
|
||||
"email": "mike.sherov@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Todd Horst",
|
||||
"email": "toddmhorst@yahoo.com"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/thorst/jquery-idletimer.git"
|
||||
},
|
||||
"bugs": "https://github.com/thorst/jquery-idletimer/issues",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/thorst/jquery-idletimer/blob/master/LICENSE-MIT"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"jquery": "1.7"
|
||||
},
|
||||
"keywords": []
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "jquery-idletimer", "http://localhost:3751", "{70FF000C-3D87-429F-86E5-C99C2CA464E0}"
|
||||
ProjectSection(WebsiteProperties) = preProject
|
||||
UseIISExpress = "true"
|
||||
TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.0"
|
||||
Debug.AspNetCompiler.VirtualPath = "/localhost_3751"
|
||||
Debug.AspNetCompiler.PhysicalPath = "..\..\..\GitHub\jquery-idletimer\"
|
||||
Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_3751\"
|
||||
Debug.AspNetCompiler.Updateable = "true"
|
||||
Debug.AspNetCompiler.ForceOverwrite = "true"
|
||||
Debug.AspNetCompiler.FixedNames = "false"
|
||||
Debug.AspNetCompiler.Debug = "True"
|
||||
Release.AspNetCompiler.VirtualPath = "/localhost_3751"
|
||||
Release.AspNetCompiler.PhysicalPath = "..\..\..\GitHub\jquery-idletimer\"
|
||||
Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_3751\"
|
||||
Release.AspNetCompiler.Updateable = "true"
|
||||
Release.AspNetCompiler.ForceOverwrite = "true"
|
||||
Release.AspNetCompiler.FixedNames = "false"
|
||||
Release.AspNetCompiler.Debug = "False"
|
||||
SlnRelativePath = "..\..\..\GitHub\jquery-idletimer\"
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{70FF000C-3D87-429F-86E5-C99C2CA464E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{70FF000C-3D87-429F-86E5-C99C2CA464E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Binary file not shown.
@@ -0,0 +1,12 @@
|
||||
(function() {
|
||||
// Default to the local version.
|
||||
var path = '../libs/jquery/jquery.js';
|
||||
// Get any jquery=___ param from the query string.
|
||||
var jqversion = location.search.match(/[?&]jquery=(.*?)(?=&|$)/);
|
||||
// If a version was specified, use that version from code.jquery.com.
|
||||
if (jqversion) {
|
||||
path = 'http://code.jquery.com/jquery-' + jqversion[1] + '.js';
|
||||
}
|
||||
// This is the only time I'll ever use document.write, I promise!
|
||||
document.write('<script src="' + path + '"></script>');
|
||||
}());
|
||||
+9404
File diff suppressed because it is too large
Load Diff
+232
@@ -0,0 +1,232 @@
|
||||
/**
|
||||
* QUnit v1.4.0 - A JavaScript Unit Testing Framework
|
||||
*
|
||||
* http://docs.jquery.com/QUnit
|
||||
*
|
||||
* Copyright (c) 2012 John Resig, Jörn Zaefferer
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* or GPL (GPL-LICENSE.txt) licenses.
|
||||
*/
|
||||
|
||||
/** Font Family and Sizes */
|
||||
|
||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
|
||||
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
|
||||
#qunit-tests { font-size: smaller; }
|
||||
|
||||
|
||||
/** Resets */
|
||||
|
||||
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
/** Header */
|
||||
|
||||
#qunit-header {
|
||||
padding: 0.5em 0 0.5em 1em;
|
||||
|
||||
color: #8699a4;
|
||||
background-color: #0d3349;
|
||||
|
||||
font-size: 1.5em;
|
||||
line-height: 1em;
|
||||
font-weight: normal;
|
||||
|
||||
border-radius: 15px 15px 0 0;
|
||||
-moz-border-radius: 15px 15px 0 0;
|
||||
-webkit-border-top-right-radius: 15px;
|
||||
-webkit-border-top-left-radius: 15px;
|
||||
}
|
||||
|
||||
#qunit-header a {
|
||||
text-decoration: none;
|
||||
color: #c2ccd1;
|
||||
}
|
||||
|
||||
#qunit-header a:hover,
|
||||
#qunit-header a:focus {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#qunit-header label {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#qunit-banner {
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar {
|
||||
padding: 0.5em 0 0.5em 2em;
|
||||
color: #5E740B;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
#qunit-userAgent {
|
||||
padding: 0.5em 0 0.5em 2.5em;
|
||||
background-color: #2b81af;
|
||||
color: #fff;
|
||||
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
|
||||
}
|
||||
|
||||
|
||||
/** Tests: Pass/Fail */
|
||||
|
||||
#qunit-tests {
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
#qunit-tests li {
|
||||
padding: 0.4em 0.5em 0.4em 2.5em;
|
||||
border-bottom: 1px solid #fff;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#qunit-tests li strong {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#qunit-tests li a {
|
||||
padding: 0.5em;
|
||||
color: #c2ccd1;
|
||||
text-decoration: none;
|
||||
}
|
||||
#qunit-tests li a:hover,
|
||||
#qunit-tests li a:focus {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#qunit-tests ol {
|
||||
margin-top: 0.5em;
|
||||
padding: 0.5em;
|
||||
|
||||
background-color: #fff;
|
||||
|
||||
border-radius: 15px;
|
||||
-moz-border-radius: 15px;
|
||||
-webkit-border-radius: 15px;
|
||||
|
||||
box-shadow: inset 0px 2px 13px #999;
|
||||
-moz-box-shadow: inset 0px 2px 13px #999;
|
||||
-webkit-box-shadow: inset 0px 2px 13px #999;
|
||||
}
|
||||
|
||||
#qunit-tests table {
|
||||
border-collapse: collapse;
|
||||
margin-top: .2em;
|
||||
}
|
||||
|
||||
#qunit-tests th {
|
||||
text-align: right;
|
||||
vertical-align: top;
|
||||
padding: 0 .5em 0 0;
|
||||
}
|
||||
|
||||
#qunit-tests td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#qunit-tests pre {
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
#qunit-tests del {
|
||||
background-color: #e0f2be;
|
||||
color: #374e0c;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#qunit-tests ins {
|
||||
background-color: #ffcaca;
|
||||
color: #500;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/*** Test Counts */
|
||||
|
||||
#qunit-tests b.counts { color: black; }
|
||||
#qunit-tests b.passed { color: #5E740B; }
|
||||
#qunit-tests b.failed { color: #710909; }
|
||||
|
||||
#qunit-tests li li {
|
||||
margin: 0.5em;
|
||||
padding: 0.4em 0.5em 0.4em 0.5em;
|
||||
background-color: #fff;
|
||||
border-bottom: none;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
/*** Passing Styles */
|
||||
|
||||
#qunit-tests li li.pass {
|
||||
color: #5E740B;
|
||||
background-color: #fff;
|
||||
border-left: 26px solid #C6E746;
|
||||
}
|
||||
|
||||
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
|
||||
#qunit-tests .pass .test-name { color: #366097; }
|
||||
|
||||
#qunit-tests .pass .test-actual,
|
||||
#qunit-tests .pass .test-expected { color: #999999; }
|
||||
|
||||
#qunit-banner.qunit-pass { background-color: #C6E746; }
|
||||
|
||||
/*** Failing Styles */
|
||||
|
||||
#qunit-tests li li.fail {
|
||||
color: #710909;
|
||||
background-color: #fff;
|
||||
border-left: 26px solid #EE5757;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
#qunit-tests > li:last-child {
|
||||
border-radius: 0 0 15px 15px;
|
||||
-moz-border-radius: 0 0 15px 15px;
|
||||
-webkit-border-bottom-right-radius: 15px;
|
||||
-webkit-border-bottom-left-radius: 15px;
|
||||
}
|
||||
|
||||
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
|
||||
#qunit-tests .fail .test-name,
|
||||
#qunit-tests .fail .module-name { color: #000000; }
|
||||
|
||||
#qunit-tests .fail .test-actual { color: #EE5757; }
|
||||
#qunit-tests .fail .test-expected { color: green; }
|
||||
|
||||
#qunit-banner.qunit-fail { background-color: #EE5757; }
|
||||
|
||||
|
||||
/** Result */
|
||||
|
||||
#qunit-testresult {
|
||||
padding: 0.5em 0.5em 0.5em 2.5em;
|
||||
|
||||
color: #2b81af;
|
||||
background-color: #D2E0E6;
|
||||
|
||||
border-bottom: 1px solid white;
|
||||
}
|
||||
|
||||
/** Fixture */
|
||||
|
||||
#qunit-fixture {
|
||||
position: absolute;
|
||||
top: -10000px;
|
||||
left: -10000px;
|
||||
width: 1000px;
|
||||
height: 1000px;
|
||||
}
|
||||
+1659
File diff suppressed because it is too large
Load Diff
+26
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "jquery-idletimer",
|
||||
"version": "0.0.0-ignored",
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "grunt qunit"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/thorst/jquery-idletimer.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"grunt-contrib-jshint": "0.9.2",
|
||||
"grunt-contrib-concat": "0.3.0",
|
||||
"grunt-contrib-uglify": "0.4.0",
|
||||
"grunt-contrib-watch": "0.6.0",
|
||||
"grunt-coveralls": "0.3.0",
|
||||
"grunt-qunit-istanbul": "^0.4.0",
|
||||
"grunt": "0.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
}
|
||||
}
|
||||
+320
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas C. Zakas
|
||||
*
|
||||
* 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, sub-license, 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.
|
||||
*/
|
||||
/*
|
||||
mousewheel (deprecated) -> IE6.0, Chrome, Opera, Safari
|
||||
DOMMouseScroll (deprecated) -> Firefox 1.0
|
||||
wheel (standard) -> Chrome 31, Firefox 17, IE9, Firefox Mobile 17.0
|
||||
|
||||
//No need to use, use DOMMouseScroll
|
||||
MozMousePixelScroll -> Firefox 3.5, Firefox Mobile 1.0
|
||||
|
||||
//Events
|
||||
WheelEvent -> see wheel
|
||||
MouseWheelEvent -> see mousewheel
|
||||
MouseScrollEvent -> Firefox 3.5, Firefox Mobile 1.0
|
||||
*/
|
||||
(function ($) {
|
||||
|
||||
$.idleTimer = function (firstParam, elem) {
|
||||
var opts;
|
||||
if ( typeof firstParam === "object" ) {
|
||||
opts = firstParam;
|
||||
firstParam = null;
|
||||
} else if (typeof firstParam === "number") {
|
||||
opts = { timeout: firstParam };
|
||||
firstParam = null;
|
||||
}
|
||||
|
||||
// element to watch
|
||||
elem = elem || document;
|
||||
|
||||
// defaults that are to be stored as instance props on the elem
|
||||
opts = $.extend({
|
||||
idle: false, // indicates if the user is idle
|
||||
timeout: 30000, // the amount of time (ms) before the user is considered idle
|
||||
events: "mousemove keydown wheel DOMMouseScroll mousewheel mousedown touchstart touchmove MSPointerDown MSPointerMove" // define active events
|
||||
}, opts);
|
||||
|
||||
var jqElem = $(elem),
|
||||
obj = jqElem.data("idleTimerObj") || {},
|
||||
|
||||
/* (intentionally not documented)
|
||||
* Toggles the idle state and fires an appropriate event.
|
||||
* @return {void}
|
||||
*/
|
||||
toggleIdleState = function (e) {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// toggle the state
|
||||
obj.idle = !obj.idle;
|
||||
|
||||
// store toggle state date time
|
||||
obj.olddate = +new Date();
|
||||
|
||||
// create a custom event, with state and name space
|
||||
var event = $.Event((obj.idle ? "idle" : "active") + ".idleTimer");
|
||||
|
||||
// trigger event on object with elem and copy of obj
|
||||
$(elem).trigger(event, [elem, $.extend({}, obj), e]);
|
||||
},
|
||||
/**
|
||||
* Handle event triggers
|
||||
* @return {void}
|
||||
* @method event
|
||||
* @static
|
||||
*/
|
||||
handleEvent = function (e) {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// this is already paused, ignore events for now
|
||||
if (obj.remaining != null) { return; }
|
||||
|
||||
/*
|
||||
mousemove is kinda buggy, it can be triggered when it should be idle.
|
||||
Typically is happening between 115 - 150 milliseconds after idle triggered.
|
||||
@psyafter & @kaellis report "always triggered if using modal (jQuery ui, with overlay)"
|
||||
@thorst has similar issues on ios7 "after $.scrollTop() on text area"
|
||||
*/
|
||||
if (e.type === "mousemove") {
|
||||
// if coord are same, it didn't move
|
||||
if (e.pageX === obj.pageX && e.pageY === obj.pageY) {
|
||||
return;
|
||||
}
|
||||
// if coord don't exist how could it move
|
||||
if (typeof e.pageX === "undefined" && typeof e.pageY === "undefined") {
|
||||
return;
|
||||
}
|
||||
// under 200 ms is hard to do, and you would have to stop, as continuous activity will bypass this
|
||||
var elapsed = (+new Date()) - obj.olddate;
|
||||
if (elapsed < 200) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// clear any existing timeout
|
||||
clearTimeout(obj.tId);
|
||||
|
||||
// if the idle timer is enabled, flip
|
||||
if (obj.idle) {
|
||||
toggleIdleState(e);
|
||||
}
|
||||
|
||||
// store when user was last active
|
||||
obj.lastActive = +new Date();
|
||||
|
||||
// update mouse coord
|
||||
obj.pageX = e.pageX;
|
||||
obj.pageY = e.pageY;
|
||||
|
||||
// set a new timeout
|
||||
obj.tId = setTimeout(toggleIdleState, obj.timeout);
|
||||
|
||||
},
|
||||
/**
|
||||
* Restore initial settings and restart timer
|
||||
* @return {void}
|
||||
* @method reset
|
||||
* @static
|
||||
*/
|
||||
reset = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// reset settings
|
||||
obj.idle = obj.idleBackup;
|
||||
obj.olddate = +new Date();
|
||||
obj.lastActive = obj.olddate;
|
||||
obj.remaining = null;
|
||||
|
||||
// reset Timers
|
||||
clearTimeout(obj.tId);
|
||||
if (!obj.idle) {
|
||||
obj.tId = setTimeout(toggleIdleState, obj.timeout);
|
||||
}
|
||||
|
||||
},
|
||||
/**
|
||||
* Store remaining time, stop timer
|
||||
* You can pause from an idle OR active state
|
||||
* @return {void}
|
||||
* @method pause
|
||||
* @static
|
||||
*/
|
||||
pause = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// this is already paused
|
||||
if ( obj.remaining != null ) { return; }
|
||||
|
||||
// define how much is left on the timer
|
||||
obj.remaining = obj.timeout - ((+new Date()) - obj.olddate);
|
||||
|
||||
// clear any existing timeout
|
||||
clearTimeout(obj.tId);
|
||||
},
|
||||
/**
|
||||
* Start timer with remaining value
|
||||
* @return {void}
|
||||
* @method resume
|
||||
* @static
|
||||
*/
|
||||
resume = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
// this isn't paused yet
|
||||
if ( obj.remaining == null ) { return; }
|
||||
|
||||
// start timer
|
||||
if ( !obj.idle ) {
|
||||
obj.tId = setTimeout(toggleIdleState, obj.remaining);
|
||||
}
|
||||
|
||||
// clear remaining
|
||||
obj.remaining = null;
|
||||
},
|
||||
/**
|
||||
* Stops the idle timer. This removes appropriate event handlers
|
||||
* and cancels any pending timeouts.
|
||||
* @return {void}
|
||||
* @method destroy
|
||||
* @static
|
||||
*/
|
||||
destroy = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
//clear any pending timeouts
|
||||
clearTimeout(obj.tId);
|
||||
|
||||
//Remove data
|
||||
jqElem.removeData("idleTimerObj");
|
||||
|
||||
//detach the event handlers
|
||||
jqElem.off("._idleTimer");
|
||||
},
|
||||
/**
|
||||
* Returns the time until becoming idle
|
||||
* @return {number}
|
||||
* @method remainingtime
|
||||
* @static
|
||||
*/
|
||||
remainingtime = function () {
|
||||
|
||||
var obj = $.data(elem, "idleTimerObj") || {};
|
||||
|
||||
//If idle there is no time remaining
|
||||
if ( obj.idle ) { return 0; }
|
||||
|
||||
//If its paused just return that
|
||||
if ( obj.remaining != null ) { return obj.remaining; }
|
||||
|
||||
//Determine remaining, if negative idle didn't finish flipping, just return 0
|
||||
var remaining = obj.timeout - ((+new Date()) - obj.lastActive);
|
||||
if (remaining < 0) { remaining = 0; }
|
||||
|
||||
//If this is paused return that number, else return current remaining
|
||||
return remaining;
|
||||
};
|
||||
|
||||
|
||||
// determine which function to call
|
||||
if (firstParam === null && typeof obj.idle !== "undefined") {
|
||||
// they think they want to init, but it already is, just reset
|
||||
reset();
|
||||
return jqElem;
|
||||
} else if (firstParam === null) {
|
||||
// they want to init
|
||||
} else if (firstParam !== null && typeof obj.idle === "undefined") {
|
||||
// they want to do something, but it isnt init
|
||||
// not sure the best way to handle this
|
||||
return false;
|
||||
} else if (firstParam === "destroy") {
|
||||
destroy();
|
||||
return jqElem;
|
||||
} else if (firstParam === "pause") {
|
||||
pause();
|
||||
return jqElem;
|
||||
} else if (firstParam === "resume") {
|
||||
resume();
|
||||
return jqElem;
|
||||
} else if (firstParam === "reset") {
|
||||
reset();
|
||||
return jqElem;
|
||||
} else if (firstParam === "getRemainingTime") {
|
||||
return remainingtime();
|
||||
} else if (firstParam === "getElapsedTime") {
|
||||
return (+new Date()) - obj.olddate;
|
||||
} else if (firstParam === "getLastActiveTime") {
|
||||
return obj.lastActive;
|
||||
} else if (firstParam === "isIdle") {
|
||||
return obj.idle;
|
||||
}
|
||||
|
||||
/* (intentionally not documented)
|
||||
* Handles a user event indicating that the user isn't idle. namespaced with internal idleTimer
|
||||
* @param {Event} event A DOM2-normalized event object.
|
||||
* @return {void}
|
||||
*/
|
||||
jqElem.on($.trim((opts.events + " ").split(" ").join("._idleTimer ")), function (e) {
|
||||
handleEvent(e);
|
||||
});
|
||||
|
||||
|
||||
// Internal Object Properties, This isn't all necessary, but we
|
||||
// explicitly define all keys here so we know what we are working with
|
||||
obj = $.extend({}, {
|
||||
olddate : +new Date(), // the last time state changed
|
||||
lastActive: +new Date(), // the last time timer was active
|
||||
idle : opts.idle, // current state
|
||||
idleBackup : opts.idle, // backup of idle parameter since it gets modified
|
||||
timeout : opts.timeout, // the interval to change state
|
||||
remaining : null, // how long until state changes
|
||||
tId : null, // the idle timer setTimeout
|
||||
pageX : null, // used to store the mouse coord
|
||||
pageY : null
|
||||
});
|
||||
|
||||
// set a timeout to toggle state. May wish to omit this in some situations
|
||||
if (!obj.idle) {
|
||||
obj.tId = setTimeout(toggleIdleState, obj.timeout);
|
||||
}
|
||||
|
||||
// store our instance on the object
|
||||
$.data(elem, "idleTimerObj", obj);
|
||||
|
||||
return jqElem;
|
||||
};
|
||||
|
||||
// This allows binding to element
|
||||
$.fn.idleTimer = function (firstParam) {
|
||||
if (this[0]) {
|
||||
return $.idleTimer(firstParam, this[0]);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Idle Timer Test Suite</title>
|
||||
<!-- Load local jQuery. This can be overridden with a ?jquery=___ param. -->
|
||||
<script src="../libs/jquery-loader.js"></script>
|
||||
<!-- Load local QUnit. -->
|
||||
<link rel="stylesheet" href="../libs/qunit/qunit.css" media="screen">
|
||||
<script src="../libs/qunit/qunit.js"></script>
|
||||
<!-- Load local lib and tests. -->
|
||||
<script src="../src/idle-timer.js"></script>
|
||||
<script src="idle-timer_test.js"></script>
|
||||
<!-- Removing access to jQuery and $. But it'll still be available as _$, if
|
||||
you REALLY want to mess around with jQuery in the console. REMEMBER WE
|
||||
ARE TESTING A PLUGIN HERE, THIS HELPS ENSURE BEST PRACTICES. REALLY. -->
|
||||
<script>window._$ = jQuery.noConflict(true);</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Idle Timer Test Suite</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="qunit-fixture">
|
||||
<span>lame test markup</span>
|
||||
<span>normal test markup</span>
|
||||
<span>awesome test markup</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,220 @@
|
||||
(function($) {
|
||||
/*
|
||||
======== A Handy Little QUnit Reference ========
|
||||
http://docs.jquery.com/QUnit
|
||||
|
||||
Test methods:
|
||||
expect(numAssertions)
|
||||
stop(increment)
|
||||
start(decrement)
|
||||
Test assertions:
|
||||
ok(value, [message])
|
||||
equal(actual, expected, [message])
|
||||
notEqual(actual, expected, [message])
|
||||
deepEqual(actual, expected, [message])
|
||||
notDeepEqual(actual, expected, [message])
|
||||
strictEqual(actual, expected, [message])
|
||||
notStrictEqual(actual, expected, [message])
|
||||
raises(block, [expected], [message])
|
||||
*/
|
||||
//Name | expects | test
|
||||
module("Events Auto Binding");
|
||||
asyncTest("idle Event Triggered", 2, function () {
|
||||
$(document).on("idle.idleTimer", function (event, elem, obj) {
|
||||
|
||||
ok(true, "idle fires at document");
|
||||
ok(obj.idle, "object returned properly");
|
||||
|
||||
$.idleTimer("destroy");
|
||||
$(document).off();
|
||||
|
||||
start();
|
||||
});
|
||||
$.idleTimer( 100 );
|
||||
});
|
||||
asyncTest( "active Event Triggered", 2, function() {
|
||||
$( document ).on( "active.idleTimer", function(event, elem, obj){
|
||||
|
||||
ok(true, "active fires at document");
|
||||
ok(!obj.idle, "object returned properly");
|
||||
|
||||
$.idleTimer("destroy");
|
||||
$(document).off();
|
||||
|
||||
start();
|
||||
});
|
||||
$.idleTimer({idle:true});
|
||||
setTimeout( function(){
|
||||
$( "#qunit-fixture" ).trigger( "keydown" );
|
||||
}, 100 );
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
module("Events Element Binding");
|
||||
asyncTest("idle Triggered", 2, function () {
|
||||
$("#qunit-fixture").on("idle.idleTimer", function (event, elem, obj) {
|
||||
|
||||
ok(true, "idle fires at document");
|
||||
ok(obj.idle, "object returned properly");
|
||||
|
||||
$("#qunit-fixture").idleTimer("destroy");
|
||||
|
||||
start();
|
||||
});
|
||||
$("#qunit-fixture").idleTimer(100);
|
||||
});
|
||||
asyncTest("active Triggered", 2, function () {
|
||||
$("#qunit-fixture").on("active.idleTimer", function (event, elem, obj) {
|
||||
|
||||
ok(true, "active fires at document");
|
||||
ok(!obj.idle, "object returned properly");
|
||||
|
||||
$("#qunit-fixture").idleTimer("destroy");
|
||||
|
||||
start();
|
||||
});
|
||||
$("#qunit-fixture").idleTimer({ idle: true });
|
||||
setTimeout(function () {
|
||||
$("#qunit-fixture").trigger("keydown");
|
||||
}, 100);
|
||||
});
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Need to actually test pause/resume/reset, not just thier return type
|
||||
*/
|
||||
module("Functional");
|
||||
asyncTest("Pause works and is a jQuery instance", 4, function () {
|
||||
|
||||
$.idleTimer(100);
|
||||
equal(typeof $.idleTimer( "pause" ).jquery , "string", "pause should be jquery" );
|
||||
|
||||
$.idleTimer("resume");
|
||||
equal(typeof $(document).idleTimer("pause").jquery, "string", "pause should be jquery");
|
||||
|
||||
setTimeout(function () {
|
||||
ok(!$.idleTimer("isIdle"), "timer still active");
|
||||
ok(!$(document).idleTimer("isIdle"), "timer still active");
|
||||
|
||||
$.idleTimer("destroy");
|
||||
$(document).off();
|
||||
|
||||
start();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
|
||||
|
||||
asyncTest("Resume works and is a jQuery instance", 4, function () {
|
||||
|
||||
$.idleTimer(100);
|
||||
|
||||
$.idleTimer("pause");
|
||||
equal(typeof $.idleTimer("resume").jquery, "string", "resume should be jquery");
|
||||
|
||||
$.idleTimer("pause");
|
||||
equal(typeof $(document).idleTimer("resume").jquery, "string", "resume should be jquery");
|
||||
|
||||
setTimeout(function () {
|
||||
ok($.idleTimer("isIdle"), "timer inactive");
|
||||
ok($(document).idleTimer("isIdle"), "timer inactive");
|
||||
|
||||
$.idleTimer("destroy");
|
||||
$(document).off();
|
||||
|
||||
start();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
test("Elapsed time is a number", 2, function () {
|
||||
|
||||
$.idleTimer(100);
|
||||
|
||||
equal(typeof $.idleTimer("getElapsedTime"), "number", "Elapsed time should be a number");
|
||||
equal(typeof $(document).idleTimer("getElapsedTime"), "number", "Elapsed time should be a number");
|
||||
});
|
||||
|
||||
test("Init works and is a jQuery instance", 4, function () {
|
||||
|
||||
equal(typeof $.idleTimer(100).jquery, "string", "Init should be jquery");
|
||||
equal(typeof $("#qunit-fixture").idleTimer(100).jquery, "string", "Destroy should be jquery");
|
||||
|
||||
equal(typeof $(document).data("idleTimerObj").idle, "boolean", "Init data added");
|
||||
equal(typeof $("#qunit-fixture").data("idleTimerObj").idle, "boolean", "Init data added");
|
||||
});
|
||||
|
||||
test("Destroy works and is a jQuery instance", 4, function () {
|
||||
|
||||
$.idleTimer(100);
|
||||
$("#qunit-fixture").idleTimer(100);
|
||||
|
||||
equal(typeof $.idleTimer("destroy").jquery, "string", "Destroy should be jquery");
|
||||
equal(typeof $("#qunit-fixture").idleTimer("destroy").jquery, "string", "Destroy should be jquery");
|
||||
|
||||
equal(typeof $(document).data("idleTimerObj"), "undefined", "destroy removed data");
|
||||
equal(typeof $("#qunit-fixture").data("idleTimerObj"), "undefined", "destroy removed data");
|
||||
});
|
||||
|
||||
asyncTest("Reset is a jQuery instance", 6, function () {
|
||||
|
||||
//start the timer
|
||||
$.idleTimer(200);
|
||||
$.idleTimer("pause");
|
||||
$("#qunit-fixture").idleTimer(200);
|
||||
$("#qunit-fixture").idleTimer("pause");
|
||||
|
||||
//After a bit, reset it
|
||||
setTimeout(function () {
|
||||
equal(typeof $.idleTimer("reset").jquery, "string", "reset should be jquery");
|
||||
equal(typeof $("#qunit-fixture").idleTimer("reset").jquery, "string", "reset should be jquery");
|
||||
|
||||
ok($(document).data("idleTimerObj").remaining===null, "reset remaining");
|
||||
ok($("#qunit-fixture").data("idleTimerObj").remaining === null, "reset remaining");
|
||||
}, 100);
|
||||
|
||||
setTimeout(function () {
|
||||
ok($.idleTimer("isIdle"), "timer inactive");
|
||||
ok($("#qunit-fixture").idleTimer("isIdle"), "timer inactive");
|
||||
|
||||
$.idleTimer("destroy");
|
||||
$("#qunit-fixture").idleTimer("destroy");
|
||||
$(document).off();
|
||||
|
||||
start();
|
||||
}, 400);
|
||||
|
||||
});
|
||||
|
||||
test("Last Active time is a number", 2, function () {
|
||||
|
||||
$.idleTimer(100);
|
||||
|
||||
equal(typeof $.idleTimer("getLastActiveTime"), "number", "Last Active time should be a number");
|
||||
equal(typeof $(document).idleTimer("getLastActiveTime"), "number", "Last Active time should be a number");
|
||||
|
||||
$.idleTimer("destroy");
|
||||
});
|
||||
|
||||
test("Remaining time is a number", 2, function () {
|
||||
|
||||
$.idleTimer(100);
|
||||
|
||||
equal( typeof $.idleTimer( "getRemainingTime" ), "number", "Remaining time should be a number" );
|
||||
equal(typeof $(document).idleTimer("getRemainingTime"), "number", "Remaining time should be a number");
|
||||
|
||||
$.idleTimer("destroy");
|
||||
});
|
||||
test("isIdle is a boolean", 2, function () {
|
||||
|
||||
$.idleTimer(100);
|
||||
|
||||
equal(typeof $.idleTimer("isIdle"), "boolean", "isIdle should be a boolean");
|
||||
equal(typeof $(document).idleTimer("isIdle"), "boolean", "isIdle should be a boolean");
|
||||
|
||||
$.idleTimer("destroy");
|
||||
});
|
||||
|
||||
}(jQuery));
|
||||
Reference in New Issue
Block a user