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