1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @fileoverview Bridge that sends Braille messages from content scripts or 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * other pages to the main background page. 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.provide('cvox.ChromeBraille'); 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.AbstractBraille'); 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.BrailleKeyEvent'); 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.ChromeVoxUserCommands'); 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.require('cvox.HostFactory'); 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @constructor 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @extends {cvox.AbstractBraille} 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeBraille = function() { 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) goog.base(this); 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /** 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @type {function(!cvox.BrailleKeyEvent, cvox.NavBraille)} 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @private 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.commandListener_ = this.defaultCommandListener_; 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /** 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @type {cvox.NavBraille} 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @private 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.lastContent_ = null; 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /** 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @type {string} 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @private 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.lastContentId_ = ''; 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /** 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @type {number} 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @private 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.nextLocalId_ = 1; 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ExtensionBridge.addMessageListener(goog.bind(function(msg, port) { 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Since ChromeVox gets injected into multiple iframes on a page, check to 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // ensure that this is the "active" iframe via its focused state. 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Furthermore, if the active element is itself an iframe, the focus is 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // within the iframe even though the containing document also has focus. 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Don't process the event if this document isn't focused or focus lies in 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // a descendant. 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!document.hasFocus() || document.activeElement.tagName == 'IFRAME') { 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (msg['message'] == 'BRAILLE' && msg['args']) { 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var content = null; 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (msg['contentId'] == this.lastContentId_) { 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content = this.lastContent_; 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.commandListener_(msg['args'], content); 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) }, this)); 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)goog.inherits(cvox.ChromeBraille, cvox.AbstractBraille); 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** @override */ 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeBraille.prototype.write = function(params) { 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.lastContent_ = params; 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.updateLastContentId_(); 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var outParams = params.toJson(); 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var message = {'target': 'BRAILLE', 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'action': 'write', 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'params': outParams, 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'contentId' : this.lastContentId_}; 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cvox.ExtensionBridge.send(message); 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** @private */ 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeBraille.prototype.updateLastContentId_ = function() { 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.lastContentId_ = cvox.ExtensionBridge.uniqueId() + '.' + 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.nextLocalId_++; 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** @override */ 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeBraille.prototype.setCommandListener = function(func) { 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this.commandListener_ = func; 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Dispatches braille input commands. 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {!cvox.BrailleKeyEvent} brailleEvt The braille key event. 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @param {cvox.NavBraille} content display content when command was issued, 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * if available. 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * @private 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.ChromeBraille.prototype.defaultCommandListener_ = function(brailleEvt, 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content) { 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) var command = cvox.ChromeVoxUserCommands.commands[brailleEvt.command]; 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (command) { 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) command({event: brailleEvt, content: content}); 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) console.error('Unknown braille command: ' + JSON.stringify(brailleEvt)); 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)/** Export platform constructor. */ 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)cvox.HostFactory.brailleConstructor = cvox.ChromeBraille; 115