webvr-libs
Version:
WebVR libraries
1,547 lines (1,276 loc) • 270 kB
JavaScript
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
// shim for using process in browser
var process = module.exports = {};
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = setTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
clearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
setTimeout(drainQueue, 0);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
},{}],2:[function(_dereq_,module,exports){
(function (process,global){
/*!
* @overview es6-promise - a tiny implementation of Promises/A+.
* @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
* @license Licensed under MIT license
* See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE
* @version 3.1.2
*/
(function() {
"use strict";
function lib$es6$promise$utils$$objectOrFunction(x) {
return typeof x === 'function' || (typeof x === 'object' && x !== null);
}
function lib$es6$promise$utils$$isFunction(x) {
return typeof x === 'function';
}
function lib$es6$promise$utils$$isMaybeThenable(x) {
return typeof x === 'object' && x !== null;
}
var lib$es6$promise$utils$$_isArray;
if (!Array.isArray) {
lib$es6$promise$utils$$_isArray = function (x) {
return Object.prototype.toString.call(x) === '[object Array]';
};
} else {
lib$es6$promise$utils$$_isArray = Array.isArray;
}
var lib$es6$promise$utils$$isArray = lib$es6$promise$utils$$_isArray;
var lib$es6$promise$asap$$len = 0;
var lib$es6$promise$asap$$vertxNext;
var lib$es6$promise$asap$$customSchedulerFn;
var lib$es6$promise$asap$$asap = function asap(callback, arg) {
lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len] = callback;
lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len + 1] = arg;
lib$es6$promise$asap$$len += 2;
if (lib$es6$promise$asap$$len === 2) {
// If len is 2, that means that we need to schedule an async flush.
// If additional callbacks are queued before the queue is flushed, they
// will be processed by this flush that we are scheduling.
if (lib$es6$promise$asap$$customSchedulerFn) {
lib$es6$promise$asap$$customSchedulerFn(lib$es6$promise$asap$$flush);
} else {
lib$es6$promise$asap$$scheduleFlush();
}
}
}
function lib$es6$promise$asap$$setScheduler(scheduleFn) {
lib$es6$promise$asap$$customSchedulerFn = scheduleFn;
}
function lib$es6$promise$asap$$setAsap(asapFn) {
lib$es6$promise$asap$$asap = asapFn;
}
var lib$es6$promise$asap$$browserWindow = (typeof window !== 'undefined') ? window : undefined;
var lib$es6$promise$asap$$browserGlobal = lib$es6$promise$asap$$browserWindow || {};
var lib$es6$promise$asap$$BrowserMutationObserver = lib$es6$promise$asap$$browserGlobal.MutationObserver || lib$es6$promise$asap$$browserGlobal.WebKitMutationObserver;
var lib$es6$promise$asap$$isNode = typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
// test for web worker but not in IE10
var lib$es6$promise$asap$$isWorker = typeof Uint8ClampedArray !== 'undefined' &&
typeof importScripts !== 'undefined' &&
typeof MessageChannel !== 'undefined';
// node
function lib$es6$promise$asap$$useNextTick() {
// node version 0.10.x displays a deprecation warning when nextTick is used recursively
// see https://github.com/cujojs/when/issues/410 for details
return function() {
process.nextTick(lib$es6$promise$asap$$flush);
};
}
// vertx
function lib$es6$promise$asap$$useVertxTimer() {
return function() {
lib$es6$promise$asap$$vertxNext(lib$es6$promise$asap$$flush);
};
}
function lib$es6$promise$asap$$useMutationObserver() {
var iterations = 0;
var observer = new lib$es6$promise$asap$$BrowserMutationObserver(lib$es6$promise$asap$$flush);
var node = document.createTextNode('');
observer.observe(node, { characterData: true });
return function() {
node.data = (iterations = ++iterations % 2);
};
}
// web worker
function lib$es6$promise$asap$$useMessageChannel() {
var channel = new MessageChannel();
channel.port1.onmessage = lib$es6$promise$asap$$flush;
return function () {
channel.port2.postMessage(0);
};
}
function lib$es6$promise$asap$$useSetTimeout() {
return function() {
setTimeout(lib$es6$promise$asap$$flush, 1);
};
}
var lib$es6$promise$asap$$queue = new Array(1000);
function lib$es6$promise$asap$$flush() {
for (var i = 0; i < lib$es6$promise$asap$$len; i+=2) {
var callback = lib$es6$promise$asap$$queue[i];
var arg = lib$es6$promise$asap$$queue[i+1];
callback(arg);
lib$es6$promise$asap$$queue[i] = undefined;
lib$es6$promise$asap$$queue[i+1] = undefined;
}
lib$es6$promise$asap$$len = 0;
}
function lib$es6$promise$asap$$attemptVertx() {
try {
var r = _dereq_;
var vertx = r('vertx');
lib$es6$promise$asap$$vertxNext = vertx.runOnLoop || vertx.runOnContext;
return lib$es6$promise$asap$$useVertxTimer();
} catch(e) {
return lib$es6$promise$asap$$useSetTimeout();
}
}
var lib$es6$promise$asap$$scheduleFlush;
// Decide what async method to use to triggering processing of queued callbacks:
if (lib$es6$promise$asap$$isNode) {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useNextTick();
} else if (lib$es6$promise$asap$$BrowserMutationObserver) {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMutationObserver();
} else if (lib$es6$promise$asap$$isWorker) {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMessageChannel();
} else if (lib$es6$promise$asap$$browserWindow === undefined && typeof _dereq_ === 'function') {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$attemptVertx();
} else {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useSetTimeout();
}
function lib$es6$promise$then$$then(onFulfillment, onRejection) {
var parent = this;
var state = parent._state;
if (state === lib$es6$promise$$internal$$FULFILLED && !onFulfillment || state === lib$es6$promise$$internal$$REJECTED && !onRejection) {
return this;
}
var child = new this.constructor(lib$es6$promise$$internal$$noop);
var result = parent._result;
if (state) {
var callback = arguments[state - 1];
lib$es6$promise$asap$$asap(function(){
lib$es6$promise$$internal$$invokeCallback(state, child, callback, result);
});
} else {
lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection);
}
return child;
}
var lib$es6$promise$then$$default = lib$es6$promise$then$$then;
function lib$es6$promise$promise$resolve$$resolve(object) {
/*jshint validthis:true */
var Constructor = this;
if (object && typeof object === 'object' && object.constructor === Constructor) {
return object;
}
var promise = new Constructor(lib$es6$promise$$internal$$noop);
lib$es6$promise$$internal$$resolve(promise, object);
return promise;
}
var lib$es6$promise$promise$resolve$$default = lib$es6$promise$promise$resolve$$resolve;
function lib$es6$promise$$internal$$noop() {}
var lib$es6$promise$$internal$$PENDING = void 0;
var lib$es6$promise$$internal$$FULFILLED = 1;
var lib$es6$promise$$internal$$REJECTED = 2;
var lib$es6$promise$$internal$$GET_THEN_ERROR = new lib$es6$promise$$internal$$ErrorObject();
function lib$es6$promise$$internal$$selfFulfillment() {
return new TypeError("You cannot resolve a promise with itself");
}
function lib$es6$promise$$internal$$cannotReturnOwn() {
return new TypeError('A promises callback cannot return that same promise.');
}
function lib$es6$promise$$internal$$getThen(promise) {
try {
return promise.then;
} catch(error) {
lib$es6$promise$$internal$$GET_THEN_ERROR.error = error;
return lib$es6$promise$$internal$$GET_THEN_ERROR;
}
}
function lib$es6$promise$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) {
try {
then.call(value, fulfillmentHandler, rejectionHandler);
} catch(e) {
return e;
}
}
function lib$es6$promise$$internal$$handleForeignThenable(promise, thenable, then) {
lib$es6$promise$asap$$asap(function(promise) {
var sealed = false;
var error = lib$es6$promise$$internal$$tryThen(then, thenable, function(value) {
if (sealed) { return; }
sealed = true;
if (thenable !== value) {
lib$es6$promise$$internal$$resolve(promise, value);
} else {
lib$es6$promise$$internal$$fulfill(promise, value);
}
}, function(reason) {
if (sealed) { return; }
sealed = true;
lib$es6$promise$$internal$$reject(promise, reason);
}, 'Settle: ' + (promise._label || ' unknown promise'));
if (!sealed && error) {
sealed = true;
lib$es6$promise$$internal$$reject(promise, error);
}
}, promise);
}
function lib$es6$promise$$internal$$handleOwnThenable(promise, thenable) {
if (thenable._state === lib$es6$promise$$internal$$FULFILLED) {
lib$es6$promise$$internal$$fulfill(promise, thenable._result);
} else if (thenable._state === lib$es6$promise$$internal$$REJECTED) {
lib$es6$promise$$internal$$reject(promise, thenable._result);
} else {
lib$es6$promise$$internal$$subscribe(thenable, undefined, function(value) {
lib$es6$promise$$internal$$resolve(promise, value);
}, function(reason) {
lib$es6$promise$$internal$$reject(promise, reason);
});
}
}
function lib$es6$promise$$internal$$handleMaybeThenable(promise, maybeThenable, then) {
if (maybeThenable.constructor === promise.constructor &&
then === lib$es6$promise$then$$default &&
constructor.resolve === lib$es6$promise$promise$resolve$$default) {
lib$es6$promise$$internal$$handleOwnThenable(promise, maybeThenable);
} else {
if (then === lib$es6$promise$$internal$$GET_THEN_ERROR) {
lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$GET_THEN_ERROR.error);
} else if (then === undefined) {
lib$es6$promise$$internal$$fulfill(promise, maybeThenable);
} else if (lib$es6$promise$utils$$isFunction(then)) {
lib$es6$promise$$internal$$handleForeignThenable(promise, maybeThenable, then);
} else {
lib$es6$promise$$internal$$fulfill(promise, maybeThenable);
}
}
}
function lib$es6$promise$$internal$$resolve(promise, value) {
if (promise === value) {
lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$selfFulfillment());
} else if (lib$es6$promise$utils$$objectOrFunction(value)) {
lib$es6$promise$$internal$$handleMaybeThenable(promise, value, lib$es6$promise$$internal$$getThen(value));
} else {
lib$es6$promise$$internal$$fulfill(promise, value);
}
}
function lib$es6$promise$$internal$$publishRejection(promise) {
if (promise._onerror) {
promise._onerror(promise._result);
}
lib$es6$promise$$internal$$publish(promise);
}
function lib$es6$promise$$internal$$fulfill(promise, value) {
if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }
promise._result = value;
promise._state = lib$es6$promise$$internal$$FULFILLED;
if (promise._subscribers.length !== 0) {
lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, promise);
}
}
function lib$es6$promise$$internal$$reject(promise, reason) {
if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }
promise._state = lib$es6$promise$$internal$$REJECTED;
promise._result = reason;
lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publishRejection, promise);
}
function lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection) {
var subscribers = parent._subscribers;
var length = subscribers.length;
parent._onerror = null;
subscribers[length] = child;
subscribers[length + lib$es6$promise$$internal$$FULFILLED] = onFulfillment;
subscribers[length + lib$es6$promise$$internal$$REJECTED] = onRejection;
if (length === 0 && parent._state) {
lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, parent);
}
}
function lib$es6$promise$$internal$$publish(promise) {
var subscribers = promise._subscribers;
var settled = promise._state;
if (subscribers.length === 0) { return; }
var child, callback, detail = promise._result;
for (var i = 0; i < subscribers.length; i += 3) {
child = subscribers[i];
callback = subscribers[i + settled];
if (child) {
lib$es6$promise$$internal$$invokeCallback(settled, child, callback, detail);
} else {
callback(detail);
}
}
promise._subscribers.length = 0;
}
function lib$es6$promise$$internal$$ErrorObject() {
this.error = null;
}
var lib$es6$promise$$internal$$TRY_CATCH_ERROR = new lib$es6$promise$$internal$$ErrorObject();
function lib$es6$promise$$internal$$tryCatch(callback, detail) {
try {
return callback(detail);
} catch(e) {
lib$es6$promise$$internal$$TRY_CATCH_ERROR.error = e;
return lib$es6$promise$$internal$$TRY_CATCH_ERROR;
}
}
function lib$es6$promise$$internal$$invokeCallback(settled, promise, callback, detail) {
var hasCallback = lib$es6$promise$utils$$isFunction(callback),
value, error, succeeded, failed;
if (hasCallback) {
value = lib$es6$promise$$internal$$tryCatch(callback, detail);
if (value === lib$es6$promise$$internal$$TRY_CATCH_ERROR) {
failed = true;
error = value.error;
value = null;
} else {
succeeded = true;
}
if (promise === value) {
lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$cannotReturnOwn());
return;
}
} else {
value = detail;
succeeded = true;
}
if (promise._state !== lib$es6$promise$$internal$$PENDING) {
// noop
} else if (hasCallback && succeeded) {
lib$es6$promise$$internal$$resolve(promise, value);
} else if (failed) {
lib$es6$promise$$internal$$reject(promise, error);
} else if (settled === lib$es6$promise$$internal$$FULFILLED) {
lib$es6$promise$$internal$$fulfill(promise, value);
} else if (settled === lib$es6$promise$$internal$$REJECTED) {
lib$es6$promise$$internal$$reject(promise, value);
}
}
function lib$es6$promise$$internal$$initializePromise(promise, resolver) {
try {
resolver(function resolvePromise(value){
lib$es6$promise$$internal$$resolve(promise, value);
}, function rejectPromise(reason) {
lib$es6$promise$$internal$$reject(promise, reason);
});
} catch(e) {
lib$es6$promise$$internal$$reject(promise, e);
}
}
function lib$es6$promise$promise$all$$all(entries) {
return new lib$es6$promise$enumerator$$default(this, entries).promise;
}
var lib$es6$promise$promise$all$$default = lib$es6$promise$promise$all$$all;
function lib$es6$promise$promise$race$$race(entries) {
/*jshint validthis:true */
var Constructor = this;
var promise = new Constructor(lib$es6$promise$$internal$$noop);
if (!lib$es6$promise$utils$$isArray(entries)) {
lib$es6$promise$$internal$$reject(promise, new TypeError('You must pass an array to race.'));
return promise;
}
var length = entries.length;
function onFulfillment(value) {
lib$es6$promise$$internal$$resolve(promise, value);
}
function onRejection(reason) {
lib$es6$promise$$internal$$reject(promise, reason);
}
for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {
lib$es6$promise$$internal$$subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);
}
return promise;
}
var lib$es6$promise$promise$race$$default = lib$es6$promise$promise$race$$race;
function lib$es6$promise$promise$reject$$reject(reason) {
/*jshint validthis:true */
var Constructor = this;
var promise = new Constructor(lib$es6$promise$$internal$$noop);
lib$es6$promise$$internal$$reject(promise, reason);
return promise;
}
var lib$es6$promise$promise$reject$$default = lib$es6$promise$promise$reject$$reject;
var lib$es6$promise$promise$$counter = 0;
function lib$es6$promise$promise$$needsResolver() {
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
}
function lib$es6$promise$promise$$needsNew() {
throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
}
var lib$es6$promise$promise$$default = lib$es6$promise$promise$$Promise;
/**
Promise objects represent the eventual result of an asynchronous operation. The
primary way of interacting with a promise is through its `then` method, which
registers callbacks to receive either a promise's eventual value or the reason
why the promise cannot be fulfilled.
Terminology
-----------
- `promise` is an object or function with a `then` method whose behavior conforms to this specification.
- `thenable` is an object or function that defines a `then` method.
- `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
- `exception` is a value that is thrown using the throw statement.
- `reason` is a value that indicates why a promise was rejected.
- `settled` the final resting state of a promise, fulfilled or rejected.
A promise can be in one of three states: pending, fulfilled, or rejected.
Promises that are fulfilled have a fulfillment value and are in the fulfilled
state. Promises that are rejected have a rejection reason and are in the
rejected state. A fulfillment value is never a thenable.
Promises can also be said to *resolve* a value. If this value is also a
promise, then the original promise's settled state will match the value's
settled state. So a promise that *resolves* a promise that rejects will
itself reject, and a promise that *resolves* a promise that fulfills will
itself fulfill.
Basic Usage:
------------
```js
var promise = new Promise(function(resolve, reject) {
// on success
resolve(value);
// on failure
reject(reason);
});
promise.then(function(value) {
// on fulfillment
}, function(reason) {
// on rejection
});
```
Advanced Usage:
---------------
Promises shine when abstracting away asynchronous interactions such as
`XMLHttpRequest`s.
```js
function getJSON(url) {
return new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = handler;
xhr.responseType = 'json';
xhr.setRequestHeader('Accept', 'application/json');
xhr.send();
function handler() {
if (this.readyState === this.DONE) {
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
}
}
};
});
}
getJSON('/posts.json').then(function(json) {
// on fulfillment
}, function(reason) {
// on rejection
});
```
Unlike callbacks, promises are great composable primitives.
```js
Promise.all([
getJSON('/posts'),
getJSON('/comments')
]).then(function(values){
values[0] // => postsJSON
values[1] // => commentsJSON
return values;
});
```
@class Promise
@param {function} resolver
Useful for tooling.
@constructor
*/
function lib$es6$promise$promise$$Promise(resolver) {
this._id = lib$es6$promise$promise$$counter++;
this._state = undefined;
this._result = undefined;
this._subscribers = [];
if (lib$es6$promise$$internal$$noop !== resolver) {
typeof resolver !== 'function' && lib$es6$promise$promise$$needsResolver();
this instanceof lib$es6$promise$promise$$Promise ? lib$es6$promise$$internal$$initializePromise(this, resolver) : lib$es6$promise$promise$$needsNew();
}
}
lib$es6$promise$promise$$Promise.all = lib$es6$promise$promise$all$$default;
lib$es6$promise$promise$$Promise.race = lib$es6$promise$promise$race$$default;
lib$es6$promise$promise$$Promise.resolve = lib$es6$promise$promise$resolve$$default;
lib$es6$promise$promise$$Promise.reject = lib$es6$promise$promise$reject$$default;
lib$es6$promise$promise$$Promise._setScheduler = lib$es6$promise$asap$$setScheduler;
lib$es6$promise$promise$$Promise._setAsap = lib$es6$promise$asap$$setAsap;
lib$es6$promise$promise$$Promise._asap = lib$es6$promise$asap$$asap;
lib$es6$promise$promise$$Promise.prototype = {
constructor: lib$es6$promise$promise$$Promise,
/**
The primary way of interacting with a promise is through its `then` method,
which registers callbacks to receive either a promise's eventual value or the
reason why the promise cannot be fulfilled.
```js
findUser().then(function(user){
// user is available
}, function(reason){
// user is unavailable, and you are given the reason why
});
```
Chaining
--------
The return value of `then` is itself a promise. This second, 'downstream'
promise is resolved with the return value of the first promise's fulfillment
or rejection handler, or rejected if the handler throws an exception.
```js
findUser().then(function (user) {
return user.name;
}, function (reason) {
return 'default name';
}).then(function (userName) {
// If `findUser` fulfilled, `userName` will be the user's name, otherwise it
// will be `'default name'`
});
findUser().then(function (user) {
throw new Error('Found user, but still unhappy');
}, function (reason) {
throw new Error('`findUser` rejected and we're unhappy');
}).then(function (value) {
// never reached
}, function (reason) {
// if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
// If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
});
```
If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
```js
findUser().then(function (user) {
throw new PedagogicalException('Upstream error');
}).then(function (value) {
// never reached
}).then(function (value) {
// never reached
}, function (reason) {
// The `PedgagocialException` is propagated all the way down to here
});
```
Assimilation
------------
Sometimes the value you want to propagate to a downstream promise can only be
retrieved asynchronously. This can be achieved by returning a promise in the
fulfillment or rejection handler. The downstream promise will then be pending
until the returned promise is settled. This is called *assimilation*.
```js
findUser().then(function (user) {
return findCommentsByAuthor(user);
}).then(function (comments) {
// The user's comments are now available
});
```
If the assimliated promise rejects, then the downstream promise will also reject.
```js
findUser().then(function (user) {
return findCommentsByAuthor(user);
}).then(function (comments) {
// If `findCommentsByAuthor` fulfills, we'll have the value here
}, function (reason) {
// If `findCommentsByAuthor` rejects, we'll have the reason here
});
```
Simple Example
--------------
Synchronous Example
```javascript
var result;
try {
result = findResult();
// success
} catch(reason) {
// failure
}
```
Errback Example
```js
findResult(function(result, err){
if (err) {
// failure
} else {
// success
}
});
```
Promise Example;
```javascript
findResult().then(function(result){
// success
}, function(reason){
// failure
});
```
Advanced Example
--------------
Synchronous Example
```javascript
var author, books;
try {
author = findAuthor();
books = findBooksByAuthor(author);
// success
} catch(reason) {
// failure
}
```
Errback Example
```js
function foundBooks(books) {
}
function failure(reason) {
}
findAuthor(function(author, err){
if (err) {
failure(err);
// failure
} else {
try {
findBoooksByAuthor(author, function(books, err) {
if (err) {
failure(err);
} else {
try {
foundBooks(books);
} catch(reason) {
failure(reason);
}
}
});
} catch(error) {
failure(err);
}
// success
}
});
```
Promise Example;
```javascript
findAuthor().
then(findBooksByAuthor).
then(function(books){
// found books
}).catch(function(reason){
// something went wrong
});
```
@method then
@param {Function} onFulfilled
@param {Function} onRejected
Useful for tooling.
@return {Promise}
*/
then: lib$es6$promise$then$$default,
/**
`catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
as the catch block of a try/catch statement.
```js
function findAuthor(){
throw new Error('couldn't find that author');
}
// synchronous
try {
findAuthor();
} catch(reason) {
// something went wrong
}
// async with promises
findAuthor().catch(function(reason){
// something went wrong
});
```
@method catch
@param {Function} onRejection
Useful for tooling.
@return {Promise}
*/
'catch': function(onRejection) {
return this.then(null, onRejection);
}
};
var lib$es6$promise$enumerator$$default = lib$es6$promise$enumerator$$Enumerator;
function lib$es6$promise$enumerator$$Enumerator(Constructor, input) {
this._instanceConstructor = Constructor;
this.promise = new Constructor(lib$es6$promise$$internal$$noop);
if (Array.isArray(input)) {
this._input = input;
this.length = input.length;
this._remaining = input.length;
this._result = new Array(this.length);
if (this.length === 0) {
lib$es6$promise$$internal$$fulfill(this.promise, this._result);
} else {
this.length = this.length || 0;
this._enumerate();
if (this._remaining === 0) {
lib$es6$promise$$internal$$fulfill(this.promise, this._result);
}
}
} else {
lib$es6$promise$$internal$$reject(this.promise, this._validationError());
}
}
lib$es6$promise$enumerator$$Enumerator.prototype._validationError = function() {
return new Error('Array Methods must be provided an Array');
};
lib$es6$promise$enumerator$$Enumerator.prototype._enumerate = function() {
var length = this.length;
var input = this._input;
for (var i = 0; this._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {
this._eachEntry(input[i], i);
}
};
lib$es6$promise$enumerator$$Enumerator.prototype._eachEntry = function(entry, i) {
var c = this._instanceConstructor;
var resolve = c.resolve;
if (resolve === lib$es6$promise$promise$resolve$$default) {
var then = lib$es6$promise$$internal$$getThen(entry);
if (then === lib$es6$promise$then$$default &&
entry._state !== lib$es6$promise$$internal$$PENDING) {
this._settledAt(entry._state, i, entry._result);
} else if (typeof then !== 'function') {
this._remaining--;
this._result[i] = entry;
} else if (c === lib$es6$promise$promise$$default) {
var promise = new c(lib$es6$promise$$internal$$noop);
lib$es6$promise$$internal$$handleMaybeThenable(promise, entry, then);
this._willSettleAt(promise, i);
} else {
this._willSettleAt(new c(function(resolve) { resolve(entry); }), i);
}
} else {
this._willSettleAt(resolve(entry), i);
}
};
lib$es6$promise$enumerator$$Enumerator.prototype._settledAt = function(state, i, value) {
var promise = this.promise;
if (promise._state === lib$es6$promise$$internal$$PENDING) {
this._remaining--;
if (state === lib$es6$promise$$internal$$REJECTED) {
lib$es6$promise$$internal$$reject(promise, value);
} else {
this._result[i] = value;
}
}
if (this._remaining === 0) {
lib$es6$promise$$internal$$fulfill(promise, this._result);
}
};
lib$es6$promise$enumerator$$Enumerator.prototype._willSettleAt = function(promise, i) {
var enumerator = this;
lib$es6$promise$$internal$$subscribe(promise, undefined, function(value) {
enumerator._settledAt(lib$es6$promise$$internal$$FULFILLED, i, value);
}, function(reason) {
enumerator._settledAt(lib$es6$promise$$internal$$REJECTED, i, reason);
});
};
function lib$es6$promise$polyfill$$polyfill() {
var local;
if (typeof global !== 'undefined') {
local = global;
} else if (typeof self !== 'undefined') {
local = self;
} else {
try {
local = Function('return this')();
} catch (e) {
throw new Error('polyfill failed because global object is unavailable in this environment');
}
}
var P = local.Promise;
if (P && Object.prototype.toString.call(P.resolve()) === '[object Promise]' && !P.cast) {
return;
}
local.Promise = lib$es6$promise$promise$$default;
}
var lib$es6$promise$polyfill$$default = lib$es6$promise$polyfill$$polyfill;
var lib$es6$promise$umd$$ES6Promise = {
'Promise': lib$es6$promise$promise$$default,
'polyfill': lib$es6$promise$polyfill$$default
};
/* global define:true module:true window: true */
if (typeof define === 'function' && define['amd']) {
define(function() { return lib$es6$promise$umd$$ES6Promise; });
} else if (typeof module !== 'undefined' && module['exports']) {
module['exports'] = lib$es6$promise$umd$$ES6Promise;
} else if (typeof this !== 'undefined') {
this['ES6Promise'] = lib$es6$promise$umd$$ES6Promise;
}
lib$es6$promise$polyfill$$default();
}).call(this);
}).call(this,_dereq_('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"_process":1}],3:[function(_dereq_,module,exports){
/*
* Copyright 2015 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var Util = _dereq_('./util.js');
var WakeLock = _dereq_('./wakelock.js');
// Start at a higher number to reduce chance of conflict.
var nextDisplayId = 1000;
/**
* The base class for all VR displays.
*/
function VRDisplay() {
this.displayId = nextDisplayId++;
this.displayName = 'webvr-polyfill displayName';
this.isConnected = true;
this.isPresenting = false;
this.capabilities = {
hasPosition: false,
hasOrientation: false,
hasExternalDisplay: false,
canPresent: false
};
this.stageParameters = null;
// "Private" members.
this.waitingForPresent_ = false;
this.layer_ = null;
this.fullscreenElement_ = null;
this.fullscreenWrapper_ = null;
this.fullscreenEventTarget_ = null;
this.fullscreenChangeHandler_ = null;
this.fullscreenErrorHandler_ = null;
this.wakelock_ = new WakeLock();
}
VRDisplay.prototype.getPose = function() {
// TODO: Technically this should retain it's value for the duration of a frame
// but I doubt that's practical to do in javascript.
return this.getImmediatePose();
};
VRDisplay.prototype.requestAnimationFrame = function(callback) {
return window.requestAnimationFrame(callback);
};
VRDisplay.prototype.cancelAnimationFrame = function(id) {
return window.cancelAnimationFrame(id);
};
VRDisplay.prototype.wrapForFullscreen = function(element) {
if (Util.isIOS())
return element;
if (!this.fullscreenWrapper_) {
this.fullscreenWrapper_ = document.createElement('div');
this.fullscreenWrapper_.classList.add('webvr-polyfill-fullscreen-wrapper');
}
if (this.fullscreenElement_ == element)
return this.fullscreenWrapper_;
// Remove any previously applied wrappers
this.removeFullscreenWrapper();
this.fullscreenElement_ = element;
var parent = this.fullscreenElement_.parentElement;
parent.insertBefore(this.fullscreenWrapper_, this.fullscreenElement_);
parent.removeChild(this.fullscreenElement_);
this.fullscreenWrapper_.insertBefore(this.fullscreenElement_, this.fullscreenWrapper_.firstChild);
return this.fullscreenWrapper_;
};
VRDisplay.prototype.removeFullscreenWrapper = function() {
if (!this.fullscreenElement_)
return;
var element = this.fullscreenElement_;
this.fullscreenElement_ = null;
var parent = this.fullscreenWrapper_.parentElement;
this.fullscreenWrapper_.removeChild(element);
parent.insertBefore(element, this.fullscreenWrapper_);
parent.removeChild(this.fullscreenWrapper_);
return element;
};
VRDisplay.prototype.requestPresent = function(layer) {
// Always use document.body for the fullscreen element, since we want to be
// able to render UI on top of the WebGL canvas.
//var fullscreenElement = layer.source;
var self = this;
this.layer_ = layer;
return new Promise(function(resolve, reject) {
if (!self.capabilities.canPresent) {
reject(new Error('VRDisplay is not capable of presenting.'));
return;
}
self.waitingForPresent_ = false;
if (layer && layer.source) {
var fullscreenElement = self.wrapForFullscreen(layer.source);
function onFullscreenChange() {
var actualFullscreenElement = Util.getFullscreenElement();
self.isPresenting = (fullscreenElement === actualFullscreenElement);
self.fireVRDisplayPresentChange_();
if (self.isPresenting) {
if (screen.orientation && screen.orientation.lock)
screen.orientation.lock('landscape-primary');
self.waitingForPresent_ = false;
self.beginPresent_();
resolve();
} else {
if (screen.orientation && screen.orientation.unlock)
screen.orientation.unlock();
self.removeFullscreenWrapper();
self.wakelock_.release();
self.endPresent_();
self.removeFullscreenListeners_();
}
}
function onFullscreenError() {
if (!self.waitingForPresent_)
return;
self.removeFullscreenWrapper();
self.removeFullscreenListeners_();
self.wakelock_.release();
self.waitingForPresent_ = false;
self.isPresenting = false;
reject(new Error('Unable to present.'));
}
self.addFullscreenListeners_(fullscreenElement,
onFullscreenChange, onFullscreenError);
if (Util.requestFullscreen(fullscreenElement)) {
self.wakelock_.request();
self.waitingForPresent_ = true;
} else if (Util.isIOS()) {
// *sigh* Just fake it.
self.wakelock_.request();
self.isPresenting = true;
self.fireVRDisplayPresentChange_();
self.beginPresent_();
resolve();
}
}
if (!self.waitingForPresent_ && !Util.isIOS()) {
Util.exitFullscreen();
reject(new Error('Unable to present.'));
}
});
};
VRDisplay.prototype.exitPresent = function() {
var wasPresenting = this.isPresenting;
var self = this;
this.isPresenting = false;
this.layer_ = null;
this.wakelock_.release();
return new Promise(function(resolve, reject) {
if (wasPresenting) {
if (!Util.exitFullscreen() && Util.isIOS()) {
self.endPresent_();
}
self.removeFullscreenWrapper();
resolve();
} else {
reject(new Error('Was not presenting to VRDisplay.'));
}
});
};
// This returns an array because future versions of the spec may accept multiple
// layers in requestPresent, and it's easier to overload function parameters
// than it is return types.
VRDisplay.prototype.getLayers = function() {
if (this.layer_) {
return [this.layer_];
}
return null;
};
VRDisplay.prototype.fireVRDisplayPresentChange_ = function() {
var event = new CustomEvent('vrdisplaypresentchange', {detail: {vrdisplay: this}});
window.dispatchEvent(event);
};
VRDisplay.prototype.addFullscreenListeners_ = function(element, changeHandler, errorHandler) {
this.removeFullscreenListeners_();
this.fullscreenEventTarget_ = element;
this.fullscreenChangeHandler_ = changeHandler;
this.fullscreenErrorHandler_ = errorHandler;
if (changeHandler) {
element.addEventListener('fullscreenchange', changeHandler, false);
element.addEventListener('webkitfullscreenchange', changeHandler, false);
document.addEventListener('mozfullscreenchange', changeHandler, false);
element.addEventListener('msfullscreenchange', changeHandler, false);
}
if (errorHandler) {
element.addEventListener('fullscreenerror', errorHandler, false);
element.addEventListener('webkitfullscreenerror', errorHandler, false);
document.addEventListener('mozfullscreenerror', errorHandler, false);
element.addEventListener('msfullscreenerror', errorHandler, false);
}
};
VRDisplay.prototype.removeFullscreenListeners_ = function() {
if (!this.fullscreenEventTarget_)
return;
var element = this.fullscreenEventTarget_;
if (this.fullscreenChangeHandler_) {
var changeHandler = this.fullscreenChangeHandler_;
element.removeEventListener('fullscreenchange', changeHandler, false);
element.removeEventListener('webkitfullscreenchange', changeHandler, false);
document.removeEventListener('mozfullscreenchange', changeHandler, false);
element.removeEventListener('msfullscreenchange', changeHandler, false);
}
if (this.fullscreenErrorHandler_) {
var errorHandler = this.fullscreenErrorHandler_;
element.removeEventListener('fullscreenerror', errorHandler, false);
element.removeEventListener('webkitfullscreenerror', errorHandler, false);
document.removeEventListener('mozfullscreenerror', errorHandler, false);
element.removeEventListener('msfullscreenerror', errorHandler, false);
}
this.fullscreenEventTarget_ = null;
this.fullscreenChangeHandler_ = null;
this.fullscreenErrorHandler_ = null;
};
VRDisplay.prototype.beginPresent_ = function() {
// Override to add custom behavior when presentation begins.
};
VRDisplay.prototype.endPresent_ = function() {
// Override to add custom behavior when presentation ends.
};
VRDisplay.prototype.submitFrame = function(pose) {
// Override to add custom behavior for frame submission.
};
VRDisplay.prototype.getEyeParameters = function(whichEye) {
// Override to return accurate eye parameters is canPresent is true.
return null;
};
/*
* Deprecated classes
*/
/**
* The base class for all VR devices. (Deprecated)
*/
function VRDevice() {
this.hardwareUnitId = 'webvr-polyfill hardwareUnitId';
this.deviceId = 'webvr-polyfill deviceId';
this.deviceName = 'webvr-polyfill deviceName';
}
/**
* The base class for all VR HMD devices. (Deprecated)
*/
function HMDVRDevice() {
}
HMDVRDevice.prototype = new VRDevice();
/**
* The base class for all VR position sensor devices. (Deprecated)
*/
function PositionSensorVRDevice() {
}
PositionSensorVRDevice.prototype = new VRDevice();
module.exports.VRDisplay = VRDisplay;
module.exports.VRDevice = VRDevice;
module.exports.HMDVRDevice = HMDVRDevice;
module.exports.PositionSensorVRDevice = PositionSensorVRDevice;
},{"./util.js":23,"./wakelock.js":25}],4:[function(_dereq_,module,exports){
/*
* Copyright 2016 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var CardboardUI = _dereq_('./cardboard-ui.js');
var Util = _dereq_('./util.js');
var WGLUPreserveGLState = _dereq_('./deps/wglu-preserve-state.js');
var distortionVS = [
'attribute vec2 position;',
'attribute vec3 texCoord;',
'varying vec2 vTexCoord;',
'uniform vec4 viewportOffsetScale[2];',
'void main() {',
' vec4 viewport = viewportOffsetScale[int(texCoord.z)];',
' vTexCoord = (texCoord.xy * viewport.zw) + viewport.xy;',
' gl_Position = vec4( position, 1.0, 1.0 );',
'}',
].join('\n');
var distortionFS = [
'precision mediump float;',
'uniform sampler2D diffuse;',
'varying vec2 vTexCoord;',
'void main() {',
' gl_FragColor = texture2D(diffuse, vTexCoord);',
'}',
].join('\n');
/**
* A mesh-based distorter.
*/
function CardboardDistorter(gl) {
this.gl = gl;
this.ctxAttribs = gl.getContextAttributes();
this.meshWidth = 20;
this.meshHeight = 20;
this.bufferScale = WebVRConfig.BUFFER_SCALE ? WebVRConfig.BUFFER_SCALE : 1.0;
this.bufferWidth = gl.drawingBufferWidth;
this.bufferHeight = gl.drawingBufferHeight;
// Patching support
this.realBindFramebuffer = gl.bindFramebuffer;
this.realEnable = gl.enable;
this.realDisable = gl.disable;
this.realColorMask = gl.colorMask;
this.realClearColor = gl.clearColor;
this.realViewport = gl.viewport;
this.realCanvasWidth = Object.getOwnPropertyDescriptor(gl.canvas.__proto__, 'width');
this.realCanvasHeight = Object.getOwnPropertyDescriptor(gl.canvas.__proto__, 'height');
this.isPatched = false;
// State tracking
this.lastBoundFramebuffer = null;
this.cullFace = false;
this.depthTest = false;
this.blend = false;
this.scissorTest = false;
this.stencilTest = false;
this.viewport = [0, 0, 0, 0];
this.colorMask = [true, true, true, true];
this.clearColor = [0, 0, 0, 0];
this.attribs = {
position: 0,
texCoord: 1
};
this.program = Util.linkProgram(gl, distortionVS, distortionFS, this.attribs);
this.uniforms = Util.getProgramUniforms(gl, this.program);
this.viewportOffsetScale = new Float32Array(8);
this.setTextureBounds();
this.vertexBuffer = gl.createBuffer();
this.indexBuffer = gl.createBuffer();
this.indexCount = 0;
this.renderTarget = gl.createTexture();
this.framebuffer = gl.createFramebuffer();
this.depthStencilBuffer = null;
this.depthBuffer = null;
this.stencilBuffer = null;
if (this.ctxAttribs.depth && this.ctxAttribs.stencil) {
this.depthStencilBuffer = gl.createRenderbuffer();
} else if (this.ctxAttribs.depth) {
this.depthBuffer = gl.createRenderbuffer();
} else if (this.ctxAttribs.stencil) {
this.stencilBuffer = gl.createRenderbuffer();
}
this.onResize();
this.cardboardUI = new CardboardUI(gl);
this.patch();
};
/**
* Tears down all the resources created by the distorter and removes any
* patches.
*/
CardboardDistorter.prototype.destroy = function() {
var gl = this.gl;
this.unpatch();
gl.deleteProgram(this.program);
gl.deleteBuffer(this.vertexBuffer);
gl.deleteBuffer(this.indexBuffer);
gl.deleteTexture(this.renderTarget);
gl.deleteFramebuffer(this.framebuffer);
if (this.depthStencilBuffer) {
gl.deleteRenderbuffer(this.depthStencilBuffer);
}
if (this.depthBuffer) {
gl.deleteRenderbuffer(this.depthBuffer);
}
if (this.stencilBuffer) {
gl.deleteRenderbuffer(this.stencilBuffer);
}
this.cardboardUI.destroy();
};
/**
* Resizes the backbuffer to match the canvas width and height.
*/
CardboardDistorter.prototype.onResize = function() {
var gl = this.gl;
var self = this;
var glState = [
gl.RENDERBUFFER_BINDING,
gl.TEXTURE_BINDING_2D, gl.TEXTURE0
];
WGLUPreserveGLState(gl, glState, function(gl) {
// Bind real backbuffer and clear it once. We don't need to clear it again
// after that because we're overwriting the same area every frame.
self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, null);
// Put things in a good state
if (self.scissorTest) { self.realDisable.call(gl, gl.SCISSOR_TEST); }
self.realColorMask.call(gl, true, true, true, true);
self.realViewport.call(gl, 0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
self.realClearColor.call(gl, 0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// Now bind and resize the fake backbuffer
self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, self.framebuffer);
gl.bindTexture(gl.TEXTURE_2D, self.renderTarget);
gl.texImage2D(gl.TEXTURE_2D, 0, self.ctxAttribs.alpha ? gl.RGBA : gl.RGB,
self.bufferWidth, self.bufferHeight, 0,
self.ctxAttribs.alpha ? gl.