mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-15 18:39:52 +00:00
Support splitting nodes in replace tree sync
This means inserting things like </p><p> are now synced correctly and split the paragraph in the model tree. Merges (removing e.g. </p><p>) aren't supported yet. Also, this needs tests, Trevor tells me he's working on porting replace tests from the old ve/ directory Change-Id: Ic5050849d7d007a1696dc36548654979aedb53a8
This commit is contained in:
parent
59f74de3b8
commit
7e1aa2336e
|
@ -197,6 +197,9 @@ ve.dm.Document.containsElementData = function( data ) {
|
||||||
* @returns {ve.Node} Lowest level parent node being affected
|
* @returns {ve.Node} Lowest level parent node being affected
|
||||||
*/
|
*/
|
||||||
ve.dm.Document.getScope = function( node, data ) {
|
ve.dm.Document.getScope = function( node, data ) {
|
||||||
|
// TODO improve this to return a set of siblings, rather than a common ancestor, that'll
|
||||||
|
// make for much more efficient rebuilds
|
||||||
|
// TODO also make it track offsets
|
||||||
var i,
|
var i,
|
||||||
length,
|
length,
|
||||||
level = 0,
|
level = 0,
|
||||||
|
|
|
@ -254,7 +254,7 @@ ve.dm.TransactionProcessor.prototype.replace = function( op ) {
|
||||||
insert = this.reversed ? op.remove : op.insert,
|
insert = this.reversed ? op.remove : op.insert,
|
||||||
removeHasStructure = ve.dm.Document.containsElementData( remove ),
|
removeHasStructure = ve.dm.Document.containsElementData( remove ),
|
||||||
insertHasStructure = ve.dm.Document.containsElementData( insert ),
|
insertHasStructure = ve.dm.Document.containsElementData( insert ),
|
||||||
node, selection;
|
node, scope, selection;
|
||||||
// Figure out if this is a structural insert or a content insert
|
// Figure out if this is a structural insert or a content insert
|
||||||
if ( !removeHasStructure && !insertHasStructure ) {
|
if ( !removeHasStructure && !insertHasStructure ) {
|
||||||
// Content replacement
|
// Content replacement
|
||||||
|
@ -272,8 +272,7 @@ ve.dm.TransactionProcessor.prototype.replace = function( op ) {
|
||||||
// Advance the cursor
|
// Advance the cursor
|
||||||
this.cursor += insert.length;
|
this.cursor += insert.length;
|
||||||
} else {
|
} else {
|
||||||
// Structural insert
|
// Structural replacement
|
||||||
// TODO generalize for insert/remove
|
|
||||||
|
|
||||||
// It's possible that multiple replace operations are needed before the
|
// It's possible that multiple replace operations are needed before the
|
||||||
// model is back in a consistent state. This loop applies the current
|
// model is back in a consistent state. This loop applies the current
|
||||||
|
@ -342,8 +341,29 @@ ve.dm.TransactionProcessor.prototype.replace = function( op ) {
|
||||||
throw 'Unbalanced set of replace operations found';
|
throw 'Unbalanced set of replace operations found';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Queue a rebuild for the replaced node
|
|
||||||
this.synchronizer.pushRebuild( new ve.Range( startOffset, this.cursor - adjustment ),
|
// TODO this handles splitting nodes but not merging nodes
|
||||||
new ve.Range( startOffset, this.cursor ) );
|
// Figure out in which node the start was
|
||||||
|
selection = this.document.selectNodes( new ve.Range( startOffset, startOffset ) );
|
||||||
|
node = selection[0].node;
|
||||||
|
// Figure out what the scope of the insertion is
|
||||||
|
scope = ve.dm.Document.getScope( node, op.insert );
|
||||||
|
if ( scope === node ) {
|
||||||
|
// Simple case: no splits occurred, we can just rebuild the affected range
|
||||||
|
this.synchronizer.pushRebuild(
|
||||||
|
new ve.Range( startOffset, this.cursor - adjustment ),
|
||||||
|
new ve.Range( startOffset, this.cursor )
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// A split occurred. Rebuild the entirety of scope
|
||||||
|
// TODO do something better to get the offset, possibly via getScope()
|
||||||
|
// or through whatever we have to do for deletion painting
|
||||||
|
var scopeStart = this.document.getDocumentNode().getOffsetFromNode( scope );
|
||||||
|
var scopeEnd = scopeStart + scope.getOuterLength();
|
||||||
|
this.synchronizer.pushRebuild(
|
||||||
|
new ve.Range( scopeStart, scopeEnd ),
|
||||||
|
new ve.Range( scopeStart, scopeEnd + adjustment )
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue