UNPKG

springroll-keyboard

Version:

Keyboard is a plugin for [SpringRoll](http://github.com/SpringRoll/SpringRoll). It is designed to make working with the keyboard outside of text editing easier. Keyboard has capabilities for detecting key presses and releases, tracking pressed keys, custo

1,933 lines (1,876 loc) 73 kB
/*! Keyboard 0.1.5 */ /** * @namespace springroll */ (function() { //A stripped down version of Detect.js, just for browser family and OS /* * Detect.js: User-Agent Parser * https://github.com/darcyclarke/Detect.js * Dual licensed under the MIT and GPL licenses. * * @version 2.2.1 * @author Darcy Clarke * @url http://darcyclarke.me * @createdat Thu Feb 13 2014 11:36:42 GMT+0000 (WET) * * Based on UA-Parser (https://github.com/tobie/ua-parser) by Tobie Langel * * Example Usage: * var agentInfo = detect.parse(navigator.userAgent); * console.log(agentInfo.browser.family); // Chrome * */ // Shim Array.prototype.map if necessary // Production steps of ECMA-262, Edition 5, 15.4.4.19 // Reference: http://es5.github.com/#x15.4.4.19 /*if (!Array.prototype.map) { Array.prototype.map = function(callback, thisArg) { var T, A, k; if (this == null) { throw new TypeError(" this is null or not defined"); } // 1. Let O be the result of calling ToObject passing the |this| value as the argument. var O = Object(this); // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length". // 3. Let len be ToUint32(lenValue). var len = O.length >>> 0; // 4. If IsCallable(callback) is false, throw a TypeError exception. // See: http://es5.github.com/#x9.11 if (typeof callback !== "function") { throw new TypeError(callback + " is not a function"); } // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. if (thisArg) { T = thisArg; } // 6. Let A be a new array created as if by the expression new Array(len) where Array is // the standard built-in constructor with that name and len is the value of len. A = new Array(len); // 7. Let k be 0 k = 0; // 8. Repeat, while k < len while (k < len) { var kValue, mappedValue; // a. Let Pk be ToString(k). // This is implicit for LHS operands of the in operator // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk. // This step can be combined with c // c. If kPresent is true, then if (k in O) { // i. Let kValue be the result of calling the Get internal method of O with argument Pk. kValue = O[k]; // ii. Let mappedValue be the result of calling the Call internal method of callback // with T as the this value and argument list containing kValue, k, and O. mappedValue = callback.call(T, kValue, k, O); // iii. Call the DefineOwnProperty internal method of A with arguments // Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true}, // and false. // In browsers that support Object.defineProperty, use the following: // Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true }); // For best browser support, use the following: A[k] = mappedValue; } // d. Increase k by 1. k++; } // 9. return A return A; }; }*/ // Detect var detect = function() { // Context var _this = function() {}; // Regexes var regexes = { browser_parsers: [ /*{ regex: "^(Opera)/(\\d+)\\.(\\d+) \\(Nintendo Wii", family_replacement: "Wii", manufacturer: "Nintendo" }, { regex: "(SeaMonkey|Camino)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)", family_replacement: "Camino", other: true },*/ { regex: "(Pale[Mm]oon)/(\\d+)\\.(\\d+)\\.?(\\d+)?", family_replacement: "Pale Moon (Firefox Variant)", other: true }, { regex: "(Fennec)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)", family_replacement: "Firefox Mobile" }, { regex: "(Fennec)/(\\d+)\\.(\\d+)(pre)", family_replacment: "Firefox Mobile" }, { regex: "(Fennec)/(\\d+)\\.(\\d+)", family_replacement: "Firefox Mobile" }, { regex: "Mobile.*(Firefox)/(\\d+)\\.(\\d+)", family_replacement: "Firefox Mobile" }, { regex: "(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?)", family_replacement: "Firefox ($1)" }, { regex: "(Firefox)/(\\d+)\\.(\\d+)(a\\d+[a-z]*)", family_replacement: "Firefox Alpha" }, { regex: "(Firefox)/(\\d+)\\.(\\d+)(b\\d+[a-z]*)", family_replacement: "Firefox Beta" }, { regex: "(Firefox)-(?:\\d+\\.\\d+)?/(\\d+)\\.(\\d+)(a\\d+[a-z]*)", family_replacement: "Firefox Alpha" }, { regex: "(Firefox)-(?:\\d+\\.\\d+)?/(\\d+)\\.(\\d+)(b\\d+[a-z]*)", family_replacement: "Firefox Beta" }, { regex: "(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)?", family_replacement: "Firefox ($1)" }, { regex: "(Firefox).*Tablet browser (\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "MicroB", tablet: true }, { regex: "(MozillaDeveloperPreview)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)?" }, /*{ regex: "(Flock)/(\\d+)\\.(\\d+)(b\\d+?)", family_replacement: "Flock", other: true }, { regex: "(RockMelt)/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Rockmelt", other: true }, { regex: "(Navigator)/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Netscape" }, { regex: "(Navigator)/(\\d+)\\.(\\d+)([ab]\\d+)", family_replacement: "Netscape" }, { regex: "(Netscape6)/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Netscape" }, { regex: "(MyIBrow)/(\\d+)\\.(\\d+)", family_replacement: "My Internet Browser", other: true }, { regex: "(Opera Tablet).*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?", family_replacement: "Opera Tablet", tablet: true }, { regex: "(Opera)/.+Opera Mobi.+Version/(\\d+)\\.(\\d+)", family_replacement: "Opera Mobile" }, { regex: "Opera Mobi", family_replacement: "Opera Mobile" }, { regex: "(Opera Mini)/(\\d+)\\.(\\d+)", family_replacement: "Opera Mini" }, { regex: "(Opera Mini)/att/(\\d+)\\.(\\d+)", family_replacement: "Opera Mini" }, { regex: "(Opera)/9.80.*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?", family_replacement: "Opera" }, { regex: "(webOSBrowser)/(\\d+)\\.(\\d+)", family_replacement: "webOS" }, { regex: "(webOS)/(\\d+)\\.(\\d+)", family_replacement: "webOS" }, { regex: "(wOSBrowser).+TouchPad/(\\d+)\\.(\\d+)", family_replacement: "webOS TouchPad" }, { regex: "(luakit)", family_replacement: "LuaKit", other: true }, { regex: "(Lightning)/(\\d+)\\.(\\d+)([ab]?\\d+[a-z]*)", family_replacement: "Lightning", other: true }, { regex: "(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?) \\(Swiftfox\\)", family_replacement: "Swiftfox", other: true }, { regex: "(Firefox)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)? \\(Swiftfox\\)", family_replacement: "Swiftfox", other: true }, { regex: "rekonq", family_replacement: "Rekonq", other: true }, { regex: "(conkeror|Conkeror)/(\\d+)\\.(\\d+)\\.?(\\d+)?", family_replacement: "Conkeror", other: true }, { regex: "(konqueror)/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Konqueror", other: true }, { regex: "(WeTab)-Browser", family_replacement: "WeTab", other: true }, { regex: "(Comodo_Dragon)/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Comodo Dragon", other: true }, { regex: "(YottaaMonitor)", family_replacement: "Yottaa Monitor", other: true }, { regex: "(Kindle)/(\\d+)\\.(\\d+)", family_replacement: "Kindle" }, { regex: "(Symphony) (\\d+).(\\d+)", family_replacement: "Symphony", other: true }, { regex: "Minimo", family_replacement: "Minimo", other: true },*/ { regex: "(CrMo)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Chrome Mobile" }, { regex: "(CriOS)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Chrome Mobile iOS" }, { regex: "(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+) Mobile", family_replacement: "Chrome Mobile" }, { regex: "(chromeframe)/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Chrome Frame" },/* { regex: "(UC Browser)(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "UC Browser", other: true }, { regex: "(SLP Browser)/(\\d+)\\.(\\d+)", family_replacement: "Tizen Browser", other: true }, { regex: "(Epiphany)/(\\d+)\\.(\\d+).(\\d+)", family_replacement: "Epiphany", other: true }, { regex: "(SE 2\\.X) MetaSr (\\d+)\\.(\\d+)", family_replacement: "Sogou Explorer", other: true }, { regex: "(Pingdom.com_bot_version_)(\\d+)\\.(\\d+)", family_replacement: "PingdomBot", other: true }, { regex: "(facebookexternalhit)/(\\d+)\\.(\\d+)", family_replacement: "FacebookBot" }, { regex: "Facebot", family_replacement: "FacebookBot" }, { regex: "(Twitterbot)/(\\d+)\\.(\\d+)", family_replacement: "TwitterBot" },*/ { regex: "(AdobeAIR|Chromium|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Shiira|Sunrise|Chrome|Flock|Netscape|Lunascape|WebPilot|NetFront|Netfront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|ThunderBrowse|Iron|Iris|UP\\.Browser|Bunjaloo|Google Earth|Raven for Mac)/(\\d+)\\.(\\d+)\\.(\\d+)" }, { regex: "(Bolt|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|Chrome|Flock|Netscape|Lunascape|Epiphany|WebPilot|Opera Mini|Opera|NetFront|Netfront|Konqueror|Googlebot|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|iCab|NetNewsWire|Iron|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris)/(\\d+)\\.(\\d+)" }, { regex: "(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\\d+)\\.(\\d+)\\.(\\d+)" }, { regex: "(iCab|Lunascape|Opera|Android|Jasmine|Polaris|BREW) (\\d+)\\.(\\d+)\\.?(\\d+)?" }, /*{ regex: "(Android) Donut", v2_replacement: "2", v1_replacement: "1" }, { regex: "(Android) Eclair", v2_replacement: "1", v1_replacement: "2" }, { regex: "(Android) Froyo", v2_replacement: "2", v1_replacement: "2" }, { regex: "(Android) Gingerbread", v2_replacement: "3", v1_replacement: "2" }, { regex: "(Android) Honeycomb", v1_replacement: "3" }, */{ regex: "(IEMobile)[ /](\\d+)\\.(\\d+)", family_replacement: "IE Mobile" }, { regex: "(MSIE) (\\d+)\\.(\\d+).*XBLWP7", family_replacement: "IE Large Screen" }, { regex: "(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+)" }, { regex: "(Firefox)/(\\d+)\\.(\\d+)(pre|[ab]\\d+[a-z]*)?" },/* { regex: "(Obigo)InternetBrowser", other: true }, { regex: "(Obigo)\\-Browser", other: true }, { regex: "(Obigo|OBIGO)[^\\d]*(\\d+)(?:.(\\d+))?", other: true }, { regex: "(MAXTHON|Maxthon) (\\d+)\\.(\\d+)", family_replacement: "Maxthon", other: true }, { regex: "(Maxthon|MyIE2|Uzbl|Shiira)", v1_replacement: "0", other: true }, { regex: "(PLAYSTATION) (\\d+)", family_replacement: "PlayStation", manufacturer: "Sony" }, { regex: "(PlayStation Portable)[^\\d]+(\\d+).(\\d+)", manufacturer: "Sony" }, { regex: "(BrowseX) \\((\\d+)\\.(\\d+)\\.(\\d+)", other: true }, { regex: "(POLARIS)/(\\d+)\\.(\\d+)", family_replacement: "Polaris", other: true }, { regex: "(Embider)/(\\d+)\\.(\\d+)", family_replacement: "Polaris", other: true }, { regex: "(BonEcho)/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Bon Echo", other: true },*/ { regex: "(iPod).+Version/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Mobile Safari", manufacturer: "Apple" }, { regex: "(iPod).*Version/(\\d+)\\.(\\d+)", family_replacement: "Mobile Safari", manufacturer: "Apple" }, { regex: "(iPod)", family_replacement: "Mobile Safari", manufacturer: "Apple" }, { regex: "(iPhone).*Version/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Mobile Safari", manufacturer: "Apple" }, { regex: "(iPhone).*Version/(\\d+)\\.(\\d+)", family_replacement: "Mobile Safari", manufacturer: "Apple" }, { regex: "(iPhone)", family_replacement: "Mobile Safari", manufacturer: "Apple" }, { regex: "(iPad).*Version/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Mobile Safari", tablet: true, manufacturer: "Apple" }, { regex: "(iPad).*Version/(\\d+)\\.(\\d+)", family_replacement: "Mobile Safari", tablet: true, manufacturer: "Apple" }, { regex: "(iPad)", family_replacement: "Mobile Safari", tablet: true, manufacturer: "Apple" },/* { regex: "(AvantGo) (\\d+).(\\d+)", other: true }, { regex: "(Avant)", v1_replacement: "1", other: true }, { regex: "^(Nokia)", family_replacement: "Nokia Services (WAP) Browser", manufacturer: "Nokia" }, { regex: "(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)\\.(\\d+)", manufacturer: "Nokia" }, { regex: "(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)", manufacturer: "Nokia" }, { regex: "(NokiaBrowser)/(\\d+)\\.(\\d+)", manufacturer: "Nokia" }, { regex: "(BrowserNG)/(\\d+)\\.(\\d+).(\\d+)", family_replacement: "NokiaBrowser", manufacturer: "Nokia" }, { regex: "(Series60)/5\\.0", v2_replacement: "0", v1_replacement: "7", family_replacement: "NokiaBrowser", manufacturer: "Nokia" }, { regex: "(Series60)/(\\d+)\\.(\\d+)", family_replacement: "Nokia OSS Browser", manufacturer: "Nokia" }, { regex: "(S40OviBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Nokia Series 40 Ovi Browser", manufacturer: "Nokia" }, { regex: "(Nokia)[EN]?(\\d+)", manufacturer: "Nokia" }, { regex: "(PlayBook).+RIM Tablet OS (\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Blackberry WebKit", tablet: true, manufacturer: "Nokia" }, { regex: "(Black[bB]erry).+Version/(\\d+)\\.(\\d+)\\.(\\d+)", family_replacement: "Blackberry WebKit", manufacturer: "RIM" }, { regex: "(Black[bB]erry)\\s?(\\d+)", family_replacement: "Blackberry", manufacturer: "RIM" }, { regex: "(OmniWeb)/v(\\d+)\\.(\\d+)", other: true }, { regex: "(Blazer)/(\\d+)\\.(\\d+)", family_replacement: "Palm Blazer", manufacturer: "Palm" }, { regex: "(Pre)/(\\d+)\\.(\\d+)", family_replacement: "Palm Pre", manufacturer: "Palm" }, { regex: "(Links) \\((\\d+)\\.(\\d+)", other: true }, { regex: "(QtWeb) Internet Browser/(\\d+)\\.(\\d+)", other: true },*/ { regex: "(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+))?", other: true, tablet: true }, { regex: "(AppleWebKit)/(\\d+)\\.?(\\d+)?\\+ .* Version/\\d+\\.\\d+.\\d+ Safari/", family_replacement: "WebKit Nightly" }, { regex: "(Version)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?.*Safari/", family_replacement: "Safari" }, { regex: "(Safari)/\\d+" }, /*{ regex: "(OLPC)/Update(\\d+)\\.(\\d+)", other: true }, { regex: "(OLPC)/Update()\\.(\\d+)", v1_replacement: "0", other: true }, { regex: "(SEMC\\-Browser)/(\\d+)\\.(\\d+)", other: true }, { regex: "(Teleca)", family_replacement: "Teleca Browser", other: true },*/ { regex: "Trident(.*)rv.(\\d+)\\.(\\d+)", family_replacement: "IE" }, { regex: "(MSIE) (\\d+)\\.(\\d+)", family_replacement: "IE" } ], os_parsers: [ { regex: "(Android) (\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]+))?" }, { regex: "(Android)\\-(\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]+))?" }, { regex: "(Android) Donut", os_v2_replacement: "2", os_v1_replacement: "1" }, { regex: "(Android) Eclair", os_v2_replacement: "1", os_v1_replacement: "2" }, { regex: "(Android) Froyo", os_v2_replacement: "2", os_v1_replacement: "2" }, { regex: "(Android) Gingerbread", os_v2_replacement: "3", os_v1_replacement: "2" }, { regex: "(Android) Honeycomb", os_v1_replacement: "3" }, { regex: "(Silk-Accelerated=[a-z]{4,5})", os_replacement: "Android" }, { regex: "(Windows Phone 6\\.5)" }, { regex: "(Windows (?:NT 5\\.2|NT 5\\.1))", os_replacement: "Windows XP" }, { regex: "(XBLWP7)", os_replacement: "Windows Phone OS" }, { regex: "(Windows NT 6\\.1)", os_replacement: "Windows 7" }, { regex: "(Windows NT 6\\.0)", os_replacement: "Windows Vista" }, { regex: "(Windows 98|Windows XP|Windows ME|Windows 95|Windows CE|Windows 7|Windows NT 4\\.0|Windows Vista|Windows 2000)" }, { regex: "(Windows NT 6\\.2)", os_replacement: "Windows 8" }, { regex: "(Windows Phone 8)", os_replacement: "Windows Phone 8" }, { regex: "(Windows NT 5\\.0)", os_replacement: "Windows 2000" }, { regex: "(Windows Phone OS) (\\d+)\\.(\\d+)" }, { regex: "(Windows ?Mobile)", os_replacement: "Windows Mobile" }, { regex: "(WinNT4.0)", os_replacement: "Windows NT 4.0" }, { regex: "(Win98)", os_replacement: "Windows 98" }, { regex: "(Tizen)/(\\d+)\\.(\\d+)", other: true }, { regex: "(Mac OS X) (\\d+)[_.](\\d+)(?:[_.](\\d+))?", manufacturer: "Apple" }, { regex: "(?:PPC|Intel) (Mac OS X)", manufacturer: "Apple" }, { regex: "(CPU OS|iPhone OS) (\\d+)_(\\d+)(?:_(\\d+))?", os_replacement: "iOS", manufacturer: "Apple" }, { regex: "(iPhone|iPad|iPod); Opera", os_replacement: "iOS", manufacturer: "Apple" }, { regex: "(iPad); Opera", tablet: true, manufacturer: "Apple" }, { regex: "(iPhone|iPad|iPod).*Mac OS X.*Version/(\\d+)\\.(\\d+)", os_replacement: "iOS", manufacturer: "Apple" }, /*{ regex: "(CrOS) [a-z0-9_]+ (\\d+)\\.(\\d+)(?:\\.(\\d+))?", os_replacement: "Chrome OS" }, { regex: "(Debian)-(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?", other: true }, { regex: "(Linux Mint)(?:/(\\d+))?", other: true }, { regex: "(Mandriva)(?: Linux)?/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?", other: true }, { regex: "(Symbian[Oo][Ss])/(\\d+)\\.(\\d+)", os_replacement: "Symbian OS" }, { regex: "(Symbian/3).+NokiaBrowser/7\\.3", os_replacement: "Symbian^3 Anna" }, { regex: "(Symbian/3).+NokiaBrowser/7\\.4", os_replacement: "Symbian^3 Belle" }, { regex: "(Symbian/3)", os_replacement: "Symbian^3" }, { regex: "(Series 60|SymbOS|S60)", os_replacement: "Symbian OS" }, { regex: "(MeeGo)", other: true }, { regex: "Symbian [Oo][Ss]", os_replacement: "Symbian OS" }, { regex: "(Black[Bb]erry)[0-9a-z]+/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?", os_replacement: "BlackBerry OS", manufacturer: "RIM" }, { regex: "(Black[Bb]erry).+Version/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?", os_replacement: "BlackBerry OS", manufacturer: "RIM" }, { regex: "(RIM Tablet OS) (\\d+)\\.(\\d+)\\.(\\d+)", os_replacement: "BlackBerry Tablet OS", tablet: true, manufacturer: "RIM" }, { regex: "(Play[Bb]ook)", os_replacement: "BlackBerry Tablet OS", tablet: true, manufacturer: "RIM" }, { regex: "(Black[Bb]erry)", os_replacement: "Blackberry OS", manufacturer: "RIM" }, { regex: "(webOS|hpwOS)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?", os_replacement: "webOS" }, { regex: "(SUSE|Fedora|Red Hat|PCLinuxOS)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)", other: true }, { regex: "(SUSE|Fedora|Red Hat|Puppy|PCLinuxOS|CentOS)/(\\d+)\\.(\\d+)\\.(\\d+)", other: true },*/ { regex: "(Ubuntu|Kindle|Bada|Lubuntu|BackTrack|Red Hat|Slackware)/(\\d+)\\.(\\d+)" }, { regex: "(Windows|OpenBSD|FreeBSD|NetBSD|Ubuntu|Kubuntu|Android|Arch Linux|CentOS|WeTab|Slackware)" }, { regex: "(Linux|BSD)", other: true } ], mobile_os_families: [ "Windows Phone 6.5", "Windows CE", "Symbian OS" ], /*device_parsers: [ { regex: "HTC ([A-Z][a-z0-9]+) Build", device_replacement: "HTC $1", manufacturer: "HTC" }, { regex: "HTC ([A-Z][a-z0-9 ]+) \\d+\\.\\d+\\.\\d+\\.\\d+", device_replacement: "HTC $1", manufacturer: "HTC" }, { regex: "HTC_Touch_([A-Za-z0-9]+)", device_replacement: "HTC Touch ($1)", manufacturer: "HTC" }, { regex: "USCCHTC(\\d+)", device_replacement: "HTC $1 (US Cellular)", manufacturer: "HTC" }, { regex: "Sprint APA(9292)", device_replacement: "HTC $1 (Sprint)", manufacturer: "HTC" }, { regex: "HTC ([A-Za-z0-9]+ [A-Z])", device_replacement: "HTC $1", manufacturer: "HTC" }, { regex: "HTC-([A-Za-z0-9]+)", device_replacement: "HTC $1", manufacturer: "HTC" }, { regex: "HTC_([A-Za-z0-9]+)", device_replacement: "HTC $1", manufacturer: "HTC" }, { regex: "HTC ([A-Za-z0-9]+)", device_replacement: "HTC $1", manufacturer: "HTC" }, { regex: "(ADR[A-Za-z0-9]+)", device_replacement: "HTC $1", manufacturer: "HTC" }, { regex: "(HTC)", manufacturer: "HTC" }, { regex: "SonyEricsson([A-Za-z0-9]+)/", device_replacement: "Ericsson $1", other: true, manufacturer: "Sony" }, { regex: "Android[\\- ][\\d]+\\.[\\d]+\\; [A-Za-z]{2}\\-[A-Za-z]{2}\\; WOWMobile (.+) Build" }, { regex: "Android[\\- ][\\d]+\\.[\\d]+\\.[\\d]+; [A-Za-z]{2}\\-[A-Za-z]{2}\\; (.+) Build" }, { regex: "Android[\\- ][\\d]+\\.[\\d]+\\-update1\\; [A-Za-z]{2}\\-[A-Za-z]{2}\\; (.+) Build" }, { regex: "Android[\\- ][\\d]+\\.[\\d]+\\; [A-Za-z]{2}\\-[A-Za-z]{2}\\; (.+) Build" }, { regex: "Android[\\- ][\\d]+\\.[\\d]+\\.[\\d]+; (.+) Build" }, { regex: "NokiaN([0-9]+)", device_replacement: "Nokia N$1", manufacturer: "Nokia" }, { regex: "Nokia([A-Za-z0-9\\v-]+)", device_replacement: "Nokia $1", manufacturer: "Nokia" }, { regex: "NOKIA ([A-Za-z0-9\\-]+)", device_replacement: "Nokia $1", manufacturer: "Nokia" }, { regex: "Nokia ([A-Za-z0-9\\-]+)", device_replacement: "Nokia $1", manufacturer: "Nokia" }, { regex: "Lumia ([A-Za-z0-9\\-]+)", device_replacement: "Lumia $1", manufacturer: "Nokia" }, { regex: "Symbian", device_replacement: "Nokia", manufacturer: "Nokia" }, { regex: "(PlayBook).+RIM Tablet OS", device_replacement: "Blackberry Playbook", tablet: true, manufacturer: "RIM" }, { regex: "(Black[Bb]erry [0-9]+);", manufacturer: "RIM" }, { regex: "Black[Bb]erry([0-9]+)", device_replacement: "BlackBerry $1", manufacturer: "RIM" }, { regex: "(Pre)/(\\d+)\\.(\\d+)", device_replacement: "Palm Pre", manufacturer: "Palm" }, { regex: "(Pixi)/(\\d+)\\.(\\d+)", device_replacement: "Palm Pixi", manufacturer: "Palm" }, { regex: "(Touchpad)/(\\d+)\\.(\\d+)", device_replacement: "HP Touchpad", manufacturer: "HP" }, { regex: "HPiPAQ([A-Za-z0-9]+)/(\\d+).(\\d+)", device_replacement: "HP iPAQ $1", manufacturer: "HP" }, { regex: "Palm([A-Za-z0-9]+)", device_replacement: "Palm $1", manufacturer: "Palm" }, { regex: "Treo([A-Za-z0-9]+)", device_replacement: "Palm Treo $1", manufacturer: "Palm" }, { regex: "webOS.*(P160UNA)/(\\d+).(\\d+)", device_replacement: "HP Veer", manufacturer: "HP" }, { regex: "(Kindle Fire)", manufacturer: "Amazon" }, { regex: "(Kindle)", manufacturer: "Amazon" }, { regex: "(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+))?", device_replacement: "Kindle Fire", tablet: true, manufacturer: "Amazon" }, { regex: "(iPad) Simulator;", manufacturer: "Apple" }, { regex: "(iPad);", manufacturer: "Apple" }, { regex: "(iPod);", manufacturer: "Apple" }, { regex: "(iPhone) Simulator;", manufacturer: "Apple" }, { regex: "(iPhone);", manufacturer: "Apple" }, { regex: "Nexus\\ ([A-Za-z0-9\\-]+)", device_replacement: "Nexus $1" }, { regex: "acer_([A-Za-z0-9]+)_", device_replacement: "Acer $1", manufacturer: "Acer" }, { regex: "acer_([A-Za-z0-9]+)_", device_replacement: "Acer $1", manufacturer: "Acer" }, { regex: "Amoi\\-([A-Za-z0-9]+)", device_replacement: "Amoi $1", other: true, manufacturer: "Amoi" }, { regex: "AMOI\\-([A-Za-z0-9]+)", device_replacement: "Amoi $1", other: true, manufacturer: "Amoi" }, { regex: "Asus\\-([A-Za-z0-9]+)", device_replacement: "Asus $1", manufacturer: "Asus" }, { regex: "ASUS\\-([A-Za-z0-9]+)", device_replacement: "Asus $1", manufacturer: "Asus" }, { regex: "BIRD\\-([A-Za-z0-9]+)", device_replacement: "Bird $1", other: true }, { regex: "BIRD\\.([A-Za-z0-9]+)", device_replacement: "Bird $1", other: true }, { regex: "BIRD ([A-Za-z0-9]+)", device_replacement: "Bird $1", other: true }, { regex: "Dell ([A-Za-z0-9]+)", device_replacement: "Dell $1", manufacturer: "Dell" }, { regex: "DoCoMo/2\\.0 ([A-Za-z0-9]+)", device_replacement: "DoCoMo $1", other: true }, { regex: "([A-Za-z0-9]+)\\_W\\;FOMA", device_replacement: "DoCoMo $1", other: true }, { regex: "([A-Za-z0-9]+)\\;FOMA", device_replacement: "DoCoMo $1", other: true }, { regex: "vodafone([A-Za-z0-9]+)", device_replacement: "Huawei Vodafone $1", other: true }, { regex: "i\\-mate ([A-Za-z0-9]+)", device_replacement: "i-mate $1", other: true }, { regex: "Kyocera\\-([A-Za-z0-9]+)", device_replacement: "Kyocera $1", other: true }, { regex: "KWC\\-([A-Za-z0-9]+)", device_replacement: "Kyocera $1", other: true }, { regex: "Lenovo\\-([A-Za-z0-9]+)", device_replacement: "Lenovo $1", manufacturer: "Lenovo" }, { regex: "Lenovo\\_([A-Za-z0-9]+)", device_replacement: "Lenovo $1", manufacturer: "Levovo" }, { regex: "LG/([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LG-LG([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LGE-LG([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LGE VX([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LG ([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LGE LG\\-AX([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LG\\-([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LGE\\-([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "LG([A-Za-z0-9]+)", device_replacement: "LG $1", manufacturer: "LG" }, { regex: "(KIN)\\.One (\\d+)\\.(\\d+)", device_replacement: "Microsoft $1" }, { regex: "(KIN)\\.Two (\\d+)\\.(\\d+)", device_replacement: "Microsoft $1" }, { regex: "(Motorola)\\-([A-Za-z0-9]+)", manufacturer: "Motorola" }, { regex: "MOTO\\-([A-Za-z0-9]+)", device_replacement: "Motorola $1", manufacturer: "Motorola" }, { regex: "MOT\\-([A-Za-z0-9]+)", device_replacement: "Motorola $1", manufacturer: "Motorola" }, { regex: "Philips([A-Za-z0-9]+)", device_replacement: "Philips $1", manufacturer: "Philips" }, { regex: "Philips ([A-Za-z0-9]+)", device_replacement: "Philips $1", manufacturer: "Philips" }, { regex: "SAMSUNG-([A-Za-z0-9\\-]+)", device_replacement: "Samsung $1", manufacturer: "Samsung" }, { regex: "SAMSUNG\\; ([A-Za-z0-9\\-]+)", device_replacement: "Samsung $1", manufacturer: "Samsung" }, { regex: "Softbank/1\\.0/([A-Za-z0-9]+)", device_replacement: "Softbank $1", other: true }, { regex: "Softbank/2\\.0/([A-Za-z0-9]+)", device_replacement: "Softbank $1", other: true }, { regex: "(hiptop|avantgo|plucker|xiino|blazer|elaine|up.browser|up.link|mmp|smartphone|midp|wap|vodafone|o2|pocket|mobile|pda)", device_replacement: "Generic Smartphone" }, { regex: "^(1207|3gso|4thp|501i|502i|503i|504i|505i|506i|6310|6590|770s|802s|a wa|acer|acs\\-|airn|alav|asus|attw|au\\-m|aur |aus |abac|acoo|aiko|alco|alca|amoi|anex|anny|anyw|aptu|arch|argo|bell|bird|bw\\-n|bw\\-u|beck|benq|bilb|blac|c55/|cdm\\-|chtm|capi|comp|cond|craw|dall|dbte|dc\\-s|dica|ds\\-d|ds12|dait|devi|dmob|doco|dopo|el49|erk0|esl8|ez40|ez60|ez70|ezos|ezze|elai|emul|eric|ezwa|fake|fly\\-|fly\\_|g\\-mo|g1 u|g560|gf\\-5|grun|gene|go.w|good|grad|hcit|hd\\-m|hd\\-p|hd\\-t|hei\\-|hp i|hpip|hs\\-c|htc |htc\\-|htca|htcg)", device_replacement: "Generic Feature Phone" }, { regex: "^(htcp|htcs|htct|htc\\_|haie|hita|huaw|hutc|i\\-20|i\\-go|i\\-ma|i230|iac|iac\\-|iac/|ig01|im1k|inno|iris|jata|java|kddi|kgt|kgt/|kpt |kwc\\-|klon|lexi|lg g|lg\\-a|lg\\-b|lg\\-c|lg\\-d|lg\\-f|lg\\-g|lg\\-k|lg\\-l|lg\\-m|lg\\-o|lg\\-p|lg\\-s|lg\\-t|lg\\-u|lg\\-w|lg/k|lg/l|lg/u|lg50|lg54|lge\\-|lge/|lynx|leno|m1\\-w|m3ga|m50/|maui|mc01|mc21|mcca|medi|meri|mio8|mioa|mo01|mo02|mode|modo|mot |mot\\-|mt50|mtp1|mtv |mate|maxo|merc|mits|mobi|motv|mozz|n100|n101|n102|n202|n203|n300|n302|n500|n502|n505|n700|n701|n710|nec\\-|nem\\-|newg|neon)", device_replacement: "Generic Feature Phone" }, { regex: "^(netf|noki|nzph|o2 x|o2\\-x|opwv|owg1|opti|oran|ot\\-s|p800|pand|pg\\-1|pg\\-2|pg\\-3|pg\\-6|pg\\-8|pg\\-c|pg13|phil|pn\\-2|pt\\-g|palm|pana|pire|pock|pose|psio|qa\\-a|qc\\-2|qc\\-3|qc\\-5|qc\\-7|qc07|qc12|qc21|qc32|qc60|qci\\-|qwap|qtek|r380|r600|raks|rim9|rove|s55/|sage|sams|sc01|sch\\-|scp\\-|sdk/|se47|sec\\-|sec0|sec1|semc|sgh\\-|shar|sie\\-|sk\\-0|sl45|slid|smb3|smt5|sp01|sph\\-|spv |spv\\-|sy01|samm|sany|sava|scoo|send|siem|smar|smit|soft|sony|t\\-mo|t218|t250|t600|t610|t618|tcl\\-|tdg\\-|telm|tim\\-|ts70|tsm\\-|tsm3|tsm5|tx\\-9|tagt)", device_replacement: "Generic Feature Phone" }, { regex: "^(talk|teli|topl|tosh|up.b|upg1|utst|v400|v750|veri|vk\\-v|vk40|vk50|vk52|vk53|vm40|vx98|virg|vite|voda|vulc|w3c |w3c\\-|wapj|wapp|wapu|wapm|wig |wapi|wapr|wapv|wapy|wapa|waps|wapt|winc|winw|wonu|x700|xda2|xdag|yas\\-|your|zte\\-|zeto|aste|audi|avan|blaz|brew|brvw|bumb|ccwa|cell|cldc|cmd\\-|dang|eml2|fetc|hipt|http|ibro|idea|ikom|ipaq|jbro|jemu|jigs|keji|kyoc|kyok|libw|m\\-cr|midp|mmef|moto|mwbp|mywa|newt|nok6|o2im|pant|pdxg|play|pluc|port|prox|rozo|sama|seri|smal|symb|treo|upsi|vx52|vx53|vx60|vx61|vx70|vx80|vx81|vx83|vx85|wap\\-|webc|whit|wmlb|xda\\-|xda\\_)", device_replacement: "Generic Feature Phone" }, { regex: "(bot|borg|google(^tv)|yahoo|slurp|msnbot|msrbot|openbot|archiver|netresearch|lycos|scooter|altavista|teoma|gigabot|baiduspider|blitzbot|oegp|charlotte|furlbot|http%20client|polybot|htdig|ichiro|mogimogi|larbin|pompos|scrubby|searchsight|seekbot|semanticdiscovery|silk|snappy|speedy|spider|voila|vortex|voyager|zao|zeal|fast\\-webcrawler|converacrawler|dataparksearch|findlinks)", device_replacement: "Spider" } ],*/ mobile_browser_families: [ "Firefox Mobile", "Opera Mobile", "Opera Mini", "Mobile Safari", "webOS", "IE Mobile", "Playstation Portable", "Nokia", "Blackberry", "Palm", "Silk", "Android", "Maemo", "Obigo", "Netfront", "AvantGo", "Teleca", "SEMC-Browser", "Bolt", "Iris", "UP.Browser", "Symphony", "Minimo", "Bunjaloo", "Jasmine", "Dolfin", "Polaris", "BREW", "Chrome Mobile", "Chrome Mobile iOS", "UC Browser", "Tizen Browser" ] }; // Parsers _this.parsers = [ /*"device_parsers",*/ "browser_parsers", "os_parsers", "mobile_os_families", "mobile_browser_families" ]; // Types _this.types = [ "browser", "os"/*, "device"*/ ]; // Regular Expressions _this.regexes = regexes || function() { var results = {}; _this.parsers.map(function(parser) { results[parser] = []; }); return results; }(); // Families _this.families = function() { var results = {}; _this.types.map(function(type) { results[type] = []; }); return results; }(); // Utility Variables var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype, nativeForEach = ArrayProto.forEach, nativeIndexOf = ArrayProto.indexOf; // Find Utility var find = function(ua, obj) { var ret = {}; for (var i = 0; i < obj.length; i++) { ret = obj[i](ua); if (ret) { break; } } return ret; }; // Remove Utility var remove = function(arr, props) { each(arr, function(obj) { each(props, function(prop) { delete obj[prop]; }); }); }; // Contains Utility var contains = function(obj, target) { var found = false; if (!obj) return found; if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; found = any(obj, function(value) { return value === target; }); return found; }; // Each Utility var forEach, each; each = forEach = function(obj, iterator, context) { if (!obj) return; if (nativeForEach && obj.forEach === nativeForEach) { obj.forEach(iterator, context); } else if (obj.length === +obj.length) { for (var i = 0, l = obj.length; i < l; i++) { iterator.call(context, obj[i], i, obj); } } else { for (var key in obj) { if (_.has(obj, key)) { iterator.call(context, obj[key], key, obj); } } } }; // Extend Utiltiy var extend = function(obj) { each(slice.call(arguments, 1), function(source) { for (var prop in source) { obj[prop] = source[prop]; } }); return obj; }; // Check String Utility var check = function(str) { return !!(str && typeof str != "undefined" && !str); }; // To Version String Utility var toVersionString = function(obj) { var output = ""; obj = obj || {}; if (check(obj)) { if (check(obj.major)) { output += obj.major; if (check(obj.minor)) { output += "." + obj.minor; if (check(obj.patch)) { output += "." + obj.patch; } } } } return output; }; // To String Utility var toString = function(obj) { obj = obj || {}; var suffix = toVersionString(obj); if (suffix) suffix = " " + suffix; return obj && check(obj.family) ? obj.family + suffix : ""; }; // Parse User-Agent String _this.parse = function(ua) { // Parsers Utility var parsers = function(type) { return _this.regexes[type + "_parsers"].map(function(obj) { var regexp = new RegExp(obj.regex), rep = obj[(type === "browser" ? "family" : type) + "_replacement"], major_rep = obj.major_version_replacement; function parser(ua) { var m = ua.match(regexp); if (!m) return null; var ret = {}; ret.family = (rep ? rep.replace("$1", m[1]) : m[1]) || "other"; /*ret.major = parseInt(major_rep ? major_rep : m[2]) || null; ret.minor = m[3] ? parseInt(m[3]) : null; ret.patch = m[4] ? parseInt(m[4]) : null;*/ ret.tablet = obj.tablet; //ret.man = obj.manufacturer || null; return ret; } return parser; }); }; // User Agent var UserAgent = function() {}; // Browsers Parsed var browser_parsers = parsers("browser"); // Operating Systems Parsed var os_parsers = parsers("os"); // Devices Parsed //var device_parsers = parsers("device"); // Set Agent var a = new UserAgent(); // Remember the original user agent string a.source = ua; // Set Browser a.browser = find(ua, browser_parsers); if (/*check(*/a.browser/*)*/) { a.browser.name = toString(a.browser); a.browser.version = toVersionString(a.browser); } else { a.browser = {}; } // Set OS a.os = find(ua, os_parsers); if (/*check(*/a.os/*)*/) { a.os.name = toString(a.os); a.os.version = toVersionString(a.os); } else { a.os = {}; } // Set Device /*a.device = find(ua, device_parsers); if (check(a.device)) { a.device.name = toString(a.device); a.device.version = toVersionString(a.device); } else { a.device = { tablet: false, family: "Other" }; }*/ // Determine Device Type var mobile_agents = {}; var mobile_browser_families = _this.regexes.mobile_browser_families.map(function(str) { mobile_agents[str] = true; }); var mobile_os_families = _this.regexes.mobile_os_families.map(function(str) { mobile_agents[str] = true; }); // Is Spider /*if (a.browser.family === "Spider") { a.device.type = "Spider"; } else if (a.browser.tablet || a.os.tablet || a.device.tablet) { a.device.type = "Tablet"; } else if (mobile_agents.hasOwnProperty(a.browser.family)) { a.device.type = "Mobile"; } else { a.device.type = "Desktop"; }*/ // Determine Device Manufacturer //a.device.manufacturer = a.browser.man || a.os.man || a.device.man || null; // Cleanup Objects remove([ a.browser, a.os/*, a.device*/ ], [ "tablet", "man" ]); // Return Agent return a; }; // Return context return _this; }; // Export the Underscore object for **Node.js** and **"CommonJS"**, // backwards-compatibility for the old `require()` API. If we're not // CommonJS, add `_` to the global object via a string identifier // the Closure Compiler "advanced" mode. Registration as an AMD // via define() happens at the end of this file /*if (typeof exports !== "undefined") { if (typeof module !== "undefined" && module.exports) { exports = module.exports = detect; } exports.detect = detect; } else { root["detect"] = detect; } // AMD define happens at the end for compatibility with AMD // that don't enforce next-turn semantics on modules if (typeof define === "function" && define.amd) { define(function(require) { return detect; }); }*/ // Assign to namespace namespace('springroll').Detect = detect(); }()); /** * @namespace springroll.keyboard */ (function() { var parsed = include('springroll.Detect').parse(navigator.userAgent); var browser, os; if(parsed.browser.family.indexOf("Safari") >= 0) { browser = "Safari"; } else if(parsed.browser.family.indexOf("Firefox") >= 0) { browser = "Firefox"; } else if(parsed.browser.family.indexOf("IE") >= 0) { browser = "IE"; } else//Assume browser with the qualities of Chrome { browser = "Chrome"; } if(parsed.os.name.indexOf("Windows") >= 0) { os = "Windows"; } else if(parsed.os.name.indexOf("Mac") >= 0) { os = "Mac"; } else if(parsed.os.name.indexOf("iOS") >= 0) { //iOS would probably report the same as OSX, right? os = "Mac"; //all iOS browsers use a WebView that is similar to iOS Safari browser = "Safari"; } else//Assume some form of Linux, including Android { os = "Linux"; } /** * USLocale is the standard keyboard layout for US computers. All standard keys are included. * Keys to note: * * * 'OS' represents both the Windows key and the 'command' key, although 'command' * is also available when the client is running MacOS. * * * 'meta' represents 'ctrl' on Windows and Linux, and 'command' on OSX. Use this when creating * keyboard shortcuts in web apps. * * @class USLocale * @static */ var USLocale = { /** * Cancel key * @property {int} cancel * @readOnly */ "cancel":3, /** * backspace key * @property {int} backspace * @readOnly */ "backspace":8, /** * tab key * @property {int} tab * @readOnly */ "tab":9, /** * enter key * @property {int} enter * @readOnly */ "enter":13, /** * shift key * @property {int} shift * @readOnly */ "shift":16, /** * ctrl key * @property {int} ctrl * @readOnly */ "ctrl":17, /** * alt key * @property {int} alt * @readOnly */ "alt":18, /** * Pause or break key * @property {int} pause/break * @readOnly */ "pause/break": os == "Mac" && browser != "Firefox" ? 126 : 19, /** * CAPS lock key * @property {int} caps_lock * @readOnly */ "caps_lock":20, /** * Escape key * @property {int} esc * @readOnly */ "esc":27, /** * Spacebar key * @property {int} spacebar * @readOnly */ "spacebar":32, /** * Page Up key * @property {int} pageup * @readOnly */ "pageup":33, /** * Page Down key * @property {int} pagedown * @readOnly */ "pagedown":34, /** * end key * @property {int} end * @readOnly */ "end":35, /** * home key * @property {int} home * @readOnly */ "home":36, /** * Toggle left key * @property {int} arrow_left * @readOnly */ "arrow_left":37, /** * Toggle up key * @property {int} arrow_up * @readOnly */ "arrow_up":38, /** * Toggle right key * @property {int} arrow_right * @readOnly */ "arrow_right":39, /** * Toggle down key * @property {int} arrow_down * @readOnly */ "arrow_down":40, /** * Print screen key * @property {int} print_screen * @readOnly */ //Note: on windows, only keyUp is fired for print_screen "print_screen": os == "Linux" ? 42 : (os == "Mac" && browser != "Firefox" ? 124 : 44), /** * insert key * @property {int} insert * @readOnly */ "insert":45, /** * delete key * @property {int} delete * @readOnly */ "delete":46, /** * Scroll lock key * @property {int} scroll_lock * @readOnly */ "scroll_lock": os == "Mac" && browser != "Firefox" ? 125 : 145, /** * The OS button, either Windows or Apple Button * @property {int} OS * @readOnly */ //command/windows - may be different for left/right, depending on browser //also might be 93, depending on OS "OS": browser == "Firefox" ? //Firefox uses the same keycode for left & right (os == "Mac" ? 224 : 91) : //other browsers use different codes for left/right, although webkit uses a different //code on OSX than Windows/Linux [ 91, os == "Mac" ? 93 : 92 ], /** * on windows keyboard, located where the right 'windows' key might be * not fired by Safari/Chrome on OSX (but is on FF?) * @property {int} context_menu * @readOnly */ "context_menu": os == "Mac" ? 0 : 93, /** * Semi-colon * @property {int} ; * @readOnly */ ";":186, /** * Equals * @property {int} = * @readOnly */ "=":187, /** * Comma * @property {int} , * @readOnly */ ",":188, /** * Hyphen * @property {int} - * @readOnly */ "-":189, /** * Period * @property {int} . * @readOnly */ ".":190, /** * Backslash * @property {int} / * @readOnly */ "/":191, /** * Tick mark * @property {int} ` * @readOnly */ "`":192, /** * Forward slash * @property {int} \ * @readOnly */ "\\":220, /** * Left bracket * @property {int} [ * @readOnly */ "[":219, /** * Right bracket * @property {int} ] * @readOnly */ "]":221, /** * An apostrophe * @property {int} ' * @readOnly */ "'":222, //number pad keys /** * Number pad times * @property {int} num_* * @readOnly */ "num_*":106, /** * Number pad plus * @property {int} num_+ * @readOnly */ "num_+":107, /** * Number pad enter * @property {int} num_enter * @readOnly */ "num_enter":108, /** * Number pad minus * @property {int} num_- * @readOnly */ "num_-":109, /** * Number pad decimal * @property {int} num_. * @readOnly */ "num_.":110, /** * Number pad divide * @property {int} num_/ * @readOnly */ "num_/":111, /** * Number pad lock, 'num lock' is 'clear' on Mac keyboards * @property {int} num_lock * @readOnly */ "num_lock": os == "Mac" ? 12 : 144, /** * Number pad clear * @property {int} clear * @readOnly */ "clear": os == "Mac" ? 12 : 144 }; var i; /** * Alpha letter A * @property {int} A * @readOnly */ /** * Alpha letter B * @property {int} B * @readOnly */ /** * Alpha letter C * @property {int} C * @readOnly */ /** * Alpha letter D * @property {int} D * @readOnly */ /** * Alpha letter E * @property {int} E * @readOnly */ /** * Alpha letter F * @property {int} F * @readOnly */ /** * Alpha letter G * @property {int} G * @readOnly */ /** * Alpha letter H * @property {int} H * @readOnly */ /** * Alpha letter I * @property {int} I * @readOnly */ /** * Alpha letter J * @property {int} J * @readOnly */ /** * Alpha letter K * @property {int} K * @readOnly */ /** * Alpha letter L * @property {int} L * @readOnly */ /** * Alpha letter M * @property {int} M * @readOnly */ /** * Alpha letter N * @property {int} N * @readOnly */ /** * Alpha letter O * @property {int} O * @readOnly */ /** * Alpha letter P * @property {int} P * @readOnly */ /** * Alpha letter Q * @property {int} Q * @readOnly */ /** * Alpha letter R * @property {int} R * @readOnly */ /** * Alpha letter S * @property {int} S * @readOnly */ /** * Alpha letter T * @property {int} T * @readOnly */ /** * Alpha letter U * @property {int} U * @readOnly */ /** * Alpha letter V * @property {int} V * @readOnly */ /** * Alpha letter W * @property {int} W * @readOnly */ /** * Alpha letter X * @property {int} X * @readOnly */ /** * Alpha letter Y * @property {int} Y * @readOnly */ /** * Alpha letter Z * @property {int} Z * @readOnly */ //A-Z for(i = 65; i <= 90; ++i) { //use the capital letter as the value for the keyCode USLocale[String.fromCharCode(i + 32)] = i; } //0-9 for(i = 48; i <= 57; ++i) { USLocale[String.fromCharCode(i)] = i; } //0-9, number pad: num_0-num_9 /** * Number pad 1 * @property {int} num_1 * @readOnly */ /** * Number pad 2 * @property {int} num_2 * @readOnly */ /** * Number pad 3 * @property {int} num_3 * @readOnly */ /** * Number pad 4 * @property {int} num_4 * @readOnly */ /** * Number pad 5 * @property {int} num_5 * @readOnly */ /** * Number pad 6 * @property {int} num_6 * @readOnly */ /** * Number pad 7 * @property {int} num_7 * @readOnly */ /** * Number pad 8 * @property {int} num_8 * @readOnly */ /** * Number pad 9 * @property {int} num_9 * @readOnly */ /** * Number pad 0 * @property {int} num_0 * @readOnly */ for(i = 96; i <= 105; ++i) { USLocale["num_" + (i-96)] = i; } /** * Function key F1 * @property {int} F1 * @readOnly */ /** * Function key F2 * @property {int} F2 * @readOnly */ /** * Function key F3 * @property {int} F3 * @readOnly */ /** * Function key F4 * @property {int} F4 * @readOnly */ /** * Function key F5 * @property {int} F5 * @readOnly */ /** * Function key F6 * @property {int} F6 * @readOnly */ /** * Function key F7 * @property {int} F7 * @readOnly */ /** * Function key F8 * @property {int} F8 * @readOnly */ /** * Function key F9 * @property {int} F9 * @readOnly */ /** * Function key F10 * @property {int} F10 * @readOnly */ /** * Function key F11 * @property {int} F11 * @readOnly */ /** * Function key F12 * @property {int} F12 * @readOnly */ for(i = 112; i <= 123; ++i) { USLocale["F" + (i - 111)] = i; } //OS specfic 'meta' key - pick ctrl or command if(os == "Mac") { //also create 'command' for people that only want command /** * The command (Mac OSX) or ctrl (Windows) key * @property {int} meta * @readOnly */ USLocale.meta = USLocale.command = USLocale.OS; } else { USLocale.meta = USLocale.ctrl; USLocale.command = 0; } // Assign to namespace namespace('springroll.keyboard').USLocale = USLocale; }()); /** * @namespace springroll */ (function() { var Application = include('springroll.Application'), Debug = include('springroll.Debug', false); /** * A class for easier keyboard controls, from simple key events to complex key combinations. * * @class Keyboard * @constructor * @param {DOMElement} target The DOM element to listen to key events on. * @param {Object} locale The keyboard locale, like springroll.USLocale, which defines keys to * keep track of. */ var Keyboard = function(target, locale) { //bind callbacks/listeners this._onFocusLost = this._onFocusLost.bind(this); this._onPaused = this._onPaused.bind(this); this._onResumed = this._onResumed.bind(this); this._update = this._update.bind(this); this._keyDown = this._keyDown.bind(this); this._keyUp = this._keyUp.bind(this); /** * The DOM element that the key event listeners are attached to. * @property {DOMElement} target * @private * @readOnly */ this.target = target; target.addEventListener('onblur', this._onFocusLost); /** * All keys that are listened to, arranged by key code. * @property {Object} _keysByCode * @private */ var _keysByCode = this._keysByCode = {}; /** * All keys that are listened to, arranged by key name. * @property {Object} _keysByName * @private */ var _keysByName = this._keysByName = {}; /** * All key combinations that have been registered * @property {Array} _activeCombos * @private */ this._activeCombos = []; /** * Keys that have been updated since the most recent frame update. This array gets wiped * each _update call. * @property {Array} _updatedKeys * @private */ this._updatedKeys = []; /** * The callback used when key de