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 9 goog.provide('cvox.MathShifter'); 10 11 goog.require('cvox.AbstractShifter'); 12 goog.require('cvox.BrailleUtil'); 13 goog.require('cvox.CursorSelection'); 14 goog.require('cvox.DomUtil'); 15 goog.require('cvox.MathmlStore'); 16 goog.require('cvox.MathmlStoreRules'); 17 goog.require('cvox.NavDescription'); 18 goog.require('cvox.SpeechRuleEngine'); 19 goog.require('cvox.TraverseMath'); 20 21 22 /** 23 * @constructor 24 * @extends {cvox.AbstractShifter} 25 * @param {cvox.CursorSelection=} sel A cursor selection. 26 */ 27 cvox.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 51 cvox.TraverseMath.getInstance().initialize(sel.start.node); 52 }; 53 goog.inherits(cvox.MathShifter, cvox.AbstractShifter); 54 55 56 /** 57 * @override 58 */ 59 cvox.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 */ 71 cvox.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 */ 80 cvox.MathShifter.prototype.getName = function() { 81 return cvox.ChromeVox.msgs.getMsg('math_shifter'); 82 }; 83 84 85 /** 86 * @override 87 */ 88 cvox.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 */ 101 cvox.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 */ 111 cvox.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 */ 120 cvox.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 */ 130 cvox.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 */ 142 cvox.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 */ 165 cvox.MathShifter.prototype.getDomainMsg = function() { 166 return cvox.TraverseMath.getInstance().domain; 167 }; 168