Divec has uploaded a new change for review.
https://gerrit.wikimedia.org/r/196207
Change subject: WIP allegro giocoso doloroso: block bogus 'emit'
......................................................................
WIP allegro giocoso doloroso: block bogus 'emit'
On delete, the DM surface sometimes emits a bogus select event before any
content change has actually taken place. This breaks with native deletion,
because the CE content is already inconsistent with the DM content.
Change-Id: If3270175ce66148ac5dbecb4c5ba11ed634ad855
---
M src/ce/ve.ce.Surface.js
M src/dm/ve.dm.SurfaceFragment.js
2 files changed, 33 insertions(+), 3 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor
refs/changes/07/196207/1
diff --git a/src/ce/ve.ce.Surface.js b/src/ce/ve.ce.Surface.js
index cac7061..8585bd4 100644
--- a/src/ce/ve.ce.Surface.js
+++ b/src/ce/ve.ce.Surface.js
@@ -3275,7 +3275,15 @@
}
}
- this.getModel().getLinearFragment( rangeToRemove ).delete( direction );
+ // 'delete' may end up emitting an early bogus no-op selection change,
which then kills
+ // onModelSelect because the DM does not yet match the CE. Pass
callbacks to apply the
+ // render lock in this case
+ this.getModel().getLinearFragment( rangeToRemove ).delete(
+ direction,
+ this.incRenderLock.bind( this ),
+ this.decRenderLock.bind( this )
+ );
+
// Rerender selection even if it didn't change
// TODO: is any of this necessary?
this.focus();
diff --git a/src/dm/ve.dm.SurfaceFragment.js b/src/dm/ve.dm.SurfaceFragment.js
index 22d282a..225c493 100644
--- a/src/dm/ve.dm.SurfaceFragment.js
+++ b/src/dm/ve.dm.SurfaceFragment.js
@@ -825,15 +825,18 @@
*
* @method
* @param {number} [directionAfterDelete=-1] Direction to move after delete: 1
or -1 or 0
+ * @param {Function} onPreBogusSelectEmit Callback before emitting a premature
select event
+ * @param {Function} onPostBogusSelectEmit Callback after emitting a premature
select event
* @chainable
*/
-ve.dm.SurfaceFragment.prototype.delete = function ( directionAfterDelete ) {
+ve.dm.SurfaceFragment.prototype.delete = function ( directionAfterDelete,
onPreBogusSelectEmit, onPostBogusSelectEmit ) {
if ( !( this.selection instanceof ve.dm.LinearSelection ) ) {
return this;
}
var rangeAfterRemove, internalListRange,
tx, startNode, endNode, endNodeData, nodeToDelete,
+
dmSurfaceEmitsABogusSelectEventThatCanBeIgnoredBecauseItWillEmitAProperOneAMomentLater,
rangeToRemove = this.getSelection( true ).getRange();
if ( rangeToRemove.isCollapsed() ) {
@@ -852,8 +855,27 @@
rangeAfterRemove = new ve.Range( 1 );
} else {
tx = ve.dm.Transaction.newFromRemoval( this.document,
rangeToRemove );
- this.change( tx );
rangeAfterRemove = tx.translateRange( rangeToRemove );
+ // Detect whether the select event that will be emitted is
bogus -- if so, it will
+ // be followed by a sensible select event below. We're slightly
lucky, because we
+ // can predict this before making a call.
+
dmSurfaceEmitsABogusSelectEventThatCanBeIgnoredBecauseItWillEmitAProperOneAMomentLater
= !rangeAfterRemove.isCollapsed();
+ if (
dmSurfaceEmitsABogusSelectEventThatCanBeIgnoredBecauseItWillEmitAProperOneAMomentLater
) {
+ // Notify the caller that we're about to spout nonsense
+ if ( onPreBogusSelectEmit ) {
+ onPreBogusSelectEmit();
+ }
+ try {
+ this.change( tx );
+ } finally {
+ if ( onPostBogusSelectEmit ) {
+ onPostBogusSelectEmit();
+ }
+ }
+ } else {
+ // Will emit sensible select event; do not notify the
caller
+ this.change( tx );
+ }
}
if ( !rangeAfterRemove.isCollapsed() ) {
// If after processing removal transaction range is not
collapsed it means that not
--
To view, visit https://gerrit.wikimedia.org/r/196207
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If3270175ce66148ac5dbecb4c5ba11ed634ad855
Gerrit-PatchSet: 1
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Divec <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits