├── .gitignore ├── .jsbeautifyrc ├── .jshintrc ├── Gruntfile.js ├── README.md ├── doc ├── api.js ├── assets │ ├── css │ │ ├── external-small.png │ │ ├── logo.png │ │ └── main.css │ ├── favicon.png │ ├── img │ │ └── spinner.gif │ ├── index.html │ ├── js │ │ ├── api-filter.js │ │ ├── api-list.js │ │ ├── api-search.js │ │ ├── apidocs.js │ │ └── yui-prettify.js │ └── vendor │ │ └── prettify │ │ ├── CHANGES.html │ │ ├── COPYING │ │ ├── README.html │ │ ├── prettify-min.css │ │ └── prettify-min.js ├── classes │ ├── AnimFrameUpdateStrategy.html │ ├── FirefoxPlatform.html │ ├── Gamepad.html │ ├── ManualUpdateStrategy.html │ ├── WebKitPlatform.html │ └── index.html ├── data.json ├── files │ ├── gamepad.js.html │ └── index.html ├── index.html └── modules │ ├── Gamepad.html │ └── index.html ├── gamepad.js ├── gamepad.min.js ├── index.html ├── package.json └── test ├── ButtonGetterTest.js ├── FirefoxPlatformTest.js ├── GamepadMappingTest.js ├── GamepadSimulator.js ├── GamepadTypeTest.js ├── GamepadUser.js ├── InterfaceTest.js ├── PlatformSimulator.js ├── PlatformTest.js ├── ResolveMappingTest.js ├── WebKitPlatformTest.js └── buster.js /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | -------------------------------------------------------------------------------- /.jsbeautifyrc: -------------------------------------------------------------------------------- 1 | { 2 | "indent_size": 1, 3 | "indent_char": "\t", 4 | "indent_level": 0, 5 | "indent_with_tabs": true, 6 | "preserve_newlines": true, 7 | "max_preserve_newlines": 4, 8 | "space_in_paren": false, 9 | "jslint_happy": false, 10 | "brace_style": "collapse", 11 | "keep_array_indentation": false, 12 | "keep_function_indentation": false, 13 | "eval_code": false, 14 | "unescape_strings": false, 15 | "break_chained_methods": false, 16 | "wrap_line_length": 100 17 | } -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "evil": true, 3 | "forin": true, 4 | "jquery": true, 5 | "browser": true, 6 | "devel": true, 7 | "bitwise": true, 8 | "camelcase": true, 9 | "curly": true, 10 | "eqeqeq": false, 11 | "forin": false, 12 | "immed": true, 13 | "latedef": true, 14 | "newcap": true, 15 | "noarg": true, 16 | "noempty": true, 17 | "nonew": true, 18 | "plusplus": false, 19 | "quotmark": "single", 20 | "undef": true, 21 | "unused": true, 22 | "strict": true, 23 | "trailing": true, 24 | "maxparams": 0, 25 | "maxlen": 120, 26 | "laxbreak": true, 27 | "loopfunc": true, 28 | "predef": ["require", "define", "module"] 29 | } -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 'use strict'; 3 | 4 | grunt.initConfig({ 5 | pkg: grunt.file.readJSON('package.json'), 6 | 7 | jsbeautifier: { 8 | files: ['Gruntfile.js', 'gamepad.js', 'test/**/*.js'], 9 | options: grunt.file.readJSON('.jsbeautifyrc') 10 | }, 11 | 12 | // Run JSHint on all sources 13 | jshint: { 14 | options: { 15 | jshintrc: './.jshintrc' 16 | }, 17 | all: ['Gruntfile.js', 'gamepad.js', 'test/**/*.js'] 18 | }, 19 | 20 | // Run js-uglify on the actual library code 21 | uglify: { 22 | lib: { 23 | files: { 24 | 'gamepad.min.js': ['gamepad.js'] 25 | }, 26 | options: { 27 | compress: { 28 | sequences: false 29 | } 30 | } 31 | } 32 | }, 33 | 34 | // Run tests using buster 35 | buster: { 36 | libRaw: { 37 | test: { 38 | reporter: 'specification', 39 | 'config-group': 'Library tests raw' 40 | } 41 | } 42 | }, 43 | 44 | // Create YUI documentation 45 | yuidoc: { 46 | lib: { 47 | name: '<%= pkg.name %>', 48 | description: '<%= pkg.description %>', 49 | version: '<%= pkg.version %>', 50 | url: '<%= pkg.homepage %>', 51 | options: { 52 | paths: ['.'], 53 | exclude: '*.min.js', 54 | outdir: 'doc/' 55 | } 56 | } 57 | } 58 | }); 59 | 60 | grunt.loadNpmTasks('grunt-buster'); 61 | grunt.loadNpmTasks('grunt-contrib-jshint'); 62 | grunt.loadNpmTasks('grunt-contrib-uglify'); 63 | grunt.loadNpmTasks('grunt-contrib-yuidoc'); 64 | grunt.loadNpmTasks('grunt-jsbeautifier'); 65 | 66 | grunt.registerTask('format', ['jsbeautifier', 'jshint']); 67 | grunt.registerTask('compile', ['uglify']); 68 | grunt.registerTask('document', ['yuidoc']); 69 | grunt.registerTask('test', ['buster']); 70 | grunt.registerTask('default', ['format', 'compile', 'test', 'document']); 71 | }; 72 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | HTML5-JavaScript-Gamepad-Controller-Library 2 | =========================================== 3 | 4 | **Library for accessing gamepads in modern browsers.** 5 | 6 | * Works with modern browsers and has mappings to many controllers. 7 | * Very easy to add mappings to new controllers. 8 | * Lightweight. 9 | * Includes settings for deadzone and maximization. 10 | * Simple event-based system. 11 | * Includes state change events. 12 | * Minimal working example provided. 13 | * Does not depend on any other library. 14 | * Includes minimized version. 15 | 16 | 17 | How to use 18 | ---------- 19 | * Include the library. 20 | ```javascript 21 | 22 | ``` 23 | 24 | * Create an instance of the Gamepad class. 25 | ```javascript 26 | var gamepad = new Gamepad(); 27 | ``` 28 | 29 | * Bind to the events 30 | ```javascript 31 | gamepad.bind(Gamepad.Event.CONNECTED, function(device) { 32 | // a new gamepad connected 33 | }); 34 | 35 | gamepad.bind(Gamepad.Event.DISCONNECTED, function(device) { 36 | // gamepad disconnected 37 | }); 38 | 39 | gamepad.bind(Gamepad.Event.UNSUPPORTED, function(device) { 40 | // an unsupported gamepad connected (add new mapping) 41 | }); 42 | 43 | gamepad.bind(Gamepad.Event.BUTTON_DOWN, function(e) { 44 | // e.control of gamepad e.gamepad pressed down 45 | }); 46 | 47 | gamepad.bind(Gamepad.Event.BUTTON_UP, function(e) { 48 | // e.control of gamepad e.gamepad released 49 | }); 50 | 51 | gamepad.bind(Gamepad.Event.AXIS_CHANGED, function(e) { 52 | // e.axis changed to value e.value for gamepad e.gamepad 53 | }); 54 | 55 | gamepad.bind(Gamepad.Event.TICK, function(gamepads) { 56 | // gamepads were updated (around 60 times a second) 57 | }); 58 | ``` 59 | 60 | * Initilize the gamepads 61 | ```javascript 62 | if (!gamepad.init()) { 63 | // Your browser does not support gamepads, get the latest Google Chrome or Firefox 64 | } 65 | ``` 66 | 67 | * Try the working example in index.html for more tips 68 | 69 | Development 70 | ---------- 71 | 72 | The library is built using [grunt](http://gruntjs.com/) and [node.js](http://www.nodejs.org/). 73 | Have them installed according to their installation guidelines. 74 | 75 | The build sequence consists of the following tasks: 76 | * 'format', executing js-beautify (according to .jsbeautifyrc) and jshint (according to .jshintrc) 77 | * 'compile', executing UglifyJS2 78 | * 'document', using [yuidoc](http://yui.github.io/yuidoc/) 79 | 80 | The default grunt task executes them in the given order. 81 | -------------------------------------------------------------------------------- /doc/api.js: -------------------------------------------------------------------------------- 1 | YUI.add("yuidoc-meta", function(Y) { 2 | Y.YUIDoc = { meta: { 3 | "classes": [ 4 | "AnimFrameUpdateStrategy", 5 | "FirefoxPlatform", 6 | "Gamepad", 7 | "ManualUpdateStrategy", 8 | "WebKitPlatform" 9 | ], 10 | "modules": [ 11 | "Gamepad" 12 | ], 13 | "allModules": [ 14 | { 15 | "displayName": "Gamepad", 16 | "name": "Gamepad", 17 | "description": "This strategy uses a timer function to call an update function.\nThe timer (re)start function can be provided or the strategy reverts to\none of the window.*requestAnimationFrame variants." 18 | } 19 | ] 20 | } }; 21 | }); -------------------------------------------------------------------------------- /doc/assets/css/external-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kallaspriit/HTML5-JavaScript-Gamepad-Controller-Library/c38f53b8c23825e0bb091ac92f0a887ab29279c3/doc/assets/css/external-small.png -------------------------------------------------------------------------------- /doc/assets/css/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kallaspriit/HTML5-JavaScript-Gamepad-Controller-Library/c38f53b8c23825e0bb091ac92f0a887ab29279c3/doc/assets/css/logo.png -------------------------------------------------------------------------------- /doc/assets/css/main.css: -------------------------------------------------------------------------------- 1 | /* 2 | Font sizes for all selectors other than the body are given in percentages, 3 | with 100% equal to 13px. To calculate a font size percentage, multiply the 4 | desired size in pixels by 7.6923076923. 5 | 6 | Here's a quick lookup table: 7 | 8 | 10px - 76.923% 9 | 11px - 84.615% 10 | 12px - 92.308% 11 | 13px - 100% 12 | 14px - 107.692% 13 | 15px - 115.385% 14 | 16px - 123.077% 15 | 17px - 130.769% 16 | 18px - 138.462% 17 | 19px - 146.154% 18 | 20px - 153.846% 19 | */ 20 | 21 | html { 22 | background: #fff; 23 | color: #333; 24 | overflow-y: scroll; 25 | } 26 | 27 | body { 28 | /*font: 13px/1.4 'Lucida Grande', 'Lucida Sans Unicode', 'DejaVu Sans', 'Bitstream Vera Sans', 'Helvetica', 'Arial', sans-serif;*/ 29 | font: 13px/1.4 'Helvetica', 'Arial', sans-serif; 30 | margin: 0; 31 | padding: 0; 32 | } 33 | 34 | /* -- Links ----------------------------------------------------------------- */ 35 | a { 36 | color: #356de4; 37 | text-decoration: none; 38 | } 39 | 40 | .hidden { 41 | display: none; 42 | } 43 | 44 | a:hover { text-decoration: underline; } 45 | 46 | /* "Jump to Table of Contents" link is shown to assistive tools, but hidden from 47 | sight until it's focused. */ 48 | .jump { 49 | position: absolute; 50 | padding: 3px 6px; 51 | left: -99999px; 52 | top: 0; 53 | } 54 | 55 | .jump:focus { left: 40%; } 56 | 57 | /* -- Paragraphs ------------------------------------------------------------ */ 58 | p { margin: 1.3em 0; } 59 | dd p, td p { margin-bottom: 0; } 60 | dd p:first-child, td p:first-child { margin-top: 0; } 61 | 62 | /* -- Headings -------------------------------------------------------------- */ 63 | h1, h2, h3, h4, h5, h6 { 64 | color: #D98527;/*was #f80*/ 65 | font-family: 'Trebuchet MS', sans-serif; 66 | font-weight: bold; 67 | line-height: 1.1; 68 | margin: 1.1em 0 0.5em; 69 | } 70 | 71 | h1 { 72 | font-size: 184.6%; 73 | color: #30418C; 74 | margin: 0.75em 0 0.5em; 75 | } 76 | 77 | h2 { 78 | font-size: 153.846%; 79 | color: #E48A2B; 80 | } 81 | 82 | h3 { font-size: 138.462%; } 83 | 84 | h4 { 85 | border-bottom: 1px solid #DBDFEA; 86 | color: #E48A2B; 87 | font-size: 115.385%; 88 | font-weight: normal; 89 | padding-bottom: 2px; 90 | } 91 | 92 | h5, h6 { font-size: 107.692%; } 93 | 94 | /* -- Code and examples ----------------------------------------------------- */ 95 | code, kbd, pre, samp { 96 | font-family: Menlo, Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; 97 | font-size: 92.308%; 98 | line-height: 1.35; 99 | } 100 | 101 | p code, p kbd, p samp, li code { 102 | background: #FCFBFA; 103 | border: 1px solid #EFEEED; 104 | padding: 0 3px; 105 | } 106 | 107 | a code, a kbd, a samp, 108 | pre code, pre kbd, pre samp, 109 | table code, table kbd, table samp, 110 | .intro code, .intro kbd, .intro samp, 111 | .toc code, .toc kbd, .toc samp { 112 | background: none; 113 | border: none; 114 | padding: 0; 115 | } 116 | 117 | pre.code, pre.terminal, pre.cmd { 118 | overflow-x: auto; 119 | *overflow-x: scroll; 120 | padding: 0.3em 0.6em; 121 | } 122 | 123 | pre.code { 124 | background: #FCFBFA; 125 | border: 1px solid #EFEEED; 126 | border-left-width: 5px; 127 | } 128 | 129 | pre.terminal, pre.cmd { 130 | background: #F0EFFC; 131 | border: 1px solid #D0CBFB; 132 | border-left: 5px solid #D0CBFB; 133 | } 134 | 135 | /* Don't reduce the font size of // elements inside
136 |    blocks. */
137 | pre code, pre kbd, pre samp { font-size: 100%; }
138 | 
139 | /* Used to denote text that shouldn't be selectable, such as line numbers or
140 |    shell prompts. Guess which browser this doesn't work in. */
141 | .noselect {
142 |     -moz-user-select: -moz-none;
143 |     -khtml-user-select: none;
144 |     -webkit-user-select: none;
145 |     -o-user-select: none;
146 |     user-select: none;
147 | }
148 | 
149 | /* -- Lists ----------------------------------------------------------------- */
150 | dd { margin: 0.2em 0 0.7em 1em; }
151 | dl { margin: 1em 0; }
152 | dt { font-weight: bold; }
153 | 
154 | /* -- Tables ---------------------------------------------------------------- */
155 | caption, th { text-align: left; }
156 | 
157 | table {
158 |     border-collapse: collapse;
159 |     width: 100%;
160 | }
161 | 
162 | td, th {
163 |     border: 1px solid #fff;
164 |     padding: 5px 12px;
165 |     vertical-align: top;
166 | }
167 | 
168 | td { background: #E6E9F5; }
169 | td dl { margin: 0; }
170 | td dl dl { margin: 1em 0; }
171 | td pre:first-child { margin-top: 0; }
172 | 
173 | th {
174 |     background: #D2D7E6;/*#97A0BF*/
175 |     border-bottom: none;
176 |     border-top: none;
177 |     color: #000;/*#FFF1D5*/
178 |     font-family: 'Trebuchet MS', sans-serif;
179 |     font-weight: bold;
180 |     line-height: 1.3;
181 |     white-space: nowrap;
182 | }
183 | 
184 | 
185 | /* -- Layout and Content ---------------------------------------------------- */
186 | #doc {
187 |     margin: auto;
188 |     min-width: 1024px;
189 | }
190 | 
191 | .content { padding: 0 20px 0 25px; }
192 | 
193 | .sidebar {
194 |     padding: 0 15px 0 10px;
195 | }
196 | #bd {
197 |     padding: 7px 0 130px;
198 |     position: relative;
199 |     width: 99%;
200 | }
201 | 
202 | /* -- Table of Contents ----------------------------------------------------- */
203 | 
204 | /* The #toc id refers to the single global table of contents, while the .toc
205 |    class refers to generic TOC lists that could be used throughout the page. */
206 | 
207 | .toc code, .toc kbd, .toc samp { font-size: 100%; }
208 | .toc li { font-weight: bold; }
209 | .toc li li { font-weight: normal; }
210 | 
211 | /* -- Intro and Example Boxes ----------------------------------------------- */
212 | /*
213 | .intro, .example { margin-bottom: 2em; }
214 | .example {
215 |     -moz-border-radius: 4px;
216 |     -webkit-border-radius: 4px;
217 |     border-radius: 4px;
218 |     -moz-box-shadow: 0 0 5px #bfbfbf;
219 |     -webkit-box-shadow: 0 0 5px #bfbfbf;
220 |     box-shadow: 0 0 5px #bfbfbf;
221 |     padding: 1em;
222 | }
223 | .intro {
224 |     background: none repeat scroll 0 0 #F0F1F8; border: 1px solid #D4D8EB; padding: 0 1em;
225 | }
226 | */
227 | 
228 | /* -- Other Styles ---------------------------------------------------------- */
229 | 
230 | /* These are probably YUI-specific, and should be moved out of Selleck's default
231 |    theme. */
232 | 
233 | .button {
234 |     border: 1px solid #dadada;
235 |     -moz-border-radius: 3px;
236 |     -webkit-border-radius: 3px;
237 |     border-radius: 3px;
238 |     color: #444;
239 |     display: inline-block;
240 |     font-family: Helvetica, Arial, sans-serif;
241 |     font-size: 92.308%;
242 |     font-weight: bold;
243 |     padding: 4px 13px 3px;
244 |     -moz-text-shadow: 1px 1px 0 #fff;
245 |     -webkit-text-shadow: 1px 1px 0 #fff;
246 |     text-shadow: 1px 1px 0 #fff;
247 |     white-space: nowrap;
248 | 
249 |     background: #EFEFEF; /* old browsers */
250 |     background: -moz-linear-gradient(top, #f5f5f5 0%, #efefef 50%, #e5e5e5 51%, #dfdfdf 100%); /* firefox */
251 |     background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f5f5f5), color-stop(50%,#efefef), color-stop(51%,#e5e5e5), color-stop(100%,#dfdfdf)); /* webkit */
252 |     filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f5f5f5', endColorstr='#dfdfdf',GradientType=0 ); /* ie */
253 | }
254 | 
255 | .button:hover {
256 |     border-color: #466899;
257 |     color: #fff;
258 |     text-decoration: none;
259 |     -moz-text-shadow: 1px 1px 0 #222;
260 |     -webkit-text-shadow: 1px 1px 0 #222;
261 |     text-shadow: 1px 1px 0 #222;
262 | 
263 |     background: #6396D8; /* old browsers */
264 |     background: -moz-linear-gradient(top, #6396D8 0%, #5A83BC 50%, #547AB7 51%, #466899 100%); /* firefox */
265 |     background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#6396D8), color-stop(50%,#5A83BC), color-stop(51%,#547AB7), color-stop(100%,#466899)); /* webkit */
266 |     filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#6396D8', endColorstr='#466899',GradientType=0 ); /* ie */
267 | }
268 | 
269 | .newwindow { text-align: center; }
270 | 
271 | .header .version em {
272 |     display: block;
273 |     text-align: right;
274 | }
275 | 
276 | 
277 | #classdocs .item {
278 |     border-bottom: 1px solid #466899;
279 |     margin: 1em 0;
280 |     padding: 1.5em;
281 | }
282 | 
283 | #classdocs .item .params p,
284 |     #classdocs .item .returns p,{
285 |     display: inline;
286 | }
287 | 
288 | #classdocs .item em code, #classdocs .item em.comment {
289 |     color: green;
290 | }
291 | 
292 | #classdocs .item em.comment a {
293 |     color: green;
294 |     text-decoration: underline;
295 | }
296 | 
297 | #classdocs .foundat {
298 |     font-size: 11px;
299 |     font-style: normal;
300 | }
301 | 
302 | .attrs .emits {
303 |     margin-left: 2em;
304 |     padding: .5em;
305 |     border-left: 1px dashed #ccc;
306 | }
307 | 
308 | abbr {
309 |     border-bottom: 1px dashed #ccc;
310 |     font-size: 80%;
311 |     cursor: help;
312 | }
313 | 
314 | .prettyprint li.L0, 
315 | .prettyprint li.L1, 
316 | .prettyprint li.L2, 
317 | .prettyprint li.L3, 
318 | .prettyprint li.L5, 
319 | .prettyprint li.L6, 
320 | .prettyprint li.L7, 
321 | .prettyprint li.L8 {
322 |     list-style: decimal;
323 | }
324 | 
325 | ul li p {
326 |     margin-top: 0;
327 | }
328 | 
329 | .method .name {
330 |     font-size: 110%;
331 | }
332 | 
333 | .apidocs .methods .extends .method,
334 | .apidocs .properties .extends .property,
335 | .apidocs .attrs .extends .attr,
336 | .apidocs .events .extends .event {
337 |     font-weight: bold;
338 | }
339 | 
340 | .apidocs .methods .extends .inherited,
341 | .apidocs .properties .extends .inherited,
342 | .apidocs .attrs .extends .inherited,
343 | .apidocs .events .extends .inherited {
344 |     font-weight: normal;
345 | }
346 | 
347 | #hd {
348 |     background: whiteSmoke;
349 |     background: -moz-linear-gradient(top,#DCDBD9 0,#F6F5F3 100%);
350 |     background: -webkit-gradient(linear,left top,left bottom,color-stop(0%,#DCDBD9),color-stop(100%,#F6F5F3));
351 |     filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dcdbd9',endColorstr='#F6F5F3',GradientType=0);
352 |     border-bottom: 1px solid #DFDFDF;
353 |     padding: 0 15px 1px 20px;
354 |     margin-bottom: 15px;
355 | }
356 | 
357 | #hd img {
358 |     margin-right: 10px;
359 |     vertical-align: middle;
360 | }
361 | 
362 | 
363 | /* -- API Docs CSS ---------------------------------------------------------- */
364 | 
365 | /*
366 | This file is organized so that more generic styles are nearer the top, and more
367 | specific styles are nearer the bottom of the file. This allows us to take full
368 | advantage of the cascade to avoid redundant style rules. Please respect this
369 | convention when making changes.
370 | */
371 | 
372 | /* -- Generic TabView styles ------------------------------------------------ */
373 | 
374 | /*
375 | These styles apply to all API doc tabviews. To change styles only for a
376 | specific tabview, see the other sections below.
377 | */
378 | 
379 | .yui3-js-enabled .apidocs .tabview {
380 |     visibility: hidden; /* Hide until the TabView finishes rendering. */
381 |     _visibility: visible;
382 | }
383 | 
384 | .apidocs .tabview.yui3-tabview-content { visibility: visible; }
385 | .apidocs .tabview .yui3-tabview-panel { background: #fff; }
386 | 
387 | /* -- Generic Content Styles ------------------------------------------------ */
388 | 
389 | /* Headings */
390 | h2, h3, h4, h5, h6 {
391 |     border: none;
392 |     color: #30418C;
393 |     font-weight: bold;
394 |     text-decoration: none;
395 | }
396 | 
397 | .link-docs {
398 |     float: right;
399 |     font-size: 15px;
400 |     margin: 4px 4px 6px;
401 |     padding: 6px 30px 5px;
402 | }
403 | 
404 | .apidocs { zoom: 1; }
405 | 
406 | /* Generic box styles. */
407 | .apidocs .box {
408 |     border: 1px solid;
409 |     border-radius: 3px;
410 |     margin: 1em 0;
411 |     padding: 0 1em;
412 | }
413 | 
414 | /* A flag is a compact, capsule-like indicator of some kind. It's used to
415 |    indicate private and protected items, item return types, etc. in an
416 |    attractive and unobtrusive way. */
417 | .apidocs .flag {
418 |     background: #bababa;
419 |     border-radius: 3px;
420 |     color: #fff;
421 |     font-size: 11px;
422 |     margin: 0 0.5em;
423 |     padding: 2px 4px 1px;
424 | }
425 | 
426 | /* Class/module metadata such as "Uses", "Extends", "Defined in", etc. */
427 | .apidocs .meta {
428 |     background: #f9f9f9;
429 |     border-color: #efefef;
430 |     color: #555;
431 |     font-size: 11px;
432 |     padding: 3px 6px;
433 | }
434 | 
435 | .apidocs .meta p { margin: 0; }
436 | 
437 | /* Deprecation warning. */
438 | .apidocs .box.deprecated,
439 | .apidocs .flag.deprecated {
440 |     background: #fdac9f;
441 |     border: 1px solid #fd7775;
442 | }
443 | 
444 | .apidocs .box.deprecated p { margin: 0.5em 0; }
445 | .apidocs .flag.deprecated { color: #333; }
446 | 
447 | /* Module/Class intro description. */
448 | .apidocs .intro {
449 |     background: #f0f1f8;
450 |     border-color: #d4d8eb;
451 | }
452 | 
453 | /* Loading spinners. */
454 | #bd.loading .apidocs,
455 | #api-list.loading .yui3-tabview-panel {
456 |     background: #fff url(../img/spinner.gif) no-repeat center 70px;
457 |     min-height: 150px;
458 | }
459 | 
460 | #bd.loading .apidocs .content,
461 | #api-list.loading .yui3-tabview-panel .apis {
462 |     display: none;
463 | }
464 | 
465 | .apidocs .no-visible-items { color: #666; }
466 | 
467 | /* Generic inline list. */
468 | .apidocs ul.inline {
469 |     display: inline;
470 |     list-style: none;
471 |     margin: 0;
472 |     padding: 0;
473 | }
474 | 
475 | .apidocs ul.inline li { display: inline; }
476 | 
477 | /* Comma-separated list. */
478 | .apidocs ul.commas li:after { content: ','; }
479 | .apidocs ul.commas li:last-child:after { content: ''; }
480 | 
481 | /* Keyboard shortcuts. */
482 | kbd .cmd { font-family: Monaco, Helvetica; }
483 | 
484 | /* -- Generic Access Level styles ------------------------------------------- */
485 | .apidocs .item.protected,
486 | .apidocs .item.private,
487 | .apidocs .index-item.protected,
488 | .apidocs .index-item.deprecated,
489 | .apidocs .index-item.private {
490 |     display: none;
491 | }
492 | 
493 | .show-deprecated .item.deprecated,
494 | .show-deprecated .index-item.deprecated,
495 | .show-protected .item.protected,
496 | .show-protected .index-item.protected,
497 | .show-private .item.private,
498 | .show-private .index-item.private {
499 |     display: block;
500 | }
501 | 
502 | .hide-inherited .item.inherited,
503 | .hide-inherited .index-item.inherited {
504 |     display: none;
505 | }
506 | 
507 | /* -- Generic Item Index styles --------------------------------------------- */
508 | .apidocs .index { margin: 1.5em 0 3em; }
509 | 
510 | .apidocs .index h3 {
511 |     border-bottom: 1px solid #efefef;
512 |     color: #333;
513 |     font-size: 13px;
514 |     margin: 2em 0 0.6em;
515 |     padding-bottom: 2px;
516 | }
517 | 
518 | .apidocs .index .no-visible-items { margin-top: 2em; }
519 | 
520 | .apidocs .index-list {
521 |     border-color: #efefef;
522 |     font-size: 12px;
523 |     list-style: none;
524 |     margin: 0;
525 |     padding: 0;
526 |     -moz-column-count: 4;
527 |     -moz-column-gap: 10px;
528 |     -moz-column-width: 170px;
529 |     -ms-column-count: 4;
530 |     -ms-column-gap: 10px;
531 |     -ms-column-width: 170px;
532 |     -o-column-count: 4;
533 |     -o-column-gap: 10px;
534 |     -o-column-width: 170px;
535 |     -webkit-column-count: 4;
536 |     -webkit-column-gap: 10px;
537 |     -webkit-column-width: 170px;
538 |     column-count: 4;
539 |     column-gap: 10px;
540 |     column-width: 170px;
541 | }
542 | 
543 | .apidocs .no-columns .index-list {
544 |     -moz-column-count: 1;
545 |     -ms-column-count: 1;
546 |     -o-column-count: 1;
547 |     -webkit-column-count: 1;
548 |     column-count: 1;
549 | }
550 | 
551 | .apidocs .index-item { white-space: nowrap; }
552 | 
553 | .apidocs .index-item .flag {
554 |     background: none;
555 |     border: none;
556 |     color: #afafaf;
557 |     display: inline;
558 |     margin: 0 0 0 0.2em;
559 |     padding: 0;
560 | }
561 | 
562 | /* -- Generic API item styles ----------------------------------------------- */
563 | .apidocs .args {
564 |     display: inline;
565 |     margin: 0 0.5em;
566 | }
567 | 
568 | .apidocs .flag.chainable { background: #46ca3b; }
569 | .apidocs .flag.protected { background: #9b86fc; }
570 | .apidocs .flag.private { background: #fd6b1b; }
571 | .apidocs .flag.async { background: #356de4; }
572 | .apidocs .flag.required { background: #e60923; }
573 | 
574 | .apidocs .item {
575 |     border-bottom: 1px solid #efefef;
576 |     margin: 1.5em 0 2em;
577 |     padding-bottom: 2em;
578 | }
579 | 
580 | .apidocs .item h4,
581 | .apidocs .item h5,
582 | .apidocs .item h6 {
583 |     color: #333;
584 |     font-family: inherit;
585 |     font-size: 100%;
586 | }
587 | 
588 | .apidocs .item .description p,
589 | .apidocs .item pre.code {
590 |     margin: 1em 0 0;
591 | }
592 | 
593 | .apidocs .item .meta {
594 |     background: none;
595 |     border: none;
596 |     padding: 0;
597 | }
598 | 
599 | .apidocs .item .name {
600 |     display: inline;
601 |     font-size: 14px;
602 | }
603 | 
604 | .apidocs .item .type,
605 | .apidocs .item .type a,
606 | .apidocs .returns-inline {
607 |     color: #555;
608 | }
609 | 
610 | .apidocs .item .type,
611 | .apidocs .returns-inline {
612 |     font-size: 11px;
613 |     margin: 0 0 0 0;
614 | }
615 | 
616 | .apidocs .item .type a { border-bottom: 1px dotted #afafaf; }
617 | .apidocs .item .type a:hover { border: none; }
618 | 
619 | /* -- Item Parameter List --------------------------------------------------- */
620 | .apidocs .params-list {
621 |     list-style: square;
622 |     margin: 1em 0 0 2em;
623 |     padding: 0;
624 | }
625 | 
626 | .apidocs .param { margin-bottom: 1em; }
627 | 
628 | .apidocs .param .type,
629 | .apidocs .param .type a {
630 |     color: #666;
631 | }
632 | 
633 | .apidocs .param .type {
634 |     margin: 0 0 0 0.5em;
635 |     *margin-left: 0.5em;
636 | }
637 | 
638 | .apidocs .param-name { font-weight: bold; }
639 | 
640 | /* -- Item "Emits" block ---------------------------------------------------- */
641 | .apidocs .item .emits {
642 |     background: #f9f9f9;
643 |     border-color: #eaeaea;
644 | }
645 | 
646 | /* -- Item "Returns" block -------------------------------------------------- */
647 | .apidocs .item .returns .type,
648 | .apidocs .item .returns .type a {
649 |     font-size: 100%;
650 |     margin: 0;
651 | }
652 | 
653 | /* -- Class Constructor block ----------------------------------------------- */
654 | .apidocs .constructor .item {
655 |     border: none;
656 |     padding-bottom: 0;
657 | }
658 | 
659 | /* -- File Source View ------------------------------------------------------ */
660 | .apidocs .file pre.code,
661 | #doc .apidocs .file pre.prettyprint {
662 |     background: inherit;
663 |     border: none;
664 |     overflow: visible;
665 |     padding: 0;
666 | }
667 | 
668 | .apidocs .L0,
669 | .apidocs .L1,
670 | .apidocs .L2,
671 | .apidocs .L3,
672 | .apidocs .L4,
673 | .apidocs .L5,
674 | .apidocs .L6,
675 | .apidocs .L7,
676 | .apidocs .L8,
677 | .apidocs .L9 {
678 |     background: inherit;
679 | }
680 | 
681 | /* -- Submodule List -------------------------------------------------------- */
682 | .apidocs .module-submodule-description {
683 |     font-size: 12px;
684 |     margin: 0.3em 0 1em;
685 | }
686 | 
687 | .apidocs .module-submodule-description p:first-child { margin-top: 0; }
688 | 
689 | /* -- Sidebar TabView ------------------------------------------------------- */
690 | #api-tabview { margin-top: 0.6em; }
691 | 
692 | #api-tabview-filter,
693 | #api-tabview-panel {
694 |     border: 1px solid #dfdfdf;
695 | }
696 | 
697 | #api-tabview-filter {
698 |     border-bottom: none;
699 |     border-top: none;
700 |     padding: 0.6em 10px 0 10px;
701 | }
702 | 
703 | #api-tabview-panel { border-top: none; }
704 | #api-filter { width: 97%; }
705 | 
706 | /* -- Content TabView ------------------------------------------------------- */
707 | #classdocs .yui3-tabview-panel { border: none; }
708 | 
709 | /* -- Source File Contents -------------------------------------------------- */
710 | .prettyprint li.L0,
711 | .prettyprint li.L1,
712 | .prettyprint li.L2,
713 | .prettyprint li.L3,
714 | .prettyprint li.L5,
715 | .prettyprint li.L6,
716 | .prettyprint li.L7,
717 | .prettyprint li.L8 {
718 |     list-style: decimal;
719 | }
720 | 
721 | /* -- API options ----------------------------------------------------------- */
722 | #api-options {
723 |     font-size: 11px;
724 |     margin-top: 2.2em;
725 |     position: absolute;
726 |     right: 1.5em;
727 | }
728 | 
729 | /*#api-options label { margin-right: 0.6em; }*/
730 | 
731 | /* -- API list -------------------------------------------------------------- */
732 | #api-list {
733 |     margin-top: 1.5em;
734 |     *zoom: 1;
735 | }
736 | 
737 | .apis {
738 |     font-size: 12px;
739 |     line-height: 1.4;
740 |     list-style: none;
741 |     margin: 0;
742 |     padding: 0.5em 0 0.5em 0.4em;
743 | }
744 | 
745 | .apis a {
746 |     border: 1px solid transparent;
747 |     display: block;
748 |     margin: 0 0 0 -4px;
749 |     padding: 1px 4px 0;
750 |     text-decoration: none;
751 |     _border: none;
752 |     _display: inline;
753 | }
754 | 
755 | .apis a:hover,
756 | .apis a:focus {
757 |     background: #E8EDFC;
758 |     background: -moz-linear-gradient(top, #e8edfc 0%, #becef7 100%);
759 |     background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#E8EDFC), color-stop(100%,#BECEF7));
760 |     border-color: #AAC0FA;
761 |     border-radius: 3px;
762 |     color: #333;
763 |     outline: none;
764 | }
765 | 
766 | .api-list-item a:hover,
767 | .api-list-item a:focus {
768 |     font-weight: bold;
769 |     text-shadow: 1px 1px 1px #fff;
770 | }
771 | 
772 | .apis .message { color: #888; }
773 | .apis .result a { padding: 3px 5px 2px; }
774 | 
775 | .apis .result .type {
776 |     right: 4px;
777 |     top: 7px;
778 | }
779 | 
780 | .api-list-item .yui3-highlight {
781 |     font-weight: bold;
782 | }
783 | 
784 | 


--------------------------------------------------------------------------------
/doc/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kallaspriit/HTML5-JavaScript-Gamepad-Controller-Library/c38f53b8c23825e0bb091ac92f0a887ab29279c3/doc/assets/favicon.png


--------------------------------------------------------------------------------
/doc/assets/img/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kallaspriit/HTML5-JavaScript-Gamepad-Controller-Library/c38f53b8c23825e0bb091ac92f0a887ab29279c3/doc/assets/img/spinner.gif


--------------------------------------------------------------------------------
/doc/assets/index.html:
--------------------------------------------------------------------------------
 1 | 
 2 | 
 3 |     
 4 |         Redirector
 5 |         
 6 |     
 7 |     
 8 |         Click here to redirect
 9 |     
10 | 
11 | 


--------------------------------------------------------------------------------
/doc/assets/js/api-filter.js:
--------------------------------------------------------------------------------
 1 | YUI.add('api-filter', function (Y) {
 2 | 
 3 | Y.APIFilter = Y.Base.create('apiFilter', Y.Base, [Y.AutoCompleteBase], {
 4 |     // -- Initializer ----------------------------------------------------------
 5 |     initializer: function () {
 6 |         this._bindUIACBase();
 7 |         this._syncUIACBase();
 8 |     },
 9 |     getDisplayName: function(name) {
10 | 
11 |         Y.each(Y.YUIDoc.meta.allModules, function(i) {
12 |             if (i.name === name && i.displayName) {
13 |                 name = i.displayName;
14 |             }
15 |         });
16 | 
17 |         return name;
18 |     }
19 | 
20 | }, {
21 |     // -- Attributes -----------------------------------------------------------
22 |     ATTRS: {
23 |         resultHighlighter: {
24 |             value: 'phraseMatch'
25 |         },
26 | 
27 |         // May be set to "classes" or "modules".
28 |         queryType: {
29 |             value: 'classes'
30 |         },
31 | 
32 |         source: {
33 |             valueFn: function() {
34 |                 var self = this;
35 |                 return function(q) {
36 |                     var data = Y.YUIDoc.meta[self.get('queryType')],
37 |                         out = [];
38 |                     Y.each(data, function(v) {
39 |                         if (v.toLowerCase().indexOf(q.toLowerCase()) > -1) {
40 |                             out.push(v);
41 |                         }
42 |                     });
43 |                     return out;
44 |                 };
45 |             }
46 |         }
47 |     }
48 | });
49 | 
50 | }, '3.4.0', {requires: [
51 |     'autocomplete-base', 'autocomplete-highlighters', 'autocomplete-sources'
52 | ]});
53 | 


--------------------------------------------------------------------------------
/doc/assets/js/api-list.js:
--------------------------------------------------------------------------------
  1 | YUI.add('api-list', function (Y) {
  2 | 
  3 | var Lang   = Y.Lang,
  4 |     YArray = Y.Array,
  5 | 
  6 |     APIList = Y.namespace('APIList'),
  7 | 
  8 |     classesNode    = Y.one('#api-classes'),
  9 |     inputNode      = Y.one('#api-filter'),
 10 |     modulesNode    = Y.one('#api-modules'),
 11 |     tabviewNode    = Y.one('#api-tabview'),
 12 | 
 13 |     tabs = APIList.tabs = {},
 14 | 
 15 |     filter = APIList.filter = new Y.APIFilter({
 16 |         inputNode : inputNode,
 17 |         maxResults: 1000,
 18 | 
 19 |         on: {
 20 |             results: onFilterResults
 21 |         }
 22 |     }),
 23 | 
 24 |     search = APIList.search = new Y.APISearch({
 25 |         inputNode : inputNode,
 26 |         maxResults: 100,
 27 | 
 28 |         on: {
 29 |             clear  : onSearchClear,
 30 |             results: onSearchResults
 31 |         }
 32 |     }),
 33 | 
 34 |     tabview = APIList.tabview = new Y.TabView({
 35 |         srcNode  : tabviewNode,
 36 |         panelNode: '#api-tabview-panel',
 37 |         render   : true,
 38 | 
 39 |         on: {
 40 |             selectionChange: onTabSelectionChange
 41 |         }
 42 |     }),
 43 | 
 44 |     focusManager = APIList.focusManager = tabviewNode.plug(Y.Plugin.NodeFocusManager, {
 45 |         circular   : true,
 46 |         descendants: '#api-filter, .yui3-tab-panel-selected .api-list-item a, .yui3-tab-panel-selected .result a',
 47 |         keys       : {next: 'down:40', previous: 'down:38'}
 48 |     }).focusManager,
 49 | 
 50 |     LIST_ITEM_TEMPLATE =
 51 |         '
  • ' + 52 | '{displayName}' + 53 | '
  • '; 54 | 55 | // -- Init --------------------------------------------------------------------- 56 | 57 | // Duckpunch FocusManager's key event handling to prevent it from handling key 58 | // events when a modifier is pressed. 59 | Y.before(function (e, activeDescendant) { 60 | if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { 61 | return new Y.Do.Prevent(); 62 | } 63 | }, focusManager, '_focusPrevious', focusManager); 64 | 65 | Y.before(function (e, activeDescendant) { 66 | if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { 67 | return new Y.Do.Prevent(); 68 | } 69 | }, focusManager, '_focusNext', focusManager); 70 | 71 | // Create a mapping of tabs in the tabview so we can refer to them easily later. 72 | tabview.each(function (tab, index) { 73 | var name = tab.get('label').toLowerCase(); 74 | 75 | tabs[name] = { 76 | index: index, 77 | name : name, 78 | tab : tab 79 | }; 80 | }); 81 | 82 | // Switch tabs on Ctrl/Cmd-Left/Right arrows. 83 | tabviewNode.on('key', onTabSwitchKey, 'down:37,39'); 84 | 85 | // Focus the filter input when the `/` key is pressed. 86 | Y.one(Y.config.doc).on('key', onSearchKey, 'down:83'); 87 | 88 | // Keep the Focus Manager up to date. 89 | inputNode.on('focus', function () { 90 | focusManager.set('activeDescendant', inputNode); 91 | }); 92 | 93 | // Update all tabview links to resolved URLs. 94 | tabview.get('panelNode').all('a').each(function (link) { 95 | link.setAttribute('href', link.get('href')); 96 | }); 97 | 98 | // -- Private Functions -------------------------------------------------------- 99 | function getFilterResultNode() { 100 | return filter.get('queryType') === 'classes' ? classesNode : modulesNode; 101 | } 102 | 103 | // -- Event Handlers ----------------------------------------------------------- 104 | function onFilterResults(e) { 105 | var frag = Y.one(Y.config.doc.createDocumentFragment()), 106 | resultNode = getFilterResultNode(), 107 | typePlural = filter.get('queryType'), 108 | typeSingular = typePlural === 'classes' ? 'class' : 'module'; 109 | 110 | if (e.results.length) { 111 | YArray.each(e.results, function (result) { 112 | frag.append(Lang.sub(LIST_ITEM_TEMPLATE, { 113 | rootPath : APIList.rootPath, 114 | displayName : filter.getDisplayName(result.highlighted), 115 | name : result.text, 116 | typePlural : typePlural, 117 | typeSingular: typeSingular 118 | })); 119 | }); 120 | } else { 121 | frag.append( 122 | '
  • ' + 123 | 'No ' + typePlural + ' found.' + 124 | '
  • ' 125 | ); 126 | } 127 | 128 | resultNode.empty(true); 129 | resultNode.append(frag); 130 | 131 | focusManager.refresh(); 132 | } 133 | 134 | function onSearchClear(e) { 135 | 136 | focusManager.refresh(); 137 | } 138 | 139 | function onSearchKey(e) { 140 | var target = e.target; 141 | 142 | if (target.test('input,select,textarea') 143 | || target.get('isContentEditable')) { 144 | return; 145 | } 146 | 147 | e.preventDefault(); 148 | 149 | inputNode.focus(); 150 | focusManager.refresh(); 151 | } 152 | 153 | function onSearchResults(e) { 154 | var frag = Y.one(Y.config.doc.createDocumentFragment()); 155 | 156 | if (e.results.length) { 157 | YArray.each(e.results, function (result) { 158 | frag.append(result.display); 159 | }); 160 | } else { 161 | frag.append( 162 | '
  • ' + 163 | 'No results found. Maybe you\'ll have better luck with a ' + 164 | 'different query?' + 165 | '
  • ' 166 | ); 167 | } 168 | 169 | 170 | focusManager.refresh(); 171 | } 172 | 173 | function onTabSelectionChange(e) { 174 | var tab = e.newVal, 175 | name = tab.get('label').toLowerCase(); 176 | 177 | tabs.selected = { 178 | index: tab.get('index'), 179 | name : name, 180 | tab : tab 181 | }; 182 | 183 | switch (name) { 184 | case 'classes': // fallthru 185 | case 'modules': 186 | filter.setAttrs({ 187 | minQueryLength: 0, 188 | queryType : name 189 | }); 190 | 191 | search.set('minQueryLength', -1); 192 | 193 | // Only send a request if this isn't the initially-selected tab. 194 | if (e.prevVal) { 195 | filter.sendRequest(filter.get('value')); 196 | } 197 | break; 198 | 199 | case 'everything': 200 | filter.set('minQueryLength', -1); 201 | search.set('minQueryLength', 1); 202 | 203 | if (search.get('value')) { 204 | search.sendRequest(search.get('value')); 205 | } else { 206 | inputNode.focus(); 207 | } 208 | break; 209 | 210 | default: 211 | // WTF? We shouldn't be here! 212 | filter.set('minQueryLength', -1); 213 | search.set('minQueryLength', -1); 214 | } 215 | 216 | if (focusManager) { 217 | setTimeout(function () { 218 | focusManager.refresh(); 219 | }, 1); 220 | } 221 | } 222 | 223 | function onTabSwitchKey(e) { 224 | var currentTabIndex = tabs.selected.index; 225 | 226 | if (!(e.ctrlKey || e.metaKey)) { 227 | return; 228 | } 229 | 230 | e.preventDefault(); 231 | 232 | switch (e.keyCode) { 233 | case 37: // left arrow 234 | if (currentTabIndex > 0) { 235 | tabview.selectChild(currentTabIndex - 1); 236 | inputNode.focus(); 237 | } 238 | break; 239 | 240 | case 39: // right arrow 241 | if (currentTabIndex < (Y.Object.size(tabs) - 2)) { 242 | tabview.selectChild(currentTabIndex + 1); 243 | inputNode.focus(); 244 | } 245 | break; 246 | } 247 | } 248 | 249 | }, '3.4.0', {requires: [ 250 | 'api-filter', 'api-search', 'event-key', 'node-focusmanager', 'tabview' 251 | ]}); 252 | -------------------------------------------------------------------------------- /doc/assets/js/api-search.js: -------------------------------------------------------------------------------- 1 | YUI.add('api-search', function (Y) { 2 | 3 | var Lang = Y.Lang, 4 | Node = Y.Node, 5 | YArray = Y.Array; 6 | 7 | Y.APISearch = Y.Base.create('apiSearch', Y.Base, [Y.AutoCompleteBase], { 8 | // -- Public Properties ---------------------------------------------------- 9 | RESULT_TEMPLATE: 10 | '
  • ' + 11 | '' + 12 | '

    {name}

    ' + 13 | '{resultType}' + 14 | '
    {description}
    ' + 15 | '{class}' + 16 | '
    ' + 17 | '
  • ', 18 | 19 | // -- Initializer ---------------------------------------------------------- 20 | initializer: function () { 21 | this._bindUIACBase(); 22 | this._syncUIACBase(); 23 | }, 24 | 25 | // -- Protected Methods ---------------------------------------------------- 26 | _apiResultFilter: function (query, results) { 27 | // Filter components out of the results. 28 | return YArray.filter(results, function (result) { 29 | return result.raw.resultType === 'component' ? false : result; 30 | }); 31 | }, 32 | 33 | _apiResultFormatter: function (query, results) { 34 | return YArray.map(results, function (result) { 35 | var raw = Y.merge(result.raw), // create a copy 36 | desc = raw.description || ''; 37 | 38 | // Convert description to text and truncate it if necessary. 39 | desc = Node.create('
    ' + desc + '
    ').get('text'); 40 | 41 | if (desc.length > 65) { 42 | desc = Y.Escape.html(desc.substr(0, 65)) + ' …'; 43 | } else { 44 | desc = Y.Escape.html(desc); 45 | } 46 | 47 | raw['class'] || (raw['class'] = ''); 48 | raw.description = desc; 49 | 50 | // Use the highlighted result name. 51 | raw.name = result.highlighted; 52 | 53 | return Lang.sub(this.RESULT_TEMPLATE, raw); 54 | }, this); 55 | }, 56 | 57 | _apiTextLocator: function (result) { 58 | return result.displayName || result.name; 59 | } 60 | }, { 61 | // -- Attributes ----------------------------------------------------------- 62 | ATTRS: { 63 | resultFormatter: { 64 | valueFn: function () { 65 | return this._apiResultFormatter; 66 | } 67 | }, 68 | 69 | resultFilters: { 70 | valueFn: function () { 71 | return this._apiResultFilter; 72 | } 73 | }, 74 | 75 | resultHighlighter: { 76 | value: 'phraseMatch' 77 | }, 78 | 79 | resultListLocator: { 80 | value: 'data.results' 81 | }, 82 | 83 | resultTextLocator: { 84 | valueFn: function () { 85 | return this._apiTextLocator; 86 | } 87 | }, 88 | 89 | source: { 90 | value: '/api/v1/search?q={query}&count={maxResults}' 91 | } 92 | } 93 | }); 94 | 95 | }, '3.4.0', {requires: [ 96 | 'autocomplete-base', 'autocomplete-highlighters', 'autocomplete-sources', 97 | 'escape' 98 | ]}); 99 | -------------------------------------------------------------------------------- /doc/assets/js/apidocs.js: -------------------------------------------------------------------------------- 1 | YUI().use( 2 | 'yuidoc-meta', 3 | 'api-list', 'history-hash', 'node-screen', 'node-style', 'pjax', 4 | function (Y) { 5 | 6 | var win = Y.config.win, 7 | localStorage = win.localStorage, 8 | 9 | bdNode = Y.one('#bd'), 10 | 11 | pjax, 12 | defaultRoute, 13 | 14 | classTabView, 15 | selectedTab; 16 | 17 | // Kill pjax functionality unless serving over HTTP. 18 | if (!Y.getLocation().protocol.match(/^https?\:/)) { 19 | Y.Router.html5 = false; 20 | } 21 | 22 | // Create the default route with middleware which enables syntax highlighting 23 | // on the loaded content. 24 | defaultRoute = Y.Pjax.defaultRoute.concat(function (req, res, next) { 25 | prettyPrint(); 26 | bdNode.removeClass('loading'); 27 | 28 | next(); 29 | }); 30 | 31 | pjax = new Y.Pjax({ 32 | container : '#docs-main', 33 | contentSelector: '#docs-main > .content', 34 | linkSelector : '#bd a', 35 | titleSelector : '#xhr-title', 36 | 37 | navigateOnHash: true, 38 | root : '/', 39 | routes : [ 40 | // -- / ---------------------------------------------------------------- 41 | { 42 | path : '/(index.html)?', 43 | callbacks: defaultRoute 44 | }, 45 | 46 | // -- /classes/* ------------------------------------------------------- 47 | { 48 | path : '/classes/:class.html*', 49 | callbacks: [defaultRoute, 'handleClasses'] 50 | }, 51 | 52 | // -- /files/* --------------------------------------------------------- 53 | { 54 | path : '/files/*file', 55 | callbacks: [defaultRoute, 'handleFiles'] 56 | }, 57 | 58 | // -- /modules/* ------------------------------------------------------- 59 | { 60 | path : '/modules/:module.html*', 61 | callbacks: defaultRoute 62 | } 63 | ] 64 | }); 65 | 66 | // -- Utility Functions -------------------------------------------------------- 67 | 68 | pjax.checkVisibility = function (tab) { 69 | tab || (tab = selectedTab); 70 | 71 | if (!tab) { return; } 72 | 73 | var panelNode = tab.get('panelNode'), 74 | visibleItems; 75 | 76 | // If no items are visible in the tab panel due to the current visibility 77 | // settings, display a message to that effect. 78 | visibleItems = panelNode.all('.item,.index-item').some(function (itemNode) { 79 | if (itemNode.getComputedStyle('display') !== 'none') { 80 | return true; 81 | } 82 | }); 83 | 84 | panelNode.all('.no-visible-items').remove(); 85 | 86 | if (!visibleItems) { 87 | if (Y.one('#index .index-item')) { 88 | panelNode.append( 89 | '
    ' + 90 | '

    ' + 91 | 'Some items are not shown due to the current visibility ' + 92 | 'settings. Use the checkboxes at the upper right of this ' + 93 | 'page to change the visibility settings.' + 94 | '

    ' + 95 | '
    ' 96 | ); 97 | } else { 98 | panelNode.append( 99 | '
    ' + 100 | '

    ' + 101 | 'This class doesn\'t provide any methods, properties, ' + 102 | 'attributes, or events.' + 103 | '

    ' + 104 | '
    ' 105 | ); 106 | } 107 | } 108 | 109 | // Hide index sections without any visible items. 110 | Y.all('.index-section').each(function (section) { 111 | var items = 0, 112 | visibleItems = 0; 113 | 114 | section.all('.index-item').each(function (itemNode) { 115 | items += 1; 116 | 117 | if (itemNode.getComputedStyle('display') !== 'none') { 118 | visibleItems += 1; 119 | } 120 | }); 121 | 122 | section.toggleClass('hidden', !visibleItems); 123 | section.toggleClass('no-columns', visibleItems < 4); 124 | }); 125 | }; 126 | 127 | pjax.initClassTabView = function () { 128 | if (!Y.all('#classdocs .api-class-tab').size()) { 129 | return; 130 | } 131 | 132 | if (classTabView) { 133 | classTabView.destroy(); 134 | selectedTab = null; 135 | } 136 | 137 | classTabView = new Y.TabView({ 138 | srcNode: '#classdocs', 139 | 140 | on: { 141 | selectionChange: pjax.onTabSelectionChange 142 | } 143 | }); 144 | 145 | pjax.updateTabState(); 146 | classTabView.render(); 147 | }; 148 | 149 | pjax.initLineNumbers = function () { 150 | var hash = win.location.hash.substring(1), 151 | container = pjax.get('container'), 152 | hasLines, node; 153 | 154 | // Add ids for each line number in the file source view. 155 | container.all('.linenums>li').each(function (lineNode, index) { 156 | lineNode.set('id', 'l' + (index + 1)); 157 | lineNode.addClass('file-line'); 158 | hasLines = true; 159 | }); 160 | 161 | // Scroll to the desired line. 162 | if (hasLines && /^l\d+$/.test(hash)) { 163 | if ((node = container.getById(hash))) { 164 | win.scroll(0, node.getY()); 165 | } 166 | } 167 | }; 168 | 169 | pjax.initRoot = function () { 170 | var terminators = /^(?:classes|files|modules)$/, 171 | parts = pjax._getPathRoot().split('/'), 172 | root = [], 173 | i, len, part; 174 | 175 | for (i = 0, len = parts.length; i < len; i += 1) { 176 | part = parts[i]; 177 | 178 | if (part.match(terminators)) { 179 | // Makes sure the path will end with a "/". 180 | root.push(''); 181 | break; 182 | } 183 | 184 | root.push(part); 185 | } 186 | 187 | pjax.set('root', root.join('/')); 188 | }; 189 | 190 | pjax.updateTabState = function (src) { 191 | var hash = win.location.hash.substring(1), 192 | defaultTab, node, tab, tabPanel; 193 | 194 | function scrollToNode() { 195 | if (node.hasClass('protected')) { 196 | Y.one('#api-show-protected').set('checked', true); 197 | pjax.updateVisibility(); 198 | } 199 | 200 | if (node.hasClass('private')) { 201 | Y.one('#api-show-private').set('checked', true); 202 | pjax.updateVisibility(); 203 | } 204 | 205 | setTimeout(function () { 206 | // For some reason, unless we re-get the node instance here, 207 | // getY() always returns 0. 208 | var node = Y.one('#classdocs').getById(hash); 209 | win.scrollTo(0, node.getY() - 70); 210 | }, 1); 211 | } 212 | 213 | if (!classTabView) { 214 | return; 215 | } 216 | 217 | if (src === 'hashchange' && !hash) { 218 | defaultTab = 'index'; 219 | } else { 220 | if (localStorage) { 221 | defaultTab = localStorage.getItem('tab_' + pjax.getPath()) || 222 | 'index'; 223 | } else { 224 | defaultTab = 'index'; 225 | } 226 | } 227 | 228 | if (hash && (node = Y.one('#classdocs').getById(hash))) { 229 | if ((tabPanel = node.ancestor('.api-class-tabpanel', true))) { 230 | if ((tab = Y.one('#classdocs .api-class-tab.' + tabPanel.get('id')))) { 231 | if (classTabView.get('rendered')) { 232 | Y.Widget.getByNode(tab).set('selected', 1); 233 | } else { 234 | tab.addClass('yui3-tab-selected'); 235 | } 236 | } 237 | } 238 | 239 | // Scroll to the desired element if this is a hash URL. 240 | if (node) { 241 | if (classTabView.get('rendered')) { 242 | scrollToNode(); 243 | } else { 244 | classTabView.once('renderedChange', scrollToNode); 245 | } 246 | } 247 | } else { 248 | tab = Y.one('#classdocs .api-class-tab.' + defaultTab); 249 | 250 | // When the `defaultTab` node isn't found, `localStorage` is stale. 251 | if (!tab && defaultTab !== 'index') { 252 | tab = Y.one('#classdocs .api-class-tab.index'); 253 | } 254 | 255 | if (classTabView.get('rendered')) { 256 | Y.Widget.getByNode(tab).set('selected', 1); 257 | } else { 258 | tab.addClass('yui3-tab-selected'); 259 | } 260 | } 261 | }; 262 | 263 | pjax.updateVisibility = function () { 264 | var container = pjax.get('container'); 265 | 266 | container.toggleClass('hide-inherited', 267 | !Y.one('#api-show-inherited').get('checked')); 268 | 269 | container.toggleClass('show-deprecated', 270 | Y.one('#api-show-deprecated').get('checked')); 271 | 272 | container.toggleClass('show-protected', 273 | Y.one('#api-show-protected').get('checked')); 274 | 275 | container.toggleClass('show-private', 276 | Y.one('#api-show-private').get('checked')); 277 | 278 | pjax.checkVisibility(); 279 | }; 280 | 281 | // -- Route Handlers ----------------------------------------------------------- 282 | 283 | pjax.handleClasses = function (req, res, next) { 284 | var status = res.ioResponse.status; 285 | 286 | // Handles success and local filesystem XHRs. 287 | if (res.ioResponse.readyState === 4 && (!status || (status >= 200 && status < 300))) { 288 | pjax.initClassTabView(); 289 | } 290 | 291 | next(); 292 | }; 293 | 294 | pjax.handleFiles = function (req, res, next) { 295 | var status = res.ioResponse.status; 296 | 297 | // Handles success and local filesystem XHRs. 298 | if (res.ioResponse.readyState === 4 && (!status || (status >= 200 && status < 300))) { 299 | pjax.initLineNumbers(); 300 | } 301 | 302 | next(); 303 | }; 304 | 305 | // -- Event Handlers ----------------------------------------------------------- 306 | 307 | pjax.onNavigate = function (e) { 308 | var hash = e.hash, 309 | originTarget = e.originEvent && e.originEvent.target, 310 | tab; 311 | 312 | if (hash) { 313 | tab = originTarget && originTarget.ancestor('.yui3-tab', true); 314 | 315 | if (hash === win.location.hash) { 316 | pjax.updateTabState('hashchange'); 317 | } else if (!tab) { 318 | win.location.hash = hash; 319 | } 320 | 321 | e.preventDefault(); 322 | return; 323 | } 324 | 325 | // Only scroll to the top of the page when the URL doesn't have a hash. 326 | this.set('scrollToTop', !e.url.match(/#.+$/)); 327 | 328 | bdNode.addClass('loading'); 329 | }; 330 | 331 | pjax.onOptionClick = function (e) { 332 | pjax.updateVisibility(); 333 | }; 334 | 335 | pjax.onTabSelectionChange = function (e) { 336 | var tab = e.newVal, 337 | tabId = tab.get('contentBox').getAttribute('href').substring(1); 338 | 339 | selectedTab = tab; 340 | 341 | // If switching from a previous tab (i.e., this is not the default tab), 342 | // replace the history entry with a hash URL that will cause this tab to 343 | // be selected if the user navigates away and then returns using the back 344 | // or forward buttons. 345 | if (e.prevVal && localStorage) { 346 | localStorage.setItem('tab_' + pjax.getPath(), tabId); 347 | } 348 | 349 | pjax.checkVisibility(tab); 350 | }; 351 | 352 | // -- Init --------------------------------------------------------------------- 353 | 354 | pjax.on('navigate', pjax.onNavigate); 355 | 356 | pjax.initRoot(); 357 | pjax.upgrade(); 358 | pjax.initClassTabView(); 359 | pjax.initLineNumbers(); 360 | pjax.updateVisibility(); 361 | 362 | Y.APIList.rootPath = pjax.get('root'); 363 | 364 | Y.one('#api-options').delegate('click', pjax.onOptionClick, 'input'); 365 | 366 | Y.on('hashchange', function (e) { 367 | pjax.updateTabState('hashchange'); 368 | }, win); 369 | 370 | }); 371 | -------------------------------------------------------------------------------- /doc/assets/js/yui-prettify.js: -------------------------------------------------------------------------------- 1 | YUI().use('node', function(Y) { 2 | var code = Y.all('.prettyprint.linenums'); 3 | if (code.size()) { 4 | code.each(function(c) { 5 | var lis = c.all('ol li'), 6 | l = 1; 7 | lis.each(function(n) { 8 | n.prepend(''); 9 | l++; 10 | }); 11 | }); 12 | var h = location.hash; 13 | location.hash = ''; 14 | h = h.replace('LINE_', 'LINENUM_'); 15 | location.hash = h; 16 | } 17 | }); 18 | -------------------------------------------------------------------------------- /doc/assets/vendor/prettify/CHANGES.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Change Log 5 | 6 | 7 | README 8 | 9 |

    Known Issues

    10 | 22 | 23 |

    Change Log

    24 |

    29 March 2007

    25 | 56 |

    4 Jul 2008

    57 | 63 |

    5 Jul 2008

    64 |
    67 |

    14 Jul 2008

    68 | 76 |

    6 Jan 2009

    77 | 93 |

    21 May 2009

    94 | 101 |

    14 August 2009

    102 | 105 |

    3 October 2009

    106 | 109 |

    19 July 2010

    110 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /doc/assets/vendor/prettify/COPYING: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /doc/assets/vendor/prettify/README.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | Javascript code prettifier 7 | 8 | 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | Languages : CH 20 |

    Javascript code prettifier

    21 | 22 |

    Setup

    23 |
      24 |
    1. Download a distribution 25 |
    2. Include the script and stylesheets in your document 26 | (you will need to make sure the css and js file are on your server, and 27 | adjust the paths in the script and link tag) 28 |
       29 | <link href="prettify.css" type="text/css" rel="stylesheet" />
       30 | <script type="text/javascript" src="prettify.js"></script>
      31 |
    3. Add onload="prettyPrint()" to your 32 | document's body tag. 33 |
    4. Modify the stylesheet to get the coloring you prefer
    5. 34 |
    35 | 36 |

    Usage

    37 |

    Put code snippets in 38 | <pre class="prettyprint">...</pre> 39 | or <code class="prettyprint">...</code> 40 | and it will automatically be pretty printed. 41 | 42 | 43 | 44 | 47 |
    The original 45 | Prettier 46 |
    class Voila {
     49 | public:
     50 |   // Voila
     51 |   static const string VOILA = "Voila";
     52 | 
     53 |   // will not interfere with embedded tags.
     54 | }
    55 | 56 |
    class Voila {
     57 | public:
     58 |   // Voila
     59 |   static const string VOILA = "Voila";
     60 | 
     61 |   // will not interfere with embedded tags.
     62 | }
    63 |
    64 | 65 |

    FAQ

    66 |

    Which languages does it work for?

    67 |

    The comments in prettify.js are authoritative but the lexer 68 | should work on a number of languages including C and friends, 69 | Java, Python, Bash, SQL, HTML, XML, CSS, Javascript, and Makefiles. 70 | It works passably on Ruby, PHP, VB, and Awk and a decent subset of Perl 71 | and Ruby, but, because of commenting conventions, doesn't work on 72 | Smalltalk, or CAML-like languages.

    73 | 74 |

    LISPy languages are supported via an extension: 75 | lang-lisp.js.

    77 |

    And similarly for 78 | CSS, 80 | Haskell, 82 | Lua, 84 | OCAML, SML, F#, 86 | Visual Basic, 88 | SQL, 90 | Protocol Buffers, and 92 | WikiText.. 94 | 95 |

    If you'd like to add an extension for your favorite language, please 96 | look at src/lang-lisp.js and file an 97 | issue including your language extension, and a testcase.

    99 | 100 |

    How do I specify which language my code is in?

    101 |

    You don't need to specify the language since prettyprint() 102 | will guess. You can specify a language by specifying the language extension 103 | along with the prettyprint class like so:

    104 |
    <pre class="prettyprint lang-html">
    106 |   The lang-* class specifies the language file extensions.
    107 |   File extensions supported by default include
    108 |     "bsh", "c", "cc", "cpp", "cs", "csh", "cyc", "cv", "htm", "html",
    109 |     "java", "js", "m", "mxml", "perl", "pl", "pm", "py", "rb", "sh",
    110 |     "xhtml", "xml", "xsl".
    111 | </pre>
    112 | 113 |

    It doesn't work on <obfuscated code sample>?

    114 |

    Yes. Prettifying obfuscated code is like putting lipstick on a pig 115 | — i.e. outside the scope of this tool.

    116 | 117 |

    Which browsers does it work with?

    118 |

    It's been tested with IE 6, Firefox 1.5 & 2, and Safari 2.0.4. 119 | Look at the test page to see if it 120 | works in your browser.

    121 | 122 |

    What's changed?

    123 |

    See the change log

    124 | 125 |

    Why doesn't Prettyprinting of strings work on WordPress?

    126 |

    Apparently wordpress does "smart quoting" which changes close quotes. 127 | This causes end quotes to not match up with open quotes. 128 |

    This breaks prettifying as well as copying and pasting of code samples. 129 | See 130 | WordPress's help center for info on how to stop smart quoting of code 132 | snippets.

    133 | 134 |

    How do I put line numbers in my code?

    135 |

    You can use the linenums class to turn on line 136 | numbering. If your code doesn't start at line number 1, you can 137 | add a colon and a line number to the end of that class as in 138 | linenums:52. 139 | 140 |

    For example 141 |

    <pre class="prettyprint linenums:4"
    142 | >// This is line 4.
    143 | foo();
    144 | bar();
    145 | baz();
    146 | boo();
    147 | far();
    148 | faz();
    149 | <pre>
    150 | produces 151 |
    // This is line 4.
    153 | foo();
    154 | bar();
    155 | baz();
    156 | boo();
    157 | far();
    158 | faz();
    159 | 
    160 | 161 |

    How do I prevent a portion of markup from being marked as code?

    162 |

    You can use the nocode class to identify a span of markup 163 | that is not code. 164 |

    <pre class=prettyprint>
    165 | int x = foo();  /* This is a comment  <span class="nocode">This is not code</span>
    166 |   Continuation of comment */
    167 | int y = bar();
    168 | </pre>
    169 | produces 170 |
    171 | int x = foo();  /* This is a comment  This is not code
    172 |   Continuation of comment */
    173 | int y = bar();
    174 | 
    175 | 176 |

    For a more complete example see the issue22 177 | testcase.

    178 | 179 |

    I get an error message "a is not a function" or "opt_whenDone is not a function"

    180 |

    If you are calling prettyPrint via an event handler, wrap it in a function. 181 | Instead of doing 182 |

    183 | addEventListener('load', prettyPrint, false); 185 |
    186 | wrap it in a closure like 187 |
    188 | addEventListener('load', function (event) { prettyPrint() }, false); 190 |
    191 | so that the browser does not pass an event object to prettyPrint which 192 | will confuse it. 193 | 194 |


    195 | 196 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /doc/assets/vendor/prettify/prettify-min.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} -------------------------------------------------------------------------------- /doc/assets/vendor/prettify/prettify-min.js: -------------------------------------------------------------------------------- 1 | window.PR_SHOULD_USE_CONTINUATION=true;var prettyPrintOne;var prettyPrint;(function(){var O=window;var j=["break,continue,do,else,for,if,return,while"];var v=[j,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var q=[v,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var m=[q,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var y=[q,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var T=[y,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,let,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var,virtual,where"];var s="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes";var x=[q,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var t="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var J=[j,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var g=[j,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var I=[j,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var B=[m,T,x,t+J,g,I];var f=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;var D="str";var A="kwd";var k="com";var Q="typ";var H="lit";var M="pun";var G="pln";var n="tag";var F="dec";var K="src";var R="atn";var o="atv";var P="nocode";var N="(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function l(ab){var af=0;var U=false;var ae=false;for(var X=0,W=ab.length;X122)){if(!(am<65||ai>90)){ah.push([Math.max(65,ai)|32,Math.min(am,90)|32])}if(!(am<97||ai>122)){ah.push([Math.max(97,ai)&~32,Math.min(am,122)&~32])}}}}ah.sort(function(aw,av){return(aw[0]-av[0])||(av[1]-aw[1])});var ak=[];var aq=[];for(var at=0;atau[0]){if(au[1]+1>au[0]){ao.push("-")}ao.push(V(au[1]))}}ao.push("]");return ao.join("")}function Y(an){var al=an.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var aj=al.length;var ap=[];for(var am=0,ao=0;am=2&&ak==="["){al[am]=Z(ai)}else{if(ak!=="\\"){al[am]=ai.replace(/[a-zA-Z]/g,function(aq){var ar=aq.charCodeAt(0);return"["+String.fromCharCode(ar&~32,ar|32)+"]"})}}}}return al.join("")}var ac=[];for(var X=0,W=ab.length;X=0;){U[ae.charAt(ag)]=aa}}var ah=aa[1];var ac=""+ah;if(!ai.hasOwnProperty(ac)){aj.push(ah);ai[ac]=null}}aj.push(/[\0-\uffff]/);X=l(aj)})();var Z=V.length;var Y=function(aj){var ab=aj.sourceCode,aa=aj.basePos;var af=[aa,G];var ah=0;var ap=ab.match(X)||[];var al={};for(var ag=0,at=ap.length;ag=5&&"lang-"===ar.substring(0,5);if(ao&&!(ak&&typeof ak[1]==="string")){ao=false;ar=K}if(!ao){al[ai]=ar}}var ad=ah;ah+=ai.length;if(!ao){af.push(aa+ad,ar)}else{var an=ak[1];var am=ai.indexOf(an);var ae=am+an.length;if(ak[2]){ae=ai.length-ak[2].length;am=ae-an.length}var au=ar.substring(5);C(aa+ad,ai.substring(0,am),Y,af);C(aa+ad+am,an,r(au,an),af);C(aa+ad+ae,ai.substring(ae),Y,af)}}aj.decorations=af};return Y}function i(V){var Y=[],U=[];if(V.tripleQuotedStrings){Y.push([D,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(V.multiLineStrings){Y.push([D,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{Y.push([D,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(V.verbatimStrings){U.push([D,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var ab=V.hashComments;if(ab){if(V.cStyleComments){if(ab>1){Y.push([k,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{Y.push([k,/^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}U.push([D,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,null])}else{Y.push([k,/^#[^\r\n]*/,null,"#"])}}if(V.cStyleComments){U.push([k,/^\/\/[^\r\n]*/,null]);U.push([k,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(V.regexLiterals){var aa=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");U.push(["lang-regex",new RegExp("^"+N+"("+aa+")")])}var X=V.types;if(X){U.push([Q,X])}var W=(""+V.keywords).replace(/^ | $/g,"");if(W.length){U.push([A,new RegExp("^(?:"+W.replace(/[\s,]+/g,"|")+")\\b"),null])}Y.push([G,/^\s+/,null," \r\n\t\xA0"]);var Z=/^.[^\s\w\.$@\'\"\`\/\\]*/;U.push([H,/^@[a-z_$][a-z_$@0-9]*/i,null],[Q,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[G,/^[a-z_$][a-z_$@0-9]*/i,null],[H,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[G,/^\\[\s\S]?/,null],[M,Z,null]);return h(Y,U)}var L=i({keywords:B,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function S(W,ah,aa){var V=/(?:^|\s)nocode(?:\s|$)/;var ac=/\r\n?|\n/;var ad=W.ownerDocument;var ag=ad.createElement("li");while(W.firstChild){ag.appendChild(W.firstChild)}var X=[ag];function af(am){switch(am.nodeType){case 1:if(V.test(am.className)){break}if("br"===am.nodeName){ae(am);if(am.parentNode){am.parentNode.removeChild(am)}}else{for(var ao=am.firstChild;ao;ao=ao.nextSibling){af(ao)}}break;case 3:case 4:if(aa){var an=am.nodeValue;var ak=an.match(ac);if(ak){var aj=an.substring(0,ak.index);am.nodeValue=aj;var ai=an.substring(ak.index+ak[0].length);if(ai){var al=am.parentNode;al.insertBefore(ad.createTextNode(ai),am.nextSibling)}ae(am);if(!aj){am.parentNode.removeChild(am)}}}break}}function ae(al){while(!al.nextSibling){al=al.parentNode;if(!al){return}}function aj(am,at){var ar=at?am.cloneNode(false):am;var ap=am.parentNode;if(ap){var aq=aj(ap,1);var ao=am.nextSibling;aq.appendChild(ar);for(var an=ao;an;an=ao){ao=an.nextSibling;aq.appendChild(an)}}return ar}var ai=aj(al.nextSibling,0);for(var ak;(ak=ai.parentNode)&&ak.nodeType===1;){ai=ak}X.push(ai)}for(var Z=0;Z=U){aj+=2}if(Y>=ar){ac+=2}}}finally{if(au){au.style.display=ak}}}var u={};function d(W,X){for(var U=X.length;--U>=0;){var V=X[U];if(!u.hasOwnProperty(V)){u[V]=W}else{if(O.console){console.warn("cannot override language handler %s",V)}}}}function r(V,U){if(!(V&&u.hasOwnProperty(V))){V=/^\s*]*(?:>|$)/],[k,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[M,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);d(h([[G,/^[\s]+/,null," \t\r\n"],[o,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[n,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[R,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[M,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);d(h([],[[o,/^[\s\S]+/]]),["uq.val"]);d(i({keywords:m,hashComments:true,cStyleComments:true,types:f}),["c","cc","cpp","cxx","cyc","m"]);d(i({keywords:"null,true,false"}),["json"]);d(i({keywords:T,hashComments:true,cStyleComments:true,verbatimStrings:true,types:f}),["cs"]);d(i({keywords:y,cStyleComments:true}),["java"]);d(i({keywords:I,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);d(i({keywords:J,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);d(i({keywords:t,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);d(i({keywords:g,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);d(i({keywords:x,cStyleComments:true,regexLiterals:true}),["js"]);d(i({keywords:s,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);d(h([],[[D,/^[\s\S]+/]]),["regex"]);function e(X){var W=X.langExtension;try{var U=b(X.sourceNode,X.pre);var V=U.sourceCode;X.sourceCode=V;X.spans=U.spans;X.basePos=0;r(W,V)(X);E(X)}catch(Y){if(O.console){console.log(Y&&Y.stack?Y.stack:Y)}}}function z(Y,X,W){var U=document.createElement("pre");U.innerHTML=Y;if(W){S(U,W,true)}var V={langExtension:X,numberLines:W,sourceNode:U,pre:1};e(V);return U.innerHTML}function c(aj){function ab(al){return document.getElementsByTagName(al)}var ah=[ab("pre"),ab("code"),ab("xmp")];var V=[];for(var ae=0;ae]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); -------------------------------------------------------------------------------- /doc/classes/AnimFrameUpdateStrategy.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AnimFrameUpdateStrategy - HTML5-JavaScript-Gamepad-Controller-Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 |
    16 |
    17 | 18 |

    19 | 20 |
    21 |
    22 | API Docs for: 0.0.1 23 |
    24 |
    25 |
    26 | 27 |
    28 | 66 |
    67 |
    68 |
    69 | Show: 70 | 74 | 75 | 79 | 80 | 84 | 88 | 89 |
    90 | 91 | 92 |
    93 |
    94 |
    95 |

    AnimFrameUpdateStrategy Class

    96 |
    97 | 98 | 99 | 100 | 101 | 102 |
    103 | Defined in: gamepad.js:45 104 |
    105 | 106 | 107 | 108 | 109 | Module: Gamepad 110 | 111 | 112 | 113 | 114 |
    115 | 116 | 117 | 118 |
    119 |

    This strategy uses a timer function to call an update function. 120 | The timer (re)start function can be provided or the strategy reverts to 121 | one of the window.*requestAnimationFrame variants.

    122 | 123 |
    124 | 125 | 126 |
    127 |

    Constructor

    128 |
    129 |

    AnimFrameUpdateStrategy

    130 | 131 | 132 |
    133 | (
      134 | 135 |
    • 136 | 137 | [requestAnimationFrame] 138 | 139 |
    • 140 | 141 |
    ) 142 |
    143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 |
    160 | 161 | 162 | 163 |

    164 | 165 | Defined in 166 | 167 | 168 | 169 | 170 | gamepad.js:45 171 | 172 |

    173 | 174 | 175 | 176 | 177 | 178 |
    179 | 180 |
    181 | 182 |
    183 | 184 | 185 |
    186 |

    Parameters:

    187 | 188 |
      189 | 190 |
    • 191 | 192 | [requestAnimationFrame] 193 | Function 194 | optional 195 | 196 | 197 | 198 | 199 |
      200 |

      function to use for timer creation

      201 | 202 |
      203 | 204 | 205 |
    • 206 | 207 |
    208 |
    209 | 210 | 211 | 212 | 213 | 214 |
    215 | 216 |
    217 | 218 | 219 |
    220 |
      221 |
    • Index
    • 222 | 223 | 224 |
    • Methods
    • 225 | 226 | 227 | 228 | 229 |
    230 | 231 |
    232 |
    233 |

    Item Index

    234 | 235 | 236 |
    237 |

    Methods

    238 | 239 |
      240 | 241 |
    • 242 | start 243 | 244 | 245 | 246 |
    • 247 | 248 |
    • 249 | startTicker 250 | 251 | 252 | 253 |
    • 254 | 255 |
    • 256 | tickFunction 257 | 258 | 259 | 260 |
    • 261 | 262 |
    263 |
    264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 |
    272 | 273 | 274 |
    275 |

    Methods

    276 | 277 | 278 |
    279 |

    start

    280 | 281 | 282 |
    283 | (
      284 | 285 |
    • 286 | 287 | updateFunction 288 | 289 |
    • 290 | 291 |
    ) 292 |
    293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 |
    310 | 311 | 312 | 313 |

    314 | 315 | Defined in 316 | 317 | 318 | 319 | 320 | gamepad.js:82 321 | 322 |

    323 | 324 | 325 | 326 | 327 | 328 |
    329 | 330 |
    331 |

    Starts the update strategy using the given function

    332 | 333 |
    334 | 335 | 336 |
    337 |

    Parameters:

    338 | 339 |
      340 | 341 |
    • 342 | 343 | updateFunction 344 | Function 345 | 346 | 347 | 348 | 349 |
      350 |

      the function to call at each update

      351 | 352 |
      353 | 354 | 355 |
    • 356 | 357 |
    358 |
    359 | 360 | 361 | 362 | 363 | 364 |
    365 | 366 | 367 |
    368 |

    startTicker

    369 | 370 | 371 | () 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 |
    389 | 390 | 391 | 392 |

    393 | 394 | Defined in 395 | 396 | 397 | 398 | 399 | gamepad.js:73 400 | 401 |

    402 | 403 | 404 | 405 | 406 | 407 |
    408 | 409 |
    410 |

    (Re)Starts the ticker

    411 | 412 |
    413 | 414 | 415 | 416 | 417 | 418 | 419 |
    420 | 421 | 422 |
    423 |

    tickFunction

    424 | 425 | 426 | () 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 |
    444 | 445 | 446 | 447 |

    448 | 449 | Defined in 450 | 451 | 452 | 453 | 454 | gamepad.js:64 455 | 456 |

    457 | 458 | 459 | 460 | 461 | 462 |
    463 | 464 |
    465 |

    This method calls the (user) update and restarts itself

    466 | 467 |
    468 | 469 | 470 | 471 | 472 | 473 | 474 |
    475 | 476 | 477 |
    478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 |
    486 |
    487 | 488 |
    489 |
    490 |
    491 |
    492 |
    493 |
    494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | -------------------------------------------------------------------------------- /doc/classes/FirefoxPlatform.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FirefoxPlatform - HTML5-JavaScript-Gamepad-Controller-Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 |
    16 |
    17 | 18 |

    19 | 20 |
    21 |
    22 | API Docs for: 0.0.1 23 |
    24 |
    25 |
    26 | 27 |
    28 | 66 |
    67 |
    68 |
    69 | Show: 70 | 74 | 75 | 79 | 80 | 84 | 88 | 89 |
    90 | 91 | 92 |
    93 |
    94 |
    95 |

    FirefoxPlatform Class

    96 |
    97 | 98 | 99 | 100 | 101 | 102 |
    103 | Defined in: gamepad.js:221 104 |
    105 | 106 | 107 | 108 | 109 | Module: Gamepad 110 | 111 | 112 | 113 | 114 |
    115 | 116 | 117 | 118 |
    119 |

    This platform is for mozilla based environments that provide gamepad 120 | updates via events.

    121 | 122 |
    123 | 124 | 125 |
    126 |

    Constructor

    127 |
    128 |

    FirefoxPlatform

    129 | 130 | 131 | () 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 |
    149 | 150 | 151 | 152 |

    153 | 154 | Defined in 155 | 156 | 157 | 158 | 159 | gamepad.js:221 160 | 161 |

    162 | 163 | 164 | 165 | 166 | 167 |
    168 | 169 |
    170 | 171 |
    172 | 173 | 174 | 175 | 176 | 177 | 178 |
    179 | 180 |
    181 | 182 | 183 |
    184 |
      185 |
    • Index
    • 186 | 187 | 188 |
    • Methods
    • 189 | 190 | 191 | 192 | 193 |
    194 | 195 |
    196 |
    197 |

    Item Index

    198 | 199 | 200 |
    201 |

    Methods

    202 | 203 |
      204 | 205 |
    • 206 | factory 207 | 208 | 209 | static 210 | 211 | 212 |
    • 213 | 214 |
    • 215 | getType() 216 | 217 | 218 | static 219 | 220 | 221 |
    • 222 | 223 |
    • 224 | getType() 225 | 226 | 227 | 228 |
    • 229 | 230 |
    • 231 | isSupported 232 | 233 | 234 | 235 |
    • 236 | 237 |
    • 238 | update 239 | 240 | 241 | 242 |
    • 243 | 244 |
    245 |
    246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 |
    254 | 255 | 256 |
    257 |

    Methods

    258 | 259 | 260 |
    261 |

    factory

    262 | 263 | 264 |
    265 | (
      266 | 267 |
    • 268 | 269 | listener 270 | 271 |
    • 272 | 273 |
    ) 274 |
    275 | 276 | 277 | 278 | 279 | Object 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | static 291 | 292 | 293 | 294 | 295 | 296 | 297 |
    298 | 299 | 300 | 301 |

    302 | 303 | Defined in 304 | 305 | 306 | 307 | 308 | gamepad.js:240 309 | 310 |

    311 | 312 | 313 | 314 | 315 | 316 |
    317 | 318 |
    319 |

    Provides a platform object that returns true for isSupported() if valid.

    320 | 321 |
    322 | 323 | 324 |
    325 |

    Parameters:

    326 | 327 |
      328 | 329 |
    • 330 | 331 | listener 332 | Object 333 | 334 | 335 | 336 | 337 |
      338 |

      the listener to use

      339 | 340 |
      341 | 342 | 343 |
    • 344 | 345 |
    346 |
    347 | 348 | 349 | 350 |
    351 |

    Returns:

    352 | 353 |
    354 | 355 | 356 | Object: 357 | 358 |

    a platform object

    359 | 360 | 361 |
    362 |
    363 | 364 | 365 | 366 |
    367 | 368 | 369 |
    370 |

    getType()

    371 | 372 | 373 | () 374 | 375 | 376 | 377 | 378 | String 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | static 390 | 391 | 392 | 393 | 394 | 395 | 396 |
    397 | 398 | 399 | 400 |

    401 | 402 | Defined in 403 | 404 | 405 | 406 | 407 | gamepad.js:257 408 | 409 |

    410 | 411 | 412 | 413 | 414 | 415 |
    416 | 417 |
    418 | 419 |
    420 | 421 | 422 | 423 | 424 |
    425 |

    Returns:

    426 | 427 |
    428 | 429 | 430 | String: 431 | 432 |

    'Firefox'

    433 | 434 | 435 |
    436 |
    437 | 438 | 439 | 440 |
    441 | 442 | 443 |
    444 |

    getType()

    445 | 446 | 447 | () 448 | 449 | 450 | 451 | 452 | String 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 |
    469 | 470 | 471 | 472 |

    473 | 474 | Defined in 475 | 476 | 477 | 478 | 479 | gamepad.js:266 480 | 481 |

    482 | 483 | 484 | 485 | 486 | 487 |
    488 | 489 |
    490 | 491 |
    492 | 493 | 494 | 495 | 496 |
    497 |

    Returns:

    498 | 499 |
    500 | 501 | 502 | String: 503 | 504 |

    'Firefox'

    505 | 506 | 507 |
    508 |
    509 | 510 | 511 | 512 |
    513 | 514 | 515 |
    516 |

    isSupported

    517 | 518 | 519 | () 520 | 521 | 522 | 523 | 524 | Boolean 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 |
    541 | 542 | 543 | 544 |

    545 | 546 | Defined in 547 | 548 | 549 | 550 | 551 | gamepad.js:274 552 | 553 |

    554 | 555 | 556 | 557 | 558 | 559 |
    560 | 561 |
    562 | 563 |
    564 | 565 | 566 | 567 | 568 |
    569 |

    Returns:

    570 | 571 |
    572 | 573 | 574 | Boolean: 575 | 576 |

    true

    577 | 578 | 579 |
    580 |
    581 | 582 | 583 | 584 |
    585 | 586 | 587 |
    588 |

    update

    589 | 590 | 591 | () 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 |
    609 | 610 | 611 | 612 |

    613 | 614 | Defined in 615 | 616 | 617 | 618 | 619 | gamepad.js:283 620 | 621 |

    622 | 623 | 624 | 625 | 626 | 627 |
    628 | 629 |
    630 |

    Does nothing on the Firefox platform

    631 | 632 |
    633 | 634 | 635 | 636 | 637 | 638 | 639 |
    640 | 641 | 642 |
    643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 |
    651 |
    652 | 653 |
    654 |
    655 |
    656 |
    657 |
    658 |
    659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | -------------------------------------------------------------------------------- /doc/classes/ManualUpdateStrategy.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ManualUpdateStrategy - HTML5-JavaScript-Gamepad-Controller-Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 |
    16 |
    17 | 18 |

    19 | 20 |
    21 |
    22 | API Docs for: 0.0.1 23 |
    24 |
    25 |
    26 | 27 |
    28 | 66 |
    67 |
    68 |
    69 | Show: 70 | 74 | 75 | 79 | 80 | 84 | 88 | 89 |
    90 | 91 | 92 |
    93 |
    94 |
    95 |

    ManualUpdateStrategy Class

    96 |
    97 | 98 | 99 | 100 | 101 | 102 |
    103 | Defined in: gamepad.js:93 104 |
    105 | 106 | 107 | 108 | 109 | Module: Gamepad 110 | 111 | 112 | 113 | 114 |
    115 | 116 | 117 | 118 |
    119 |

    This strategy gives the user the ability to call the library internal 120 | update function on request. Use this strategy if you already have a 121 | timer function running by requestAnimationFrame and you need fine control 122 | over when the gamepads are updated.

    123 | 124 |
    125 | 126 | 127 |
    128 |

    Constructor

    129 |
    130 |

    ManualUpdateStrategy

    131 | 132 | 133 | () 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 |
    151 | 152 | 153 | 154 |

    155 | 156 | Defined in 157 | 158 | 159 | 160 | 161 | gamepad.js:93 162 | 163 |

    164 | 165 | 166 | 167 | 168 | 169 |
    170 | 171 |
    172 | 173 |
    174 | 175 | 176 | 177 | 178 | 179 | 180 |
    181 | 182 |
    183 | 184 | 185 |
    186 |
      187 |
    • Index
    • 188 | 189 | 190 |
    • Methods
    • 191 | 192 | 193 | 194 | 195 |
    196 | 197 |
    198 |
    199 |

    Item Index

    200 | 201 | 202 |
    203 |

    Methods

    204 | 205 |
      206 | 207 |
    • 208 | start 209 | 210 | 211 | 212 |
    • 213 | 214 |
    • 215 | update 216 | 217 | 218 | 219 |
    • 220 | 221 |
    222 |
    223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 |
    231 | 232 | 233 |
    234 |

    Methods

    235 | 236 | 237 |
    238 |

    start

    239 | 240 | 241 |
    242 | (
      243 | 244 |
    • 245 | 246 | updateFunction 247 | 248 |
    • 249 | 250 |
    ) 251 |
    252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 |
    269 | 270 | 271 | 272 |

    273 | 274 | Defined in 275 | 276 | 277 | 278 | 279 | gamepad.js:113 280 | 281 |

    282 | 283 | 284 | 285 | 286 | 287 |
    288 | 289 |
    290 |

    Starts the update strategy using the given function

    291 | 292 |
    293 | 294 | 295 |
    296 |

    Parameters:

    297 | 298 |
      299 | 300 |
    • 301 | 302 | updateFunction 303 | Function 304 | 305 | 306 | 307 | 308 |
      309 |

      the function to call at each update

      310 | 311 |
      312 | 313 | 314 |
    • 315 | 316 |
    317 |
    318 | 319 | 320 | 321 | 322 | 323 |
    324 | 325 | 326 |
    327 |

    update

    328 | 329 | 330 | () 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 |
    348 | 349 | 350 | 351 |

    352 | 353 | Defined in 354 | 355 | 356 | 357 | 358 | gamepad.js:107 359 | 360 |

    361 | 362 | 363 | 364 | 365 | 366 |
    367 | 368 |
    369 |

    Calls the update function in the started state. Does nothing otherwise.

    370 | 371 |
    372 | 373 | 374 | 375 | 376 | 377 | 378 |
    379 | 380 | 381 |
    382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 |
    390 |
    391 | 392 |
    393 |
    394 |
    395 |
    396 |
    397 |
    398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | -------------------------------------------------------------------------------- /doc/classes/WebKitPlatform.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebKitPlatform - HTML5-JavaScript-Gamepad-Controller-Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 |
    16 |
    17 | 18 |

    19 | 20 |
    21 |
    22 | API Docs for: 0.0.1 23 |
    24 |
    25 |
    26 | 27 |
    28 | 66 |
    67 |
    68 |
    69 | Show: 70 | 74 | 75 | 79 | 80 | 84 | 88 | 89 |
    90 | 91 | 92 |
    93 |
    94 |
    95 |

    WebKitPlatform Class

    96 |
    97 | 98 | 99 | 100 | 101 | 102 |
    103 | Defined in: gamepad.js:123 104 |
    105 | 106 | 107 | 108 | 109 | Module: Gamepad 110 | 111 | 112 | 113 | 114 |
    115 | 116 | 117 | 118 |
    119 |

    This platform is for webkit based environments that need to be polled 120 | for updates.

    121 | 122 |
    123 | 124 | 125 |
    126 |

    Constructor

    127 |
    128 |

    WebKitPlatform

    129 | 130 | 131 |
    132 | (
      133 | 134 |
    • 135 | 136 | listener 137 | 138 |
    • 139 | 140 |
    • 141 | 142 | gamepadGetter 143 | 144 |
    • 145 | 146 |
    ) 147 |
    148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 |
    165 | 166 | 167 | 168 |

    169 | 170 | Defined in 171 | 172 | 173 | 174 | 175 | gamepad.js:123 176 | 177 |

    178 | 179 | 180 | 181 | 182 | 183 |
    184 | 185 |
    186 | 187 |
    188 | 189 | 190 |
    191 |

    Parameters:

    192 | 193 |
      194 | 195 |
    • 196 | 197 | listener 198 | Object 199 | 200 | 201 | 202 | 203 |
      204 |

      the listener to provide _connect and _disconnect callbacks

      205 | 206 |
      207 | 208 | 209 |
    • 210 | 211 |
    • 212 | 213 | gamepadGetter 214 | Function 215 | 216 | 217 | 218 | 219 |
      220 |

      the poll function to return an array of connected gamepads

      221 | 222 |
      223 | 224 | 225 |
    • 226 | 227 |
    228 |
    229 | 230 | 231 | 232 | 233 | 234 |
    235 | 236 |
    237 | 238 | 239 |
    240 |
      241 |
    • Index
    • 242 | 243 | 244 |
    • Methods
    • 245 | 246 | 247 | 248 | 249 |
    250 | 251 |
    252 |
    253 |

    Item Index

    254 | 255 | 256 |
    257 |

    Methods

    258 | 259 |
      260 | 261 |
    • 262 | factory 263 | 264 | 265 | static 266 | 267 | 268 |
    • 269 | 270 |
    • 271 | getType() 272 | 273 | 274 | static 275 | 276 | 277 |
    • 278 | 279 |
    • 280 | getType() 281 | 282 | 283 | 284 |
    • 285 | 286 |
    • 287 | isSupported 288 | 289 | 290 | 291 |
    • 292 | 293 |
    • 294 | update 295 | 296 | 297 | 298 |
    • 299 | 300 |
    301 |
    302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 |
    310 | 311 | 312 |
    313 |

    Methods

    314 | 315 | 316 |
    317 |

    factory

    318 | 319 | 320 |
    321 | (
      322 | 323 |
    • 324 | 325 | listener 326 | 327 |
    • 328 | 329 |
    ) 330 |
    331 | 332 | 333 | 334 | 335 | Object 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | static 347 | 348 | 349 | 350 | 351 | 352 | 353 |
    354 | 355 | 356 | 357 |

    358 | 359 | Defined in 360 | 361 | 362 | 363 | 364 | gamepad.js:139 365 | 366 |

    367 | 368 | 369 | 370 | 371 | 372 |
    373 | 374 |
    375 |

    Provides a platform object that returns true for isSupported() if valid.

    376 | 377 |
    378 | 379 | 380 |
    381 |

    Parameters:

    382 | 383 |
      384 | 385 |
    • 386 | 387 | listener 388 | Object 389 | 390 | 391 | 392 | 393 |
      394 |

      the listener to use

      395 | 396 |
      397 | 398 | 399 |
    • 400 | 401 |
    402 |
    403 | 404 | 405 | 406 |
    407 |

    Returns:

    408 | 409 |
    410 | 411 | 412 | Object: 413 | 414 |

    a platform object

    415 | 416 | 417 |
    418 |
    419 | 420 | 421 | 422 |
    423 | 424 | 425 |
    426 |

    getType()

    427 | 428 | 429 | () 430 | 431 | 432 | 433 | 434 | String 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | static 446 | 447 | 448 | 449 | 450 | 451 | 452 |
    453 | 454 | 455 | 456 |

    457 | 458 | Defined in 459 | 460 | 461 | 462 | 463 | gamepad.js:169 464 | 465 |

    466 | 467 | 468 | 469 | 470 | 471 |
    472 | 473 |
    474 | 475 |
    476 | 477 | 478 | 479 | 480 |
    481 |

    Returns:

    482 | 483 |
    484 | 485 | 486 | String: 487 | 488 |

    'WebKit'

    489 | 490 | 491 |
    492 |
    493 | 494 | 495 | 496 |
    497 | 498 | 499 |
    500 |

    getType()

    501 | 502 | 503 | () 504 | 505 | 506 | 507 | 508 | String 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 |
    525 | 526 | 527 | 528 |

    529 | 530 | Defined in 531 | 532 | 533 | 534 | 535 | gamepad.js:178 536 | 537 |

    538 | 539 | 540 | 541 | 542 | 543 |
    544 | 545 |
    546 | 547 |
    548 | 549 | 550 | 551 | 552 |
    553 |

    Returns:

    554 | 555 |
    556 | 557 | 558 | String: 559 | 560 |

    'WebKit'

    561 | 562 | 563 |
    564 |
    565 | 566 | 567 | 568 |
    569 | 570 | 571 |
    572 |

    isSupported

    573 | 574 | 575 | () 576 | 577 | 578 | 579 | 580 | Boolean 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 |
    597 | 598 | 599 | 600 |

    601 | 602 | Defined in 603 | 604 | 605 | 606 | 607 | gamepad.js:186 608 | 609 |

    610 | 611 | 612 | 613 | 614 | 615 |
    616 | 617 |
    618 | 619 |
    620 | 621 | 622 | 623 | 624 |
    625 |

    Returns:

    626 | 627 |
    628 | 629 | 630 | Boolean: 631 | 632 |

    true

    633 | 634 | 635 |
    636 |
    637 | 638 | 639 | 640 |
    641 | 642 | 643 |
    644 |

    update

    645 | 646 | 647 | () 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 |
    665 | 666 | 667 | 668 |

    669 | 670 | Defined in 671 | 672 | 673 | 674 | 675 | gamepad.js:194 676 | 677 |

    678 | 679 | 680 | 681 | 682 | 683 |
    684 | 685 |
    686 |

    Queries the currently connected gamepads and reports any changes.

    687 | 688 |
    689 | 690 | 691 | 692 | 693 | 694 | 695 |
    696 | 697 | 698 |
    699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 |
    707 |
    708 | 709 |
    710 |
    711 |
    712 |
    713 |
    714 |
    715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | -------------------------------------------------------------------------------- /doc/classes/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Redirector 5 | 6 | 7 | 8 | Click here to redirect 9 | 10 | 11 | -------------------------------------------------------------------------------- /doc/files/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Redirector 5 | 6 | 7 | 8 | Click here to redirect 9 | 10 | 11 | -------------------------------------------------------------------------------- /doc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HTML5-JavaScript-Gamepad-Controller-Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 |
    16 |
    17 | 18 |

    19 | 20 |
    21 |
    22 | API Docs for: 0.0.1 23 |
    24 |
    25 |
    26 | 27 |
    28 | 66 |
    67 |
    68 |
    69 | Show: 70 | 74 | 75 | 79 | 80 | 84 | 88 | 89 |
    90 | 91 | 92 |
    93 |
    94 |
    95 |
    96 |
    97 |

    98 | Browse to a module or class using the sidebar to view its API documentation. 99 |

    100 | 101 |

    Keyboard Shortcuts

    102 | 103 |
      104 |
    • Press s to focus the API search box.

    • 105 | 106 |
    • Use Up and Down to select classes, modules, and search results.

    • 107 | 108 |
    • With the API search box or sidebar focused, use -Left or -Right to switch sidebar tabs.

    • 109 | 110 |
    • With the API search box or sidebar focused, use Ctrl+Left and Ctrl+Right to switch sidebar tabs.

    • 111 |
    112 |
    113 |
    114 | 115 | 116 | 117 |
    118 |
    119 |
    120 |
    121 |
    122 |
    123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /doc/modules/Gamepad.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Gamepad - HTML5-JavaScript-Gamepad-Controller-Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
    15 |
    16 |
    17 | 18 |

    19 | 20 |
    21 |
    22 | API Docs for: 0.0.1 23 |
    24 |
    25 |
    26 | 27 |
    28 | 66 |
    67 |
    68 |
    69 | Show: 70 | 74 | 75 | 79 | 80 | 84 | 88 | 89 |
    90 | 91 | 92 |
    93 |
    94 |
    95 |

    Gamepad Module

    96 |
    97 | 98 | 99 | 100 | 101 | 102 |
    103 | Defined in: gamepad.js:289 104 |
    105 | 106 | 107 | 108 |
    109 | 110 | 111 | 112 |
    113 |

    This strategy uses a timer function to call an update function. 114 | The timer (re)start function can be provided or the strategy reverts to 115 | one of the window.*requestAnimationFrame variants.

    116 | 117 |
    118 | 119 | 120 | 121 |
    122 |
    123 | 124 |

    This module provides the following classes:

    125 | 126 | 159 | 160 |
    161 | 162 |
    163 | 164 |
    165 |
    166 | 167 |
    168 |
    169 |
    170 |
    171 |
    172 |
    173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /doc/modules/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Redirector 5 | 6 | 7 | 8 | Click here to redirect 9 | 10 | 11 | -------------------------------------------------------------------------------- /gamepad.min.js: -------------------------------------------------------------------------------- 1 | !function(a){"use strict";var b=function(){},c={getType:function(){return"null"},isSupported:function(){return!1},update:b},d=function(a){var c=this,d=window;this.update=b;this.requestAnimationFrame=a||d.requestAnimationFrame||d.webkitRequestAnimationFrame||d.mozRequestAnimationFrame;this.tickFunction=function(){c.update();c.startTicker()};this.startTicker=function(){c.requestAnimationFrame.apply(d,[c.tickFunction])}};d.prototype.start=function(a){this.update=a||b;this.startTicker()};var e=function(){};e.prototype.update=b;e.prototype.start=function(a){this.update=a||b};var f=function(a,b){this.listener=a;this.gamepadGetter=b;this.knownGamepads=[]};f.factory=function(a){var b=c,d=window&&window.navigator;d&&("undefined"!=typeof d.getGamepads?b=new f(a,function(){return d.getGamepads()}):"undefined"!=typeof d.webkitGamepads?b=new f(a,function(){return d.webkitGamepads()}):"undefined"!=typeof d.webkitGetGamepads&&(b=new f(a,function(){return d.webkitGetGamepads()})));return b};f.getType=function(){return"WebKit"},f.prototype.getType=function(){return f.getType()},f.prototype.isSupported=function(){return!0};f.prototype.update=function(){var a,b,c=this,d=Array.prototype.slice.call(this.gamepadGetter(),0);for(b=this.knownGamepads.length-1;b>=0;b--){a=this.knownGamepads[b];if(d.indexOf(a)<0){this.knownGamepads.splice(b,1);this.listener._disconnect(a)}}for(b=0;bc;c++)this._addButtonUpdater(a,d,c);b=d.axes.byAxis.length;for(c=0;b>c;c++)this._addAxisUpdater(a,d,c);this.gamepads[a.index]=a;this._fire(h.Event.CONNECTED,a)};h.prototype._addButtonUpdater=function(a,c,d){var e=b,f=i(h.StandardButtons,d,"EXTRA_BUTTON_"),g=this._createButtonGetter(a,c.buttons,d),j=this,k={gamepad:a,control:f};a.state[f]=0;a.lastState[f]=0;e=function(){var b=g(),c=a.lastState[f],d=b>.5,e=c>.5;a.state[f]=b;d&&!e?j._fire(h.Event.BUTTON_DOWN,Object.create(k)):!d&&e&&j._fire(h.Event.BUTTON_UP,Object.create(k));0!==b&&1!==b&&b!==c&&j._fireAxisChangedEvent(a,f,b);a.lastState[f]=b};a.updater.push(e)};h.prototype._addAxisUpdater=function(a,c,d){var e=b,f=i(h.StandardAxes,d,"EXTRA_AXIS_"),g=this._createAxisGetter(a,c.axes,d),j=this;a.state[f]=0;a.lastState[f]=0;e=function(){var b=g(),c=a.lastState[f];a.state[f]=b;b!==c&&j._fireAxisChangedEvent(a,f,b);a.lastState[f]=b};a.updater.push(e)};h.prototype._fireAxisChangedEvent=function(a,b,c){var d={gamepad:a,axis:b,value:c};this._fire(h.Event.AXIS_CHANGED,d)};h.prototype._createButtonGetter=function(){var a=function(){return 0},b=function(b,c,d){var e=a;d>c?e=function(){var a=d-c,e=b();e=(e-c)/a;return 0>e?0:e}:c>d&&(e=function(){var a=c-d,e=b();e=(e-d)/a;return e>1?0:1-e});return e},c=function(a){return"[object Array]"===Object.prototype.toString.call(a)};return function(d,e,f){var g,h=a,i=this;g=e.byButton[f];if(-1!==g)"number"==typeof g&&g0&&this._fire(h.Event.TICK,this.gamepads)},h.prototype._applyDeadzoneMaximize=function(a,b,c){b="undefined"!=typeof b?b:this.deadzone;c="undefined"!=typeof c?c:this.maximizeThreshold;a>=0?b>a?a=0:a>c&&(a=1):a>-b?a=0:-c>a&&(a=-1);return a};a.Gamepad=h}("undefined"!=typeof module&&module.exports||window); -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | GamePad Library Demo 5 | 6 | 7 | 8 | 9 | 10 |
      11 |

      Connect your controller and press any button.

      12 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HTML5-JavaScript-Gamepad-Controller-Library", 3 | "version": "0.0.1", 4 | "description": "Library for accessing gamepads in modern browsers.", 5 | "homepage": "https://github.com/kallaspriit/HTML5-JavaScript-Gamepad-Controller-Library", 6 | "bugs": "https://github.com/kallaspriit/HTML5-JavaScript-Gamepad-Controller-Library/issues", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/kallaspriit/HTML5-JavaScript-Gamepad-Controller-Library.git" 10 | }, 11 | "dependencies": {}, 12 | "devDependencies": { 13 | "buster": "~0.6.12", 14 | "grunt": "~0.4.1", 15 | "grunt-buster": "git://github.com/busterjs/grunt-buster.git", 16 | "grunt-contrib-jshint": "~0.4.3", 17 | "grunt-contrib-yuidoc": "~0.4.0", 18 | "grunt-jsbeautifier": "~0.1.9", 19 | "grunt-contrib-uglify": "~0.2.2" 20 | }, 21 | "scripts": { 22 | "grunt": "node -e \"require('grunt').tasks();\"" 23 | } 24 | } -------------------------------------------------------------------------------- /test/ButtonGetterTest.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var buster = require('buster'); 5 | var assert = buster.assert; 6 | 7 | buster.testCase('ButtonGetter', { 8 | setUp: function() { 9 | this.Gamepad = require('../gamepad.js').Gamepad; 10 | 11 | this.updater = new this.Gamepad.UpdateStrategies.ManualUpdateStrategy(); 12 | this.obj = new this.Gamepad(this.updater); 13 | }, 14 | 15 | 16 | 'value by button': { 17 | setUp: function() { 18 | var buttons = { 19 | byButton: [0] 20 | }; 21 | 22 | this.gamepad = { 23 | buttons: ['uninitialized'] 24 | }; 25 | 26 | 27 | this.getter = this.obj._createButtonGetter(this.gamepad, buttons, 0); 28 | }, 29 | 30 | 'should be 0 if the raw value is 0': function() { 31 | this.gamepad.buttons[0] = 0; 32 | 33 | var result = this.getter(); 34 | 35 | assert.equals(result, 0); 36 | }, 37 | 38 | 'should be 1 if the raw value is 1': function() { 39 | this.gamepad.buttons[0] = 1; 40 | 41 | var result = this.getter(); 42 | 43 | assert.equals(result, 1); 44 | }, 45 | 46 | 'should be 0.25 if the raw value is 0.25': function() { 47 | this.gamepad.buttons[0] = 0.25; 48 | 49 | var result = this.getter(); 50 | 51 | assert.equals(result, 0.25); 52 | }, 53 | 54 | 'should read GamepadButton objects if available': function() { 55 | function GamepadButton(value) { 56 | this.value = value; 57 | } 58 | this.gamepad.buttons[0] = new GamepadButton(1); 59 | 60 | var result = this.getter(); 61 | 62 | assert.equals(result, 1); 63 | } 64 | }, 65 | 66 | 'value by axis': { 67 | setUp: function() { 68 | this.buttons = { 69 | byButton: [-1], 70 | byAxis: ['uninitialized'] 71 | }; 72 | 73 | this.gamepad = { 74 | axes: ['uninitialized'] 75 | }; 76 | }, 77 | 78 | 'should be 0 for range 0..1 with raw value 0': function() { 79 | this.buttons.byAxis[0] = [0, 0, 1]; 80 | var getter = this.obj._createButtonGetter(this.gamepad, this.buttons, 0); 81 | 82 | this.gamepad.axes[0] = 0; 83 | 84 | var result = getter(); 85 | 86 | assert.equals(result, 0); 87 | }, 88 | 89 | 'should be 1 for range 0..1 with raw value 1': function() { 90 | this.buttons.byAxis[0] = [0, 0, 1]; 91 | var getter = this.obj._createButtonGetter(this.gamepad, this.buttons, 0); 92 | 93 | this.gamepad.axes[0] = 1; 94 | 95 | var result = getter(); 96 | 97 | assert.equals(result, 1); 98 | }, 99 | 100 | 'should be 0.25 for range 0..1 with raw value 0.25': function() { 101 | this.buttons.byAxis[0] = [0, 0, 1]; 102 | var getter = this.obj._createButtonGetter(this.gamepad, this.buttons, 0); 103 | 104 | this.gamepad.axes[0] = 0.25; 105 | 106 | var result = getter(); 107 | 108 | assert.equals(result, 0.25); 109 | }, 110 | 111 | 'should be 0 for range 0..-1 with raw value 0': function() { 112 | this.buttons.byAxis[0] = [0, 0, -1]; 113 | var getter = this.obj._createButtonGetter(this.gamepad, this.buttons, 0); 114 | 115 | this.gamepad.axes[0] = 0; 116 | 117 | var result = getter(); 118 | 119 | assert.equals(result, 0); 120 | }, 121 | 122 | 'should be 1 for range 0..-1 with raw value -1': function() { 123 | this.buttons.byAxis[0] = [0, 0, -1]; 124 | var getter = this.obj._createButtonGetter(this.gamepad, this.buttons, 0); 125 | 126 | this.gamepad.axes[0] = -1; 127 | 128 | var result = getter(); 129 | 130 | assert.equals(result, 1); 131 | }, 132 | 133 | 'should be 0 for range 0..1 with raw value -0.25': function() { 134 | this.buttons.byAxis[0] = [0, 0, 1]; 135 | var getter = this.obj._createButtonGetter(this.gamepad, this.buttons, 0); 136 | 137 | this.gamepad.axes[0] = -0.25; 138 | 139 | var result = getter(); 140 | 141 | assert.equals(result, 0); 142 | }, 143 | 144 | 'should be 0 for range 0..-1 with raw value 0.25': function() { 145 | this.buttons.byAxis[0] = [0, 0, -1]; 146 | var getter = this.obj._createButtonGetter(this.gamepad, this.buttons, 0); 147 | 148 | this.gamepad.axes[0] = 0.25; 149 | 150 | var result = getter(); 151 | 152 | assert.equals(result, 0); 153 | }, 154 | 155 | // seen with PS3 buttons (extra buttons) 156 | 'should be 0 for range -1..1 with raw value -1': function() { 157 | this.buttons.byAxis[0] = [0, -1, 1]; 158 | var getter = this.obj._createButtonGetter(this.gamepad, this.buttons, 0); 159 | 160 | this.gamepad.axes[0] = -1; 161 | 162 | var result = getter(); 163 | 164 | assert.equals(result, 0); 165 | }, 166 | 167 | // seen with PS3 buttons (extra buttons) 168 | 'should be 0.75 for range -1..1 with raw value 0.5': function() { 169 | this.buttons.byAxis[0] = [0, -1, 1]; 170 | var getter = this.obj._createButtonGetter(this.gamepad, this.buttons, 0); 171 | 172 | this.gamepad.axes[0] = 0.5; 173 | 174 | var result = getter(); 175 | 176 | assert.equals(result, 0.75); 177 | } 178 | 179 | } 180 | }); 181 | })(); 182 | -------------------------------------------------------------------------------- /test/FirefoxPlatformTest.js: -------------------------------------------------------------------------------- 1 | /* global global */ 2 | (function() { 3 | 'use strict'; 4 | 5 | var buster = require('buster'); 6 | var assert = buster.assert; 7 | 8 | var GamepadSimulator = require('./GamepadSimulator.js'); 9 | 10 | buster.testCase('Firefox', { 11 | setUp: function() { 12 | var simulator = new GamepadSimulator(); 13 | var nullFunction = function() {}; 14 | 15 | this.simulator = simulator; 16 | global.window = { 17 | addEventListener: nullFunction, 18 | navigator: { 19 | userAgent: 'Firefox' 20 | } 21 | }; 22 | 23 | this.listener = { 24 | _connect: nullFunction, 25 | _disconnect: nullFunction 26 | }; 27 | 28 | this.Gamepad = require('../gamepad.js').Gamepad; 29 | this.platform = this.Gamepad.resolvePlatform(this.listener); 30 | }, 31 | 32 | 'should be supported': function() { 33 | assert(this.platform.isSupported()); 34 | }, 35 | 36 | 'should have type "Firefox"': function() { 37 | var result = this.platform.getType(); 38 | 39 | assert.equals(result, 'Firefox'); 40 | } 41 | 42 | }); 43 | })(); 44 | -------------------------------------------------------------------------------- /test/GamepadMappingTest.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var buster = require('buster'); 5 | var assert = buster.assert; 6 | 7 | var GamepadSimulator = require('./GamepadSimulator.js'); 8 | var PlatformSimulator = require('./PlatformSimulator.js'); 9 | var GamepadUser = require('./GamepadUser.js'); 10 | 11 | /* 12 | * Probes all controls; 13 | * First all buttons (setting their value to 1.0, then reset to 0.0), 14 | * then all axes (first 1.0, then -1.0, then reset to 0.0) 15 | */ 16 | 17 | function probeControls(test) { 18 | var i; 19 | var buttons = test.gamepad.buttons; 20 | var axes = test.gamepad.axes; 21 | 22 | for (i = 0; i < buttons.length; i++) { 23 | buttons[i] = 1.0; 24 | test.updater.update(); 25 | buttons[i] = 0.0; 26 | } 27 | for (i = 0; i < axes.length; i++) { 28 | axes[i] = 1.0; 29 | test.updater.update(); 30 | axes[i] = -1.0; 31 | test.updater.update(); 32 | axes[i] = 0.0; 33 | } 34 | } 35 | 36 | /* 37 | * Tests the report of BUTTON_DOWN with control names for buttons. 38 | * The method first iterates from 0..N of all gamepad buttons and fires them, 39 | * then does the same for all axes. 40 | * 41 | * @param {Object} test the buster test to run in 42 | * @param {Array} expected the expected list of buttons to be reported 43 | */ 44 | 45 | function buttonsTest(test, expected) { 46 | var result = []; 47 | 48 | test.user.onButtonDown = function(data) { 49 | result.push(data.control); 50 | }; 51 | probeControls(test); 52 | 53 | assert.equals(result, expected); 54 | } 55 | 56 | /* 57 | * Tests the report of AXIS_CHANGED with control names for axes. 58 | * The method first iterates from 0..N of all gamepad buttons and fires them, 59 | * then does the same for all axes. 60 | * 61 | * @param {Object} test the buster test to run in 62 | * @param {Array} expected the expected list of axes to be reported 63 | */ 64 | 65 | function axesTest(test, expected) { 66 | var result = []; 67 | 68 | test.user.onAxisChanged = function(data) { 69 | if ((data.value > 0.0) && (result[result.length - 1] !== data.axis)) { 70 | result.push(data.axis); 71 | } 72 | }; 73 | probeControls(test); 74 | 75 | assert.equals(result, expected); 76 | } 77 | 78 | buster.testCase('Gamepad Mapping', { 79 | setUp: function() { 80 | var gamepadSimulator = new GamepadSimulator(); 81 | var that = this; 82 | 83 | this.gamepadSimulator = gamepadSimulator; 84 | 85 | this.Gamepad = require('../gamepad.js').Gamepad; 86 | 87 | this.PlatformFactories = this.Gamepad.PlatformFactories; 88 | this.Gamepad.PlatformFactories = [ 89 | function(listener) { 90 | var platform = that.platform = new PlatformSimulator(listener); 91 | 92 | return platform; 93 | } 94 | ]; 95 | 96 | this.updater = new this.Gamepad.UpdateStrategies.ManualUpdateStrategy(); 97 | 98 | this.obj = new this.Gamepad(this.updater); 99 | this.user = new GamepadUser(this.Gamepad.Event, this.obj); 100 | this.obj.init(); 101 | 102 | }, 103 | 104 | tearDown: function() { 105 | this.Gamepad.PlatformFactories = this.PlatformFactories; 106 | }, 107 | 108 | 'XBOX controller': { 109 | 110 | setUp: function() { 111 | this.gamepad = this.gamepadSimulator.addGamepad(0, 'xbox gamepad', 17); 112 | this.platform.listener._connect(this.gamepad); 113 | }, 114 | 115 | 'should have all buttons mapped': function() { 116 | buttonsTest(this, ['FACE_1', 'FACE_2', 'FACE_3', 'FACE_4', 'LEFT_TOP_SHOULDER', 117 | 'RIGHT_TOP_SHOULDER', 118 | 'LEFT_BOTTOM_SHOULDER', 'RIGHT_BOTTOM_SHOULDER', 119 | 'SELECT_BACK', 'START_FORWARD', 'LEFT_STICK', 'RIGHT_STICK', 120 | 'DPAD_UP', 'DPAD_DOWN', 'DPAD_LEFT', 'DPAD_RIGHT', 121 | 'HOME' 122 | ]); 123 | }, 124 | 125 | 'should have all axes mapped': function() { 126 | axesTest(this, ['LEFT_STICK_X', 'LEFT_STICK_Y', 'RIGHT_STICK_X', 'RIGHT_STICK_Y']); 127 | } 128 | }, 129 | 130 | 'Logitech controller on WebKit': { 131 | setUp: function() { 132 | this.gamepad = this.gamepadSimulator.addGamepad(0, 'logitech gamepad'); 133 | this.platform.type = 'WebKit'; 134 | this.platform.listener._connect(this.gamepad); 135 | }, 136 | 137 | 'should have all buttons mapped': function() { 138 | buttonsTest(this, ['FACE_3', 'FACE_1', 'FACE_2', 'FACE_4', 139 | 'LEFT_TOP_SHOULDER', 'RIGHT_TOP_SHOULDER', 'LEFT_BOTTOM_SHOULDER', 'RIGHT_BOTTOM_SHOULDER', 140 | 'SELECT_BACK', 'START_FORWARD', 'LEFT_STICK', 'HOME', 'RIGHT_STICK', 141 | 'DPAD_UP', 'DPAD_DOWN', 'DPAD_LEFT', 'DPAD_RIGHT' 142 | ]); 143 | }, 144 | 145 | 'should have all axes mapped': function() { 146 | axesTest(this, ['LEFT_STICK_X', 'LEFT_STICK_Y', 'RIGHT_STICK_X', 'RIGHT_STICK_Y']); 147 | } 148 | }, 149 | 150 | 'Logitech controller on Firefox': { 151 | setUp: function() { 152 | this.gamepad = this.gamepadSimulator.addGamepad(0, 'logitech gamepad', 15, 5); 153 | this.platform.type = 'Firefox'; 154 | this.platform.listener._connect(this.gamepad); 155 | }, 156 | 157 | 'should have all buttons mapped': function() { 158 | buttonsTest(this, ['FACE_1', 'FACE_2', 'FACE_3', 'FACE_4', 159 | 'LEFT_TOP_SHOULDER', 'RIGHT_TOP_SHOULDER', 160 | 'SELECT_BACK', 'START_FORWARD', 'LEFT_STICK', 'RIGHT_STICK', 'HOME', 161 | 'DPAD_UP', 'DPAD_DOWN', 'DPAD_LEFT', 'DPAD_RIGHT', 162 | 'LEFT_BOTTOM_SHOULDER', 'RIGHT_BOTTOM_SHOULDER' 163 | ]); 164 | }, 165 | 166 | 'should have all axes mapped': function() { 167 | axesTest(this, ['LEFT_STICK_X', 'LEFT_STICK_Y', 'RIGHT_STICK_X', 'RIGHT_STICK_Y']); 168 | } 169 | }, 170 | 171 | 'Playstation controller on WebKit': { 172 | setUp: function() { 173 | this.gamepad = this.gamepadSimulator.addGamepad(0, 'playstation gamepad', 17); 174 | this.platform.type = 'WebKit'; 175 | this.platform.listener._connect(this.gamepad); 176 | }, 177 | 178 | 'should have all buttons mapped': function() { 179 | buttonsTest(this, ['FACE_1', 'FACE_2', 'FACE_3', 'FACE_4', 'LEFT_TOP_SHOULDER', 180 | 'RIGHT_TOP_SHOULDER', 181 | 'LEFT_BOTTOM_SHOULDER', 'RIGHT_BOTTOM_SHOULDER', 182 | 'SELECT_BACK', 'START_FORWARD', 'LEFT_STICK', 'RIGHT_STICK', 183 | 'DPAD_UP', 'DPAD_DOWN', 'DPAD_LEFT', 'DPAD_RIGHT', 184 | 'HOME' 185 | ]); 186 | }, 187 | 188 | 'should have all axes mapped': function() { 189 | axesTest(this, ['LEFT_STICK_X', 'LEFT_STICK_Y', 'RIGHT_STICK_X', 'RIGHT_STICK_Y']); 190 | } 191 | }, 192 | 193 | 'Playstation controller on Firefox': { 194 | setUp: function() { 195 | this.gamepad = this.gamepadSimulator.addGamepad(0, 'playstation gamepad'); 196 | this.platform.type = 'Firefox'; 197 | this.platform.listener._connect(this.gamepad); 198 | }, 199 | 200 | 'should have all buttons mapped': function() { 201 | buttonsTest(this, ['SELECT_BACK', 'LEFT_STICK', 'RIGHT_STICK', 'START_FORWARD', 202 | 'DPAD_UP', 'DPAD_RIGHT', 'DPAD_DOWN', 'DPAD_LEFT', 203 | 'LEFT_BOTTOM_SHOULDER', 'RIGHT_BOTTOM_SHOULDER', 'LEFT_TOP_SHOULDER', 'RIGHT_TOP_SHOULDER', 204 | 'FACE_4', 'FACE_2', 'FACE_1', 'FACE_3' 205 | ]); 206 | }, 207 | 208 | 'should have all axes mapped': function() { 209 | axesTest(this, ['LEFT_STICK_X', 'LEFT_STICK_Y', 'RIGHT_STICK_X', 'RIGHT_STICK_Y']); 210 | } 211 | }, 212 | 213 | 'Retrolink N64 controller on Firefox': { 214 | setUp: function() { 215 | this.gamepad = this.gamepadSimulator.addGamepad(0, 216 | '79-6-Generic USB Joystick '); 217 | this.platform.type = 'Firefox'; 218 | this.platform.listener._connect(this.gamepad); 219 | }, 220 | 221 | 'should have all buttons mapped': function() { 222 | buttonsTest(this, ['FACE_4', 'FACE_2', 'FACE_1', 'FACE_3', 223 | 'LEFT_TOP_SHOULDER', 'RIGHT_TOP_SHOULDER', 'SELECT_BACK', 224 | 'START_FORWARD', 'DPAD_UP', 'DPAD_DOWN', 'DPAD_LEFT', 225 | 'DPAD_RIGHT' 226 | ]); 227 | }, 228 | 229 | 'should have all axes mapped': function() { 230 | axesTest(this, ['LEFT_STICK_X', 'LEFT_STICK_Y']); 231 | } 232 | }, 233 | 234 | 'Retrolink N64 controller on WebKit': { 235 | setUp: function() { 236 | this.gamepad = this.gamepadSimulator.addGamepad(0, 237 | 'Generic USB Joystick (STANDARD GAMEPAD Vendor: 0079 Product: 0006)'); 238 | this.platform.type = 'WebKit'; 239 | this.platform.listener._connect(this.gamepad); 240 | }, 241 | 242 | 'should have all buttons mapped': function() { 243 | buttonsTest(this, ['FACE_4', 'FACE_2', 'FACE_1', 'FACE_3', 244 | 'LEFT_TOP_SHOULDER', 'RIGHT_TOP_SHOULDER', 'SELECT_BACK', 245 | 'START_FORWARD', 'DPAD_UP', 'DPAD_DOWN', 'DPAD_LEFT', 246 | 'DPAD_RIGHT' 247 | ]); 248 | }, 249 | 250 | 'should have all axes mapped': function() { 251 | axesTest(this, ['LEFT_STICK_X', 'LEFT_STICK_Y']); 252 | } 253 | } 254 | }); 255 | })(); 256 | -------------------------------------------------------------------------------- /test/GamepadSimulator.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var Gamepad = function(index, id, buttonCount, axisCount) { 5 | this.index = index; 6 | this.id = id; 7 | 8 | this.buttons = []; 9 | while (this.buttons.length < (buttonCount || 16)) { 10 | this.buttons.push(0.0); 11 | } 12 | this.axes = []; 13 | while (this.axes.length < (axisCount || 4)) { 14 | this.axes.push(0.0); 15 | } 16 | }; 17 | 18 | var GamepadSimulator = function() { 19 | this.gamepads = []; 20 | }; 21 | 22 | GamepadSimulator.prototype.getGamepads = function() { 23 | return this.gamepads; 24 | }; 25 | 26 | GamepadSimulator.prototype.addGamepad = function(index, id, buttonCount, axisCount) { 27 | var gamepad = new Gamepad(index, id, buttonCount, axisCount); 28 | 29 | while (index >= this.gamepads.length) { 30 | this.gamepads.push(null); 31 | } 32 | this.gamepads[index] = gamepad; 33 | 34 | return gamepad; 35 | }; 36 | 37 | GamepadSimulator.prototype.removeGamepad = function(index) { 38 | this.gamepads[index] = null; 39 | }; 40 | 41 | module.exports = GamepadSimulator; 42 | })(); 43 | -------------------------------------------------------------------------------- /test/GamepadTypeTest.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var buster = require('buster'); 5 | var assert = buster.assert; 6 | 7 | var GamepadSimulator = require('./GamepadSimulator.js'); 8 | var PlatformSimulator = require('./PlatformSimulator.js'); 9 | var GamepadUser = require('./GamepadUser.js'); 10 | 11 | buster.testCase('Gamepad', { 12 | setUp: function() { 13 | var gamepadSimulator = new GamepadSimulator(); 14 | var that = this; 15 | 16 | this.gamepadSimulator = gamepadSimulator; 17 | 18 | this.Gamepad = require('../gamepad.js').Gamepad; 19 | this.PlatformFactories = this.Gamepad.PlatformFactories; 20 | 21 | this.Gamepad.PlatformFactories = [ 22 | function(listener) { 23 | var platform = that.platform = new PlatformSimulator(listener); 24 | 25 | return platform; 26 | } 27 | ]; 28 | 29 | this.updater = new this.Gamepad.UpdateStrategies.ManualUpdateStrategy(); 30 | 31 | this.obj = new this.Gamepad(this.updater); 32 | this.user = new GamepadUser(this.Gamepad.Event, this.obj); 33 | this.obj.init(); 34 | }, 35 | 36 | tearDown: function() { 37 | this.Gamepad.PlatformFactories = this.PlatformFactories; 38 | }, 39 | 40 | 'should cause CONNECTED event when XBOX type added': function() { 41 | var spy = this.spy(this.user, 'onConnected'); 42 | var gamepad = this.gamepadSimulator.addGamepad(0, 'xbox gamepad identificaiton'); 43 | 44 | this.platform.listener._connect(gamepad); 45 | 46 | assert.calledWith(spy, gamepad); 47 | }, 48 | 49 | 'should cause CONNECTED event when platform resolves mapping': function() { 50 | var spy = this.spy(this.user, 'onConnected'); 51 | var gamepad = this.gamepadSimulator.addGamepad(0, 'playstation thingie'); 52 | 53 | this.platform.mapping = {}; 54 | this.platform.listener._connect(gamepad); 55 | 56 | assert.calledWith(spy, gamepad); 57 | } 58 | }); 59 | })(); 60 | -------------------------------------------------------------------------------- /test/GamepadUser.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var nullFunction = function() {}; 5 | 6 | var GamepadUser = function(events, api) { 7 | var that = this; 8 | 9 | function binder(event, handlerName) { 10 | api.bind(event, function() { 11 | that[handlerName].apply(that, arguments); 12 | }); 13 | } 14 | 15 | binder(events.CONNECTED, 'onConnected'); 16 | binder(events.DISCONNECTED, 'onDisconnected'); 17 | binder(events.BUTTON_DOWN, 'onButtonDown'); 18 | binder(events.BUTTON_UP, 'onButtonUp'); 19 | binder(events.AXIS_CHANGED, 'onAxisChanged'); 20 | }; 21 | 22 | GamepadUser.prototype.onConnected = nullFunction; 23 | GamepadUser.prototype.onDisconnected = nullFunction; 24 | GamepadUser.prototype.onButtonDown = nullFunction; 25 | GamepadUser.prototype.onButtonUp = nullFunction; 26 | GamepadUser.prototype.onAxisChanged = nullFunction; 27 | 28 | 29 | module.exports = GamepadUser; 30 | })(); 31 | -------------------------------------------------------------------------------- /test/InterfaceTest.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var buster = require('buster'); 5 | var assert = buster.assert; 6 | 7 | buster.testCase('Gamepad Interface', { 8 | setUp: function() { 9 | this.Gamepad = require('../gamepad.js').Gamepad; 10 | }, 11 | 12 | 'object': { 13 | setUp: function() { 14 | this.obj = new this.Gamepad(new this.Gamepad.UpdateStrategies.ManualUpdateStrategy()); 15 | }, 16 | 17 | 'should be instantiable': function() { 18 | assert.isObject(this.obj); 19 | }, 20 | 21 | 'should provide init method': function() { 22 | assert.isFunction(this.obj.init); 23 | }, 24 | 25 | 'should provide bind method': function() { 26 | assert.isFunction(this.obj.bind); 27 | }, 28 | 29 | 'should provide unbind method': function() { 30 | assert.isFunction(this.obj.unbind); 31 | }, 32 | 33 | 'should provide count method': function() { 34 | assert.isFunction(this.obj.count); 35 | } 36 | } 37 | }); 38 | })(); 39 | -------------------------------------------------------------------------------- /test/PlatformSimulator.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var PlatformSimulator = function(listener) { 5 | this.listener = listener; 6 | this.type = 'Simulator'; 7 | this.mapping = null; 8 | }; 9 | 10 | PlatformSimulator.prototype.getType = function() { 11 | return this.type; 12 | }; 13 | 14 | PlatformSimulator.prototype.isSupported = function() { 15 | return true; 16 | }; 17 | 18 | PlatformSimulator.prototype.update = function() { 19 | 20 | }; 21 | 22 | module.exports = PlatformSimulator; 23 | })(); 24 | -------------------------------------------------------------------------------- /test/PlatformTest.js: -------------------------------------------------------------------------------- 1 | /* global global */ 2 | 3 | (function() { 4 | 'use strict'; 5 | 6 | var buster = require('buster'); 7 | var assert = buster.assert; 8 | var refute = buster.refute; 9 | 10 | buster.testCase('Platform', { 11 | setUp: function() { 12 | this.Gamepad = require('../gamepad.js').Gamepad; 13 | this.obj = new this.Gamepad(new this.Gamepad.UpdateStrategies.ManualUpdateStrategy()); 14 | }, 15 | 16 | 'unsupported should cause init() to return false': function() { 17 | global.window = { 18 | navigator: {} 19 | }; 20 | var result = this.obj.init(); 21 | 22 | refute(result); 23 | }, 24 | 25 | 'Gamepad.getNullPlatform()': { 26 | setUp: function() { 27 | this.platform = this.Gamepad.getNullPlatform(); 28 | }, 29 | 30 | 'should return an object': function() { 31 | assert.isObject(this.platform); 32 | }, 33 | 34 | 'should return false for isSupported()': function() { 35 | refute(this.platform.isSupported()); 36 | }, 37 | 38 | 'should provide update method': function() { 39 | assert.isFunction(this.platform.update); 40 | }, 41 | 42 | 'should provide an immutable object': function() { 43 | this.platform.isSupported = function() { 44 | return true; 45 | }; 46 | 47 | var newObject = this.Gamepad.getNullPlatform(); 48 | 49 | refute.same(newObject, this.platform); 50 | } 51 | }, 52 | 53 | 'Gamepad.resolvePlatform()': { 54 | setUp: function() { 55 | this.PlatformFactories = this.Gamepad.PlatformFactories; 56 | }, 57 | 58 | tearDown: function() { 59 | this.Gamepad.PlatformFactories = this.PlatformFactories; 60 | delete global.window; 61 | }, 62 | 63 | 'should provide unsupported platform when no factories available': function() { 64 | this.Gamepad.PlatformFactories = []; 65 | 66 | var platform = this.Gamepad.resolvePlatform(); 67 | 68 | refute(platform.isSupported()); 69 | }, 70 | 71 | 'should provide platform for polling window.navigator.webkitGamepads array': function() { 72 | global.window = { 73 | navigator: { 74 | webkitGamepads: [1, 2, 3] 75 | } 76 | }; 77 | 78 | var platform = this.Gamepad.resolvePlatform(); 79 | 80 | assert(platform.isSupported()); 81 | }, 82 | 83 | 'should provide platform for polling window.navigator.getGamepads() function': function() { 84 | global.window = { 85 | navigator: { 86 | getGamepads: function() { 87 | return ['game1']; 88 | } 89 | } 90 | }; 91 | 92 | var platform = this.Gamepad.resolvePlatform(); 93 | 94 | assert(platform.isSupported()); 95 | assert(platform.gamepadGetter()[0] === 'game1'); 96 | }, 97 | 98 | 'should provide platform for polling window.navigator.webkitGamepads() function': function() { 99 | global.window = { 100 | navigator: { 101 | webkitGamepads: function() { 102 | return ['game1']; 103 | } 104 | } 105 | }; 106 | 107 | var platform = this.Gamepad.resolvePlatform(); 108 | 109 | assert(platform.isSupported()); 110 | assert(platform.gamepadGetter()[0] === 'game1'); 111 | }, 112 | 113 | 'should provide platform for polling window.navigator.webkitGetGamepads() function': function() { 114 | global.window = { 115 | navigator: { 116 | webkitGetGamepads: function() { 117 | return ['game1']; 118 | } 119 | } 120 | }; 121 | 122 | var platform = this.Gamepad.resolvePlatform(); 123 | 124 | assert(platform.isSupported()); 125 | assert(platform.gamepadGetter()[0] === 'game1'); 126 | }, 127 | 128 | 'should provide platform for Firefox': function() { 129 | global.window = { 130 | addEventListener: function() {}, 131 | navigator: { 132 | userAgent: 'Firefox' 133 | } 134 | }; 135 | 136 | var platform = this.Gamepad.resolvePlatform(); 137 | 138 | assert(platform.isSupported()); 139 | } 140 | 141 | } 142 | }); 143 | })(); 144 | -------------------------------------------------------------------------------- /test/ResolveMappingTest.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | var buster = require('buster'); 5 | var assert = buster.assert; 6 | var refute = buster.refute; 7 | 8 | var GamepadSimulator = require('./GamepadSimulator.js'); 9 | var PlatformSimulator = require('./PlatformSimulator.js'); 10 | var GamepadUser = require('./GamepadUser.js'); 11 | 12 | buster.testCase('Resolve Mapping', { 13 | 'envMatchesFilter()': { 14 | setUp: function() { 15 | this.Gamepad = require('../gamepad.js').Gamepad; 16 | 17 | }, 18 | 19 | 'should return true for empty filter': function() { 20 | var filter = {}; 21 | var env = { 22 | type: 'someType' 23 | }; 24 | var result = this.Gamepad.envMatchesFilter(filter, env); 25 | 26 | assert(result); 27 | }, 28 | 29 | 'should return false for a filter property not found in env': function() { 30 | var filter = { 31 | type: 'logitech' 32 | }; 33 | var env = {}; 34 | var result = this.Gamepad.envMatchesFilter(filter, env); 35 | 36 | refute(result); 37 | }, 38 | 39 | 'should return false for a non matching filter property': function() { 40 | var filter = { 41 | type: 'logitech' 42 | }; 43 | var env = { 44 | type: 'playstation' 45 | }; 46 | var result = this.Gamepad.envMatchesFilter(filter, env); 47 | 48 | refute(result); 49 | }, 50 | 51 | 'should return false for partially not matching type': function() { 52 | var filter = { 53 | platform: 'WebKit', 54 | type: 'logitech' 55 | }; 56 | var env = { 57 | platform: 'WebKit', 58 | type: 'playstation' 59 | }; 60 | var result = this.Gamepad.envMatchesFilter(filter, env); 61 | 62 | refute(result); 63 | }, 64 | 65 | 'should return false for partially not matching platform': function() { 66 | var filter = { 67 | platform: 'Firefox', 68 | type: 'playstation' 69 | }; 70 | var env = { 71 | platform: 'WebKit', 72 | type: 'playstation' 73 | }; 74 | var result = this.Gamepad.envMatchesFilter(filter, env); 75 | 76 | refute(result); 77 | }, 78 | 79 | 'should return true for matching both': function() { 80 | var filter = { 81 | platform: 'Firefox', 82 | type: 'playstation' 83 | }; 84 | var env = { 85 | platform: 'Firefox', 86 | type: 'playstation' 87 | }; 88 | var result = this.Gamepad.envMatchesFilter(filter, env); 89 | 90 | assert(result); 91 | } 92 | }, 93 | 'method ': { 94 | setUp: function() { 95 | var gamepadSimulator = new GamepadSimulator(); 96 | var that = this; 97 | 98 | this.gamepadSimulator = gamepadSimulator; 99 | 100 | this.Gamepad = require('../gamepad.js').Gamepad; 101 | 102 | this.Mappings = this.Gamepad.Mappings; 103 | this.PlatformFactories = this.Gamepad.PlatformFactories; 104 | this.Gamepad.PlatformFactories = [ 105 | function(listener) { 106 | var platform = that.platform = new PlatformSimulator(listener); 107 | 108 | return platform; 109 | } 110 | ]; 111 | 112 | this.updater = new this.Gamepad.UpdateStrategies.ManualUpdateStrategy(); 113 | 114 | this.obj = new this.Gamepad(this.updater); 115 | this.user = new GamepadUser(this.Gamepad.Event, this.obj); 116 | this.obj.init(); 117 | }, 118 | 119 | tearDown: function() { 120 | this.Gamepad.PlatformFactories = this.PlatformFactories; 121 | this.Gamepad.Mappings = this.Mappings; 122 | }, 123 | 124 | 'should return standard mapping if specials empty ': function() { 125 | var gamepad = this.gamepadSimulator.addGamepad(0, 'Logitech stuff '); 126 | this.Gamepad.Mappings = []; 127 | 128 | var result = this.obj._resolveMapping(gamepad); 129 | 130 | assert.equals(result, this.Gamepad.StandardMapping); 131 | }, 132 | 133 | // found under Windows with an old Logitech gamepad 134 | 'should return standard mapping if id empty ': function() { 135 | var gamepad = this.gamepadSimulator.addGamepad(0, ''); 136 | this.Gamepad.Mappings = [{ 137 | env: { 138 | type: this.Gamepad.Type.LOGITECH 139 | } 140 | }]; 141 | 142 | var result = this.obj._resolveMapping(gamepad); 143 | 144 | assert.equals(result, this.Gamepad.StandardMapping); 145 | }, 146 | 147 | 'should return mapping for type if matching': function() { 148 | var gamepad = this.gamepadSimulator.addGamepad(0, 'Playstation stuff'); 149 | var logitechMapping = { 150 | env: { 151 | type: this.Gamepad.Type.PLAYSTATION 152 | } 153 | }; 154 | this.Gamepad.Mappings = [logitechMapping]; 155 | 156 | var result = this.obj._resolveMapping(gamepad); 157 | 158 | assert.equals(result, logitechMapping); 159 | } 160 | } 161 | }); 162 | 163 | })(); 164 | -------------------------------------------------------------------------------- /test/WebKitPlatformTest.js: -------------------------------------------------------------------------------- 1 | /* global global */ 2 | (function() { 3 | 'use strict'; 4 | 5 | var buster = require('buster'); 6 | var assert = buster.assert; 7 | var refute = buster.refute; 8 | 9 | var GamepadSimulator = require('./GamepadSimulator.js'); 10 | 11 | buster.testCase('WebKit', { 12 | setUp: function() { 13 | var simulator = new GamepadSimulator(); 14 | var nullFunction = function() {}; 15 | 16 | this.simulator = simulator; 17 | global.window = { 18 | navigator: { 19 | webkitGetGamepads: function() { 20 | return simulator.getGamepads(); 21 | } 22 | } 23 | }; 24 | 25 | this.listener = { 26 | _connect: nullFunction, 27 | _disconnect: nullFunction 28 | }; 29 | 30 | this.Gamepad = require('../gamepad.js').Gamepad; 31 | this.platform = this.Gamepad.resolvePlatform(this.listener); 32 | }, 33 | 34 | 'should be supported by polling webkitGetGamepads()': function() { 35 | assert(this.platform.isSupported()); 36 | }, 37 | 38 | 'should call nothing if list of gamepads stays empty': function() { 39 | var spy = this.spy(this.listener, '_connect'); 40 | 41 | this.platform.update(); 42 | this.platform.update(); 43 | 44 | refute.called(spy); 45 | }, 46 | 47 | 'should report a connected gamepad if added': function() { 48 | var spy = this.spy(this.listener, '_connect'); 49 | var gamepad = this.simulator.addGamepad(0, 'Testpad1'); 50 | 51 | this.platform.update(); 52 | 53 | assert.calledWith(spy, gamepad); 54 | }, 55 | 56 | 'should call nothing if list of gamepads remains same': function() { 57 | var spy = this.spy(this.listener, '_connect'); 58 | this.simulator.addGamepad(0, 'Testpad1'); 59 | 60 | this.platform.update(); 61 | this.platform.update(); 62 | 63 | assert.calledOnce(spy); 64 | }, 65 | 66 | 'should report a disconnected gamepad if removed': function() { 67 | var spy = this.spy(this.listener, '_disconnect'); 68 | var gamepad = this.simulator.addGamepad(0, 'Testpad1'); 69 | this.platform.update(); 70 | 71 | this.simulator.removeGamepad(0); 72 | this.platform.update(); 73 | 74 | assert.calledWith(spy, gamepad); 75 | }, 76 | 77 | 'should report a second connected gamepad if added': function() { 78 | var spy = this.spy(this.listener, '_connect'); 79 | var gamepad = this.simulator.addGamepad(1, 'Testpad2'); 80 | 81 | this.platform.update(); 82 | 83 | assert.calledWith(spy, gamepad); 84 | }, 85 | 86 | 'should handle connection of second gamepad in same slot': function() { 87 | var spy = this.spy(this.listener, '_connect'); 88 | 89 | this.simulator.addGamepad(0, 'Testpad1'); 90 | this.platform.update(); 91 | 92 | this.simulator.addGamepad(0, 'Testpad2'); 93 | this.platform.update(); 94 | 95 | assert.calledTwice(spy); 96 | }, 97 | 98 | 'should have type "WebKit"': function() { 99 | var result = this.platform.getType(); 100 | 101 | assert.equals(result, 'WebKit'); 102 | } 103 | 104 | }); 105 | })(); 106 | -------------------------------------------------------------------------------- /test/buster.js: -------------------------------------------------------------------------------- 1 | var config = module.exports; 2 | 3 | config['Library tests raw'] = { 4 | rootPath: '../', 5 | environment: 'node', 6 | tests: ['test/**/*Test.js'] 7 | }; 8 | --------------------------------------------------------------------------------