Expand all

ve.dm.VisualDiff

Constructor

new ve.dm.VisualDiff(oldDocOrNode, newDocOrNode, [timeout]) #

VisualDiff

Gets the diff between two VisualEditor DataModel DocumentNodes

Parameters:

Name Type Attributes Default Description
oldDocOrNode ve.dm.Document | ve.dm.BranchNode
newDocOrNode ve.dm.Document | ve.dm.BranchNode
timeout number optional
1000

Timeout after which to stop performing linear diffs (in ms)

Source:

VisualDiff

Gets the diff between two VisualEditor DataModel DocumentNodes

Methods

alignTrees(oldTree, newTree) → {Array|boolean} #

Align two tree structures

Parameters:

Name Type Description
oldTree treeDiffer.Tree

Tree rooted at the old node

newTree treeDiffer.Tree

Tree rooted at the new node

Source:

Returns:

Corresponding tree node indices, or false if timed out

Type
Array | boolean
Align two tree structures

calculateDiffMoves(oldToNew, newToOld) → {Array.<(number|string)>} #

Calculate how items in a new list have moved, compared to items in the old list. More specifically, calculate the minimal moves, keeping the maximum possible number of nodes unmoved. Do this by finding the longest increasing subsequence in the sequence of oldDoc node indices, sorted by their corresponding newDoc nodes' indices. Those indices in the longest increasing subsequence represent the unmoved nodes.

Parameters:

Name Type Description
oldToNew Object.<number, (number|Object)>

Map of oldDoc nodes to corresponding newDoc nodes. Keys are indices of nodes in the list. Values are either indices of nodes in the list for unchanged nodes, or objects where the node property is the index for changed nodes.

newToOld Object.<number, (number|Object)>

Map of newDoc nodes to corresponding oldDoc nodes. Same format at oldToNew.

Source:

Returns:

Record of whether and how each newDoc node has moved (0, 'up', 'down')

Type
Array.<(number|string)>
Calculate how items in a new list have moved, compared to items in the old list.

diffAttributes(oldNode, newNode, [diffTypeAsAttribute]) → {ve.dm.VisualDiff.AttributeDiff|boolean} #

Find the difference between attributes of two nodes

Parameters:

Name Type Attributes Description
oldNode ve.dm.Node

Node from the old document

newNode ve.dm.Node

Node from the new document

diffTypeAsAttribute string optional

Diff the type of the node as an attribute with this name

Source:

Returns:

The attributes diff, or false if unchanged

Type
ve.dm.VisualDiff.AttributeDiff | boolean
Find the difference between attributes of two nodes

diffContent(oldNode, newNode) → {Array|boolean} #

Find the difference between linear data in two content branch nodes

Parameters:

Name Type Description
oldNode ve.dm.ContentBranchNode

Node from the old document

newNode ve.dm.ContentBranchNode

Node from the new document

Source:

Returns:

The linear diff, or false if timed out

Type
Array | boolean
Find the difference between linear data in two content branch nodes

diffDocs(oldRoot, newRoot, skipInternalLists) → {ve.dm.VisualDiff.DocDiff} #

Diff two nodes as documents, comaparing their children as lists.

Parameters:

Name Type Description
oldRoot ve.dm.Node

Old root

newRoot ve.dm.Node

New root

skipInternalLists boolean

Skip internal list nodes

Source:

Returns:

Object containing diff information

Type
ve.dm.VisualDiff.DocDiff
Diff two nodes as documents, comaparing their children as lists.

diffLeafNodes(oldNode, newNode) → {ve.dm.VisualDiff.LeafDiff|boolean} #

Diff two leaf nodes

Parameters:

Name Type Description
oldNode ve.dm.Node

Node from the old document

newNode ve.dm.Node

Node from the new document

Source:

Returns:

Leaf diff, or false if the nodes are too different or if the diff timed out

Type
ve.dm.VisualDiff.LeafDiff | boolean
Diff two leaf nodes

diffList(oldNodes, newNodes) → {ve.dm.VisualDiff.ListDiff} #

Get the diff between two lists of nodes.

Parameters:

Name Type Description
oldNodes Array.<ve.dm.Node>

Nodes from the old document

newNodes Array.<ve.dm.Node>

Nodes from the new document

Source:

Returns:

Object containing diff information

Type
ve.dm.VisualDiff.ListDiff
Get the diff between two lists of nodes.

diffListNodes(oldNode, newNode) → {ve.dm.VisualDiff.ListDiff|boolean} #

Diff two list nodes

Parameters:

