jenkins-bot has submitted this change and it was merged.

Change subject: Implement next/prevBreakOffset and word skipping
......................................................................


Implement next/prevBreakOffset and word skipping

This provides the functionality for keyboard word skipping
(i.e. pressing ctrl/alt + arrow key).

Bug: 46794
Change-Id: Ib0861fa075df805410717a148b8a6e166d947849
---
M modules/unicodejs/unicodejs.wordbreak.js
M modules/unicodejs/unicodejs.wordbreak.test.js
M modules/ve/dm/lineardata/ve.dm.ElementLinearData.js
3 files changed, 105 insertions(+), 27 deletions(-)

Approvals:
  Catrope: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/modules/unicodejs/unicodejs.wordbreak.js 
b/modules/unicodejs/unicodejs.wordbreak.js
index 6c1b79f..f6a9e3c 100644
--- a/modules/unicodejs/unicodejs.wordbreak.js
+++ b/modules/unicodejs/unicodejs.wordbreak.js
@@ -32,15 +32,55 @@
                return null;
        }
 
+       /**
+        * Find the next word break offset.
+        * @param {unicodeJS.TextString} string TextString
+        * @param {number} pos Character position
+        * @param {boolean} [onlyAlphaNumeric=false] When set, ignores a break 
if the previous character is not alphaNumeric
+        * @returns {number} Returns the next offset which is a word break
+        */
+       wordbreak.nextBreakOffset = function( string, pos, onlyAlphaNumeric ) {
+               return wordbreak.moveBreakOffset( 1, string, pos, 
onlyAlphaNumeric );
+       };
 
        /**
-        * Evaluates if the specified position within some text is a word 
boundary.
-        * @param {string} text Text
+        * Find the previous word break offset.
+        * @param {unicodeJS.TextString} string TextString
         * @param {number} pos Character position
-        * @returns {boolean} Is the position a word boundary
+        * @param {boolean} [onlyAlphaNumeric=false] When set, ignores a break 
if the previous character is not alphaNumeric
+        * @returns {number} Returns the previous offset which is a word break
         */
-       wordbreak.isBreakInText = function ( text, pos ) {
-               return unicodeJS.wordbreak.isBreakInTextString( new 
unicodeJS.TextString( text ), pos );
+       wordbreak.prevBreakOffset = function( string, pos, onlyAlphaNumeric ) {
+               return wordbreak.moveBreakOffset( -1, string, pos, 
onlyAlphaNumeric );
+       };
+
+       /**
+        * Find the next word break offset in a specified direction.
+        * @param {number} direction Direction to search in, should be plus or 
minus one
+        * @param {unicodeJS.TextString} string TextString
+        * @param {number} pos Character position
+        * @param {boolean} [onlyAlphaNumeric=false] When set, ignores a break 
if the previous character is not alphaNumeric
+        * @returns {number} Returns the previous offset which is word break
+        */
+       wordbreak.moveBreakOffset = function( direction, string, pos, 
onlyAlphaNumeric ) {
+               var lastGroup, i = pos,
+                       // when moving backwards, use the character to the left 
of the cursor
+                       readCharOffset = direction > 0 ? 0 : -1;
+               // Search backwards for the previous break point
+               while ( string.read( i + readCharOffset ) !== null ) {
+                       i += direction;
+                       if ( unicodeJS.wordbreak.isBreak( string, i ) ) {
+                               // Check previous character was alpha-numeric 
if required
+                               if ( onlyAlphaNumeric ) {
+                                       lastGroup = getGroup( string.read( i - 
direction + readCharOffset ) );
+                                       if( lastGroup !== 'ALetter' && 
lastGroup !== 'Numeric' && lastGroup !== 'Katakana' ) {
+                                               continue;
+                                       }
+                               }
+                               break;
+                       }
+               }
+               return i;
        };
 
        /**
@@ -49,7 +89,7 @@
         * @param {number} pos Character position
         * @returns {boolean} Is the position a word boundary
         */
-       wordbreak.isBreakInTextString = function ( string, pos ) {
+       wordbreak.isBreak = function ( string, pos ) {
                // Break at the start and end of text.
                // WB1: sot ÷
                // WB2: ÷ eot
diff --git a/modules/unicodejs/unicodejs.wordbreak.test.js 
b/modules/unicodejs/unicodejs.wordbreak.test.js
index 69cff69..769e610 100644
--- a/modules/unicodejs/unicodejs.wordbreak.test.js
+++ b/modules/unicodejs/unicodejs.wordbreak.test.js
@@ -7,7 +7,7 @@
 
 QUnit.module( 'unicodeJS.wordbreak' );
 
-QUnit.test( 'isBreakInText', function ( assert ) {
+QUnit.test( 'isBreak', function ( assert ) {
        var i, result, context,
                text =
                        /*jshint quotmark:double */
@@ -24,6 +24,7 @@
                        // 50 - 60
                        " c\u0300\u0327",
                        /*jshint quotmark:single */
+               textString = new unicodeJS.TextString( text ),
                breaks = [
                        0, 1, 6, 7, 8, 9, 10,
                        11, 12, 13, 14, 15, 16, 17, 19,
@@ -43,9 +44,59 @@
                        text.substring( i, Math.min( i + 4, text.length ) )
                ;
                assert.equal(
-                       unicodeJS.wordbreak.isBreakInText( text, i ),
+                       unicodeJS.wordbreak.isBreak( textString, i ),
                        result,
                        'Position ' + i + ' is ' + ( result ? '' : 'not ' ) + 
'a break: ' + context
                );
        }
 });
+
+QUnit.test( 'nextBreakOffset/prevBreakOffset', function ( assert ) {
+       var i, offset = 0,
+               text = 'The quick brown fox',
+               textString = new unicodeJS.TextString( text ),
+               breaks = [ 0, 0, 3, 4, 9, 10, 15, 16, 19, 19 ];
+
+       QUnit.expect( 2*(breaks.length - 2) );
+
+       for ( i = 2; i < breaks.length; i++ ) {
+               offset = unicodeJS.wordbreak.nextBreakOffset( textString, 
offset );
+               assert.equal( offset, breaks[i], 'Next break is at position ' + 
breaks[i] );
+       }
+       for ( i = breaks.length - 3; i >= 0; i-- ) {
+               offset = unicodeJS.wordbreak.prevBreakOffset( textString, 
offset );
+               assert.equal( offset, breaks[i], 'Previous break is at position 
' + breaks[i] );
+       }
+});
+
+QUnit.test( 'nextBreakOffset/prevBreakOffset (ignore whitespace)', function ( 
assert ) {
+       var i, offset = 0,
+               text = '   The quick  brown ..fox jumps... 3.14159 すどくスドク   ',
+               textString = new unicodeJS.TextString( text ),
+               nextBreaks = [ 6, 12, 19, 25, 31, 42, 49, 52 ],
+               prevBreaks = [ 46, 35, 26, 22, 14, 7, 3, 0 ];
+
+       QUnit.expect( nextBreaks.length + prevBreaks.length + 6 );
+
+       for ( i = 0; i < nextBreaks.length; i++ ) {
+               offset = unicodeJS.wordbreak.nextBreakOffset( textString, 
offset, true );
+               assert.equal( offset, nextBreaks[i], 'Next break is at position 
' + nextBreaks[i] );
+       }
+       for ( i = 0; i < prevBreaks.length; i++ ) {
+               offset = unicodeJS.wordbreak.prevBreakOffset( textString, 
offset, true );
+               assert.equal( offset, prevBreaks[i], 'Previous break is at 
position ' + prevBreaks[i] );
+       }
+
+       assert.equal( unicodeJS.wordbreak.nextBreakOffset( textString, 9, true 
),
+                12, 'Jump to end of word when starting in middle of word');
+       assert.equal( unicodeJS.wordbreak.nextBreakOffset( textString, 3, true 
),
+                6, 'Jump to end of word when starting at start of word');
+       assert.equal( unicodeJS.wordbreak.nextBreakOffset( textString, 13, true 
),
+                19, 'Jump to end of word when starting in double whitespace');
+       assert.equal( unicodeJS.wordbreak.prevBreakOffset( textString, 17, true 
),
+                14, 'Jump to start of word when starting in middle of word');
+       assert.equal( unicodeJS.wordbreak.prevBreakOffset( textString, 6, true 
),
+                3, 'Jump to start of word when starting at end of word');
+       assert.equal( unicodeJS.wordbreak.prevBreakOffset( textString, 13, true 
),
+                7, 'Jump to start of word when starting in double whitespace');
+});
diff --git a/modules/ve/dm/lineardata/ve.dm.ElementLinearData.js 
b/modules/ve/dm/lineardata/ve.dm.ElementLinearData.js
index 6cb9075..ac1fdd6 100644
--- a/modules/ve/dm/lineardata/ve.dm.ElementLinearData.js
+++ b/modules/ve/dm/lineardata/ve.dm.ElementLinearData.js
@@ -671,7 +671,7 @@
  * @returns {ve.Range} Range around nearest word boundaries
  */
 ve.dm.ElementLinearData.prototype.getNearestWordRange = function ( offset ) {
-       var offsetLeft, offsetRight, i,
+       var offsetLeft, offsetRight,
                dataString = new ve.dm.DataString( this.getData() );
 
        offset = this.getNearestContentOffset( offset );
@@ -679,10 +679,10 @@
        // If the cursor offset is a break (i.e. the start/end of word) we 
should
        // check one position either side to see if there is a non-break
        // and if so, move the offset accordingly
-       if ( unicodeJS.wordbreak.isBreakInTextString( dataString, offset ) ) {
-               if ( !unicodeJS.wordbreak.isBreakInTextString( dataString, 
offset + 1 ) ) {
+       if ( unicodeJS.wordbreak.isBreak( dataString, offset ) ) {
+               if ( !unicodeJS.wordbreak.isBreak( dataString, offset + 1 ) ) {
                        offset++;
-               } else if ( !unicodeJS.wordbreak.isBreakInTextString( 
dataString, offset - 1 ) ) {
+               } else if ( !unicodeJS.wordbreak.isBreak( dataString, offset - 
1 ) ) {
                        offset--;
                } else {
                        // just return one character to the right, unless we 
are at the end
@@ -695,21 +695,8 @@
                }
        }
 
-       i = offset;
-       // Search left and right for next break points
-       while ( dataString.read( i++ ) !== null ) {
-               offsetRight = i;
-               if ( unicodeJS.wordbreak.isBreakInTextString( dataString, i ) ) 
{
-                       break;
-               }
-       }
-       i = offset;
-       while ( dataString.read( i-- ) !== null ) {
-               offsetLeft = i;
-               if ( unicodeJS.wordbreak.isBreakInTextString( dataString, i ) ) 
{
-                       break;
-               }
-       }
+       offsetRight = unicodeJS.wordbreak.nextBreakOffset( dataString, offset );
+       offsetLeft = unicodeJS.wordbreak.prevBreakOffset( dataString, offset );
 
        return new ve.Range( offsetLeft, offsetRight );
 };
\ No newline at end of file

-- 
To view, visit https://gerrit.wikimedia.org/r/57076
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ib0861fa075df805410717a148b8a6e166d947849
Gerrit-PatchSet: 12
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Esanders <[email protected]>
Gerrit-Reviewer: Catrope <[email protected]>
Gerrit-Reviewer: Esanders <[email protected]>
Gerrit-Reviewer: Inez <[email protected]>
Gerrit-Reviewer: Trevor Parscal <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to