| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| /** |
| * @fileoverview A class for walking mathml expressions. |
| */ |
| |
| goog.provide('cvox.MathShifter'); |
| |
| goog.require('cvox.AbstractShifter'); |
| goog.require('cvox.BrailleUtil'); |
| goog.require('cvox.CursorSelection'); |
| goog.require('cvox.DomUtil'); |
| goog.require('cvox.MathmlStore'); |
| goog.require('cvox.MathmlStoreRules'); |
| goog.require('cvox.NavDescription'); |
| goog.require('cvox.SpeechRuleEngine'); |
| goog.require('cvox.TraverseMath'); |
| |
| |
| /** |
| * @constructor |
| * @extends {cvox.AbstractShifter} |
| * @param {cvox.CursorSelection=} sel A cursor selection. |
| */ |
| cvox.MathShifter = function(sel) { |
| goog.base(this); |
| |
| /** |
| * Indicates the depth of the currently read expression. |
| * @type {number} |
| * @private |
| */ |
| this.level_ = 0; |
| |
| /** |
| * Indicates the vertical direction of movement (true for up, false for down). |
| * @type {boolean} |
| * @private |
| */ |
| this.direction_ = false; |
| |
| /** |
| * Indicates whether or not we've bumped against an edge in the math |
| * structure. |
| * @private |
| */ |
| this.bumped_ = false; |
| |
| cvox.TraverseMath.getInstance().initialize(sel.start.node); |
| }; |
| goog.inherits(cvox.MathShifter, cvox.AbstractShifter); |
| |
| |
| /** |
| * @override |
| */ |
| cvox.MathShifter.prototype.next = function(sel) { |
| // Delegate to TraverseMath which manages selection inside of the math tree. |
| var r = sel.isReversed(); |
| this.bumped_ = !cvox.TraverseMath.getInstance().nextSibling(r); |
| var attachedNode = cvox.TraverseMath.getInstance().getAttachedActiveNode(); |
| return attachedNode ? cvox.CursorSelection.fromNode(attachedNode) : sel; |
| }; |
| |
| |
| /** |
| * @override |
| */ |
| cvox.MathShifter.prototype.sync = function(sel) { |
| var attachedNode = cvox.TraverseMath.getInstance().getAttachedActiveNode(); |
| return attachedNode ? cvox.CursorSelection.fromNode(attachedNode) : sel; |
| }; |
| |
| |
| /** |
| * @override |
| */ |
| cvox.MathShifter.prototype.getName = function() { |
| return Msgs.getMsg('math_shifter'); |
| }; |
| |
| |
| /** |
| * @override |
| */ |
| cvox.MathShifter.prototype.getDescription = function(prevSel, sel) { |
| var descs = cvox.SpeechRuleEngine.getInstance().evaluateNode( |
| cvox.TraverseMath.getInstance().activeNode); |
| if (this.bumped_ && descs.length > 0) { |
| descs[0].pushEarcon(cvox.Earcon.WRAP_EDGE); |
| } |
| return descs; |
| }; |
| |
| |
| /** |
| * @override |
| */ |
| cvox.MathShifter.prototype.getBraille = function(prevSel, sel) { |
| return new cvox.NavBraille({ |
| text: cvox.BrailleUtil.getTemplated(prevSel.start.node, sel.start.node) |
| }); |
| }; |
| |
| |
| /** |
| * @override |
| */ |
| cvox.MathShifter.prototype.getGranularityMsg = function() { |
| return this.direction_ ? 'up to level ' + this.level_ : |
| 'down to level ' + this.level_; |
| }; |
| |
| |
| /** |
| * @override |
| */ |
| cvox.MathShifter.prototype.makeLessGranular = function() { |
| this.level_ = this.level_ > 0 ? this.level_ - 1 : 0; |
| this.direction_ = true; |
| this.bumped_ = !cvox.TraverseMath.getInstance().nextParentChild(true); |
| }; |
| |
| |
| /** |
| * @override |
| */ |
| cvox.MathShifter.prototype.makeMoreGranular = function() { |
| this.direction_ = false; |
| this.bumped_ = !cvox.TraverseMath.getInstance().nextParentChild(false); |
| if (!this.bumped_) { |
| this.level_++; |
| } |
| }; |
| |
| |
| /** |
| * @override |
| */ |
| cvox.MathShifter.create = function(sel) { |
| if (cvox.DomPredicates.mathPredicate( |
| cvox.DomUtil.getAncestors(sel.start.node))) { |
| var mathNode = cvox.DomUtil.getContainingMath(sel.end.node); |
| cvox.TraverseMath.getInstance().initialize(mathNode); |
| cvox.SpeechRuleEngine.getInstance().parameterize( |
| cvox.MathmlStore.getInstance()); |
| // TODO (sorge) Embed these changes into a local context menu/options menu. |
| var dynamicCstr = cvox.MathStore.createDynamicConstraint( |
| cvox.TraverseMath.getInstance().domain, |
| cvox.TraverseMath.getInstance().style); |
| cvox.SpeechRuleEngine.getInstance().setDynamicConstraint(dynamicCstr); |
| return new cvox.MathShifter(sel); |
| } |
| return null; |
| }; |
| |
| |
| /** |
| * The active domain of the MathShifter. |
| * |
| * @return {string} The name of the current Math Domain. |
| */ |
| cvox.MathShifter.prototype.getDomainMsg = function() { |
| return cvox.TraverseMath.getInstance().domain; |
| }; |