Name Type Description
oldNode ve.dm.Node

Node from the old document

newNode ve.dm.Node

Node from the new document

Source:

Returns:

Leaf diff, or false if the nodes are too different or if the diff timed out

Type
ve.dm.VisualDiff.ListDiff | boolean
Diff two list nodes

diffNodes(oldNode, newNode, [noTreeDiff]) → {ve.dm.VisualDiff.LeafDiff|ve.dm.VisualDiff.ListDiff|ve.dm.VisualDiff.DocDiff|ve.dm.VisualDiff.TreeDiff|boolean} #

Get the diff between a node from the old document and a node from the new document.

Parameters:

Name Type Attributes Description
oldNode ve.dm.Node

Node from the old document

newNode ve.dm.Node

Node from the new document

noTreeDiff boolean optional

Don't perform a tree diff of the nodes (used internally to avoid recursion)

Source:

Returns:

The diff, or false if the nodes are too different

Type
ve.dm.VisualDiff.LeafDiff | ve.dm.VisualDiff.ListDiff | ve.dm.VisualDiff.DocDiff | ve.dm.VisualDiff.TreeDiff | boolean

Get the diff between a node from the old document and a node from the new document.

diffTreeNodes(oldTreeNode, newTreeNode) → {ve.dm.VisualDiff.TreeDiff|boolean} #

Do a tree diff. There are three steps: (1) Do a tree diff to find the minimal transactions between the old tree and the new tree. Allowed transactions are: remove a node, insert a node, or change an old node to a new node. (The cost of each transaction is the same, and the change always costs the same, no matter how similar the nodes are.) The tree differ is not currently aware of legal relationships between nodes, and ve.dm.ContentBranchNodes are treated as leaves. (2) Do a linear diff on the linear data of any changed pair that are both ve.dm.ContentBranchNodes. (3) Find the ratio of the linear data that has changed to the linear data that is retained. If this is above a threshold, the nodes are too different and the old node has not been changed to make the new node, and the diff should be discarded. Otherwise the diff should be cleaned and returned.

TODO: It would be possible to discover within-node moves by comparing removed and inserted nodes from the tree differ.

Parameters:

Name Type Description
oldTreeNode ve.dm.Node

Node from the old document

newTreeNode ve.dm.Node

Node from the new document

Source:

Returns:

Diff object, or false if the nodes are too different or if the diff timed out.

Type
ve.dm.VisualDiff.TreeDiff | boolean
Do a tree diff.

findModifiedNodes(oldIndices, newIndices, oldNodes, newNodes, diff) #

Diff each old node against each new node in the list. If the differs decide that an old node is similar enough to a new node, record these as a change from the old to the new node and don't diff either of these nodes any more.

This might not find the optimal diff in some cases (e.g. if the old node is similar to two of the new nodes), but diffing every old node against every new node could have a heavy performance cost.

Parameters:

Name Type Description
oldIndices Array.<number>

Indices of the old nodes

newIndices Array.<number>

Indices of the new nodes

oldNodes Array.<ve.dm.Node>

Nodes from the old document

newNodes Array.<ve.dm.Node>

Nodes from the new document

diff Object

Object that will contain information about the diff

Source:
Diff each old node against each new node in the list.

flattenList(listNode, flatList, depth) #

Flatten a (potentially nested) list, ready for diffing. Lists are common, and tree diffs of lists are expensive, so lists are flattened then diffed as linear structures.

Appends information for each list item to a flat list object. Will be called once for each list node within a nested list.

Only nested lists at the end of list items are flattened.

If a list item contains a non-list node that contains a list, that list will not get flattened out. A list node followed by a non-list node will not be flattened out either. If a list item contains more than one identical list node, they will be flattened out to the same depth, and the information that they were separate lists will be lost.

If a list item contains more than one un-flattened node, each one of them will be treated as a separate list item when flattened, but the original items will be put back together later. (T345891)

Parameters:

Name Type Description
listNode ve.dm.Node

A list node, possibly nested inside another list

flatList Object

Flat structure describing the entire list

depth number

Depth of this list node with respect to the outermost

Source:
Flatten a (potentially nested) list, ready for diffing.

freezeInternalListIndices(doc) #

Attach the internal list indexOrder to each node referenced by the internal list, ahead of document merge.

Parameters:

Name Type Description
doc ve.dm.Document
Source:

Attach the internal list indexOrder to each node referenced by the internal list, ahead of document merge.

getMetaListDiff(oldMetaList, newMetaList) → {ve.dm.VisualDiff.MetaListDiff} #

