Divec has uploaded a new change for review.
https://gerrit.wikimedia.org/r/80080
Change subject: WIP:Don't emit Surface changes back to the Surface
......................................................................
WIP:Don't emit Surface changes back to the Surface
modules/ve/ce/ve.ce.SurfaceObserver.js
* add emitContentChanges argument to poll (and start and stop)
modules/ve/ce/ve.ce.Surface.js
* Pass emitContentChanges=false to calls to start/stop in certain places
* Explicitly pass emitContentChanges=true elsewhere, to preserve prior behaviour
modules/ve/ui/ve.ui.Surface.js
* Explicitly pass emitContentChanges=true to poll
modules/ve/test/ve.test.js
* Escape non-BMP unicode text literals (to prevent potential editor problems)
Change-Id: I19ec7eaa0e3224cbfc7e7188e964183d7393c9a7
---
M modules/ve/ce/ve.ce.Surface.js
M modules/ve/ce/ve.ce.SurfaceObserver.js
M modules/ve/test/ve.test.js
M modules/ve/ui/ve.ui.Surface.js
4 files changed, 56 insertions(+), 50 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor
refs/changes/80/80080/1
diff --git a/modules/ve/ce/ve.ce.Surface.js b/modules/ve/ce/ve.ce.Surface.js
index 3c554f4..cbc5ba1 100644
--- a/modules/ve/ce/ve.ce.Surface.js
+++ b/modules/ve/ce/ve.ce.Surface.js
@@ -292,7 +292,7 @@
'compositionstart.ve-ce-Surface': ve.bind(
this.onDocumentCompositionStart, this ),
'compositionend.ve-ce-Surface': ve.bind(
this.onDocumentCompositionEnd, this )
} );
- this.surfaceObserver.start( true );
+ this.surfaceObserver.start( true, true );
};
/**
@@ -303,7 +303,7 @@
*/
ve.ce.Surface.prototype.documentOnBlur = function () {
this.$document.off( '.ve-ce-Surface' );
- this.surfaceObserver.stop( true );
+ this.surfaceObserver.stop( true, true );
this.dragging = false;
};
@@ -323,7 +323,7 @@
// this.$$( e.target ).closest( '.ve-ce-documentNode' ).length === 0
if ( e.which === 1 ) {
- this.surfaceObserver.stop( true );
+ this.surfaceObserver.stop( true, true );
}
// Handle triple click
@@ -349,7 +349,7 @@
* @emits selectionEnd
*/
ve.ce.Surface.prototype.onDocumentMouseUp = function ( e ) {
- this.surfaceObserver.start();
+ this.surfaceObserver.start( false, true );
if ( !e.shiftKey && this.selecting ) {
this.emit( 'selectionEnd' );
this.selecting = false;
@@ -467,7 +467,7 @@
return;
}
- this.surfaceObserver.stop( true );
+ this.surfaceObserver.stop( true, false );
switch ( e.keyCode ) {
case ve.Keys.LEFT:
case ve.Keys.RIGHT:
@@ -502,7 +502,7 @@
}
break;
}
- this.surfaceObserver.start();
+ this.surfaceObserver.start( false, false );
};
/**
@@ -540,7 +540,7 @@
this.handleInsertion();
setTimeout( ve.bind( function () {
- this.surfaceObserver.start();
+ this.surfaceObserver.start( false, true );
}, this ) );
};
@@ -566,7 +566,7 @@
* @param {jQuery.Event} e Cut event
*/
ve.ce.Surface.prototype.onCut = function ( e ) {
- this.surfaceObserver.stop();
+ this.surfaceObserver.stop( false, true );
this.onCopy( e );
setTimeout( ve.bind( function () {
var selection, tx;
@@ -580,7 +580,7 @@
this.model.change( tx, new ve.Range( selection.start ) );
this.surfaceObserver.clear();
- this.surfaceObserver.start();
+ this.surfaceObserver.start( false, true );
}, this ) );
};
@@ -627,7 +627,7 @@
view = this,
selection = this.model.getSelection();
- this.surfaceObserver.stop();
+ this.surfaceObserver.stop( false, true );
// Pasting into a range? Remove first.
if ( !rangy.getSelection( this.$document[0] ).isCollapsed ) {
@@ -708,7 +708,7 @@
*/
ve.ce.Surface.prototype.onDocumentCompositionEnd = function () {
this.inIme = false;
- this.surfaceObserver.start();
+ this.surfaceObserver.start( false, false );
};
/*! Custom Events */
@@ -942,7 +942,7 @@
* @method
*/
ve.ce.Surface.prototype.onLock = function () {
- this.surfaceObserver.stop();
+ this.surfaceObserver.stop( false, true );
};
/**
@@ -952,7 +952,7 @@
*/
ve.ce.Surface.prototype.onUnlock = function () {
this.surfaceObserver.clear( this.model.getSelection() );
- this.surfaceObserver.start();
+ this.surfaceObserver.start( false, true );
};
/*! Relocation */
@@ -1000,7 +1000,7 @@
// Selection is going to be displayed programmatically so prevent
default browser behaviour
e.preventDefault();
// Stop with final poll cycle so we have correct information in model
- this.surfaceObserver.stop( true );
+ this.surfaceObserver.stop( true, false );
selection = this.model.getSelection();
if ( this.$$( e.target ).css( 'direction' ) === 'rtl' ) {
// If the language direction is RTL, switch left/right
directions:
@@ -1017,7 +1017,7 @@
);
this.model.change( null, range );
- this.surfaceObserver.start();
+ this.surfaceObserver.start( false, true );
};
/**
@@ -1034,7 +1034,7 @@
nativeSel.modify( 'extend', 'left', 'character' );
return;
}
- this.surfaceObserver.stop( true );
+ this.surfaceObserver.stop( true, true );
selection = this.model.getSelection();
rangySelection = rangy.getSelection( this.$document[0] );
// Perform programatic handling only for selection that is expanded and
backwards according to
@@ -1058,18 +1058,18 @@
if ( !$element.hasClass( 've-ce-branchNode-slug' ) ) {
$element.remove();
}
- this.surfaceObserver.start();
- this.surfaceObserver.stop( false );
+ this.surfaceObserver.start( false, true );
+ this.surfaceObserver.stop( false, true );
if ( e.shiftKey === true ) { // expanded range
range = new ve.Range( selection.from,
this.model.getSelection().to );
} else { // collapsed range (just a cursor)
range = new ve.Range(
this.model.getSelection().to );
}
this.model.change( null, range );
- this.surfaceObserver.start();
+ this.surfaceObserver.start( false, true );
}, this ), 0 );
} else {
- this.surfaceObserver.start();
+ this.surfaceObserver.start( false, true );
}
};
@@ -1125,7 +1125,7 @@
}
}
- this.surfaceObserver.stop( true );
+ this.surfaceObserver.stop( true, true );
};
/**
diff --git a/modules/ve/ce/ve.ce.SurfaceObserver.js
b/modules/ve/ce/ve.ce.SurfaceObserver.js
index 1124813..e49f406 100644
--- a/modules/ve/ce/ve.ce.SurfaceObserver.js
+++ b/modules/ve/ce/ve.ce.SurfaceObserver.js
@@ -82,15 +82,16 @@
/**
* Start polling.
*
- * If {async} is false or undefined the first poll cycle will occur
immediately and synchronously.
+ * If {postpone} is false or undefined the first poll cycle will occur
immediately and synchronously.
*
* @method
- * @param {boolean} async Poll the first time asynchronously
+ * @param {boolean} postpone Add the first poll to the end of the event queue
+ * @param {boolean} emitContentChanges Allow contentChange to be emitted
*/
-ve.ce.SurfaceObserver.prototype.start = function ( async ) {
+ve.ce.SurfaceObserver.prototype.start = function ( postpone,
emitContentChanges ) {
this.domDocument =
this.documentView.getDocumentNode().getElementDocument();
this.polling = true;
- this.poll( async );
+ this.poll( postpone, emitContentChanges );
};
/**
@@ -101,11 +102,12 @@
*
* @method
* @param {boolean} poll Poll one last time before stopping future polling
+ * @param {boolean} emitContentChanges Allow contentChange to be emitted
*/
-ve.ce.SurfaceObserver.prototype.stop = function ( poll ) {
+ve.ce.SurfaceObserver.prototype.stop = function ( poll, emitContentChanges ) {
if ( this.polling === true ) {
if ( poll === true ) {
- this.poll();
+ this.poll( false, emitContentChanges );
}
this.polling = false;
clearTimeout( this.timeoutId );
@@ -116,7 +118,7 @@
/**
* Poll for changes.
*
- * If `async` is false or undefined then polling will occcur asynchronously.
+ * If `postpone` is false or undefined then polling will occcur immediately.
*
* TODO: fixing selection in certain cases, handling selection across multiple
nodes in Firefox
*
@@ -124,12 +126,13 @@
* with a mouse.
*
* @method
- * @param {boolean} async Poll asynchronously
+ * @param {boolean} postpone Append the poll action to the end of the event
queue
+ * @param {boolean} emitContentChanges Allow contentChange to be emitted
* @emits contentChange
* @emits selectionChange
*/
-ve.ce.SurfaceObserver.prototype.poll = function ( async ) {
- var delayPoll, $nodeOrSlug, node, text, hash, range, rangyRange;
+ve.ce.SurfaceObserver.prototype.poll = function ( postpone, emitContentChanges
) {
+ var $nodeOrSlug, node, text, hash, range, rangyRange;
if ( this.polling === false ) {
return;
@@ -140,15 +143,13 @@
this.timeoutId = null;
}
- delayPoll = ve.bind( function ( async ) {
+ if ( postpone === true ) {
this.timeoutId = setTimeout(
ve.bind( this.poll, this ),
- async === true ? 0 : this.frequency
+ 0,
+ false,
+ emitContentChanges
);
- }, this );
-
- if ( async === true ) {
- delayPoll( true );
return;
}
@@ -178,20 +179,20 @@
this.hash = ve.ce.getDomHash( node.$[0] );
this.node = node;
}
- } else {
- if ( node !== null ) {
- text = ve.ce.getDomText( node.$[0] );
- hash = ve.ce.getDomHash( node.$[0] );
- if ( this.text !== text || this.hash !== hash ) {
+ } else if ( node !== null ) {
+ text = ve.ce.getDomText( node.$[0] );
+ hash = ve.ce.getDomHash( node.$[0] );
+ if ( this.text !== text || this.hash !== hash ) {
+ if ( emitContentChanges ) {
this.emit(
'contentChange',
node,
{ 'text': this.text, 'hash': this.hash,
'range': this.range },
{ 'text': text, 'hash': hash, 'range':
range }
);
- this.text = text;
- this.hash = hash;
}
+ this.text = text;
+ this.hash = hash;
}
}
@@ -205,5 +206,10 @@
this.range = range;
}
- delayPoll();
+ this.timeoutId = setTimeout(
+ ve.bind( this.poll, this ),
+ this.frequency,
+ false,
+ emitContentChanges
+ );
};
diff --git a/modules/ve/test/ve.test.js b/modules/ve/test/ve.test.js
index c87ba9c..a48a1d0 100644
--- a/modules/ve/test/ve.test.js
+++ b/modules/ve/test/ve.test.js
@@ -454,18 +454,18 @@
// TODO: ve.getCharacterOffset
QUnit.test( 'graphemeSafeSubstring', function ( assert ) {
- var i, text = '12𨋢45𨋢789𨋢bc', cases = [
+ var i, text = '12\ud860\udee245\ud860\udee2789\ud860\udee2bc', cases = [
{
'msg': 'start and end inside multibyte',
'start': 3,
'end': 12,
- 'expected': [ '𨋢45𨋢789𨋢', '45𨋢789' ]
+ 'expected': [
'\ud860\udee245\ud860\udee2789\ud860\udee2', '45\ud860\udee2789' ]
},
{
'msg': 'start and end next to multibyte',
'start': 4,
'end': 11,
- 'expected': [ '45𨋢789', '45𨋢789' ]
+ 'expected': [ '45\ud860\udee2789',
'45\ud860\udee2789' ]
},
{
'msg': 'complete string',
@@ -477,7 +477,7 @@
'msg': 'collapsed selection inside multibyte',
'start': 3,
'end': 3,
- 'expected': [ '𨋢', '' ]
+ 'expected': [ '\ud860\udee2', '' ]
}
];
QUnit.expect( cases.length * 2 );
diff --git a/modules/ve/ui/ve.ui.Surface.js b/modules/ve/ui/ve.ui.Surface.js
index e31ab14..1510eff 100644
--- a/modules/ve/ui/ve.ui.Surface.js
+++ b/modules/ve/ui/ve.ui.Surface.js
@@ -82,7 +82,7 @@
// By re-asserting the current selection and forcing a poll we force
selection to be something
// reasonable - otherwise in Firefox, the initial selection is (0,0),
causing bug 42277
this.model.getFragment().select();
- this.view.surfaceObserver.poll();
+ this.view.surfaceObserver.poll( false, true );
this.model.startHistoryTracking();
};
--
To view, visit https://gerrit.wikimedia.org/r/80080
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I19ec7eaa0e3224cbfc7e7188e964183d7393c9a7
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Divec <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits