1 /** 2 * LineaBrowser class used to communicate between the Linea device and javascript. 3 * @constructor 4 * @namespace LineaBrowser Class 5 */ 6 LineaBrowser = function (){ 7 var deligates = { 8 buttonPress: [], 9 buttonRelease: [], 10 barcodeData: [], 11 magneticCardData: [], 12 magneticCardRawData: [], 13 magneticCardEncryptedData: [], 14 magneticCardEncryptedRawData: [], 15 connectionState: [], 16 creditCardData: [] 17 }; 18 var scopes = { 19 buttonPress: [], 20 buttonRelease: [], 21 barcodeData: [], 22 magneticCardData: [], 23 magneticCardRawData: [], 24 magneticCardEncryptedData: [], 25 magneticCardEncryptedRawData: [], 26 connectionState: [], 27 creditCardData: [] 28 }; 29 var commandQueue = ''; 30 var addToQueue = function (command, args){ 31 var builtArgs = ''; 32 var len = args.length; 33 for(var i=0;i<len;i++){ 34 if(args[i] instanceof Array) 35 args[i] = args[i].join(','); 36 builtArgs += ':' + args[i]; 37 } 38 if(!commandQueue) 39 commandQueue = 'lineaBrowser://' + command + builtArgs; 40 else 41 commandQueue += '&' + command + builtArgs; 42 window.location.href = commandQueue; 43 }; 44 /** 45 * @lends LineaBrowser 46 */ 47 return { 48 //CONN_STATES 49 /** 50 * For Connection State Changes 51 * @constant 52 */ 53 CONN_DISCONNECTED:0, 54 /** 55 * For Connection State Changes 56 * @constant 57 */ 58 CONN_CONNECTING:1, 59 /** 60 * For Connection State Changes 61 * @constant 62 */ 63 CONN_CONNECTED:2, 64 /** 65 * For Scan Modes 66 * @constant 67 */ 68 MODE_SINGLE_SCAN:0, 69 /** 70 * For Scan Modes 71 * @constant 72 */ 73 MODE_MULTI_SCAN:1, 74 75 /** 76 * For Button States 77 * @constant 78 */ 79 BUTTON_DISABLED:0, 80 /** 81 * For Button States 82 * @constant 83 */ 84 BUTTON_ENABLED:1, 85 /** 86 * For Card Processing 87 * @constant 88 */ 89 MS_PROCESSED_CARD_DATA:0, 90 /** 91 * For Card Processing 92 * @constant 93 */ 94 MS_RAW_CARD_DATA:1, 95 /** 96 * For Barcode Scan Type Return Mode 97 * @constant 98 */ 99 BARCODE_TYPE_DEFAULT:0, 100 /** 101 * For Barcode Scan Type Return Mode 102 * @constant 103 */ 104 BARCODE_TYPE_EXTENDED:1, 105 106 /** 107 * For Naming Barcode Types (used in Scan listeners and Setting any barcode type data) 108 * @type LineaBrowser.BAR_TYPES 109 * @constructor 110 */ 111 BAR_TYPES: { 112 /** @constant */ 113 BAR_ALL: 0, 114 /** @constant */ 115 BAR_UPC: 1, 116 /** @constant */ 117 BAR_CODABAR: 2, 118 /** @constant */ 119 BAR_CODE25_NI2OF5: 3, 120 /** @constant */ 121 BAR_CODE25_I2OF5: 4, 122 /** @constant */ 123 BAR_CODE39: 5, 124 /** @constant */ 125 BAR_CODE93: 6, 126 /** @constant */ 127 BAR_CODE128: 7, 128 /** @constant */ 129 BAR_CODE11: 8, 130 /** @constant */ 131 BAR_CPCBINARY: 9, 132 /** @constant */ 133 BAR_DUN14: 10, 134 /** @constant */ 135 BAR_EAN2: 11, 136 /** @constant */ 137 BAR_EAN5: 12, 138 /** @constant */ 139 BAR_EAN8: 13, 140 /** @constant */ 141 BAR_EAN13: 14, 142 /** @constant */ 143 BAR_EAN128: 15, 144 /** @constant */ 145 BAR_GS1DATABAR: 16, 146 /** @constant */ 147 BAR_ITF14: 17, 148 /** @constant */ 149 BAR_LATENT_IMAGE: 18, 150 /** @constant */ 151 BAR_PHARMACODE: 19, 152 /** @constant */ 153 BAR_PLANET: 20, 154 /** @constant */ 155 BAR_POSTNET: 21, 156 /** @constant */ 157 BAR_INTELLIGENT_MAIL: 22, 158 /** @constant */ 159 BAR_MSI: 23, 160 /** @constant */ 161 BAR_POSTBAR: 24, 162 /** @constant */ 163 BAR_RM4SCC: 25, 164 /** @constant */ 165 BAR_TELEPEN: 26, 166 /** @constant */ 167 BAR_PLESSEY: 27, 168 /** @constant */ 169 BAR_PDF417: 28, 170 /** @constant */ 171 BAR_MICROPDF417: 29, 172 /** @constant */ 173 BAR_DATAMATRIX: 30, 174 /** @constant */ 175 BAR_AZTEK: 31, 176 /** @constant */ 177 BAR_QRCODE: 32, 178 /** @constant */ 179 BAR_MAXICODE: 33, 180 /** @constant */ 181 BAR_LAST: 34, 182 183 /** @constant */ 184 BAR_EX_ALL:0, 185 /** @constant */ 186 BAR_EX_UPCA:1, 187 /** @constant */ 188 BAR_EX_CODABAR:2, 189 /** @constant */ 190 BAR_EX_CODE25_NI2OF5:3, 191 /** @constant */ 192 BAR_EX_CODE25_I2OF5:4, 193 /** @constant */ 194 BAR_EX_CODE39:5, 195 /** @constant */ 196 BAR_EX_CODE93:6, 197 /** @constant */ 198 BAR_EX_CODE128:7, 199 /** @constant */ 200 BAR_EX_CODE11:8, 201 /** @constant */ 202 BAR_EX_CPCBINARY:9, 203 /** @constant */ 204 BAR_EX_DUN14:10, 205 /** @constant */ 206 BAR_EX_EAN2:11, 207 /** @constant */ 208 BAR_EX_EAN5:12, 209 /** @constant */ 210 BAR_EX_EAN8:13, 211 /** @constant */ 212 BAR_EX_EAN13:14, 213 /** @constant */ 214 BAR_EX_EAN128:15, 215 /** @constant */ 216 BAR_EX_GS1DATABAR:16, 217 /** @constant */ 218 BAR_EX_ITF14:17, 219 /** @constant */ 220 BAR_EX_LATENT_IMAGE:18, 221 /** @constant */ 222 BAR_EX_PHARMACODE:19, 223 /** @constant */ 224 BAR_EX_PLANET:20, 225 /** @constant */ 226 BAR_EX_POSTNET:21, 227 /** @constant */ 228 BAR_EX_INTELLIGENT_MAIL:22, 229 /** @constant */ 230 BAR_EX_MSI_PLESSEY:23, 231 /** @constant */ 232 BAR_EX_POSTBAR:24, 233 /** @constant */ 234 BAR_EX_RM4SCC:25, 235 /** @constant */ 236 BAR_EX_TELEPEN:26, 237 /** @constant */ 238 BAR_EX_UK_PLESSEY:27, 239 /** @constant */ 240 BAR_EX_PDF417:28, 241 /** @constant */ 242 BAR_EX_MICROPDF417:29, 243 /** @constant */ 244 BAR_EX_DATAMATRIX:30, 245 /** @constant */ 246 BAR_EX_AZTEK:31, 247 /** @constant */ 248 BAR_EX_QRCODE:32, 249 /** @constant */ 250 BAR_EX_MAXICODE:33, 251 /** @constant */ 252 BAR_EX_RESERVED1:34, 253 /** @constant */ 254 BAR_EX_RESERVED2:35, 255 /** @constant */ 256 BAR_EX_RESERVED3:36, 257 /** @constant */ 258 BAR_EX_RESERVED4:37, 259 /** @constant */ 260 BAR_EX_RESERVED5:38, 261 /** @constant */ 262 BAR_EX_UPCA_2:39, 263 /** @constant */ 264 BAR_EX_UPCA_5:40, 265 /** @constant */ 266 BAR_EX_UPCE:41, 267 /** @constant */ 268 BAR_EX_UPCE_2:42, 269 /** @constant */ 270 BAR_EX_UPCE_5:43, 271 /** @constant */ 272 BAR_EX_EAN13_2:44, 273 /** @constant */ 274 BAR_EX_EAN13_5:45, 275 /** @constant */ 276 BAR_EX_EAN8_2:46, 277 /** @constant */ 278 BAR_EX_EAN8_5:47, 279 /** @constant */ 280 BAR_EX_CODE39_FULL:48, 281 /** @constant */ 282 BAR_EX_ITA_PHARMA:49, 283 /** @constant */ 284 BAR_EX_CODABAR_ABC:50, 285 /** @constant */ 286 BAR_EX_CODABAR_CX:51, 287 /** @constant */ 288 BAR_EX_SCODE:52, 289 /** @constant */ 290 BAR_EX_MATRIX_2OF5:53, 291 /** @constant */ 292 BAR_EX_IATA:54, 293 /** @constant */ 294 BAR_EX_KOREAN_POSTAL:55, 295 /** @constant */ 296 BAR_EX_CCA:56, 297 /** @constant */ 298 BAR_EX_CCB:57, 299 /** @constant */ 300 BAR_EX_CCC:58, 301 /** @constant */ 302 BAR_EX_LAST:59 303 }, 304 /** 305 * Clears the queue of commands about to be sent to the LineaBrowser app. 306 * @public 307 */ 308 clearCommandQueue: function(){ 309 commandQueue = ''; 310 window.location.href = 'javascript:void(0);'; 311 }, 312 /** 313 * Adds an event listener to the specified event. 314 * @param {String} event The event name to attach function to. 315 * @param {Function} fn The function to execute when event fires. 316 * @public 317 */ 318 on: function (event, fn, scope){ 319 if(typeof deligates[event] == 'undefined'){ 320 throw "LineaBrowser.on: first argument must be a valid event."; 321 return false; 322 } 323 if(!(fn instanceof Function)){ 324 throw "LineaBrowser.on: second argument must be of type function."; 325 return false; 326 } 327 deligates[event].push(fn); 328 scopes[event].push(scope || window); 329 return true; 330 }, 331 /** 332 * Removes an event listener. 333 * @param {String} event The event name to search for function in. 334 * @param {Function} fn The function to remove. 335 * @public 336 */ 337 un: function (event, fn){ 338 if(typeof deligates[event] == 'undefined'){ 339 throw "LineaBrowser.un: first argument must be a valid event."; 340 return false; 341 } 342 var len = deligates[event].length; 343 for(var i=0;i<len;i++) 344 if(deligates[event][i] === fn){ 345 deligates[event].splice(i, 1); 346 scopes[event].splice(i, 1); 347 return true; 348 } 349 return false; 350 }, 351 /** 352 * Enables or disables the specified barcode. 353 * @param {Integer} barcodeType The specified barcode of LineaBrowser.BAR_TYPES.* 354 * @param {Boolean} enabled Weather the barcode will be enabled or disabled. 355 * @public 356 */ 357 enableBarcode: function (barcodeType, enabled){ 358 barcodeType = parseInt(barcodeType) || 0; 359 enabled = (enabled)?1:0; 360 addToQueue('enableBarcode', [barcodeType, enabled]); 361 return true; 362 }, 363 /** 364 * Plays a sound though the Linea device. 365 * @param {Integer} volume The volume to play sound at (Currently the Linea device does not support other values than 0 or 100). 366 * @param {Array} beepData An array of data to play. 367 * @example LineaBrowser.playSound(100, [1000, 200, 4000, 100, 100, 500]); // This will play as the following: 1000mhz @ 200ms, 4000mhz @ 100ms, 100mhz @ 500ms 368 * @public 369 */ 370 playSound: function (volume, beepData){ 371 volume = parseInt(volume) || 0; 372 if(!(beepData instanceof Array)){ 373 throw "Error on LineaBrowser.playSound: second argument must be an array"; 374 return false; 375 } 376 var len = beepData.length; 377 for(var i=0;i<len;i++) 378 beepData[i] = parseInt(beepData[i]) || 0; 379 addToQueue('playSound', [volume, beepData]); 380 return true; 381 }, 382 /** 383 * Turns on the barcode lazer (it will accept barcodes). 384 * @public 385 */ 386 startScan: function (){ 387 addToQueue('startScan', []); 388 return true; 389 }, 390 /** 391 * Turns off the barcode lazer (it will stop accepting barcodes). 392 * @public 393 */ 394 stopScan: function (){ 395 addToQueue('stopScan', []); 396 return true; 397 }, 398 /** 399 * Used to turn off the lazer after a the specified amount of time has passed without scanning a barcode. 400 * @param {Integer} timeout The time in seconds to turn off lazer on no barcode scan (0 will never timeout). 401 * @public 402 */ 403 setScanTimeout: function (timeout){ 404 timeout = parseInt(timeout) || 0; 405 addToQueue('setScanTimeout', [timeout]); 406 return true; 407 }, 408 /** 409 * Used to specifiy weather the button on the device will activate the lazer when pressed. (the buttonPress and buttonRelease event will still fire) 410 * @param {Integer} mode One of the following: LineaBrowser.BUTTON_DISABLED or LineaBrowser.BUTTON_ENABLED 411 * @public 412 */ 413 setScanButtonMode: function (mode){ 414 mode = (mode)?1:0; 415 addToQueue('setScanButtonMode', [mode]); 416 return true; 417 }, 418 /** 419 * Used to tell the barcode engine to go into persistant scanning or not. Persistant scanning will keep 420 * the lazer active even when a barcode is scanned allowing you to scan multiple barcodes in sequence 421 * without having to keep pressing and depressing the button. 422 * @param {Integer} mode The mode the barcode engine goes into. Should be on of the following: LineaBrowser.MODE_SINGLE_SCAN or LineaBrowser.MODE_MULTI_SCAN. 423 * @public 424 */ 425 setScanMode: function (mode){ 426 mode = (mode)?1:0; 427 addToQueue('setScanMode', [mode]); 428 return true; 429 }, 430 /** 431 * Sets the beep settings for when a barcode is successfully scanned. 432 * @param {Boolean} Weather the beep should play or not. 433 * @param {Integer} Volume to play the sound at (Currently the Linea device does not support this). 434 * @param {Array} Beep data to send (see LineaBrowser.playSound for more info) 435 * @public 436 */ 437 setScanBeep: function (enabled, volume, beepData){ 438 enabled = (enabled)?1:0; 439 volume = parseInt(volume) || 0; 440 if(!(beepData instanceof Array)){ 441 throw "Error on LineaBrowser.playSound: second argument must be an array"; 442 return false; 443 } 444 if(!(beepData instanceof Array)){ 445 throw "Error on LineaBrowser.setScanBeep: forth argument must be an array"; 446 return false; 447 } 448 var len = beepData.length; 449 for(var i=0;i<len;i++) 450 beepData[i] = parseInt(beepData[i]) || 0; 451 addToQueue('setScanBeep', [enabled, volume, beepData]); 452 return true; 453 }, 454 /** 455 * Hides the config bar at the bottom of the screen to give more realestate or to make your own. (this will resize the window size) 456 * @public 457 */ 458 hideConfigBar:function (){ 459 addToQueue('hideConfigBar', []); 460 return true; 461 }, 462 /** 463 * Shows the config bar at the bottom of the screen. (this will resize the window size) 464 * @public 465 */ 466 showConfigBar: function (){ 467 addToQueue('showConfigBar', []); 468 return true; 469 }, 470 /** 471 * Sets the mode which the card reader data is returned. If MS_PROCESSED_CARD_DATA is used it will return with magneticCardData event 472 * if MS_RAW_CARD_DATA is used it will return the card data with magenticCardRawData. 473 * @param {Integer} mode The mode to use. (should be one of the following LineaBrowser.MS_PROCESSED_CARD_DATA or LineaBrowser.MS_RAW_CARD_DATA) 474 * @public 475 */ 476 setMSCardDataMode: function (mode){ 477 mode = parseInt(mode) || 0; 478 addToQueue('setMSCardDataMode', [mode]); 479 return true; 480 }, 481 /** 482 * Sets which barcode type subset is used for returning. If BARCODE_TYPE_DEFAULT is used it will use 483 * LineaBrowser.BAR_TYPES.*(^_EX) (without the _EX extension). If BARCODE_TYPE_EXTENDED is used it wil 484 * return barcode types using LineaBrowser.BAR_TYPES.*_EX (with the _EX extension). 485 * @param {Integer} mode The mode to return the barcode type as. (Should be one of LineaBrowser.BARCODE_TYPE_DEFAULT or LineaBrowser.BARCODE_TYPE_EXTENDED) 486 * @public 487 */ 488 setBarcodeTypeMode: function (mode){ 489 mode = parseInt(mode) || 0; 490 addToQueue('setBarcodeTypeMode', [mode]); 491 return true; 492 }, 493 /** 494 * This function will be fired when the button is pressed on the LineaDevice. You may attach a listener to this by calling: 495 * <pre><code> 496 * LineaBrowser.on('buttonPressed', function (button){ 497 * // Your Code 498 * }); 499 * </code></pre> 500 * The first parameter is which button was pressed, however it will always return 0 currently. 501 * @private 502 */ 503 buttonPressed: function (){ 504 var len = deligates.buttonPress.length; 505 for(var i=0;i<len;i++) 506 deligates.buttonPress[i].apply(scopes.buttonPress[i], arguments); 507 }, 508 /** 509 * This function will be fired when the button is released on the LineaDevice. You may attach a listener to this by calling: 510 * <pre><code> 511 * LineaBrowser.on('buttonReleased', function (button){ 512 * // Your Code 513 * }); 514 * </code></pre> 515 * The first parameter is which button was pressed, however it will always return 0 currently. 516 * @private 517 */ 518 buttonReleased: function (){ 519 var len = deligates.buttonRelease.length; 520 for(var i=0;i<len;i++) 521 deligates.buttonRelease[i].apply(scopes.buttonRelease[i], arguments); 522 }, 523 /** 524 * This function will be fired when a card is successfully read on the LineaDevice. You may attach a listener to this by calling: 525 * <pre><code> 526 * LineaBrowser.on('magneticCardData', function (track1, track2, track3){ 527 * // Your Code 528 * }); 529 * </code></pre> 530 * The parameters passed are track1, track2, and track3. 531 * @private 532 */ 533 magneticCardData: function (){ 534 var len = deligates.magneticCardData.length; 535 for(var i=0;i<len;i++) 536 deligates.magneticCardData[i].apply(scopes.magneticCardData[i], arguments); 537 }, 538 /** 539 * Currently not fully supported! 540 */ 541 magneticCardRawData: function (){ 542 var len = deligates.magneticCardRawData.length; 543 for(var i=0;i<len;i++) 544 deligates.magneticCardRawData[i].apply(scopes.magneticCardRawData[i], arguments); 545 }, 546 /** 547 * Currently not fully supported! 548 */ 549 magneticCardEncryptedData: function (){ 550 var len = deligates.magneticCardEncryptedData.length; 551 for(var i=0;i<len;i++) 552 deligates.magneticCardEncryptedData[i].apply(scopes.magneticCardEncryptedData[i], arguments); 553 }, 554 /** 555 * Currently not fully supported! 556 */ 557 magneticCardEncryptedRawData: function (){ 558 var len = deligates.magneticCardEncryptedRawData.length; 559 for(var i=0;i<len;i++) 560 deligates.magneticCardEncryptedRawData[i].apply(scopes.magneticCardEncryptedRawData[i], arguments); 561 }, 562 /** 563 * This function will be fired when a barcode is successfully read on the LineaDevice. You may attach a listener to this by calling: 564 * <pre><code> 565 * LineaBrowser.on('barcodeData', function (barcode, type){ 566 * // Your Code 567 * }); 568 * </code></pre> 569 * The first argument is the barcode's data as a string and the second argument is the 570 * barcode type as an integer which should correspond to the number in LineaBrowser.BAR_TYPES.*(_EX)? 571 * @private 572 */ 573 barcodeData: function (){ 574 var len = deligates.barcodeData.length; 575 for(var i=0;i<len;i++) 576 deligates.barcodeData[i].apply(scopes.barcodeData[i], arguments); 577 }, 578 /** 579 * This function will be fired when the LineaDevice changes connection state. You may attach a listener to this by calling: 580 * <pre><code> 581 * LineaBrowser.on('connectionState', function (state){ 582 * // Your Code 583 * }); 584 * </code></pre> 585 * The first parameter is the state corresponding to LineaBrowser.CONN_* for which state it was changed into. 586 * @private 587 */ 588 connectionState: function (){ 589 var len = deligates.connectionState.length; 590 for(var i=0;i<len;i++) 591 deligates.connectionState[i].apply(scopes.connectionState[i], arguments); 592 }, 593 /** 594 * This function will be fired when the LineaDevice reads a credit card. You may attach a listener to this by calling: 595 * <pre><code> 596 * LineaBrowser.on('creditCardData', function (accountNumber, cardholderName, experationYear, experationMonth, serviceCode, discretionaryData, firstName, lastName){ 597 * // Your Code 598 * }); 599 * </code></pre> 600 * See above for the parameters passed and their names. 601 * @private 602 */ 603 creditCardData: function (){ 604 var len = deligates.creditCardData.length; 605 for(var i=0;i<len;i++) 606 deligates.creditCardData[i].apply(scopes.creditCardData[i], arguments); 607 } 608 }; 609 }(); 610 if(window.onLineaBrowserLoad) 611 /** 612 * This custom function gets called when the the Linea Browser API loads and is ready to send and receive commands. 613 * @function 614 * @exmple 615 * window.onLineaBrowserLoad = function (){ 616 * LineaBrowser.playSound(100, [1000, 200, 4000, 100, 100, 500]); 617 * }; 618 */ 619 window.onLineaBrowserLoad();