Home | History | Annotate | Download | only in common
      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 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  */
     15 
     16 goog.provide('cvox.PageSelection');
     17 
     18 goog.require('cvox.AbstractEarcons');
     19 goog.require('cvox.CursorSelection');
     20 goog.require('cvox.NavDescription');
     21 
     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;
     30 };
     31 
     32 
     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.AbstractEarcons.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.AbstractEarcons.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.AbstractEarcons.SELECTION_REVERSE);
     61       prevDesc[0].pushEarcon(cvox.AbstractEarcons.WRAP);
     62       desc = prevDesc.concat(desc);
     63     }
     64   }
     65   return desc;
     66 };
     67 
     68 
     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')})];
     80 };
     81 
     82 
     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);
    107 };
    108