blob: f9eeb051c731a6452bbae36e26a8071a57b5d710 [file] [log] [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview Handles math output and exploration.
*/
import {AutomationPredicate} from '/common/automation_predicate.js';
import {CursorRange} from '/common/cursors/range.js';
import {Msgs} from '../common/msgs.js';
import {QueueMode} from '../common/tts_types.js';
import {ChromeVox} from './chromevox.js';
import {InternalKeyEvent} from './input/background_keyboard_handler.js';
import AutomationNode = chrome.automation.AutomationNode;
// Speech Rule Engine is included as a global variable in background.html.
declare var SRE: any;
/**
* Handles specialized code to navigate, announce, and interact with math
* content (encoded in MathML).
*/
export class MathHandler {
private node_: AutomationNode;
static instance: MathHandler|undefined = undefined;
private constructor(node: AutomationNode) {
this.node_ = node;
}
/**
* Speaks the current node.
* @return Boolean indicating whether any math was spoken.
*/
speak(): boolean {
const mathml = this.node_.mathContent;
if (!mathml) {
return false;
}
let text: string|null = null;
try {
text = SRE.walk(mathml);
} catch (e) {
// Swallow exceptions from third party library.
}
if (!text) {
return false;
}
ChromeVox.tts.speak(text, QueueMode.FLUSH);
ChromeVox.tts.speak(Msgs.getMsg('hint_math_keyboard'), QueueMode.QUEUE);
return true;
}
/**
* Initializes the global instance.
* @return Boolean indicating whether an instance was created.
*/
static init(range: CursorRange): boolean {
const node = range.start.node;
if (node && AutomationPredicate.math(node)) {
MathHandler.instance = new MathHandler(node);
} else {
MathHandler.instance = undefined;
}
return Boolean(MathHandler.instance);
}
/**
* Handles key events.
* @return Boolean indicating whether an event should propagate.
*/
static onKeyDown(evt: InternalKeyEvent): boolean {
if (!MathHandler.instance) {
return true;
}
if (evt.ctrlKey || evt.altKey || evt.metaKey || evt.shiftKey ||
evt.stickyMode) {
return true;
}
const output: string = SRE.move(evt.keyCode);
if (output) {
ChromeVox.tts.speak(output, QueueMode.FLUSH);
}
return false;
}
}