math_shifter.js revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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 A class for walking mathml expressions. 7 */ 8 9goog.provide('cvox.MathShifter'); 10 11goog.require('cvox.AbstractShifter'); 12goog.require('cvox.BrailleUtil'); 13goog.require('cvox.CursorSelection'); 14goog.require('cvox.DomUtil'); 15goog.require('cvox.MathmlStore'); 16goog.require('cvox.MathmlStoreRules'); 17goog.require('cvox.NavDescription'); 18goog.require('cvox.SpeechRuleEngine'); 19goog.require('cvox.TraverseMath'); 20 21 22/** 23 * @constructor 24 * @extends {cvox.AbstractShifter} 25 * @param {cvox.CursorSelection=} sel A cursor selection. 26 */ 27cvox.MathShifter = function(sel) { 28 goog.base(this); 29 30 /** 31 * Indicates the depth of the currently read expression. 32 * @type {number} 33 * @private 34 */ 35 this.level_ = 0; 36 37 /** 38 * Indicates the vertical direction of movement (true for up, false for down). 39 * @type {boolean} 40 * @private 41 */ 42 this.direction_ = false; 43 44 /** 45 * Indicates whether or not we've bumped against an edge in the math 46 * structure. 47 * @private 48 */ 49 this.bumped_ = false; 50 51cvox.TraverseMath.getInstance().initialize(sel.start.node); 52}; 53goog.inherits(cvox.MathShifter, cvox.AbstractShifter); 54 55 56/** 57 * @override 58 */ 59cvox.MathShifter.prototype.next = function(sel) { 60 // Delegate to TraverseMath which manages selection inside of the math tree. 61 var r = sel.isReversed(); 62 this.bumped_ = !cvox.TraverseMath.getInstance().nextSibling(r); 63 var attachedNode = cvox.TraverseMath.getInstance().getAttachedActiveNode(); 64 return attachedNode ? cvox.CursorSelection.fromNode(attachedNode) : sel; 65}; 66 67 68/** 69 * @override 70 */ 71cvox.MathShifter.prototype.sync = function(sel) { 72 var attachedNode = cvox.TraverseMath.getInstance().getAttachedActiveNode(); 73 return attachedNode ? cvox.CursorSelection.fromNode(attachedNode) : sel; 74}; 75 76 77/** 78 * @override 79 */ 80cvox.MathShifter.prototype.getName = function() { 81 return cvox.ChromeVox.msgs.getMsg('math_shifter'); 82}; 83 84 85/** 86 * @override 87 */ 88cvox.MathShifter.prototype.getDescription = function(prevSel, sel) { 89 var descs = cvox.SpeechRuleEngine.getInstance().evaluateNode( 90 cvox.TraverseMath.getInstance().activeNode); 91 if (this.bumped_ && descs.length > 0) { 92 descs[0].pushEarcon(cvox.AbstractEarcons.WRAP_EDGE); 93 } 94 return descs; 95}; 96 97 98/** 99 * @override 100 */ 101cvox.MathShifter.prototype.getBraille = function(prevSel, sel) { 102 return new cvox.NavBraille({ 103 text: cvox.BrailleUtil.getTemplated(prevSel.start.node, sel.start.node) 104 }); 105}; 106 107 108/** 109 * @override 110 */ 111cvox.MathShifter.prototype.getGranularityMsg = function() { 112 return this.direction_ ? 'up to level ' + this.level_ : 113 'down to level ' + this.level_; 114}; 115 116 117/** 118 * @override 119 */ 120cvox.MathShifter.prototype.makeLessGranular = function() { 121 this.level_ = this.level_ > 0 ? this.level_ - 1 : 0; 122 this.direction_ = true; 123 this.bumped_ = !cvox.TraverseMath.getInstance().nextParentChild(true); 124}; 125 126 127/** 128 * @override 129 */ 130cvox.MathShifter.prototype.makeMoreGranular = function() { 131 this.direction_ = false; 132 this.bumped_ = !cvox.TraverseMath.getInstance().nextParentChild(false); 133 if (!this.bumped_) { 134 this.level_++; 135 } 136}; 137 138 139/** 140 * @override 141 */ 142cvox.MathShifter.create = function(sel) { 143 if (cvox.DomPredicates.mathPredicate( 144 cvox.DomUtil.getAncestors(sel.start.node))) { 145 var mathNode = cvox.DomUtil.getContainingMath(sel.end.node); 146 cvox.TraverseMath.getInstance().initialize(mathNode); 147 cvox.SpeechRuleEngine.getInstance().parameterize( 148 cvox.MathmlStore.getInstance()); 149 // TODO (sorge) Embed these changes into a local context menu/options menu. 150 var dynamicCstr = cvox.MathStore.createDynamicConstraint( 151 cvox.TraverseMath.getInstance().domain, 152 cvox.TraverseMath.getInstance().style); 153 cvox.SpeechRuleEngine.getInstance().setDynamicConstraint(dynamicCstr); 154 return new cvox.MathShifter(sel); 155 } 156 return null; 157}; 158 159 160/** 161 * The active domain of the MathShifter. 162 * 163 * @return {string} The name of the current Math Domain. 164 */ 165cvox.MathShifter.prototype.getDomainMsg = function() { 166 return cvox.TraverseMath.getInstance().domain; 167}; 168