Calculate a meta list diff

Parameters:

Name Type Description
oldMetaList ve.dm.MetaList
newMetaList ve.dm.MetaList
Source:

Returns:

Type
ve.dm.VisualDiff.MetaListDiff
Calculate a meta list diff

hasChanges(diff, isInternalListDiff) → {boolean} #

Check if a list diff object has any changes

Parameters:

Name Type Description
diff Object

Diff object

isInternalListDiff boolean

Is an internal list diff

Source:

Returns:

The diff object has changes

Type
boolean
Check if a list diff object has any changes

underDiffThreshold(changeRecord) → {boolean} #

Check whether the proportion of changed content between two nodes is under the threshold for accepting that the two nodes correspond.

Parameters:

Name Type Description
changeRecord Object

Record for the proportion of content changed

Source:

Returns:

The proportion of changed content is under the threshold

Type
boolean

Check whether the proportion of changed content between two nodes is under the threshold for accepting that the two nodes correspond.

updateChangeRecord(length, removed, changeRecord) #

Increment the record of the length of changed and unchanged content for a node, given the length the removed or inserted content in one of its descendants

Parameters:

Name Type Description
length number

Length of removed or inserted content

removed boolean

The content was removed (if false, was inserted)

changeRecord Object

Record of the running totals for changed and unchanged content

Source:

Increment the record of the length of changed and unchanged content for a node, given the length the removed or inserted content in one of its descendants

updateChangeRecordLinearDiff(linearDiff, changeRecord) #

Increment the record of the length of changed and unchanged content for a node, given the linear diff for one of its descendants

Parameters:

Name Type Description
linearDiff Array

Diff of the content

changeRecord Object

Record of the running totals for changed and unchanged content

Source:

Increment the record of the length of changed and unchanged content for a node, given the linear diff for one of its descendants

compareNodes(oldNode, newNode) → {boolean}static #

Compare the linear data for two nodes

Parameters:

Name Type Description
oldNode ve.dm.Node

Node from the old document

newNode ve.dm.Node

Node from the new document

Source:

Returns:

The linear data is the same

Type
boolean
Compare the linear data for two nodes

getDataFromNode(node, innerRange) → {Array}static #

Get the original linear data from a node

Parameters:

Name Type Description
node ve.dm.Node

Node

innerRange boolean

Get the node's inner range

Source:

Returns:

Linear data

Type
Array
Get the original linear data from a node

Type Definitions

AttributeDiff #

Type:

Properties:

Name Type Description
oldAttributes Object
newAttributes Object
Source:

DocDiff #

Type:

Properties:

Name Type Description
oldRoot ve.dm.Node
newRoot ve.dm.Node
attributeChange ve.dm.VisualDiff.AttributeDiff
Source:

InternalListDiff #

Type:

Properties:

Name Type Description
groups Object.<string, ve.dm.VisualDiff.ListDiff>

List diffs, indexed by group

oldDocInternalListNode ve.dm.InternalListNode
newDocInternalListNode ve.dm.InternalListNode
Source:

LeafDiff #

Type:

Properties:

Name Type Description
attributeChange ve.dm.VisualDiff.AttributeDiff | boolean
linearDiff Array | boolean
Source:

ListDiff #

Type:

Properties:

Name Type Description
oldNodes Array.<ve.dm.Node>
newNodes Array.<ve.dm.Node>
oldToNew Object
newToOld Object
remove Array.<number>
insert Array.<number>
Source:

MetaListDiff #

Type:

Properties:

Name Type Description
groups Object.<string, ve.dm.VisualDiff.ListDiff>

List diffs, indexed by group

Source:

TreeDiff #

Type:

Properties:

Name Type Description
oldTreeOrderedNodes Array.<ve.DiffTreeNode>

Nodes of the old tree, deepest first then in document order

newTreeOrderedNodes Array.<ve.DiffTreeNode>

Nodes of the new tree, deepest first then in document order

treeDiff Array.<Array>

Node correspondences as indexes in *TreeOrderedNodes

Properties:
Name Type Description
i Array.<number>

The i'th correspondence [ oldTreeOrderedNodes index, newTreeOrderedNodes index ]

diffInfo Object | null

Linear diffs applying to each corresponding node pair

Properties:
Name Type Description
i Object

Linear diff applying to i'th node in newTreeOrderedNodes

Properties:
Name Type Description
linearDiff Array | boolean

Output of #diffContent

attributeChange ve.dm.VisualDiff.AttributeDiff | boolean

Attribute diff

Source: