crossbrowdy
Version:
A Multimedia JavaScript framework to create real cross-platform and hybrid game engines, games, emulators, multimedia libraries and apps.
976 lines (835 loc) • 30.9 kB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Gamepads = f()}})(function(){var define,module,exports;return (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(require,module,exports){
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _libGamepadsJs = require('./lib/gamepads.js');
var _libGamepadsJs2 = _interopRequireDefault(_libGamepadsJs);
exports['default'] = _libGamepadsJs2['default'];
module.exports = exports['default'];
},{"./lib/gamepads.js":3}],2:[function(require,module,exports){
/**
* A simple event-emitter class. Like Node's but much simpler.
*/
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var EventEmitter = (function () {
function EventEmitter() {
_classCallCheck(this, EventEmitter);
this._listeners = {};
}
_createClass(EventEmitter, [{
key: "emit",
value: function emit(name) {
var _this = this;
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
// console.log('emit', name, args, this._listeners);
(this._listeners[name] || []).forEach(function (func) {
return func.apply(_this, args);
});
return this;
}
}, {
key: "on",
value: function on(name, func) {
if (name in this._listeners) {
this._listeners[name].push(func);
} else {
this._listeners[name] = [func];
}
return this;
}
}, {
key: "off",
value: function off(name) {
if (name) {
this._listeners[name] = [];
} else {
this._listeners = {};
}
return this;
}
}]);
return EventEmitter;
})();
exports["default"] = EventEmitter;
module.exports = exports["default"];
},{}],3:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var _event_emitterJs = require('./event_emitter.js');
var _event_emitterJs2 = _interopRequireDefault(_event_emitterJs);
var _utilsJs = require('./utils.js');
var _utilsJs2 = _interopRequireDefault(_utilsJs);
var utils = new _utilsJs2['default']();
var DEFAULT_CONFIG = {
'axisThreshold': 0.15,
'gamepadAttributesEnabled': true,
'gamepadIndicesEnabled': true,
'keyEventsEnabled': true,
'nonstandardEventsEnabled': true,
'indices': undefined,
'keyEvents': undefined
};
var DEFAULT_STATE = {
// The standard gamepad has 4 axes and 17 buttons.
// Some gamepads have 5-6 axes and 18-20 buttons.
buttons: new Array(20),
axes: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
};
for (var i = 0; i < 20; i++) {
DEFAULT_STATE.buttons[i] = {
pressed: false,
value: 0.0
};
}
var Gamepads = (function (_EventEmitter) {
_inherits(Gamepads, _EventEmitter);
function Gamepads(config) {
var _this = this;
_classCallCheck(this, Gamepads);
_get(Object.getPrototypeOf(Gamepads.prototype), 'constructor', this).call(this);
this.polyfill();
//this._gamepadApis = ['getGamepads', 'webkitGetGamepads', 'webkitGamepads'];
this._gamepadDOMEvents = ['gamepadconnected', 'gamepaddisconnected'];
this._gamepadInternalEvents = ['gamepadconnected', 'gamepaddisconnected', 'gamepadbuttondown', 'gamepadbuttonup', 'gamepadaxismove'];
this._seenEvents = {};
this.dataSource = this.getGamepadDataSource();
this.gamepadsSupported = this._hasGamepads();
this.indices = {};
this.keyEvents = {};
this.previousState = {};
this.state = {};
// Mark the events we see (keyed off gamepad index)
// so we don't fire the same event twice.
this._gamepadDOMEvents.forEach(function (eventName) {
window.addEventListener(eventName, function (e) {
_this.addSeenEvent(e.gamepad, eventName, 'dom');
// Let the events fire again, if they've been disconnected/reconnected.
if (eventName === 'gamepaddisconnected') {
_this.removeSeenEvent(e.gamepad, 'gamepadconnected', 'dom');
} else if (eventName === 'gamepadconnected') {
_this.removeSeenEvent(e.gamepad, 'gamepaddisconnected', 'dom');
}
});
});
this._gamepadInternalEvents.forEach(function (eventName) {
_this.on(eventName, function (gamepad) {
_this.addSeenEvent(gamepad, eventName, 'internal');
if (eventName === 'gamepaddisconnected') {
_this.removeSeenEvent(gamepad, 'gamepadconnected', 'internal');
} else {
_this.removeSeenEvent(gamepad, 'gamepaddisconnected', 'internal');
}
});
});
config = config || {};
Object.keys(DEFAULT_CONFIG).forEach(function (key) {
_this[key] = typeof config[key] === 'undefined' ? DEFAULT_CONFIG[key] : utils.clone(config[key]);
});
if (this.gamepadIndicesEnabled) {
this.on('gamepadconnected', this._onGamepadConnected.bind(this));
this.on('gamepaddisconnected', this._onGamepadDisconnected.bind(this));
this.on('gamepadbuttondown', this._onGamepadButtonDown.bind(this));
this.on('gamepadbuttonup', this._onGamepadButtonUp.bind(this));
this.on('gamepadaxismove', this._onGamepadAxisMove.bind(this));
}
}
/**
* Make gamepads API support check static
* @returns {string[]}
*/
_createClass(Gamepads, [{
key: 'polyfill',
value: function polyfill() {
if (this._polyfilled) {
return;
}
if (!('performance' in window)) {
window.performance = {};
}
if (!('now' in window.performance)) {
window.performance.now = function () {
return +new Date();
};
}
if (!('GamepadButton' in window)) {
var GamepadButton = window.GamepadButton = function (obj) {
return {
pressed: obj.pressed,
value: obj.value
};
};
}
this._polyfilled = true;
}
}, {
key: '_getVendorProductIds',
value: function _getVendorProductIds(gamepad) {
var bits = gamepad.id.split('-');
var match;
if (bits.length < 2) {
match = gamepad.id.match(/vendor: (\w+) product: (\w+)/i);
if (match) {
return match.slice(1).map(utils.stripLeadingZeros);
}
}
match = gamepad.id.match(/(\w+)-(\w+)/);
if (match) {
return match.slice(1).map(utils.stripLeadingZeros);
}
return bits.slice(0, 2).map(utils.stripLeadingZeros);
}
/**
* Make gamepads API support static
* @returns {boolean}
*/
}, {
key: '_hasGamepads',
value: function _hasGamepads() {
return Gamepads.hasGamepads();
}
}, {
key: '_getGamepads',
value: function _getGamepads() {
return Gamepads.getGamepads();
}
}, {
key: 'updateGamepad',
value: function updateGamepad(gamepad) {
this.previousState[gamepad.index] = utils.clone(this.state[gamepad.index] || DEFAULT_STATE);
this.state[gamepad.index] = gamepad ? utils.clone(gamepad) : DEFAULT_STATE;
// Fire connection event, if gamepad was actually connected.
this.fireConnectionEvent(this.state[gamepad.index], true);
}
}, {
key: 'removeGamepad',
value: function removeGamepad(gamepad) {
delete this.state[gamepad.index];
// Fire disconnection event.
this.fireConnectionEvent(gamepad, false);
}
}, {
key: 'observeButtonChanges',
value: function observeButtonChanges(gamepad) {
var _this2 = this;
var previousPad = this.previousState[gamepad.index];
var currentPad = this.state[gamepad.index];
if (!previousPad || !Object.keys(previousPad).length || !currentPad || !Object.keys(currentPad).length) {
return;
}
currentPad.buttons.forEach(function (button, buttonIdx) {
if (button.value !== previousPad.buttons[buttonIdx].value) {
// Fire button events.
_this2.fireButtonEvent(currentPad, buttonIdx, button.value);
// Fire synthetic keyboard events, if needed.
_this2.fireKeyEvent(currentPad, buttonIdx, button.value);
}
});
}
}, {
key: 'observeAxisChanges',
value: function observeAxisChanges(gamepad) {
var _this3 = this;
var previousPad = this.previousState[gamepad.index];
var currentPad = this.state[gamepad.index];
if (!previousPad || !Object.keys(previousPad).length || !currentPad || !Object.keys(currentPad).length) {
return;
}
currentPad.axes.forEach(function (axis, axisIdx) {
// Fire axis events.
if (axis !== previousPad.axes[axisIdx]) {
_this3.fireAxisMoveEvent(currentPad, axisIdx, axis);
}
});
}
/**
* @function
* @name Gamepads#update
* @description
* Update the current and previous states of the gamepads.
* This must be called every frame for events to work.
*/
}, {
key: 'update',
value: function update() {
var _this4 = this;
var activePads = {};
this.poll().forEach(function (pad) {
// Keep track of which gamepads are still active (not disconnected).
activePads[pad.index] = true;
// Add/update connected gamepads
// (and fire internal events + polyfilled events, if needed).
_this4.updateGamepad(pad);
// Never seen this actually be the case, but if a pad is still in the
// `navigator.getGamepads()` list and it's disconnected, emit the event.
if (!pad.connected) {
_this4.removeGamepad(_this4.state[padIdx]);
}
// Fire internal events + polyfilled non-standard events, if needed.
_this4.observeButtonChanges(pad);
_this4.observeAxisChanges(pad);
});
Object.keys(this.state).forEach(function (padIdx) {
if (!(padIdx in activePads)) {
// Remove disconnected gamepads
// (and fire internal events + polyfilled events, if needed).
_this4.removeGamepad(_this4.state[padIdx]);
}
});
}
/**
* @function
* @name Gamepads#getGamepadDataSource
* @description Get gamepad data source (e.g., linuxjoy, hid, dinput, xinput).
* @returns {String} A string of gamepad data source.
*/
}, {
key: 'getGamepadDataSource',
value: function getGamepadDataSource() {
var dataSource;
if (navigator.platform.match(/^Linux/)) {
dataSource = 'linuxjoy';
} else if (navigator.platform.match(/^Mac/)) {
dataSource = 'hid';
} else if (navigator.platform.match(/^Win/)) {
var m = navigator.userAgent.match('Gecko/(..)');
if (m && parseInt(m[1]) < 32) {
dataSource = 'dinput';
} else {
dataSource = 'hid';
}
}
return dataSource;
}
/**
* @function
* @name Gamepads#poll
* @description Poll for the latest data from the gamepad API.
* @returns {Array} An array of gamepads and mappings for the model of the connected gamepad.
* @example
* var gamepads = new Gamepads();
* var pads = gamepads.poll();
*/
}, {
key: 'poll',
value: function poll() {
var pads = [];
if (this.gamepadsSupported) {
var padsRaw = this._getGamepads();
var pad;
for (var i = 0, len = padsRaw.length; i < len; i++) {
pad = padsRaw[i];
if (!pad) {
continue;
}
pad = this.extend(pad);
pads.push(pad);
}
}
return pads;
}
/**
* @function
* @name Gamepads#extend
* @description Set new properties on a gamepad object.
* @param {Object} gamepad The original gamepad object.
* @returns {Object} An extended copy of the gamepad.
*/
}, {
key: 'extend',
value: function extend(gamepad) {
if (gamepad._extended) {
return gamepad;
}
var pad = utils.clone(gamepad);
pad._extended = true;
if (this.gamepadAttributesEnabled) {
pad.attributes = this._getAttributes(pad);
}
if (!pad.timestamp) {
pad.timestamp = window.performance.now();
}
if (this.gamepadIndicesEnabled) {
pad.indices = this._getIndices(pad);
}
return pad;
}
/**
* @function
* @name Gamepads#_getAttributes
* @description Generate and return the attributes of a gamepad.
* @param {Object} gamepad The gamepad object.
* @returns {Object} The attributes for this gamepad.
*/
}, {
key: '_getAttributes',
value: function _getAttributes(gamepad) {
var padIds = this._getVendorProductIds(gamepad);
return {
vendorId: padIds[0],
productId: padIds[1],
name: gamepad.id,
dataSource: this.dataSource
};
}
/**
* @function
* @name Gamepads#_getIndices
* @description Return the named indices of a gamepad.
* @param {Object} gamepad The gamepad object.
* @returns {Object} The named indices for this gamepad.
*/
}, {
key: '_getIndices',
value: function _getIndices(gamepad) {
return this.indices[gamepad.id] || this.indices.standard || {};
}
/**
* @function
* @name Gamepads#_mapAxis
* @description Set the value for one of the analogue axes of the pad.
* @param {Number} axis The button to get the value of.
* @returns {Number} The value of the axis between -1 and 1.
*/
}, {
key: '_mapAxis',
value: function _mapAxis(axis) {
if (Math.abs(axis) < this.axisThreshold) {
return 0;
}
return axis;
}
/**
* @function
* @name Gamepads#_mapButton
* @description Set the value for one of the buttons of the pad.
* @param {Number} button The button to get the value of.
* @returns {Object} An object resembling a `GamepadButton` object.
*/
}, {
key: '_mapButton',
value: function _mapButton(button) {
if (typeof button === 'number') {
// Old versions of the API used to return just numbers instead
// of `GamepadButton` objects.
button = new GamepadButton({
pressed: button === 1,
value: button
});
}
return button;
}
}, {
key: 'setIndices',
value: function setIndices(indices) {
this.indices = utils.clone(indices);
}
}, {
key: 'fireConnectionEvent',
value: function fireConnectionEvent(gamepad, connected) {
var name = connected ? 'gamepadconnected' : 'gamepaddisconnected';
if (!this.hasSeenEvent(gamepad, name, 'internal')) {
// Fire internal event.
this.emit(name, gamepad);
}
// Don't fire the 'gamepadconnected'/'gamepaddisconnected' events if the
// browser has already fired them. (Unfortunately, we can't feature detect
// if they'll get fired.)
if (!this.hasSeenEvent(gamepad, name, 'dom')) {
var data = {
bubbles: false,
cancelable: false,
detail: {
gamepad: gamepad
}
};
utils.triggerEvent(window, name, data);
}
}
}, {
key: 'fireButtonEvent',
value: function fireButtonEvent(gamepad, button, value) {
var name = value === 1 ? 'gamepadbuttondown' : 'gamepadbuttonup';
// Fire internal event.
this.emit(name, gamepad, button, value);
if (this.nonstandardEventsEnabled && !('GamepadButtonEvent' in window)) {
var data = {
bubbles: false,
cancelable: false,
detail: {
button: button,
gamepad: gamepad
}
};
utils.triggerEvent(window, name, data);
}
}
}, {
key: 'fireAxisMoveEvent',
value: function fireAxisMoveEvent(gamepad, axis, value) {
var name = 'gamepadaxismove';
// Fire internal event.
this.emit(name, gamepad, axis, value);
if (!this.nonstandardEventsEnabled || 'GamepadAxisMoveEvent' in window) {
return;
}
if (Math.abs(value) < this.axisThreshold) {
return;
}
var data = {
bubbles: false,
cancelable: false,
detail: {
axis: axis,
gamepad: gamepad,
value: value
}
};
utils.triggerEvent(window, name, data);
}
}, {
key: 'fireKeyEvent',
value: function fireKeyEvent(gamepad, button, value) {
if (!this.keyEventsEnabled || !this.keyEvents) {
return;
}
var buttonName = utils.swap(gamepad.indices)[button];
if (typeof buttonName === 'undefined') {
return;
}
var names = value === 1 ? ['keydown', 'keypress'] : ['keyup'];
var data = this.keyEvents[buttonName];
if (!data) {
return;
}
if (!('bubbles' in data)) {
data.bubbles = true;
}
if (!data.detail) {
data.detail = {};
}
data.detail.button = button;
data.detail.gamepad = gamepad;
names.forEach(function (name) {
utils.triggerEvent(data.target || document.activeElement, name, data);
});
}
}, {
key: 'addSeenEvent',
value: function addSeenEvent(gamepad, eventType, namespace) {
var key = [gamepad.index, eventType, namespace].join('.');
this._seenEvents[key] = true;
}
}, {
key: 'hasSeenEvent',
value: function hasSeenEvent(gamepad, eventType, namespace) {
var key = [gamepad.index, eventType, namespace].join('.');
return !!this._seenEvents[key];
}
}, {
key: 'removeSeenEvent',
value: function removeSeenEvent(gamepad, eventType, namespace) {
var key = [gamepad.index, eventType, namespace].join('.');
delete this._seenEvents[key];
}
}, {
key: 'buttonEvent2axisEvent',
value: function buttonEvent2axisEvent(e) {
if (e.type === 'gamepadbuttondown') {
e.axis = e.button;
e.value = 1.0;
} else if (e.type === 'gamepadbuttonup') {
e.axis = e.button;
e.value = 0.0;
}
return e;
}
/**
* Returns whether a `button` index equals the supplied `key`.
*
* Useful for determining whether ``navigator.getGamepads()[0].buttons[`$button`]``
* has any bindings defined (in `FrameManager`).
*
* @param {Number} button Index of gamepad button (e.g., `4`).
* @param {String} key Human-readable format for button binding (e.g., 'b4').
*/
}, {
key: '_buttonDownEqualsKey',
value: function _buttonDownEqualsKey(button, key) {
return 'b' + button + '.down' === key.trim().toLowerCase();
}
}, {
key: '_buttonUpEqualsKey',
value: function _buttonUpEqualsKey(button, key) {
var keyClean = key.trim().toLowerCase();
return 'b' + button + '.up' === keyClean || 'b' + button === keyClean;
}
/**
* Returns whether an `axis` index equals the supplied `key`.
*
* Useful for determining whether ``navigator.getGamepads()[0].axes[`$button`]``
* has any bindings defined (in `FrameManager`).
*
* @param {Number} button Index of gamepad axis (e.g., `1`).
* @param {String} key Human-readable format for button binding (e.g., 'a1').
*/
}, {
key: '_axisMoveEqualsKey',
value: function _axisMoveEqualsKey(axis, key) {
return 'a' + axis === key.trim().toLowerCase();
}
/**
* Calls any bindings defined for 'connected' (in `FrameManager`).
*
* (Called by event listener for `gamepadconnected`.)
*
* @param {Gamepad} gamepad Gamepad object (after it's been wrapped by gamepad-plus).
*/
}, {
key: '_onGamepadConnected',
value: function _onGamepadConnected(gamepad) {
if ('connected' in gamepad.indices) {
gamepad.indices.connected(gamepad);
}
}
/**
* Calls any bindings defined for 'disconnected' (in `FrameManager`).
*
* (Called by event listener for `gamepadconnected`.)
*
* @param {Gamepad} gamepad Gamepad object (after it's been wrapped by gamepad-plus).
*/
}, {
key: '_onGamepadDisconnected',
value: function _onGamepadDisconnected(gamepad) {
if ('disconnected' in gamepad.indices) {
gamepad.indices.disconnected(gamepad);
}
}
/**
* Calls any bindings defined for buttons (e.g., 'b4.up' in `FrameManager`).
*
* (Called by event listener for `gamepadconnected`.)
*
* @param {Gamepad} gamepad Gamepad object (after it's been wrapped by gamepad-plus).
* @param {Number} button Index of gamepad button (integer) being pressed
* (per `gamepadbuttondown` event).
*/
}, {
key: '_onGamepadButtonDown',
value: function _onGamepadButtonDown(gamepad, button) {
for (var key in gamepad.indices) {
if (this._buttonDownEqualsKey(button, key)) {
gamepad.indices[key](gamepad, button);
}
}
}
/**
* Calls any bindings defined for buttons (e.g., 'b4.down' in `FrameManager`).
*
* (Called by event listener for `gamepadconnected`.)
*
* @param {Gamepad} gamepad Gamepad object (after it's been wrapped by gamepad-plus).
* @param {Number} button Index of gamepad button (integer) being released
* (per `gamepadbuttonup` event).
*/
}, {
key: '_onGamepadButtonUp',
value: function _onGamepadButtonUp(gamepad, button) {
for (var key in gamepad.indices) {
if (this._buttonUpEqualsKey(button, key)) {
gamepad.indices[key](gamepad, button);
}
}
}
/**
* Calls any bindings defined for axes (e.g., 'a1' in `FrameManager`).
*
* (Called by event listener for `gamepadaxismove`.)
*
* @param {Gamepad} gamepad Gamepad object (after it's been wrapped by gamepad-plus).
* @param {Number} axis Index of gamepad axis (integer) being changed
* (per `gamepadaxismove` event).
* @param {Number} value Value of gamepad axis (from -1.0 to 1.0) being
* changed (per `gamepadaxismove` event).
*/
}, {
key: '_onGamepadAxisMove',
value: function _onGamepadAxisMove(gamepad, axis, value) {
for (var key in gamepad.indices) {
if (this._axisMoveEqualsKey(axis, key)) {
gamepad.indices[key](gamepad, axis, value);
}
}
}
}], [{
key: 'hasGamepads',
value: function hasGamepads() {
for (var i = 0, len = Gamepads.gamepadApis.length; i < len; i++) {
if (Gamepads.gamepadApis[i] in navigator) {
return true;
}
}
return false;
}
/**
* Make gamepads API support static
* @returns {*}
*/
}, {
key: 'getGamepads',
value: function getGamepads() {
for (var i = 0, len = Gamepads.gamepadApis.length; i < len; i++) {
if (Gamepads.gamepadApis[i] in navigator) {
return navigator[Gamepads.gamepadApis[i]]();
}
}
return [];
}
}, {
key: 'gamepadApis',
get: function get() {
return ['getGamepads', 'webkitGetGamepads', 'webkitGamepads'];
}
}]);
return Gamepads;
})(_event_emitterJs2['default']);
exports['default'] = Gamepads;
Gamepads.utils = utils;
module.exports = exports['default'];
},{"./event_emitter.js":2,"./utils.js":4}],4:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
var Utils = (function () {
function Utils() {
_classCallCheck(this, Utils);
this.browser = this.getBrowser();
this.engine = this.getEngine(this.browser);
}
_createClass(Utils, [{
key: 'clone',
value: function clone(obj) {
if (obj === null || typeof obj === 'function' || !(obj instanceof Object)) {
return obj;
}
var ret = '';
if (obj instanceof Date) {
ret = new Date();
ret.setTime(obj.getTime());
return ret;
}
if (obj instanceof Array) {
ret = [];
for (var i = 0, len = obj.length; i < len; i++) {
ret[i] = this.clone(obj[i]);
}
return ret;
}
if (obj instanceof Object) {
ret = {};
for (var attr in obj) {
if (attr in obj) {
ret[attr] = this.clone(obj[attr]);
}
}
return ret;
}
throw new Error('Unable to clone object of unexpected type!');
}
}, {
key: 'swap',
value: function swap(obj) {
var ret = {};
for (var attr in obj) {
if (attr in obj) {
ret[obj[attr]] = attr;
}
}
return ret;
}
}, {
key: 'getBrowser',
value: function getBrowser() {
if (typeof window === 'undefined') {
return;
}
if (!!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0) {
// Opera 8.0+ (UA detection to detect Blink/v8-powered Opera).
return 'opera';
} else if ('chrome' in window) {
// Chrome 1+.
return 'chrome';
} else if (typeof InstallTrigger !== 'undefined') {
// Firefox 1.0+.
return 'firefox';
} else if (Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0) {
// At least Safari 3+: "[object HTMLElementConstructor]".
return 'safari';
} else if ( /*@cc_on!@*/false || !!document.documentMode) {
// At least IE6.
return 'ie';
}
}
}, {
key: 'getEngine',
value: function getEngine(browser) {
browser = browser || this.getBrowser();
if (browser === 'firefox') {
return 'gecko';
} else if (browser === 'opera' || browser === 'chrome' || browser === 'safari') {
return 'webkit';
} else if (browser === 'ie') {
return 'trident';
}
}
}, {
key: 'stripLeadingZeros',
value: function stripLeadingZeros(str) {
if (typeof str !== 'string') {
return str;
}
return str.replace(/^0+(?=\d+)/g, '');
}
}, {
key: 'triggerEvent',
value: function triggerEvent(el, name, data) {
data = data || {};
data.detail = data.detail || {};
var event;
if ('CustomEvent' in window) {
event = new CustomEvent(name, data);
} else {
event = document.createEvent('CustomEvent');
event.initCustomEvent(name, data.bubbles, data.cancelable, data.detail);
}
Object.keys(data.detail).forEach(function (key) {
event[key] = data.detail[key];
});
el.dispatchEvent(event);
}
}]);
return Utils;
})();
exports['default'] = Utils;
module.exports = exports['default'];
},{}]},{},[1])(1)
});