blob: 1f866772fceb17ab0bacc8fa492d7275b3a2cfe4 [file] [log] [blame]
// 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 = Msgs.getMsg('describe_unselected');
desc[0].pushEarcon(cvox.Earcon.SELECTION_REVERSE);
} else {
// A growing selection.
desc = navShifter.getDescription(prevSel, curSel);
desc[0].annotation = Msgs.getMsg('describe_selected');
desc[0].pushEarcon(cvox.Earcon.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 = Msgs.getMsg('describe_unselected');
prevDesc[0].pushEarcon(cvox.Earcon.SELECTION_REVERSE);
prevDesc[0].pushEarcon(cvox.Earcon.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: 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);
};