summaryrefslogtreecommitdiffstats
path: root/chrome/browser/resources/chromeos/chromevox/common/page_selection.js
blob: ad39e4a59e3e00d0923e3a89949d4167a127b0cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// 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 representing a DOM selection conveyed through
 * CursorSelection idioms.
 * A PageSelection is just a DOM selection. The class itself manages a single
 * CursorSelection that surrounds a fragment on the page. It also provides an
 * extend operation to either grow or shrink the selection given a
 * CursorSelection. The class handles correctly moving the internal
 * CursorSelection and providing immediate access to a full description of the
 * selection at any time.
 */

goog.provide('cvox.PageSelection');

goog.require('cvox.AbstractEarcons');
goog.require('cvox.CursorSelection');
goog.require('cvox.NavDescription');

/**
 * @constructor
 * @param {!cvox.CursorSelection} sel The initial selection.
 */
cvox.PageSelection = function(sel) {
  this.sel_ = sel.clone();
  this.sel_.select();
  this.wasBegin_ = true;
};


/**
 * Gets a description for the DOM selection during the course of navigation.
 * @param {cvox.AbstractShifter} navShifter Used to obtain walker-based
 * descriptions.
 * @param {!cvox.CursorSelection} prevSel Previous CursorSelection in
 * navigation.
 * @param {!cvox.CursorSelection} curSel Current CursorSelection in navigation.
 * @return {Array<cvox.NavDescription>} The new description.
 */
cvox.PageSelection.prototype.getDescription =
    function(navShifter, prevSel, curSel) {
  var desc = [];
  if (this.sel_.isReversed() != curSel.isReversed()) {
    // A shrinking selection.
    desc = navShifter.getDescription(curSel, prevSel);
    desc[0].annotation = cvox.ChromeVox.msgs.getMsg('describe_unselected');
    desc[0].pushEarcon(cvox.AbstractEarcons.SELECTION_REVERSE);
  } else {
    // A growing selection.
    desc = navShifter.getDescription(prevSel, curSel);
    desc[0].annotation = cvox.ChromeVox.msgs.getMsg('describe_selected');
    desc[0].pushEarcon(cvox.AbstractEarcons.SELECTION);
    if (!this.wasBegin_ && this.sel_.absEquals(curSel.clone().normalize())) {
      // A selection has inverted across the start cursor. Describe it.
      var prevDesc = navShifter.getDescription(curSel, prevSel);
      prevDesc[0].annotation =
          cvox.ChromeVox.msgs.getMsg('describe_unselected');
      prevDesc[0].pushEarcon(cvox.AbstractEarcons.SELECTION_REVERSE);
      prevDesc[0].pushEarcon(cvox.AbstractEarcons.WRAP);
      desc = prevDesc.concat(desc);
    }
  }
  return desc;
};


/**
 * Gets a full description for the entire DOM selection.
 * Use this description when you want to describe the entire selection
 * represented by this instance.
 *
 * @return {Array<cvox.NavDescription>} The new description.
 */
cvox.PageSelection.prototype.getFullDescription = function() {
  return [new cvox.NavDescription(
      {text: window.getSelection().toString(),
       context: cvox.ChromeVox.msgs.getMsg('selection_is')})];
};


/**
 * Extends this selection.
 * @param {!cvox.CursorSelection} sel Extend DOM selection to the selection.
 * @return {boolean} True if the extension occurred, false if the PageSelection
 * was reset to sel.
 */
cvox.PageSelection.prototype.extend = function(sel) {
  if (!this.sel_.directedBefore(sel)) {
    // Do not allow for crossed selections. This restarts a page selection that
    // has been collapsed. This occurs when two CursorSelection's point away
    // from one another.
    this.sel_ = sel.clone();
  } else {
    // Otherwise, it is assumed that the CursorSelection's are in directed
    // document order. The CursorSelection's are either pointing in the same
    // direction or towards one another. In the first case, shrink/extend this
    // PageSelection to the end of "sel". In the second case, shrink/extend this
    // PageSelection to the start of "sel".
    this.sel_.end = this.sel_.isReversed() == sel.isReversed() ?
        sel.end.clone() : sel.start.clone();
  }
  this.sel_.select();
  this.wasBegin_ = false;
  return !this.sel_.absEquals(sel);
};