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 Overlay that shows the current braille display contents,
7 * both as text and braille, on screen in a document.
8 */
9
10goog.provide('cvox.BrailleOverlayWidget');
11
12goog.require('cvox.ExtensionBridge');
13
14/**
15 * @constructor
16 */
17cvox.BrailleOverlayWidget = function() {
18  /**
19   * Whether the widget is active in the prefs.
20   * @type {boolean}
21   * @private
22   */
23  this.active_ = false;
24  /**
25   * @type {Element}
26   * @private
27   */
28  this.containerNode_ = null;
29  /**
30   * @type {Element}
31   * @private
32   */
33  this.contentNode_ = null;
34  /**
35   * @type {Element}
36   * @private
37   */
38  this.brailleNode_ = null;
39};
40goog.addSingletonGetter(cvox.BrailleOverlayWidget);
41
42
43/**
44 * One-time initializer, to be called in a top-level document.  Adds a
45 * listener for braille content messages from the background page.
46 */
47cvox.BrailleOverlayWidget.prototype.init = function() {
48  cvox.ExtensionBridge.addMessageListener(goog.bind(
49      this.onMessage_, this));
50};
51
52
53/**
54 * Sets whether the overlay is active and hides it if it is not active.
55 * @param {boolean} value Whether the overlay is active.
56 */
57cvox.BrailleOverlayWidget.prototype.setActive = function(value) {
58  this.active_ = value;
59  if (!value) {
60    this.hide_();
61  }
62};
63
64
65/**
66 * @return {boolean} Whether the overlay is active according to prefs.
67 */
68cvox.BrailleOverlayWidget.prototype.isActive = function() {
69  return this.active_;
70};
71
72
73/** @private */
74cvox.BrailleOverlayWidget.prototype.show_ = function() {
75  var containerNode = this.createContainerNode_();
76  this.containerNode_ = containerNode;
77
78  var overlayNode = this.createOverlayNode_();
79  containerNode.appendChild(overlayNode);
80
81  this.contentNode_ = document.createElement('div');
82  this.brailleNode_ = document.createElement('div');
83
84  overlayNode.appendChild(this.contentNode_);
85  overlayNode.appendChild(this.brailleNode_);
86
87  document.body.appendChild(containerNode);
88
89  window.setTimeout(function() {
90    containerNode.style['opacity'] = '1.0';
91  }, 0);
92};
93
94
95/**
96 * Hides the overlay if it is shown.
97 * @private
98 */
99// TODO(plundblad): Call when chromevox is deactivated and on some
100// window focus changes.
101cvox.BrailleOverlayWidget.prototype.hide_ = function() {
102  if (this.containerNode_) {
103    var containerNode = this.containerNode_;
104    containerNode.style.opacity = '0.0';
105    window.setTimeout(function() {
106      document.body.removeChild(containerNode);
107    }, 1000);
108    this.containerNode_ = null;
109    this.contentNode_ = null;
110    this.brailleNode_ = null;
111  }
112};
113
114
115/**
116 * @param {string} text The text represnting what was output on the display.
117 * @param {string} brailleChars The Unicode characters representing the
118 *        braille patterns currently on the display.
119 * @private
120 */
121cvox.BrailleOverlayWidget.prototype.setContent_ = function(text, brailleChars) {
122  if (!this.contentNode_) {
123    this.show_();
124  }
125  this.contentNode_.textContent = text;
126  this.brailleNode_.textContent = brailleChars;
127};
128
129
130/**
131 * Create the container node for the braille overlay.
132 *
133 * @return {!Element} The new element, not yet added to the document.
134 * @private
135 */
136cvox.BrailleOverlayWidget.prototype.createContainerNode_ = function() {
137  var containerNode = document.createElement('div');
138  containerNode.id = 'cvox-braille-overlay';
139  containerNode.style['position'] = 'fixed';
140  containerNode.style['top'] = '50%';
141  containerNode.style['left'] = '50%';
142  containerNode.style['-webkit-transition'] = 'all 0.3s ease-in';
143  containerNode.style['opacity'] = '0.0';
144  containerNode.style['z-index'] = '2147483647';
145  containerNode.setAttribute('aria-hidden', 'true');
146  return containerNode;
147};
148
149
150/**
151 * Create the braille overlay.  This should be a child of the node
152 * returned from createContainerNode.
153 *
154 * @return {!Element} The new element, not yet added to the document.
155 * @private
156 */
157cvox.BrailleOverlayWidget.prototype.createOverlayNode_ = function() {
158  var overlayNode = document.createElement('div');
159  overlayNode.style['position'] = 'fixed';
160  overlayNode.style['left'] = '40px';
161  overlayNode.style['bottom'] = '20px';
162  overlayNode.style['line-height'] = '1.2em';
163  overlayNode.style['font-size'] = '20px';
164  overlayNode.style['font-family'] = 'monospace';
165  overlayNode.style['padding'] = '30px';
166  overlayNode.style['min-width'] = '150px';
167  overlayNode.style['color'] = '#fff';
168  overlayNode.style['background-color'] = 'rgba(0, 0, 0, 0.7)';
169  overlayNode.style['border-radius'] = '10px';
170  return overlayNode;
171};
172
173
174/**
175 * Listens for background page messages and show braille content when it
176 * arrives.
177 * @param {Object} msg Message from background page.
178 * @private
179 */
180cvox.BrailleOverlayWidget.prototype.onMessage_ = function(msg) {
181  if (msg['message'] == 'BRAILLE_CAPTION') {
182    this.setContent_(msg['text'], msg['brailleChars']);
183  }
184};
185