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

Commit

Permalink
Changed: Extracted getCorrectWordBreakPosition() from `getCorrectPo…
Browse files Browse the repository at this point in the history
…sition()` in modifyselection.
  • Loading branch information
jodator committed Feb 15, 2018
1 parent 3d8223a commit 74df0ae
Showing 1 changed file with 51 additions and 27 deletions.
78 changes: 51 additions & 27 deletions src/model/utils/modifyselection.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ 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' ) {
if ( data.unit === 'word' ) {
return getCorrectWordBreakPosition( data.walker, data.isForward );
}

return getCorrectPosition( data.walker, data.unit, data.isForward );
}

Expand Down Expand Up @@ -125,45 +129,56 @@ function tryExtendingTo( data, value ) {
//
// @param {module:engine/model/treewalker~TreeWalker} walker
// @param {String} unit The unit by which selection should be modified.
function getCorrectPosition( walker, unit ) {
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 ) ) ) {
walker.next();

offset = walker.position.offset - textNode.startOffset;
}
}

return walker.position;
}

// Finds a correct position of a word break by walking in a text node and checking whether selection can be extended to given position
// or should be extended further.
//
// @param {module:engine/model/treewalker~TreeWalker} walker
// @param {Boolean} isForward Is the direction in which the selection should be modified is forward.
function getCorrectPosition( walker, unit, isForward ) {
function getCorrectWordBreakPosition( walker, isForward ) {
let textNode = walker.position.textNode;

if ( textNode ) {
let data = textNode.data;
let offset = walker.position.offset - textNode.startOffset;
let isAtNodeBoundary = offset === ( isForward ? textNode.endOffset : 0 );

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

// Check of adjacent text nodes with different attributes (like BOLD).
// Example : 'foofoo []bar<$text bold="true">bar</$text> bazbaz'
// should expand to : 'foofoo [bar<$text bold="true">bar</$text>] bazbaz'.
if ( unit == 'word' && !isAtNodeBoundary ) {
const nextNode = isForward ? walker.position.nodeAfter : walker.position.nodeBefore;

if ( nextNode ) {
// Check boundary char of an adjacent text node.
const boundaryChar = nextNode.data.charAt( isForward ? 0 : nextNode.data.length - 1 );

// Go to the next node if the character at the boundary of that node belongs to the same word.
if ( !wordBoundaryCharacters.includes( boundaryChar ) ) {
// If adjacent text node belongs to the same word go to it & reset values.
walker.next();

textNode = walker.position.textNode;
data = textNode.data;
}
// Example : 'foofoo []bar<$text bold="true">bar</$text> bazbaz'
// should expand to : 'foofoo [bar<$text bold="true">bar</$text>] bazbaz'.
const nextNode = isForward ? walker.position.nodeAfter : walker.position.nodeBefore;

if ( nextNode ) {
// Check boundary char of an adjacent text node.
const boundaryChar = nextNode.data.charAt( isForward ? 0 : nextNode.data.length - 1 );

// Go to the next node if the character at the boundary of that node belongs to the same word.
if ( !wordBoundaryCharacters.includes( boundaryChar ) ) {
// If adjacent text node belongs to the same word go to it & reset values.
walker.next();

textNode = walker.position.textNode;
}
}

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

Expand All @@ -183,7 +198,7 @@ function getSearchRange( start, isForward ) {

// Checks if selection is on word boundary.
//
// @param {module:engine/view/text~Text} textNode The text node to investigate.
// @param {String} data The text node value to investigate.
// @param {Number} offset Position offset.
// @param {Boolean} isForward Is the direction in which the selection should be modified is forward.
function isAtWordBoundary( data, offset, isForward ) {
Expand All @@ -192,3 +207,12 @@ function isAtWordBoundary( data, offset, isForward ) {

return wordBoundaryCharacters.includes( data.charAt( offsetToCheck ) );
}

// Checks if selection is on node boundary.
//
// @param {module:engine/model/text~Text} textNode The text node to investigate.
// @param {Number} offset Position offset.
// @param {Boolean} isForward Is the direction in which the selection should be modified is forward.
function isAtNodeBoundary( textNode, offset, isForward ) {
return offset === ( isForward ? textNode.endOffset : 0 );
}

0 comments on commit 74df0ae

Please sign in to comment.