Divec has uploaded a new change for review. https://gerrit.wikimedia.org/r/86688
Change subject: WIP: Don't bounce selection changes DM->CE ...................................................................... WIP: Don't bounce selection changes DM->CE ve.dm.Surface.js * 'change' event has a 'source' field, to detect bouncing * changeSelectionFromCE() for selection changes which are already in the CE [TODO: Structure not right yet: DM shouldn't know about CE] * changeSelection() for other selection changes ve.ce.Surface.js * onChange() ignores events originating in the CE Change-Id: I758e7a72a5690463f12f456419c6e471dd29a9db TODO: Revisit the pattern of emitted oojs events generally. --- M modules/ve/ce/ve.ce.Surface.js M modules/ve/dm/ve.dm.Surface.js 2 files changed, 68 insertions(+), 13 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor refs/changes/88/86688/1 diff --git a/modules/ve/ce/ve.ce.Surface.js b/modules/ve/ce/ve.ce.Surface.js index c3d4d68..ba6da70 100644 --- a/modules/ve/ce/ve.ce.Surface.js +++ b/modules/ve/ce/ve.ce.Surface.js @@ -372,7 +372,7 @@ while ( node.parent !== null && node.model.isContent() ) { node = node.parent; } - this.model.change( null, node.model.getRange() ); + this.model.changeSelection( node.model.getRange() ); } }; @@ -575,7 +575,7 @@ prevNode.isContent() && documentModel.data.isCloseElementData( selection.start - 1 ) ) { - this.model.change( null, new ve.Range( selection.start ) ); + this.model.changeSelection( new ve.Range( selection.start ) ); } } } @@ -859,7 +859,7 @@ selection = tx.translateRange( selection ); this.model.change( tx, new ve.Range( selection.start ) ); // Move cursor to end of selection - this.model.change( null, new ve.Range( selection.end ) ); + this.model.changeSelection( new ve.Range( selection.end ) ); // Allow pasting again this.pasting = false; @@ -908,10 +908,15 @@ * @param {ve.dm.Transaction|null} transaction * @param {ve.Range|undefined} selection */ -ve.ce.Surface.prototype.onChange = function ( transaction, selection ) { +ve.ce.Surface.prototype.onChange = function ( transaction, selection, source ) { var start, end, rangySel, rangyRange, next = null, previous = this.focusedNode; + + if ( source === 'ce' ) { + // Don't need to process; this change is already in the ContentEditable + return; + } if ( selection ) { // Detect when only a single inline element is selected @@ -975,7 +980,7 @@ } this.incRenderLock(); try { - this.model.change( null, newRange ); + this.model.changeSelectionFromCE( newRange ); } finally { this.decRenderLock(); } @@ -1237,7 +1242,7 @@ ( e.altKey === true || e.ctrlKey === true ) ? 'word' : 'character', e.shiftKey ); - this.model.change( null, range ); + this.model.changeSelection( range ); // TODO: onDocumentKeyDown does this anyway this.surfaceObserver.startTimerLoop(); this.surfaceObserver.pollOnce(); @@ -1291,7 +1296,7 @@ } else { // collapsed range (just a cursor) range = new ve.Range( this.model.getSelection().to ); } - this.model.change( null, range ); + this.model.changeSelection( range ); this.surfaceObserver.pollOnce(); }, this ), 0 ); } else { @@ -1475,12 +1480,12 @@ // Now we can move the cursor forward if ( advanceCursor ) { - this.model.change( - null, new ve.Range( documentModel.data.getRelativeContentOffset( selection.from, 1 ) ) + this.model.changeSelection( + new ve.Range( documentModel.data.getRelativeContentOffset( selection.from, 1 ) ) ); } else { - this.model.change( - null, new ve.Range( documentModel.data.getNearestContentOffset( selection.from ) ) + this.model.changeSelection( + new ve.Range( documentModel.data.getNearestContentOffset( selection.from ) ) ); } // Reset and resume polling @@ -1562,7 +1567,7 @@ } } } - this.model.change( null, new ve.Range( rangeToRemove.start ) ); + this.model.changeSelection( new ve.Range( rangeToRemove.start ) ); this.surfaceObserver.clear(); }; diff --git a/modules/ve/dm/ve.dm.Surface.js b/modules/ve/dm/ve.dm.Surface.js index b6aec21..6e19c4d 100644 --- a/modules/ve/dm/ve.dm.Surface.js +++ b/modules/ve/dm/ve.dm.Surface.js @@ -64,6 +64,7 @@ * @see #method-change * @param {ve.dm.Transaction|null} transaction * @param {ve.Range|undefined} selection + * @param {string|null} source */ /** @@ -300,6 +301,25 @@ * @emits unlock */ ve.dm.Surface.prototype.change = function ( transactions, selection ) { + this.changeInternal( transactions, selection, null ); +}; + +/** + * Apply a transactions and selection changes to the document. + * + * @method + * @param {ve.dm.Transaction|ve.dm.Transaction[]|null} transactions One or more transactions to + * process, or null to process none + * @param {ve.Range|undefined} selection + * @param {string|null} source Source of the change (to prevent emit cycles) + * @emits lock + * @emits select + * @emits transact + * @emits contextChange + * @emits change + * @emits unlock + */ +ve.dm.Surface.prototype.changeInternal = function ( transactions, selection, source ) { if ( !this.enabled ) { return; } @@ -406,13 +426,43 @@ this.emit( 'contextChange' ); } - this.emit( 'change', transactions, selection ); + if ( transactions !== null ) { + this.emit( 'change', transactions, selection, source ); + } // Continue observation polling, we want to know about things that change from here on out this.emit( 'unlock' ); }; /** + * Apply selection changes to the document. + * + * @method + * @param {ve.Range} selection + * @emits lock + * @emits select + * @emits contextChange + * @emits change + * @emits unlock + */ +ve.dm.Surface.prototype.changeSelection = function ( selection ) { + this.changeInternal( null, selection, null ); +}; + +/** + * Apply selection changes from the surface to the document. + * + * @method + * @param {ve.Range} selection + * @emits lock + * @emits contextChange + * @emits unlock + */ +ve.dm.Surface.prototype.changeSelectionFromCE = function ( selection ) { + this.changeInternal( null, selection, 'ce' ); +}; + +/** * Set a history state breakpoint. * * @method -- To view, visit https://gerrit.wikimedia.org/r/86688 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I758e7a72a5690463f12f456419c6e471dd29a9db Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/VisualEditor Gerrit-Branch: master Gerrit-Owner: Divec <da...@sheetmusic.org.uk> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits