Remove the old signature of NotificationManager::closePersistent().
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / chromevox / braille / pan_strategy.js
blob9984b263efff43d017cd7e99aeb440cd876d7940
1 // Copyright 2015 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.
5 /** @fileoverview Logic for panning a braille display within a line of braille
6  * content that might not fit on a single display.
7  */
9 goog.provide('cvox.PanStrategy');
11 /**
12  * @constructor
13  *
14  * A stateful class that keeps track of the current 'viewport' of a braille
15  * display in a line of content.
16  */
17 cvox.PanStrategy = function() {
18   /**
19    * @type {number}
20    * @private
21    */
22   this.displaySize_ = 0;
23   /**
24    * @type {number}
25    * @private
26    */
27   this.contentLength_ = 0;
28   /**
29    * Points before which it is desirable to break content if it doesn't fit
30    * on the display.
31    * @type {!Array<number>}
32    * @private
33    */
34   this.breakPoints_ = [];
35   /**
36    * @type {!cvox.PanStrategy.Range}
37    * @private
38    */
39   this.viewPort_ = {start: 0, end: 0};
42 /**
43  * A range used to represent the viewport with inclusive start and xclusive
44  * end position.
45  * @typedef {{start: number, end: number}}
46  */
47 cvox.PanStrategy.Range;
49 cvox.PanStrategy.prototype = {
50   /**
51    * Gets the current viewport which is never larger than the current
52    * display size and whose end points are always within the limits of
53    * the current content.
54    * @type {!cvox.PanStrategy.Range}
55    */
56   get viewPort() {
57     return this.viewPort_;
58   },
60   /**
61    * Sets the display size.  This call may update the viewport.
62    * @param {number} size the new display size, or {@code 0} if no display is
63    *     present.
64    */
65   setDisplaySize: function(size) {
66     this.displaySize_ = size;
67     this.panToPosition_(this.viewPort_.start);
68   },
70   /**
71    * Sets the current content that panning should happen within.  This call may
72    * change the viewport.
73    * @param {!ArrayBuffer} translatedContent The new content.
74    * @param {number} targetPosition Target position.  The viewport is changed
75    *     to overlap this position.
76    */
77   setContent: function(translatedContent, targetPosition) {
78     this.breakPoints_ = this.calculateBreakPoints_(translatedContent);
79     this.contentLength_ = translatedContent.byteLength;
80     this.panToPosition_(targetPosition);
81   },
83   /**
84    * If possible, changes the viewport to a part of the line that follows
85    * the current viewport.
86    * @return {boolean} {@code true} if the viewport was changed.
87    */
88   next: function() {
89     var newStart = this.viewPort_.end;
90     var newEnd;
91     if (newStart + this.displaySize_ < this.contentLength_) {
92       newEnd = this.extendRight_(newStart);
93     } else {
94       newEnd = this.contentLength_;
95     }
96     if (newEnd > newStart) {
97       this.viewPort_ = {start: newStart, end: newEnd};
98       return true;
99     }
100     return false;
101   },
103   /**
104    * If possible, changes the viewport to a part of the line that precedes
105    * the current viewport.
106    * @return {boolean} {@code true} if the viewport was changed.
107    */
108   previous: function() {
109     if (this.viewPort_.start > 0) {
110       var newStart, newEnd;
111       if (this.viewPort_.start <= this.displaySize_) {
112         newStart = 0;
113         newEnd = this.extendRight_(newStart);
114       } else {
115         newEnd = this.viewPort_.start;
116         var limit = newEnd - this.displaySize_;
117         newStart = limit;
118         var pos = 0;
119         while (pos < this.breakPoints_.length &&
120             this.breakPoints_[pos] < limit) {
121           pos++;
122         }
123         if (pos < this.breakPoints_.length &&
124             this.breakPoints_[pos] < newEnd) {
125           newStart = this.breakPoints_[pos];
126         }
127       }
128       if (newStart < newEnd) {
129         this.viewPort_ = {start: newStart, end: newEnd};
130         return true;
131       }
132     }
133     return false;
134   },
136   /**
137    * Finds the end position for a new viewport start position, considering
138    * current breakpoints as well as display size and content length.
139    * @param {number} from Start of the region to extend.
140    * @return {number}
141    * @private
142    */
143   extendRight_: function(from) {
144     var limit = Math.min(from + this.displaySize_, this.contentLength_);
145     var pos = 0;
146     var result = limit;
147     while (pos < this.breakPoints_.length && this.breakPoints_[pos] <= from) {
148       pos++;
149     }
150     while (pos < this.breakPoints_.length && this.breakPoints_[pos] <= limit) {
151       result = this.breakPoints_[pos];
152       pos++;
153     }
154     return result;
155   },
157   /**
158    * Overridden by subclasses to provide breakpoints given translated
159    * braille cell content.
160    * @param {!ArrayBuffer} content New display content.
161    * @return {!Array<number>} The points before which it is desirable to break
162    *     content if needed or the empty array if no points are more desirable
163    *     than any position.
164    * @private
165    */
166   calculateBreakPoints_: function(content) {return [];},
168   /**
169    * Moves the viewport so that it overlaps a target position without taking
170    * the current viewport position into consideration.
171    * @param {number} position Target position.
172    */
173   panToPosition_: function(position) {
174     if (this.displaySize_ > 0) {
175       this.viewPort_ = {start: 0, end: 0};
176       while (this.next() && this.viewPort_.end <= position) {
177         // Nothing to do.
178       }
179     } else {
180       this.viewPort_ = {start: position, end: position};
181     }
182   },
186  * A pan strategy that fits as much content on the display as possible, that
187  * is, it doesn't do any wrapping.
188  * @constructor
189  * @extends {cvox.PanStrategy}
190  */
191 cvox.FixedPanStrategy = cvox.PanStrategy;
193  * A pan strategy that tries to wrap 'words' when breaking content.
194  * A 'word' in this context is just a chunk of non-blank braille cells
195  * delimited by blank cells.
196  * @constructor
197  * @extends {cvox.PanStrategy}
198  */
199 cvox.WrappingPanStrategy = function() {
200   cvox.PanStrategy.call(this);
203 cvox.WrappingPanStrategy.prototype = {
204   __proto__: cvox.PanStrategy.prototype,
206   /** @override */
207   calculateBreakPoints_: function(content) {
208     var view = new Uint8Array(content);
209     var newContentLength = view.length;
210     var result = [];
211     var lastCellWasBlank = false;
212     for (var pos = 0; pos < view.length; ++pos) {
213       if (lastCellWasBlank && view[pos] != 0) {
214         result.push(pos);
215       }
216       lastCellWasBlank = (view[pos] == 0);
217     }
218     return result;
219   },