mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-09-27 12:16:51 +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
|
||||
*/
|
||||
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,
|
||||
length,
|
||||
level = 0,
|
||||
|
|
|
@ -254,7 +254,7 @@ ve.dm.TransactionProcessor.prototype.replace = function( op ) {
|
|||
insert = this.reversed ? op.remove : op.insert,
|
||||
removeHasStructure = ve.dm.Document.containsElementData( remove ),
|
||||
insertHasStructure = ve.dm.Document.containsElementData( insert ),
|
||||
node, selection;
|
||||
node, scope, selection;
|
||||
// Figure out if this is a structural insert or a content insert
|
||||
if ( !removeHasStructure && !insertHasStructure ) {
|
||||
// Content replacement
|
||||
|
@ -272,8 +272,7 @@ ve.dm.TransactionProcessor.prototype.replace = function( op ) {
|
|||
// Advance the cursor
|
||||
this.cursor += insert.length;
|
||||
} else {
|
||||
// Structural insert
|
||||
// TODO generalize for insert/remove
|
||||
// Structural replacement
|
||||
|
||||
// It's possible that multiple replace operations are needed before the
|
||||
// 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';
|
||||
}
|
||||
}
|
||||
// Queue a rebuild for the replaced node
|
||||
this.synchronizer.pushRebuild( new ve.Range( startOffset, this.cursor - adjustment ),
|
||||
new ve.Range( startOffset, this.cursor ) );
|
||||
|
||||
// TODO this handles splitting nodes but not merging nodes
|
||||
// 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