Simplify onSelect handler implementation

Optimizations for the code introduced in Ic403e0a:
* Skip this entirely when something is selected (as discussed
  in Ic403e0a).
* Use a combination of existing methods. I benchmarked these
  again. This approach is "significantly" slower compared to
  the custom code from before. However, "significantly" here
  means something like 1 nanosecond vs. 4 nanoseconds. Both
  is effectively nothing.
* Use the same approach in another place. This one is triggered
  every time a change is made, e.g. a character typed. I
  benchmarked this as well. The new code is about 500x faster
  (yes, seriously).

Bug: T269094
Change-Id: I00fe595a89be7a257e27ed28d38568c81483338b
This commit is contained in:
Thiemo Kreuz 2021-01-05 15:26:14 +01:00 committed by Thiemo Kreuz (WMDE)
parent 773b308fab
commit a43984fc67

View file

@ -148,53 +148,16 @@ ve.ui.CodeMirrorAction.prototype.toggle = function ( enable ) {
* @param {ve.dm.Selection} selection
*/
ve.ui.CodeMirrorAction.prototype.onSelect = function ( selection ) {
var fromPos, toPos,
range = selection.getCoveringRange(),
dmDoc = this.surface.getModel().getDocument();
var range = selection.getCoveringRange();
if ( !range ) {
// Do not re-trigger bracket matching as long as something is selected
if ( !range || !range.isCollapsed() ) {
return;
}
/**
* Convert a DM offset to a CM position (line + ch)
*
* @param {number} offset VE DM offset
* @return {Object} CM position
* @throws {Error} Offset out of bounds
*/
function getPosFromOffset( offset ) {
var lineLength,
lineOffset = 0,
line = 0,
lines = dmDoc.getDocumentNode().getChildren();
if ( offset < 0 ) {
throw new Error( 'Offset out of bounds' );
}
while ( lineOffset < offset ) {
if ( !lines[ line ] || lines[ line ].isInternal() ) {
throw new Error( 'Offset out of bounds' );
}
lineLength = lines[ line ].getOuterLength();
if ( lineOffset + lineLength > offset ) {
return {
line: line,
ch: offset - lineOffset - 1
};
}
lineOffset += lineLength;
line++;
}
throw new Error( 'Offset out of bounds' );
}
fromPos = getPosFromOffset( range.from );
// Don't do the calculation twice when the range is collapsed
toPos = range.isCollapsed() ? fromPos : getPosFromOffset( range.to );
this.surface.mirror.setSelection( fromPos, toPos );
this.surface.mirror.setSelection( this.surface.mirror.posFromIndex(
this.surface.getModel().getSourceOffsetFromOffset( range.from )
) );
};
/**
@ -219,8 +182,8 @@ ve.ui.CodeMirrorAction.prototype.onDocumentPrecommit = function ( tx ) {
var i,
offset = 0,
replacements = [],
linearData = this.surface.getModel().getDocument().data,
store = linearData.getStore(),
model = this.surface.getModel(),
store = model.getDocument().getStore(),
mirror = this.surface.mirror;
/**
@ -231,8 +194,7 @@ ve.ui.CodeMirrorAction.prototype.onDocumentPrecommit = function ( tx ) {
* @return {Object} Code mirror position, containing 'line' and 'ch'
*/
function convertOffset( veOffset ) {
var cmOffset = linearData.getSourceText( new ve.Range( 0, veOffset ) ).length;
return mirror.posFromIndex( cmOffset );
return mirror.posFromIndex( model.getSourceOffsetFromOffset( veOffset ) );
}
tx.operations.forEach( function ( op ) {