Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / chromevox / common / page_selection.js
blobde87d9f69587dcb277fa628a89e91bd8e1b90e23
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.
5 /**
6  * @fileoverview A class representing a DOM selection conveyed through
7  * CursorSelection idioms.
8  * A PageSelection is just a DOM selection. The class itself manages a single
9  * CursorSelection that surrounds a fragment on the page. It also provides an
10  * extend operation to either grow or shrink the selection given a
11  * CursorSelection. The class handles correctly moving the internal
12  * CursorSelection and providing immediate access to a full description of the
13  * selection at any time.
14  */
16 goog.provide('cvox.PageSelection');
18 goog.require('cvox.AbstractEarcons');
19 goog.require('cvox.CursorSelection');
20 goog.require('cvox.NavDescription');
22 /**
23  * @constructor
24  * @param {!cvox.CursorSelection} sel The initial selection.
25  */
26 cvox.PageSelection = function(sel) {
27   this.sel_ = sel.clone();
28   this.sel_.select();
29   this.wasBegin_ = true;
33 /**
34  * Gets a description for the DOM selection during the course of navigation.
35  * @param {cvox.AbstractShifter} navShifter Used to obtain walker-based
36  * descriptions.
37  * @param {!cvox.CursorSelection} prevSel Previous CursorSelection in
38  * navigation.
39  * @param {!cvox.CursorSelection} curSel Current CursorSelection in navigation.
40  * @return {Array<cvox.NavDescription>} The new description.
41  */
42 cvox.PageSelection.prototype.getDescription =
43     function(navShifter, prevSel, curSel) {
44   var desc = [];
45   if (this.sel_.isReversed() != curSel.isReversed()) {
46     // A shrinking selection.
47     desc = navShifter.getDescription(curSel, prevSel);
48     desc[0].annotation = cvox.ChromeVox.msgs.getMsg('describe_unselected');
49     desc[0].pushEarcon(cvox.Earcon.SELECTION_REVERSE);
50   } else {
51     // A growing selection.
52     desc = navShifter.getDescription(prevSel, curSel);
53     desc[0].annotation = cvox.ChromeVox.msgs.getMsg('describe_selected');
54     desc[0].pushEarcon(cvox.Earcon.SELECTION);
55     if (!this.wasBegin_ && this.sel_.absEquals(curSel.clone().normalize())) {
56       // A selection has inverted across the start cursor. Describe it.
57       var prevDesc = navShifter.getDescription(curSel, prevSel);
58       prevDesc[0].annotation =
59           cvox.ChromeVox.msgs.getMsg('describe_unselected');
60       prevDesc[0].pushEarcon(cvox.Earcon.SELECTION_REVERSE);
61       prevDesc[0].pushEarcon(cvox.Earcon.WRAP);
62       desc = prevDesc.concat(desc);
63     }
64   }
65   return desc;
69 /**
70  * Gets a full description for the entire DOM selection.
71  * Use this description when you want to describe the entire selection
72  * represented by this instance.
73  *
74  * @return {Array<cvox.NavDescription>} The new description.
75  */
76 cvox.PageSelection.prototype.getFullDescription = function() {
77   return [new cvox.NavDescription(
78       {text: window.getSelection().toString(),
79        context: cvox.ChromeVox.msgs.getMsg('selection_is')})];
83 /**
84  * Extends this selection.
85  * @param {!cvox.CursorSelection} sel Extend DOM selection to the selection.
86  * @return {boolean} True if the extension occurred, false if the PageSelection
87  * was reset to sel.
88  */
89 cvox.PageSelection.prototype.extend = function(sel) {
90   if (!this.sel_.directedBefore(sel)) {
91     // Do not allow for crossed selections. This restarts a page selection that
92     // has been collapsed. This occurs when two CursorSelection's point away
93     // from one another.
94     this.sel_ = sel.clone();
95   } else {
96     // Otherwise, it is assumed that the CursorSelection's are in directed
97     // document order. The CursorSelection's are either pointing in the same
98     // direction or towards one another. In the first case, shrink/extend this
99     // PageSelection to the end of "sel". In the second case, shrink/extend this
100     // PageSelection to the start of "sel".
101     this.sel_.end = this.sel_.isReversed() == sel.isReversed() ?
102         sel.end.clone() : sel.start.clone();
103   }
104   this.sel_.select();
105   this.wasBegin_ = false;
106   return !this.sel_.absEquals(sel);