mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 02:35:49 +00:00
feature(bower) add domtokenlist-shim
This commit is contained in:
parent
0020afcf92
commit
e2d4a95c44
26 changed files with 13243 additions and 1104 deletions
|
|
@ -29,6 +29,6 @@
|
|||
"rendy": "~1.1.0",
|
||||
"github": "~0.10.6",
|
||||
"vk-openapi": "~0.0.1",
|
||||
"html5-polyfills": "*"
|
||||
"domtokenlist-shim": "~1.1.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,10 +21,7 @@
|
|||
LIB + '*.js',
|
||||
LIB_CLIENT + '/*.js',
|
||||
LIB_CLIENT + 'storage/*.js',
|
||||
LIB_SERVER + '/**/*.js',
|
||||
'!' + LIB + 'diff/diff-match-patch.js',
|
||||
'!' + LIB + 'promise.js',
|
||||
'!' + LIB_CLIENT + 'jquery.js'
|
||||
LIB_SERVER + '/**/*.js'
|
||||
];
|
||||
|
||||
gulp.task('release', function() {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ var CloudCmd;
|
|||
|
||||
moduleFiles = [
|
||||
'promise-polyfill/Promise',
|
||||
'domtokenlist-shim/dist/domtokenlist',
|
||||
'format-io/lib/format',
|
||||
'rendy/lib/rendy',
|
||||
].map(function(name) {
|
||||
|
|
|
|||
40
modules/domtokenlist-shim/.bower.json
Normal file
40
modules/domtokenlist-shim/.bower.json
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"name": "domtokenlist-shim",
|
||||
"description": "A super strict shim/polyfill for DOMTokenList",
|
||||
"main": "dist/domtokenlist.js",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"*.json",
|
||||
"*.md",
|
||||
"gulpfile.js",
|
||||
"src",
|
||||
"tests",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test"
|
||||
],
|
||||
"keywords": [
|
||||
"classlist",
|
||||
"domtokenlist",
|
||||
"polyfill",
|
||||
"rellist",
|
||||
"shim"
|
||||
],
|
||||
"authors": [
|
||||
"Jonathan Wilsson <jonathan.wilsson@gmail.com>",
|
||||
"Bogdan Chadkin <trysound@yandex.ru>"
|
||||
],
|
||||
"homepage": "https://github.com/jwilsson/domtokenlist",
|
||||
"version": "1.1.0",
|
||||
"_release": "1.1.0",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "1.1.0",
|
||||
"commit": "61eb3d90801480205a2b994ff535e60f14c65ce6"
|
||||
},
|
||||
"_source": "git://github.com/jwilsson/domtokenlist.git",
|
||||
"_target": "~1.1.0",
|
||||
"_originalSource": "domtokenlist-shim",
|
||||
"_direct": true
|
||||
}
|
||||
29
modules/domtokenlist-shim/bower.json
Normal file
29
modules/domtokenlist-shim/bower.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"name": "domtokenlist-shim",
|
||||
"description": "A super strict shim/polyfill for DOMTokenList",
|
||||
"main": "dist/domtokenlist.js",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"*.json",
|
||||
"*.md",
|
||||
"gulpfile.js",
|
||||
"src",
|
||||
"tests",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test"
|
||||
],
|
||||
"keywords": [
|
||||
"classlist",
|
||||
"domtokenlist",
|
||||
"polyfill",
|
||||
"rellist",
|
||||
"shim"
|
||||
],
|
||||
"authors": [
|
||||
"Jonathan Wilsson <jonathan.wilsson@gmail.com>",
|
||||
"Bogdan Chadkin <trysound@yandex.ru>"
|
||||
],
|
||||
"homepage": "https://github.com/jwilsson/domtokenlist"
|
||||
}
|
||||
12954
modules/domtokenlist-shim/browserstack-logo.svg
Normal file
12954
modules/domtokenlist-shim/browserstack-logo.svg
Normal file
File diff suppressed because it is too large
Load diff
|
After Width: | Height: | Size: 950 KiB |
215
modules/domtokenlist-shim/dist/domtokenlist.js
vendored
Normal file
215
modules/domtokenlist-shim/dist/domtokenlist.js
vendored
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
/*! DOMTokenlist shim | Copyright 2015 Jonathan Wilsson and Bogdan Chadkin. */
|
||||
;(function (window) {
|
||||
'use strict';
|
||||
|
||||
if (!window.DOMTokenList) {
|
||||
return;
|
||||
}
|
||||
|
||||
var el = document.createElement('a').classList;
|
||||
var dtp = DOMTokenList.prototype;
|
||||
var add = dtp.add;
|
||||
var remove = dtp.remove;
|
||||
var toggle = dtp.toggle;
|
||||
|
||||
el.add('c1', 'c2');
|
||||
|
||||
// Older versions of the HTMLElement.classList spec didn't allow multiple
|
||||
// arguments, easy to test for
|
||||
var iterateArg = function (fn) {
|
||||
return function () {
|
||||
var tokens = arguments;
|
||||
var i;
|
||||
|
||||
for (i = 0; i < tokens.length; i += 1) {
|
||||
fn.call(this, tokens[i]);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
if (!el.contains('c2')) {
|
||||
dtp.add = iterateArg(add);
|
||||
dtp.remove = iterateArg(remove);
|
||||
}
|
||||
|
||||
// Older versions of the spec didn't have a forcedState argument for
|
||||
// `toggle` either, test by checking the return value after forcing
|
||||
if (!el.toggle('c1', true)) {
|
||||
dtp.toggle = function (cls, force) {
|
||||
if (force === undefined) {
|
||||
return toggle.call(this, cls);
|
||||
}
|
||||
|
||||
(force ? add : remove).call(this, cls);
|
||||
return !!force;
|
||||
};
|
||||
}
|
||||
}(window));
|
||||
|
||||
;(function (window) {
|
||||
'use strict';
|
||||
|
||||
if (window.DOMTokenList) {
|
||||
return;
|
||||
}
|
||||
|
||||
var arr = [];
|
||||
|
||||
var inArray = function (array, value) {
|
||||
var i;
|
||||
|
||||
if (arr.indexOf) {
|
||||
return arr.indexOf.call(array, value);
|
||||
}
|
||||
|
||||
for (i = 0; i < array.length; i++) {
|
||||
if (array[i] === value) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
var validateToken = function (token) {
|
||||
var whitespace = /[\u0009\u000A\u000C\u000D\u0020]/;
|
||||
|
||||
if (token === '' || whitespace.test(token)) {
|
||||
throw new Error('Token must not be empty or contain whitespace.');
|
||||
}
|
||||
};
|
||||
|
||||
var DOMTokenList = function (element, prop) {
|
||||
var inst = this;
|
||||
var i;
|
||||
var values = [];
|
||||
|
||||
if (element && prop) {
|
||||
inst.element = element;
|
||||
inst.prop = prop;
|
||||
|
||||
if (element[prop]) {
|
||||
values = element[prop].replace(/^\s+|\s+$/g, '').split(/\s+/);
|
||||
|
||||
for (i = 0; i < values.length; i++) {
|
||||
inst[i] = values[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inst.length = values.length;
|
||||
};
|
||||
|
||||
DOMTokenList.prototype = {
|
||||
add: function () {
|
||||
var inst = this;
|
||||
var i;
|
||||
var tokens = arguments;
|
||||
|
||||
for (i = 0; i < tokens.length; i++) {
|
||||
validateToken(tokens[i]);
|
||||
|
||||
if (!inst.contains(tokens[i])) {
|
||||
arr.push.call(inst, tokens[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (inst.element) {
|
||||
inst.element[inst.prop] = inst;
|
||||
}
|
||||
},
|
||||
|
||||
contains: function (token) {
|
||||
validateToken(token);
|
||||
|
||||
return inArray(this, token) !== -1;
|
||||
},
|
||||
|
||||
item: function (index) {
|
||||
return this[index] || null;
|
||||
},
|
||||
|
||||
remove: function () {
|
||||
var tokens = arguments;
|
||||
var inst = this;
|
||||
var key;
|
||||
var i;
|
||||
|
||||
for (i = 0; i < tokens.length; i++) {
|
||||
validateToken(tokens[i]);
|
||||
|
||||
key = inArray(inst, tokens[i]);
|
||||
|
||||
if (key !== -1) {
|
||||
arr.splice.call(inst, key, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (inst.element) {
|
||||
inst.element[inst.prop] = inst;
|
||||
}
|
||||
},
|
||||
|
||||
toggle: function (token, force) {
|
||||
var inst = this;
|
||||
|
||||
if (inst.contains(token)) {
|
||||
if (force) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inst.remove(token);
|
||||
|
||||
return false;
|
||||
} else {
|
||||
if (force === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inst.add(token);
|
||||
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
toString: function () {
|
||||
return arr.join.call(this, ' ');
|
||||
}
|
||||
};
|
||||
|
||||
window.DOMTokenList = DOMTokenList;
|
||||
}(window));
|
||||
|
||||
;(function () {
|
||||
'use strict';
|
||||
|
||||
if ('classList' in document.createElement('a') && !window.QUnit) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object.defineProperty(Element.prototype, 'classList', {
|
||||
get: function () {
|
||||
return new DOMTokenList(this, 'className');
|
||||
}
|
||||
});
|
||||
}());
|
||||
|
||||
;(function () {
|
||||
'use strict';
|
||||
|
||||
if ('relList' in document.createElement('a') && !window.QUnit) {
|
||||
return;
|
||||
}
|
||||
|
||||
var i;
|
||||
var elements = [HTMLAnchorElement, HTMLAreaElement, HTMLLinkElement];
|
||||
var getter = function () {
|
||||
return new DOMTokenList(this, 'rel');
|
||||
};
|
||||
|
||||
for (i = 0; i < elements.length; i++) {
|
||||
Object.defineProperty(elements[i].prototype, 'relList', {
|
||||
get: getter
|
||||
});
|
||||
}
|
||||
}());
|
||||
2
modules/domtokenlist-shim/dist/domtokenlist.min.js
vendored
Normal file
2
modules/domtokenlist-shim/dist/domtokenlist.min.js
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/*! DOMTokenlist shim | Copyright 2015 Jonathan Wilsson and Bogdan Chadkin. */
|
||||
!function(t){"use strict";if(t.DOMTokenList){var e=document.createElement("a").classList,n=DOMTokenList.prototype,i=n.add,r=n.remove,o=n.toggle;e.add("c1","c2");var s=function(t){return function(){var e,n=arguments;for(e=0;e<n.length;e+=1)t.call(this,n[e])}};e.contains("c2")||(n.add=s(i),n.remove=s(r)),e.toggle("c1",!0)||(n.toggle=function(t,e){return void 0===e?o.call(this,t):((e?i:r).call(this,t),!!e)})}}(window),function(t){"use strict";if(!t.DOMTokenList){var e=[],n=function(t,n){var i;if(e.indexOf)return e.indexOf.call(t,n);for(i=0;i<t.length;i++)if(t[i]===n)return i;return-1},i=function(t){var e=/[\u0009\u000A\u000C\u000D\u0020]/;if(""===t||e.test(t))throw new Error("Token must not be empty or contain whitespace.")},r=function(t,e){var n,i=this,r=[];if(t&&e&&(i.element=t,i.prop=e,t[e]))for(r=t[e].replace(/^\s+|\s+$/g,"").split(/\s+/),n=0;n<r.length;n++)i[n]=r[n];i.length=r.length};r.prototype={add:function(){var t,n=this,r=arguments;for(t=0;t<r.length;t++)i(r[t]),n.contains(r[t])||e.push.call(n,r[t]);n.element&&(n.element[n.prop]=n)},contains:function(t){return i(t),-1!==n(this,t)},item:function(t){return this[t]||null},remove:function(){var t,r,o=arguments,s=this;for(r=0;r<o.length;r++)i(o[r]),t=n(s,o[r]),-1!==t&&e.splice.call(s,t,1);s.element&&(s.element[s.prop]=s)},toggle:function(t,e){var n=this;return n.contains(t)?e?!0:(n.remove(t),!1):e===!1?!1:(n.add(t),!0)},toString:function(){return e.join.call(this," ")}},t.DOMTokenList=r}}(window),function(){"use strict";"classList"in document.createElement("a")&&!window.QUnit||Object.defineProperty(Element.prototype,"classList",{get:function(){return new DOMTokenList(this,"className")}})}(),function(){"use strict";if(!("relList"in document.createElement("a"))||window.QUnit){var t,e=[HTMLAnchorElement,HTMLAreaElement,HTMLLinkElement],n=function(){return new DOMTokenList(this,"rel")};for(t=0;t<e.length;t++)Object.defineProperty(e[t].prototype,"relList",{get:n})}}();
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
{
|
||||
"name": "html5-polyfills",
|
||||
"description": "Collection of polyfills by Remy Sharp",
|
||||
"homepage": "https://github.com/remy/polyfills",
|
||||
"keywords": [
|
||||
"polyfill",
|
||||
"client",
|
||||
"browser"
|
||||
],
|
||||
"author": {
|
||||
"name": "Remy Sharp",
|
||||
"email": "remy@leftlogic.com"
|
||||
},
|
||||
"readme": "This is my own collection of code snippets that support different native features of browsers using JavaScript (and if required, Flash in some cases).",
|
||||
"readmeFilename": "README.md",
|
||||
"_id": "html5-polyfills@0.0.20130621",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/remy/polyfills.git"
|
||||
},
|
||||
"_release": "768ce355de",
|
||||
"_resolution": {
|
||||
"type": "branch",
|
||||
"branch": "master",
|
||||
"commit": "768ce355de8f31d8d0a99aa3aba3708daa54e873"
|
||||
},
|
||||
"_source": "git://github.com/remy/polyfills.git",
|
||||
"_target": "*",
|
||||
"_originalSource": "html5-polyfills",
|
||||
"_direct": true
|
||||
}
|
||||
|
|
@ -1,186 +0,0 @@
|
|||
;(function (global) {
|
||||
|
||||
if ("EventSource" in global) return;
|
||||
|
||||
var reTrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g;
|
||||
|
||||
var EventSource = function (url) {
|
||||
var eventsource = this,
|
||||
interval = 500, // polling interval
|
||||
lastEventId = null,
|
||||
cache = '';
|
||||
|
||||
if (!url || typeof url != 'string') {
|
||||
throw new SyntaxError('Not enough arguments');
|
||||
}
|
||||
|
||||
this.URL = url;
|
||||
this.readyState = this.CONNECTING;
|
||||
this._pollTimer = null;
|
||||
this._xhr = null;
|
||||
|
||||
function pollAgain(interval) {
|
||||
eventsource._pollTimer = setTimeout(function () {
|
||||
poll.call(eventsource);
|
||||
}, interval);
|
||||
}
|
||||
|
||||
function poll() {
|
||||
try { // force hiding of the error message... insane?
|
||||
if (eventsource.readyState == eventsource.CLOSED) return;
|
||||
|
||||
// NOTE: IE7 and upwards support
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', eventsource.URL, true);
|
||||
xhr.setRequestHeader('Accept', 'text/event-stream');
|
||||
xhr.setRequestHeader('Cache-Control', 'no-cache');
|
||||
// we must make use of this on the server side if we're working with Android - because they don't trigger
|
||||
// readychange until the server connection is closed
|
||||
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
||||
|
||||
if (lastEventId != null) xhr.setRequestHeader('Last-Event-ID', lastEventId);
|
||||
cache = '';
|
||||
|
||||
xhr.timeout = 50000;
|
||||
xhr.onreadystatechange = function () {
|
||||
if (this.readyState == 3 || (this.readyState == 4 && this.status == 200)) {
|
||||
// on success
|
||||
if (eventsource.readyState == eventsource.CONNECTING) {
|
||||
eventsource.readyState = eventsource.OPEN;
|
||||
eventsource.dispatchEvent('open', { type: 'open' });
|
||||
}
|
||||
|
||||
var responseText = '';
|
||||
try {
|
||||
responseText = this.responseText || '';
|
||||
} catch (e) {}
|
||||
|
||||
// process this.responseText
|
||||
var parts = responseText.substr(cache.length).split("\n"),
|
||||
eventType = 'message',
|
||||
data = [],
|
||||
i = 0,
|
||||
line = '';
|
||||
|
||||
cache = responseText;
|
||||
|
||||
// TODO handle 'event' (for buffer name), retry
|
||||
for (; i < parts.length; i++) {
|
||||
line = parts[i].replace(reTrim, '');
|
||||
if (line.indexOf('event') == 0) {
|
||||
eventType = line.replace(/event:?\s*/, '');
|
||||
} else if (line.indexOf('retry') == 0) {
|
||||
retry = parseInt(line.replace(/retry:?\s*/, ''));
|
||||
if(!isNaN(retry)) { interval = retry; }
|
||||
} else if (line.indexOf('data') == 0) {
|
||||
data.push(line.replace(/data:?\s*/, ''));
|
||||
} else if (line.indexOf('id:') == 0) {
|
||||
lastEventId = line.replace(/id:?\s*/, '');
|
||||
} else if (line.indexOf('id') == 0) { // this resets the id
|
||||
lastEventId = null;
|
||||
} else if (line == '') {
|
||||
if (data.length) {
|
||||
var event = new MessageEvent(data.join('\n'), eventsource.url, lastEventId);
|
||||
eventsource.dispatchEvent(eventType, event);
|
||||
data = [];
|
||||
eventType = 'message';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.readyState == 4) pollAgain(interval);
|
||||
// don't need to poll again, because we're long-loading
|
||||
} else if (eventsource.readyState !== eventsource.CLOSED) {
|
||||
if (this.readyState == 4) { // and some other status
|
||||
// dispatch error
|
||||
eventsource.readyState = eventsource.CONNECTING;
|
||||
eventsource.dispatchEvent('error', { type: 'error' });
|
||||
pollAgain(interval);
|
||||
} else if (this.readyState == 0) { // likely aborted
|
||||
pollAgain(interval);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send();
|
||||
|
||||
setTimeout(function () {
|
||||
if (true || xhr.readyState == 3) xhr.abort();
|
||||
}, xhr.timeout);
|
||||
|
||||
eventsource._xhr = xhr;
|
||||
|
||||
} catch (e) { // in an attempt to silence the errors
|
||||
eventsource.dispatchEvent('error', { type: 'error', data: e.message }); // ???
|
||||
}
|
||||
};
|
||||
|
||||
poll(); // init now
|
||||
};
|
||||
|
||||
EventSource.prototype = {
|
||||
close: function () {
|
||||
// closes the connection - disabling the polling
|
||||
this.readyState = this.CLOSED;
|
||||
clearInterval(this._pollTimer);
|
||||
this._xhr.abort();
|
||||
},
|
||||
CONNECTING: 0,
|
||||
OPEN: 1,
|
||||
CLOSED: 2,
|
||||
dispatchEvent: function (type, event) {
|
||||
var handlers = this['_' + type + 'Handlers'];
|
||||
if (handlers) {
|
||||
for (var i = 0; i < handlers.length; i++) {
|
||||
handlers[i].call(this, event);
|
||||
}
|
||||
}
|
||||
|
||||
if (this['on' + type]) {
|
||||
this['on' + type].call(this, event);
|
||||
}
|
||||
},
|
||||
addEventListener: function (type, handler) {
|
||||
if (!this['_' + type + 'Handlers']) {
|
||||
this['_' + type + 'Handlers'] = [];
|
||||
}
|
||||
|
||||
this['_' + type + 'Handlers'].push(handler);
|
||||
},
|
||||
removeEventListener: function (type, handler) {
|
||||
var handlers = this['_' + type + 'Handlers'];
|
||||
if (!handlers) {
|
||||
return;
|
||||
}
|
||||
for (var i = handlers.length - 1; i >= 0; --i) {
|
||||
if (handlers[i] === handler) {
|
||||
handlers.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
onerror: null,
|
||||
onmessage: null,
|
||||
onopen: null,
|
||||
readyState: 0,
|
||||
URL: ''
|
||||
};
|
||||
|
||||
var MessageEvent = function (data, origin, lastEventId) {
|
||||
this.data = data;
|
||||
this.origin = origin;
|
||||
this.lastEventId = lastEventId || '';
|
||||
};
|
||||
|
||||
MessageEvent.prototype = {
|
||||
data: null,
|
||||
type: 'message',
|
||||
lastEventId: '',
|
||||
origin: ''
|
||||
};
|
||||
|
||||
if ('module' in global) module.exports = EventSource;
|
||||
global.EventSource = EventSource;
|
||||
|
||||
})(this);
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
Copyright (c) 2010 Remy Sharp, http://remysharp.com
|
||||
|
||||
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.
|
||||
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
# Polyfills
|
||||
|
||||
> A way of getting the browser to behave and support the latest specifications.
|
||||
|
||||
This is my own collection of code snippets that support different native features of browsers using JavaScript (and if required, Flash in some cases).
|
||||
|
||||
## Component Installation
|
||||
|
||||
You can install polyfills using component:
|
||||
|
||||
```
|
||||
component install remy/polyfills
|
||||
```
|
||||
|
||||
If you'd like to include all polyfills (except device motion), you can just:
|
||||
|
||||
```
|
||||
require( 'polyfills' );
|
||||
```
|
||||
|
||||
If you'd only like a specific polyfill, you can require indivual ones like this:
|
||||
|
||||
```
|
||||
require( 'polyfills/classList' );
|
||||
|
||||
// now we can use classList in lots of browsers!
|
||||
element.classList.add( 'foo' );
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
License: http://rem.mit-license.org
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
if (typeof window.localStorage == 'undefined' || typeof window.sessionStorage == 'undefined') (function () {
|
||||
|
||||
var Storage = function (type) {
|
||||
function createCookie(name, value, days) {
|
||||
var date, expires;
|
||||
|
||||
if (days) {
|
||||
date = new Date();
|
||||
date.setTime(date.getTime()+(days*24*60*60*1000));
|
||||
expires = "; expires="+date.toGMTString();
|
||||
} else {
|
||||
expires = "";
|
||||
}
|
||||
document.cookie = name+"="+value+expires+"; path=/";
|
||||
}
|
||||
|
||||
function readCookie(name) {
|
||||
var nameEQ = name + "=",
|
||||
ca = document.cookie.split(';'),
|
||||
i, c;
|
||||
|
||||
for (i=0; i < ca.length; i++) {
|
||||
c = ca[i];
|
||||
while (c.charAt(0)==' ') {
|
||||
c = c.substring(1,c.length);
|
||||
}
|
||||
|
||||
if (c.indexOf(nameEQ) == 0) {
|
||||
return c.substring(nameEQ.length,c.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function setData(data) {
|
||||
data = JSON.stringify(data);
|
||||
if (type == 'session') {
|
||||
window.name = data;
|
||||
} else {
|
||||
createCookie('localStorage', data, 365);
|
||||
}
|
||||
}
|
||||
|
||||
function clearData() {
|
||||
if (type == 'session') {
|
||||
window.name = '';
|
||||
} else {
|
||||
createCookie('localStorage', '', 365);
|
||||
}
|
||||
}
|
||||
|
||||
function getData() {
|
||||
var data = type == 'session' ? window.name : readCookie('localStorage');
|
||||
return data ? JSON.parse(data) : {};
|
||||
}
|
||||
|
||||
|
||||
// initialise if there's already data
|
||||
var data = getData();
|
||||
|
||||
return {
|
||||
length: 0,
|
||||
clear: function () {
|
||||
data = {};
|
||||
this.length = 0;
|
||||
clearData();
|
||||
},
|
||||
getItem: function (key) {
|
||||
return data[key] === undefined ? null : data[key];
|
||||
},
|
||||
key: function (i) {
|
||||
// not perfect, but works
|
||||
var ctr = 0;
|
||||
for (var k in data) {
|
||||
if (ctr == i) return k;
|
||||
else ctr++;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
removeItem: function (key) {
|
||||
delete data[key];
|
||||
this.length--;
|
||||
setData(data);
|
||||
},
|
||||
setItem: function (key, value) {
|
||||
data[key] = value+''; // forces the value to a string
|
||||
this.length++;
|
||||
setData(data);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
if (typeof window.localStorage == 'undefined') window.localStorage = new Storage('local');
|
||||
if (typeof window.sessionStorage == 'undefined') window.sessionStorage = new Storage('session');
|
||||
|
||||
})();
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"name": "html5-polyfills",
|
||||
"description": "Collection of polyfills by Remy Sharp",
|
||||
"homepage": "https://github.com/remy/polyfills",
|
||||
"keywords": [
|
||||
"polyfill",
|
||||
"client",
|
||||
"browser"
|
||||
],
|
||||
"author": {
|
||||
"name": "Remy Sharp",
|
||||
"email": "remy@leftlogic.com"
|
||||
},
|
||||
"version": "0.0.20130621",
|
||||
"readme": "This is my own collection of code snippets that support different native features of browsers using JavaScript (and if required, Flash in some cases).",
|
||||
"readmeFilename": "README.md",
|
||||
"_id": "html5-polyfills@0.0.20130621",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/remy/polyfills.git"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
(function () {
|
||||
|
||||
if (typeof window.Element === "undefined" || "classList" in document.documentElement) return;
|
||||
|
||||
var prototype = Array.prototype,
|
||||
push = prototype.push,
|
||||
splice = prototype.splice,
|
||||
join = prototype.join;
|
||||
|
||||
function DOMTokenList(el) {
|
||||
this.el = el;
|
||||
// The className needs to be trimmed and split on whitespace
|
||||
// to retrieve a list of classes.
|
||||
var classes = el.className.replace(/^\s+|\s+$/g,'').split(/\s+/);
|
||||
for (var i = 0; i < classes.length; i++) {
|
||||
push.call(this, classes[i]);
|
||||
}
|
||||
};
|
||||
|
||||
DOMTokenList.prototype = {
|
||||
add: function(token) {
|
||||
if(this.contains(token)) return;
|
||||
push.call(this, token);
|
||||
this.el.className = this.toString();
|
||||
},
|
||||
contains: function(token) {
|
||||
return this.el.className.indexOf(token) != -1;
|
||||
},
|
||||
item: function(index) {
|
||||
return this[index] || null;
|
||||
},
|
||||
remove: function(token) {
|
||||
if (!this.contains(token)) return;
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
if (this[i] == token) break;
|
||||
}
|
||||
splice.call(this, i, 1);
|
||||
this.el.className = this.toString();
|
||||
},
|
||||
toString: function() {
|
||||
return join.call(this, ' ');
|
||||
},
|
||||
toggle: function(token) {
|
||||
if (!this.contains(token)) {
|
||||
this.add(token);
|
||||
} else {
|
||||
this.remove(token);
|
||||
}
|
||||
|
||||
return this.contains(token);
|
||||
}
|
||||
};
|
||||
|
||||
window.DOMTokenList = DOMTokenList;
|
||||
|
||||
function defineElementGetter (obj, prop, getter) {
|
||||
if (Object.defineProperty) {
|
||||
Object.defineProperty(obj, prop,{
|
||||
get : getter
|
||||
});
|
||||
} else {
|
||||
obj.__defineGetter__(prop, getter);
|
||||
}
|
||||
}
|
||||
|
||||
defineElementGetter(Element.prototype, 'classList', function () {
|
||||
return new DOMTokenList(this);
|
||||
});
|
||||
|
||||
})();
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"name": "polyfills",
|
||||
"scripts": [
|
||||
"classList.js",
|
||||
"dataset.js",
|
||||
"device-motion-polyfill.js",
|
||||
"EventSource.js",
|
||||
"index.js",
|
||||
"input-target.js",
|
||||
"offline-events.js",
|
||||
"range.js",
|
||||
"sessionStorage.js",
|
||||
"Storage.js"
|
||||
],
|
||||
"main": "index.js"
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
(function () {
|
||||
var forEach = [].forEach,
|
||||
regex = /^data-(.+)/,
|
||||
dashChar = /\-([a-z])/ig,
|
||||
el = document.createElement('div'),
|
||||
mutationSupported = false,
|
||||
match
|
||||
;
|
||||
|
||||
function detectMutation() {
|
||||
mutationSupported = true;
|
||||
this.removeEventListener('DOMAttrModified', detectMutation, false);
|
||||
}
|
||||
|
||||
function toCamelCase(s) {
|
||||
return s.replace(dashChar, function (m,l) { return l.toUpperCase(); });
|
||||
}
|
||||
|
||||
function updateDataset() {
|
||||
var dataset = {};
|
||||
forEach.call(this.attributes, function(attr) {
|
||||
if (match = attr.name.match(regex))
|
||||
dataset[toCamelCase(match[1])] = attr.value;
|
||||
});
|
||||
return dataset;
|
||||
}
|
||||
|
||||
// only add support if the browser doesn't support data-* natively
|
||||
if (el.dataset != undefined) return;
|
||||
|
||||
el.addEventListener('DOMAttrModified', detectMutation, false);
|
||||
el.setAttribute('foo', 'bar');
|
||||
|
||||
function defineElementGetter (obj, prop, getter) {
|
||||
if (Object.defineProperty) {
|
||||
Object.defineProperty(obj, prop,{
|
||||
get : getter
|
||||
});
|
||||
} else {
|
||||
obj.__defineGetter__(prop, getter);
|
||||
}
|
||||
}
|
||||
|
||||
defineElementGetter(Element.prototype, 'dataset', mutationSupported
|
||||
? function () {
|
||||
if (!this._datasetCache) {
|
||||
this._datasetCache = updateDataset.call(this);
|
||||
}
|
||||
return this._datasetCache;
|
||||
}
|
||||
: updateDataset
|
||||
);
|
||||
|
||||
document.addEventListener('DOMAttrModified', function (event) {
|
||||
delete event.target._datasetCache;
|
||||
}, false);
|
||||
})();
|
||||
|
|
@ -1,253 +0,0 @@
|
|||
/**
|
||||
* DeviceMotion and DeviceOrientation polyfill
|
||||
* by Remy Sharp / leftlogic.com
|
||||
* MIT http://rem.mit-license.org
|
||||
*
|
||||
* Usage: used for testing motion events, include
|
||||
* script in head of test document and allow popup
|
||||
* to open to control device orientation.
|
||||
*/
|
||||
(!document.DeviceOrientationEvent || !document.DeviceMotionEvent) && (function () {
|
||||
|
||||
// thankfully we don't have to do anything, because the event only fires on the window object
|
||||
var polyfill = {
|
||||
motion: !document.DeviceMotionEvent,
|
||||
orientation: !document.DeviceOrientationEvent
|
||||
};
|
||||
|
||||
if (polyfill.orientation) window.DeviceOrientationEvent = function () {};
|
||||
|
||||
if (polyfill.motion) window.DeviceMotionEvent = function () {};
|
||||
|
||||
// images - yes I do like to be self contained don't I?! :)
|
||||
var imageSrc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFsAAACpCAYAAABEbEGLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxODkwMDQ2NTNDNEYxMUUxQTYyOTk2M0QwMjU4OThGOCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxODkwMDQ2NjNDNEYxMUUxQTYyOTk2M0QwMjU4OThGOCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4OTAwNDYzM0M0RjExRTFBNjI5OTYzRDAyNTg5OEY4IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4OTAwNDY0M0M0RjExRTFBNjI5OTYzRDAyNTg5OEY4Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+jKamsAAAAtNJREFUeNrs2t1t01AYgGG3dACPkA3qEcIlV5QJSCdAnaAwAWKCsgFs0HQChwmaS+6SThCOKwuigtP4J+ln9LzSRyWaRMmTE8fHcJLt3yRNkeY8U9VDmkWa+ZAPOktTptmYf84qzU29GDtXQG49111XM7xuUy3QfF/oa2DHAbeijwReABp8vjVh+zI8zFw4fBxv7q3qF1jdp1s7Qx2ut9UfZ0Gh+26BJ313dANXRDuvXg38xuf1NjrKoeTxMBKlq/rCzlCt01zWP0N0GujjtjzQ4y4iYS+DPJd8ZI/bCTtKHw7wmLNIJwBngbCn9QZgOcDZSF4/XqgzrUjY26ds0//xZPs0E2zYgg1bsGHDFuwRt2sHOcfTqSJruPi1C/s1t07dZg2XGxxGHLNhCzZswYYNW7BhCzZs2IINW7BhCzZs2IINW7BhwxZs2IINW7BhwxZs2IING7ZgwxZs2IING7ZgwxZs2LAFG7Zgw4Yt2LAFG7Zgw4Yt2LAFGzZswYYt2LAFGzZswYYt2LBhCzZswYYt2LBhCzZswYYNW7BhCzZs2IINW7BhCzZs2IINW7BhwxZs2IIdvbMdv7vG06lJF+yP3BxGYAs2bGcj8VukmadZb/1dkWaaJh/Li6hO8TaB57YGbSofwWvYjAH7psWiqd6QVWTsyMfsr2kuW9x+3vL2viDrlmmuOtzve/0mwW7RlydfhG36BLv9Cu3zqVjCbgf2kve3qRl5OezjtY6KPXnh+x/sMPIj4POa9oSOhr3YfnLRdlv3PV7YTfSdcBnwCX7uAF0E3apfbD/JWdAnOWsJvRrLp7TM4l6Meu4S6kXgi1C/V/XJk5VRRj1tqq953GV/X89+X/+MuhN+1/TLqIeTMU759BP5quEUZZqp7+WCN2l+7nNjK3zAFb3vt3sJr9X0/l9kM+g7Z1WfMT27az1puQ2uVvu5Q/JjD9mff/Hfq18CDADFyFpnRW9JPwAAAABJRU5ErkJggg==';
|
||||
|
||||
var imageBackSrc = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFsAAACpCAIAAADLDtbcAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIE1hY2ludG9zaCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo3OTFCRTMwQTNDNjMxMUUxQTYyOTk2M0QwMjU4OThGOCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo3OTFCRTMwQjNDNjMxMUUxQTYyOTk2M0QwMjU4OThGOCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4OTAwNDZCM0M0RjExRTFBNjI5OTYzRDAyNTg5OEY4IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4OTAwNDZDM0M0RjExRTFBNjI5OTYzRDAyNTg5OEY4Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+zWf2VgAABt9JREFUeNrsnU1P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';
|
||||
|
||||
var id = (+new Date).toString(32),
|
||||
body = document.documentElement, // yep - cheatin' Yud'up! :)
|
||||
height = 320;
|
||||
|
||||
// if the url hash doesn't contain tiltremote (our key) then fireup the popup, else we are the popup
|
||||
if (window.location.hash.indexOf('tiltremote') === -1) {
|
||||
initServer();
|
||||
} else {
|
||||
initRemote();
|
||||
}
|
||||
|
||||
function initServer() {
|
||||
// old way didn't work. Shame, but I like the new way too :)
|
||||
// var remote = window.open('data:text/html,<script src="' + src + '?tiltremote"></script>', 'Tilt', 'width=300,height=' + height);
|
||||
|
||||
var remote = window.open(window.location.toString() + '#tiltremote', 'Tilt', 'width=300,height=' + height);
|
||||
if (!remote) {
|
||||
alert('The remote control for the orientation event uses a popup')
|
||||
}
|
||||
|
||||
// TODO add remote-tilt.com support
|
||||
}
|
||||
|
||||
function initRemote() {
|
||||
var TO_RADIANS = Math.PI / 180;
|
||||
orientation = {
|
||||
alpha: 180,
|
||||
beta: 0,
|
||||
gamma: 0
|
||||
},
|
||||
accelerationIncludingGravity = { x: 0, y: 0, z: -9.81 },
|
||||
guid = (+new Date).toString(32);
|
||||
|
||||
function update(fromInput) {
|
||||
var preview = document.getElementById('preview');
|
||||
preview.style.webkitTransform = 'rotateY('+ gamma.value + 'deg) rotate3d(1,0,0, '+ (beta.value*-1) + 'deg)';
|
||||
preview.parentNode.style.webkitTransform = 'rotate(' + (180-orientation.alpha) + 'deg)';
|
||||
|
||||
if (!fromInput) {
|
||||
for (var key in orientation) {
|
||||
var el = document.getElementById(key);
|
||||
oninput.call(window, { target: el });
|
||||
}
|
||||
}
|
||||
|
||||
fireEvent();
|
||||
}
|
||||
|
||||
function fireDeviceOrienationEvent() {
|
||||
var event = document.createEvent('HTMLEvents');
|
||||
event.initEvent('deviceorientation', true, true);
|
||||
event.eventName = 'deviceorientation';
|
||||
event.alpha = orientation.alpha;
|
||||
event.beta = orientation.beta;
|
||||
event.gamma = orientation.gamma;
|
||||
|
||||
window.opener.dispatchEvent(event);
|
||||
}
|
||||
|
||||
function fireDeviceMotionEvent() {
|
||||
var event = document.createEvent('HTMLEvents');
|
||||
event.initEvent('devicemotion', true, true);
|
||||
event.eventName = 'devicemotion';
|
||||
|
||||
event.accelerationIncludingGravity = {};
|
||||
event.accelerationIncludingGravity.x = accelerationIncludingGravity.x;
|
||||
event.accelerationIncludingGravity.y = accelerationIncludingGravity.y;
|
||||
event.accelerationIncludingGravity.z = accelerationIncludingGravity.z;
|
||||
|
||||
window.opener.dispatchEvent(event);
|
||||
}
|
||||
|
||||
function fireEvent() {
|
||||
if (polyfill.orientation) fireDeviceOrienationEvent();
|
||||
if (polyfill.motion) fireDeviceMotionEvent();
|
||||
}
|
||||
|
||||
// hides the old body - but doesn't prevent the JavaScript from running.
|
||||
// just a clean up thing - lame, but tidier
|
||||
setTimeout(function () {
|
||||
var bodies = document.getElementsByTagName('body'),
|
||||
body = bodies[1];
|
||||
if (bodies.length == 2) {
|
||||
if (body.id == guid) body = bodies[0];
|
||||
}
|
||||
document.documentElement.removeChild(body);
|
||||
});
|
||||
|
||||
body.innerHTML = ['<head><title>Motion Emulator</title>',
|
||||
'<style>',
|
||||
'html { height: ' + height + 'px; }',
|
||||
'body { margin: 10px; font-family: sans-serif; overflow: hidden; }',
|
||||
'#pov { height: 170px; position: relative; -webkit-perspective: 500; perspective: 500; cursor: move; }',
|
||||
'#controls { position: relative; z-index: 1; }',
|
||||
'#preview { display: block; margin: 20px auto; max-width: 100%; width: 100px; height: 170px; }',
|
||||
'#preview div { width: 100%; height: 170px; position: absolute; top: 0; left: 0; -webkit-backface-visibility: hidden; }',
|
||||
'#front { background: url(' + imageSrc + ') no-repeat center; }',
|
||||
'#back { background: url(' + imageBackSrc + ') no-repeat center; -webkit-transform: rotateY(180deg); }',
|
||||
'label { display: block; clear: both; }',
|
||||
'label input[type=range] { display:inline-block; float: right; }',
|
||||
'#buttons { margin-top: 2px; }',
|
||||
'#south { position: absolute; bottom: 0; width: 100%; left: 0; text-align: center; color: #aaa; }',
|
||||
'</style>',
|
||||
'</head>',
|
||||
'<body id="' + guid + '">',
|
||||
'<div id=controls>',
|
||||
'<label for=gamma>Left - Right <input min=-180 max=180 id=gamma value=0 type=range step=0.001> <output id=og>0</output></label>',
|
||||
'<label for=beta>Back - Front <input min=-180 max=180 id=beta value=0 type=range step=0.001> <output id=ob>0</output></label>',
|
||||
'<label for=alpha>Rotate <input min=0 max=360 id=alpha value=180 type=range step=0.001> <output id=oa>180</output></label>',
|
||||
'<label for=wobble>Emulate slight shake<input type=checkbox id=wobble></label>',
|
||||
'<div id=buttons><button id=flat>Flat on it\'s back</button> ',
|
||||
'</div>',
|
||||
'</div>', // end of controls
|
||||
'<div id=pov>',
|
||||
'<div id=preview>',
|
||||
'<div id=front></div>',
|
||||
'<div id=back></div>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'<span id=south>south</span>',
|
||||
'</body>'
|
||||
].join('');
|
||||
|
||||
function oninput(event) {
|
||||
var target = event.target;
|
||||
if (target.nodeName == 'INPUT') {
|
||||
|
||||
var value = target.value * 1;
|
||||
|
||||
if (target.id == 'beta') {
|
||||
// parseFloat + toFixed avoids the massive 0.00000000 and infinitely small numbers
|
||||
accelerationIncludingGravity.z = parseFloat( (Math.sin( (TO_RADIANS * (value - 90))) * 9.81).toFixed(10) );
|
||||
accelerationIncludingGravity.y = parseFloat((Math.sin( (TO_RADIANS * (value - 180))) * 9.81).toFixed(10));
|
||||
value = parseFloat((Math.sin(value * TO_RADIANS) * 90).toFixed(10));
|
||||
} else if (target.id == 'gamma') {
|
||||
accelerationIncludingGravity.x = parseFloat( (Math.sin( (TO_RADIANS * (value - 180))) * -9.81).toFixed(10) );
|
||||
}
|
||||
|
||||
document.getElementById('o' + target.id.substring(0, 1)).value = parseFloat(value.toFixed(2));
|
||||
|
||||
orientation[target.id] = value;
|
||||
|
||||
if (this !== window) update(true); // i.e. if not called manually
|
||||
}
|
||||
}
|
||||
|
||||
body.addEventListener('input', oninput, false);
|
||||
|
||||
var down = false,
|
||||
last = { x: null, y: null },
|
||||
pov = document.getElementById('pov'),
|
||||
alpha = document.getElementById('alpha'),
|
||||
beta = document.getElementById('beta'),
|
||||
gamma = document.getElementById('gamma');
|
||||
|
||||
pov.addEventListener('mousedown', function (event) {
|
||||
down = true;
|
||||
last.x = event.pageX;
|
||||
last.y = event.pageY;
|
||||
event.preventDefault();
|
||||
}, false);
|
||||
|
||||
body.addEventListener('mousemove', function (event) {
|
||||
if (down) {
|
||||
var dx = (last.x - event.pageX)// * 0.1,
|
||||
dy = (last.y - event.pageY); // * 0.1;
|
||||
last.x = event.pageX;
|
||||
last.y = event.pageY;
|
||||
gamma.value -= dx;
|
||||
beta.value -= dy;
|
||||
update();
|
||||
}
|
||||
}, false);
|
||||
|
||||
body.addEventListener('mouseup', function (event) {
|
||||
down = false;
|
||||
}, false);
|
||||
|
||||
body.addEventListener('click', function (event) {
|
||||
var target = event.target;
|
||||
if (target.nodeName == 'BUTTON') {
|
||||
if (target.id == 'flat') {
|
||||
alpha.value = 180;
|
||||
beta.value = 0;
|
||||
gamma.value = 0;
|
||||
|
||||
}
|
||||
update();
|
||||
} else if (target.id == 'wobble') {
|
||||
if (target.checked) startShake();
|
||||
else stopShake();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function startShake() {
|
||||
shake = setInterval(function () {
|
||||
alpha.value = parseFloat(alpha.value) + (Math.random() * (Math.random() < 0.5 ? 1 : -1) * 0.05);
|
||||
beta.value = parseFloat(beta.value) + (Math.random() * (Math.random() < 0.5 ? 1 : -1) * 0.05);
|
||||
gamma.value = parseFloat(gamma.value) + (Math.random() * (Math.random() < 0.5 ? 1 : -1) * 0.05);
|
||||
update();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function stopShake() {
|
||||
clearInterval(shake);
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
require( "./classList.js" );
|
||||
require( "./dataset.js" );
|
||||
require( "./EventSource.js" );
|
||||
require( "./input-target.js" );
|
||||
require( "./offline-events.js" );
|
||||
require( "./range.js" );
|
||||
require( "./sessionStorage.js" );
|
||||
require( "./Storage.js" );
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
(function () {
|
||||
|
||||
// setup for detection
|
||||
var form = document.createElement('form'),
|
||||
input = document.createElement('input'),
|
||||
body = document.body,
|
||||
id = 'f' + +new Date,
|
||||
inputTargetSupported = false;
|
||||
|
||||
// insert into DOM, work out if it's supported
|
||||
form.setAttribute('id', id);
|
||||
input.setAttribute('form', id);
|
||||
body.appendChild(form);
|
||||
body.appendChild(input);
|
||||
|
||||
inputTargetSupported = input.form !== null;
|
||||
body.removeChild(form);
|
||||
body.removeChild(input);
|
||||
|
||||
// if not, hook click handlers to all existing submit elements
|
||||
function click(event) {
|
||||
event = event || window.event;
|
||||
|
||||
// http://www.quirksmode.org/js/events_properties.html#target
|
||||
var target = event.target || event.srcElement;
|
||||
if (target.nodeType === 3) target = target.parentNode;
|
||||
|
||||
if (target.nodeName === 'INPUT' && target.type === 'submit' && target.form === null) {
|
||||
form = document.getElementById(target.getAttribute('form'));
|
||||
var clone = target.cloneNode(true);
|
||||
clone.style.display = 'none';
|
||||
form.appendChild(clone);
|
||||
clone.click(); // doing this because form.submit won't fire handles the way I want
|
||||
form.removeChild(clone);
|
||||
}
|
||||
}
|
||||
|
||||
if (!inputTargetSupported) {
|
||||
body.addEventListener ? body.addEventListener('click', click, false) : body.attachEvent('onclick', click);
|
||||
}
|
||||
|
||||
})();
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
// Working demo: http://jsbin.com/ozusa6/2/
|
||||
(function () {
|
||||
|
||||
function triggerEvent(type) {
|
||||
var event = document.createEvent('HTMLEvents');
|
||||
event.initEvent(type, true, true);
|
||||
event.eventName = type;
|
||||
(document.body || window).dispatchEvent(event);
|
||||
}
|
||||
|
||||
function testConnection() {
|
||||
// make sync-ajax request
|
||||
var xhr = new XMLHttpRequest();
|
||||
// phone home
|
||||
xhr.open('HEAD', '/', false); // async=false
|
||||
try {
|
||||
xhr.send();
|
||||
onLine = true;
|
||||
} catch (e) {
|
||||
// throws NETWORK_ERR when disconnected
|
||||
onLine = false;
|
||||
}
|
||||
|
||||
return onLine;
|
||||
}
|
||||
|
||||
var onLine = true,
|
||||
lastOnLineStatus = true;
|
||||
|
||||
// note: this doesn't allow us to define a getter in Safari
|
||||
navigator.__defineGetter__("onLine", testConnection);
|
||||
testConnection();
|
||||
|
||||
if (onLine === false) {
|
||||
lastOnLineStatus = false;
|
||||
// trigger offline event
|
||||
triggerEvent('offline');
|
||||
}
|
||||
|
||||
setInterval(function () {
|
||||
testConnection();
|
||||
if (onLine !== lastOnLineStatus) {
|
||||
triggerEvent(onLine ? 'online' : 'offline');
|
||||
lastOnLineStatus = onLine;
|
||||
}
|
||||
}, 5000); // 5 seconds, made up - can't find docs to suggest interval time
|
||||
})();
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
/**
|
||||
* This was from a proposal that James Edwards / Brothercake had during
|
||||
* 2011 Highland Fling - to use select elements as a starting point for
|
||||
* the range element - so it's a pretty darn good fit, I put this together
|
||||
* during his Q&A. In the end I needed to lift the detection code from
|
||||
* Modernizr - which credit really goes to @miketaylr.
|
||||
* My code starts from "if (bool) {"
|
||||
*
|
||||
* This code is looking for <select type="range"> and will progressively
|
||||
* enhance to a input[type=range] copying much of the attributes across.
|
||||
*/
|
||||
!function () {
|
||||
var rangeTest = document.createElement('input'),
|
||||
smile = ':)';
|
||||
rangeTest.setAttribute('type', 'range');
|
||||
|
||||
var bool = rangeTest.type !== 'text';
|
||||
if (bool) {
|
||||
rangeTest.style.cssText = 'position:absolute;visibility:hidden;';
|
||||
rangeTest.value = smile;
|
||||
if (rangeTest.style.WebkitAppearance !== undefined ) {
|
||||
|
||||
document.body.appendChild(rangeTest);
|
||||
defaultView = document.defaultView;
|
||||
|
||||
// Safari 2-4 allows the smiley as a value, despite making a slider
|
||||
bool = defaultView.getComputedStyle &&
|
||||
defaultView.getComputedStyle(rangeTest, null).WebkitAppearance !== 'textfield' &&
|
||||
// Mobile android web browser has false positive, so must
|
||||
// check the height to see if the widget is actually there.
|
||||
(rangeTest.offsetHeight !== 0);
|
||||
|
||||
document.body.removeChild(rangeTest);
|
||||
}
|
||||
} else {
|
||||
bool = rangeTest.value == smile;
|
||||
}
|
||||
|
||||
// if the input[range] is natively supported, then upgrade the <select type="range">
|
||||
// into a range element.
|
||||
if (bool) {
|
||||
function firstChild(el, nodeName) {
|
||||
nodeName = nodeName.toUpperCase();
|
||||
if (el.firstChild.nodeName === nodeName) {
|
||||
return el.firstChild;
|
||||
} else {
|
||||
return el.firstChild.nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
function lastChild(el, nodeName) {
|
||||
nodeName = nodeName.toUpperCase();
|
||||
if (el.lastChild.nodeName === nodeName) {
|
||||
return el.lastChild;
|
||||
} else {
|
||||
return el.lastChild.previousSibling;
|
||||
}
|
||||
}
|
||||
|
||||
var selects = document.getElementsByTagName('select'),
|
||||
i = 0;
|
||||
|
||||
for (; i < selects.length; i++) {
|
||||
if (selects[i].getAttribute('data-type') == 'range') (function (select) {
|
||||
var range = document.createElement('input'),
|
||||
parent = select.parentNode;
|
||||
|
||||
range.setAttribute('type', 'range');
|
||||
// works with the select element removed from the DOM
|
||||
select = parent.replaceChild(range, select);
|
||||
range.autofocus = select.autofocus;
|
||||
range.disabled = select.disabled;
|
||||
range.autocomplete = select.autocomplete; // eh? how would this even work?
|
||||
range.className = select.className;
|
||||
range.id = select.id;
|
||||
range.style = select.style;
|
||||
range.tabindex = select.tabindex;
|
||||
range.title = select.title;
|
||||
range.min = firstChild(select, 'option').value;
|
||||
range.max = lastChild(select, 'option').value;
|
||||
range.value = select.value;
|
||||
range.name = select.name;
|
||||
// Add step support
|
||||
if ( select.getAttribute('data-type-range-step') ) {
|
||||
range.step = select.getAttribute('data-type-range-step');
|
||||
}
|
||||
// yeah, this is filth, but it's because getElementsByTagName is
|
||||
// a live DOM collection, so when we removed the select element
|
||||
// the selects object reduced in length. Freaky, eh?
|
||||
i--;
|
||||
})(selects[i]);
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
if (!sessionStorage && JSON) {
|
||||
sessionStorage = (function () {
|
||||
var data = window.name ? JSON.parse(window.name) : {};
|
||||
|
||||
return {
|
||||
clear: function () {
|
||||
data = {};
|
||||
window.name = '';
|
||||
},
|
||||
getItem: function (key) {
|
||||
return data[key] === undefined ? null : data[key];
|
||||
},
|
||||
removeItem: function (key) {
|
||||
delete data[key];
|
||||
window.name = JSON.stringify(data);
|
||||
},
|
||||
setItem: function (key, value) {
|
||||
data[key] = value;
|
||||
window.name = JSON.stringify(data);
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset=utf-8 />
|
||||
<title>event source test</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="../EventSource.js"></script>
|
||||
<script>
|
||||
var es = new EventSource('/sse/');
|
||||
es.onmessage = function (event) {
|
||||
console.log('msg: ' + event.data);
|
||||
};
|
||||
|
||||
es.onopen = function () {
|
||||
console.log('connected');
|
||||
}
|
||||
|
||||
console.log(es);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Online and offline event tests</title>
|
||||
<style>
|
||||
* { font-family: sans-serif; }
|
||||
body { width: 600px; margin: 40px auto; }
|
||||
#status { padding: 10px; text-align: center; }
|
||||
#status.online { background: #0c0; }
|
||||
#status.offline { background: #c00; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p><strong>Directions:</strong> disconnect the internet connection from your machine and watch the status switch from online to offline (and back again if you want to see the online event fire).</p>
|
||||
<p>Note that this polyfill <em>phones home</em> so it will also fire the offline event if the server this script is hosted on, goes down (feature or bug? who knows!).</p>
|
||||
<p class="online" id="status">ONLINE</p>
|
||||
<script src="../offline-events.js"></script>
|
||||
<script>
|
||||
(function () {
|
||||
var status = document.getElementById('status');
|
||||
status.className = navigator.onLine ? 'online' : 'offline';
|
||||
window.addEventListener('online', function () {
|
||||
status.className = 'online';
|
||||
status.innerHTML = 'ONLINE';
|
||||
}, false);
|
||||
|
||||
window.addEventListener('offline', function () {
|
||||
status.className = 'offline';
|
||||
status.innerHTML = 'OFFLINE';
|
||||
}, false);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>range polyfill...</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<select class="foo" id="first" title="1-5 please" data-type="range">
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3">3</option>
|
||||
<option value="4">4</option>
|
||||
<option selected value="5">5</option>
|
||||
</select>
|
||||
</div>
|
||||
<br>
|
||||
<select>
|
||||
<option value="3">3</option>
|
||||
<option value="4">4</option>
|
||||
<option value="5">5</option>
|
||||
</select>
|
||||
<br>
|
||||
<select autofocus data-type="range">
|
||||
<option value="1">3</option>
|
||||
<option selected value="4">4</option>
|
||||
<option value="50">5</option>
|
||||
</select>
|
||||
<br>
|
||||
<p>Last two examples are as the previous, but add <code>data-type-range-step="5"</code>:</p>
|
||||
<select data-type="range" data-type-range-step="5">
|
||||
<option value="1">3</option>
|
||||
<option selected value="4">4</option>
|
||||
<option value="50">5</option>
|
||||
</select>
|
||||
<br>
|
||||
<p>This one has the last value set to 51, instead of 50:</p>
|
||||
<select data-type="range" data-type-range-step="5">
|
||||
<option value="1">3</option>
|
||||
<option selected value="4">4</option>
|
||||
<option value="51">5</option>
|
||||
</select>
|
||||
<script src="../range.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue