Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Added: Support for "word" unit in modifyselection() helper.
Browse files Browse the repository at this point in the history
  • Loading branch information
jodator committed Feb 7, 2018
1 parent c2d4cec commit 1b76554
Show file tree
Hide file tree
Showing 2 changed files with 361 additions and 3 deletions.
25 changes: 22 additions & 3 deletions src/model/utils/modifyselection.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import DocumentSelection from '../documentselection';
* For example `𨭎` is represented in `String` by `\uD862\uDF4E`. Both `\uD862` and `\uDF4E` do not have any meaning
* outside the pair (are rendered as ? when alone). Position between them would be incorrect. In this case, selection
* extension will include whole "surrogate pair".
* * `'word'` - moves selection by whole word.
*
* **Note:** if you extend a forward selection in a backward direction you will in fact shrink it.
*
Expand Down Expand Up @@ -79,11 +80,13 @@ export default function modifySelection( model, selection, options = {} ) {
}

// Checks whether the selection can be extended to the the walker's next value (next position).
// @param {{ walker, unit, isForward, schema }} data
// @param {{ item, nextPosition, type}} value
function tryExtendingTo( data, value ) {
// If found text, we can certainly put the focus in it. Let's just find a correct position
// based on the unit.
if ( value.type == 'text' ) {
return getCorrectPosition( data.walker, data.unit );
return getCorrectPosition( data.walker, data.unit, data.isForward );
}

// Entering an element.
Expand Down Expand Up @@ -117,17 +120,27 @@ function tryExtendingTo( data, value ) {

// Finds a correct position by walking in a text node and checking whether selection can be extended to given position
// or should be extended further.
function getCorrectPosition( walker, unit ) {
//
// @param {} walker
// @param {String} unit A boundary limit: character, codePoint, word.
function getCorrectPosition( walker, unit, isForward ) {
const textNode = walker.position.textNode;

if ( textNode ) {
const data = textNode.data;
let offset = walker.position.offset - textNode.startOffset;

while ( isInsideSurrogatePair( data, offset ) || ( unit == 'character' && isInsideCombinedSymbol( data, offset ) ) ) {
let endOffset = isForward ? textNode.endOffset : 0;

while (
isInsideSurrogatePair( data, offset ) ||
( unit == 'character' && isInsideCombinedSymbol( data, offset ) ) ||
( unit == 'word' && !isAtWordEnd( data, offset, isForward ) && !( offset === endOffset ) )
) {
walker.next();

offset = walker.position.offset - textNode.startOffset;
endOffset = isForward ? textNode.endOffset : 0;
}
}

Expand All @@ -144,3 +157,9 @@ function getSearchRange( start, isForward ) {
return new Range( searchEnd, start );
}
}

function isAtWordEnd( data, offset, isForward ) {
const char = data.charAt( offset + ( isForward ? 0 : -1 ) );

return ' ,.-'.includes( char );
}
Loading

0 comments on commit 1b76554

Please sign in to comment.