| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- /**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
- 'use strict';
- import Position from '../position.js';
- import TreeWalker from '../treewalker.js';
- import Range from '../range.js';
- /**
- * Modifies the selection. Currently the supported modifications are:
- *
- * * Extending. The selection focus is moved in the specified `options.direction` with a step specified in `options.unit`
- * (defaults to `'CHARACTER'`, other values are not not yet supported).
- * Note: if you extend a forward selection in a backward direction you will in fact shrink it.
- *
- * @method engine.treeModel.composer.modifySelection
- * @param {engine.treeModel.Selection} The selection to modify.
- * @param {Object} [options]
- * @param {'FORWARD'|'BACKWARD'} [options.direction='FORWARD'] The direction in which the selection should be modified.
- */
- export default function modifySelection( selection, options = {} ) {
- const isForward = options.direction != 'BACKWARD';
- const focus = selection.focus;
- const walker = new TreeWalker( {
- boundaries: getSearchRange( focus, isForward ),
- singleCharacters: true,
- direction: isForward ? 'FORWARD' : 'BACKWARD'
- } );
- let next = walker.next();
- // 1. Nothing to do here.
- if ( next.done ) {
- return;
- }
- let value = next.value;
- // 2. Consume next character.
- if ( value.type == 'CHARACTER' ) {
- selection.setFocus( value.nextPosition );
- return;
- }
- // 3. We're entering an element, so let's consume it fully.
- if ( value.type == ( isForward ? 'ELEMENT_START' : 'ELEMENT_END' ) ) {
- selection.setFocus( value.item, isForward ? 'AFTER' : 'BEFORE' );
- return;
- }
- // 4. We're leaving an element. That's more tricky.
- next = walker.next();
- // 4.1. Nothing left, so let's stay where we were.
- if ( next.done ) {
- return;
- }
- // Replace TreeWalker step wrapper by clean step value.
- value = next.value;
- // 4.2. Character found after element end. Not really a valid case in our data model, but let's
- // do something sensible and put the selection focus before that character.
- if ( value.type == 'CHARACTER' ) {
- selection.setFocus( value.previousPosition );
- }
- // 4.3. OK, we're entering a new element. So let's place there the focus.
- else {
- selection.setFocus( value.item, isForward ? 0 : 'END' );
- }
- }
- function getSearchRange( start, isForward ) {
- const root = start.root;
- const searchEnd = Position.createAt( root, isForward ? 'END' : 0 );
- if ( isForward ) {
- return new Range( start, searchEnd );
- } else {
- return new Range( searchEnd, start );
- }
- }
|