Esanders has uploaded a new change for review.
https://gerrit.wikimedia.org/r/59651
Change subject: DM support for MW references
......................................................................
DM support for MW references
So far just read-only.
Change-Id: I6daff5c5969e5fdc871f8f346cf790b4302ae080
---
M VisualEditor.php
M demos/ve/index.php
M modules/ve/ce/nodes/ve.ce.AlienNode.js
M modules/ve/ce/nodes/ve.ce.GeneratedContentNode.js
A modules/ve/ce/nodes/ve.ce.InternalReferenceListNode.js
A modules/ve/ce/nodes/ve.ce.InternalReferenceNode.js
A modules/ve/ce/nodes/ve.ce.MWReferenceNode.js
M modules/ve/ce/nodes/ve.ce.MWTemplateNode.js
M modules/ve/ce/ve.ce.ContentBranchNode.js
A modules/ve/dm/nodes/ve.dm.InternalReferenceListNode.js
A modules/ve/dm/nodes/ve.dm.InternalReferenceNode.js
M modules/ve/dm/nodes/ve.dm.MWHeadingNode.js
M modules/ve/dm/nodes/ve.dm.MWPreformattedNode.js
A modules/ve/dm/nodes/ve.dm.MWReferenceNode.js
M modules/ve/dm/ve.dm.Converter.js
M modules/ve/dm/ve.dm.Document.js
M modules/ve/dm/ve.dm.Model.js
A modules/ve/dm/ve.dm.ReferenceList.js
M modules/ve/init/mw/ve.init.mw.Target.js
M modules/ve/test/dm/ve.dm.Converter.test.js
M modules/ve/test/index.php
21 files changed, 473 insertions(+), 67 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor
refs/changes/51/59651/1
diff --git a/VisualEditor.php b/VisualEditor.php
index 2453d51..da3bf46 100644
--- a/VisualEditor.php
+++ b/VisualEditor.php
@@ -236,6 +236,7 @@
've/dm/ve.dm.Annotation.js',
've/dm/ve.dm.MetaItem.js',
've/dm/ve.dm.MetaList.js',
+ 've/dm/ve.dm.ReferenceList.js',
've/dm/ve.dm.TransactionProcessor.js',
've/dm/ve.dm.Transaction.js',
've/dm/ve.dm.Surface.js',
@@ -260,6 +261,8 @@
've/dm/nodes/ve.dm.DocumentNode.js',
've/dm/nodes/ve.dm.HeadingNode.js',
've/dm/nodes/ve.dm.ImageNode.js',
+ 've/dm/nodes/ve.dm.InternalReferenceListNode.js',
+ 've/dm/nodes/ve.dm.InternalReferenceNode.js',
've/dm/nodes/ve.dm.ListItemNode.js',
've/dm/nodes/ve.dm.ListNode.js',
've/dm/nodes/ve.dm.ParagraphNode.js',
@@ -274,6 +277,7 @@
've/dm/nodes/ve.dm.MWHeadingNode.js',
've/dm/nodes/ve.dm.MWImageNode.js',
've/dm/nodes/ve.dm.MWPreformattedNode.js',
+ 've/dm/nodes/ve.dm.MWReferenceNode.js',
've/dm/nodes/ve.dm.MWTemplateNode.js',
've/dm/annotations/ve.dm.LinkAnnotation.js',
@@ -310,6 +314,8 @@
've/ce/nodes/ve.ce.DocumentNode.js',
've/ce/nodes/ve.ce.HeadingNode.js',
've/ce/nodes/ve.ce.ImageNode.js',
+ 've/ce/nodes/ve.ce.InternalReferenceListNode.js',
+ 've/ce/nodes/ve.ce.InternalReferenceNode.js',
've/ce/nodes/ve.ce.ListItemNode.js',
've/ce/nodes/ve.ce.ListNode.js',
've/ce/nodes/ve.ce.ParagraphNode.js',
@@ -324,6 +330,7 @@
've/ce/nodes/ve.ce.MWHeadingNode.js',
've/ce/nodes/ve.ce.MWImageNode.js',
've/ce/nodes/ve.ce.MWPreformattedNode.js',
+ 've/ce/nodes/ve.ce.MWReferenceNode.js',
've/ce/nodes/ve.ce.MWTemplateNode.js',
've/ce/annotations/ve.ce.LinkAnnotation.js',
diff --git a/demos/ve/index.php b/demos/ve/index.php
index 57cd489..d9b48ec 100644
--- a/demos/ve/index.php
+++ b/demos/ve/index.php
@@ -126,6 +126,7 @@
<script src="../../modules/ve/dm/ve.dm.Annotation.js"></script>
<script src="../../modules/ve/dm/ve.dm.MetaItem.js"></script>
<script src="../../modules/ve/dm/ve.dm.MetaList.js"></script>
+ <script
src="../../modules/ve/dm/ve.dm.ReferenceList.js"></script>
<script
src="../../modules/ve/dm/ve.dm.TransactionProcessor.js"></script>
<script src="../../modules/ve/dm/ve.dm.Transaction.js"></script>
<script src="../../modules/ve/dm/ve.dm.Surface.js"></script>
@@ -148,6 +149,8 @@
<script
src="../../modules/ve/dm/nodes/ve.dm.DocumentNode.js"></script>
<script
src="../../modules/ve/dm/nodes/ve.dm.HeadingNode.js"></script>
<script
src="../../modules/ve/dm/nodes/ve.dm.ImageNode.js"></script>
+ <script
src="../../modules/ve/dm/nodes/ve.dm.InternalReferenceListNode.js"></script>
+ <script
src="../../modules/ve/dm/nodes/ve.dm.InternalReferenceNode.js"></script>
<script
src="../../modules/ve/dm/nodes/ve.dm.ListItemNode.js"></script>
<script
src="../../modules/ve/dm/nodes/ve.dm.ListNode.js"></script>
<script
src="../../modules/ve/dm/nodes/ve.dm.ParagraphNode.js"></script>
@@ -161,6 +164,7 @@
<script
src="../../modules/ve/dm/nodes/ve.dm.MWHeadingNode.js"></script>
<script
src="../../modules/ve/dm/nodes/ve.dm.MWImageNode.js"></script>
<script
src="../../modules/ve/dm/nodes/ve.dm.MWPreformattedNode.js"></script>
+ <script
src="../../modules/ve/dm/nodes/ve.dm.MWReferenceNode.js"></script>
<script
src="../../modules/ve/dm/nodes/ve.dm.MWTemplateNode.js"></script>
<script
src="../../modules/ve/dm/annotations/ve.dm.LinkAnnotation.js"></script>
<script
src="../../modules/ve/dm/annotations/ve.dm.MWExternalLinkAnnotation.js"></script>
@@ -192,6 +196,8 @@
<script
src="../../modules/ve/ce/nodes/ve.ce.DocumentNode.js"></script>
<script
src="../../modules/ve/ce/nodes/ve.ce.HeadingNode.js"></script>
<script
src="../../modules/ve/ce/nodes/ve.ce.ImageNode.js"></script>
+ <script
src="../../modules/ve/ce/nodes/ve.ce.InternalReferenceListNode.js"></script>
+ <script
src="../../modules/ve/ce/nodes/ve.ce.InternalReferenceNode.js"></script>
<script
src="../../modules/ve/ce/nodes/ve.ce.ListItemNode.js"></script>
<script
src="../../modules/ve/ce/nodes/ve.ce.ListNode.js"></script>
<script
src="../../modules/ve/ce/nodes/ve.ce.ParagraphNode.js"></script>
@@ -205,6 +211,7 @@
<script
src="../../modules/ve/ce/nodes/ve.ce.MWHeadingNode.js"></script>
<script
src="../../modules/ve/ce/nodes/ve.ce.MWImageNode.js"></script>
<script
src="../../modules/ve/ce/nodes/ve.ce.MWPreformattedNode.js"></script>
+ <script
src="../../modules/ve/ce/nodes/ve.ce.MWReferenceNode.js"></script>
<script
src="../../modules/ve/ce/nodes/ve.ce.MWTemplateNode.js"></script>
<script
src="../../modules/ve/ce/annotations/ve.ce.LinkAnnotation.js"></script>
<script
src="../../modules/ve/ce/annotations/ve.ce.MWExternalLinkAnnotation.js"></script>
diff --git a/modules/ve/ce/nodes/ve.ce.AlienNode.js
b/modules/ve/ce/nodes/ve.ce.AlienNode.js
index b0705ea..9ccccca 100644
--- a/modules/ve/ce/nodes/ve.ce.AlienNode.js
+++ b/modules/ve/ce/nodes/ve.ce.AlienNode.js
@@ -1,5 +1,5 @@
/*!
- * VisualEditor ContentEditable AlienNode class.
+ * VisualEditor ContentEditable AlienNode, AlienBlockNode and AlienInlineNode
classes.
*
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
@@ -119,7 +119,7 @@
* @param {jQuery.Event} e
*/
ve.ce.AlienNode.prototype.onSurfaceMouseOut = function ( e ) {
- if ( e.toElement === null) {
+ if ( e.toElement === null ) {
this.clearPhantoms();
}
};
diff --git a/modules/ve/ce/nodes/ve.ce.GeneratedContentNode.js
b/modules/ve/ce/nodes/ve.ce.GeneratedContentNode.js
index 7d54b08..63bb61b 100644
--- a/modules/ve/ce/nodes/ve.ce.GeneratedContentNode.js
+++ b/modules/ve/ce/nodes/ve.ce.GeneratedContentNode.js
@@ -1,5 +1,5 @@
/*!
- * VisualEditor ContentEditable GeneratedContent class.
+ * VisualEditor ContentEditable GeneratedContentNode class.
*
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
diff --git a/modules/ve/ce/nodes/ve.ce.InternalReferenceListNode.js
b/modules/ve/ce/nodes/ve.ce.InternalReferenceListNode.js
new file mode 100644
index 0000000..86e79e4
--- /dev/null
+++ b/modules/ve/ce/nodes/ve.ce.InternalReferenceListNode.js
@@ -0,0 +1,36 @@
+/*!
+ * VisualEditor InternalReferenceListNode class.
+ *
+ * @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * ContentEditable internal reference list node.
+ *
+ * @class
+ * @extends ve.ce.BranchNode
+ * @constructor
+ * @param {ve.dm.InternalReferenceListNode} model Model to observe
+ */
+ve.ce.InternalReferenceListNode = function VeCeInternalReferenceListNode(
model ) {
+ // Parent constructor
+ ve.ce.BranchNode.call(
+ this, model, $( '<span>' )
+ );
+
+ // TODO: render nothing
+ this.$.hide();
+};
+
+/* Inheritance */
+
+ve.inheritClass( ve.ce.InternalReferenceListNode, ve.ce.BranchNode );
+
+/* Static Properties */
+
+ve.ce.InternalReferenceListNode.static.name = 'internalReferenceList';
+
+/* Registration */
+
+ve.ce.nodeFactory.register( ve.ce.InternalReferenceListNode );
diff --git a/modules/ve/ce/nodes/ve.ce.InternalReferenceNode.js
b/modules/ve/ce/nodes/ve.ce.InternalReferenceNode.js
new file mode 100644
index 0000000..932b201
--- /dev/null
+++ b/modules/ve/ce/nodes/ve.ce.InternalReferenceNode.js
@@ -0,0 +1,34 @@
+/*!
+ * VisualEditor InternalReferenceNode class.
+ *
+ * @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * ContentEditable internal reference node.
+ *
+ * @class
+ * @extends ve.ce.BranchNode
+ * @constructor
+ * @param {ve.dm.InternalReferenceNode} model Model to observe
+ */
+ve.ce.InternalReferenceNode = function VeCeInternalReferenceNode( model ) {
+ // Parent constructor
+ ve.ce.BranchNode.call(
+ // TODO: render nothing
+ this, model, $( '<span>' )
+ );
+};
+
+/* Inheritance */
+
+ve.inheritClass( ve.ce.InternalReferenceNode, ve.ce.BranchNode );
+
+/* Static Properties */
+
+ve.ce.InternalReferenceNode.static.name = 'internalReference';
+
+/* Registration */
+
+ve.ce.nodeFactory.register( ve.ce.InternalReferenceNode );
diff --git a/modules/ve/ce/nodes/ve.ce.MWReferenceNode.js
b/modules/ve/ce/nodes/ve.ce.MWReferenceNode.js
new file mode 100644
index 0000000..7b9139e
--- /dev/null
+++ b/modules/ve/ce/nodes/ve.ce.MWReferenceNode.js
@@ -0,0 +1,55 @@
+/*!
+ * VisualEditor ContentEditable MWReferenceNode class.
+ *
+ * @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * ContentEditable MediaWiki template node.
+ *
+ * @class
+ * @extends ve.ce.LeafNode
+ * @constructor
+ * @param {ve.dm.MWReferenceNode} model Model to observe
+ */
+ve.ce.MWReferenceNode = function VeCeMWReferenceNode( model ) {
+ // Parent constructor
+ ve.ce.LeafNode.call( this, model, $( '<sup>' ) );
+
+ // DOM Changes
+ this.$link = $( '<a>' ).attr( 'href', '#' );
+ this.$.addClass( 've-ce-MWreferenceNode', 'reference' )
+ .attr( 'contenteditable', false )
+ .append( this.$link );
+
+ // Events
+ this.model.addListenerMethod( this, 'update', 'onUpdate' );
+ this.$link.click( ve.bind( this.onClick, this ) );
+
+ // Initialization
+ this.onUpdate();
+};
+
+/* Inheritance */
+
+ve.inheritClass( ve.ce.MWReferenceNode, ve.ce.LeafNode );
+
+/* Static Properties */
+
+ve.ce.MWReferenceNode.static.name = 'MWreference';
+
+/* Methods */
+
+ve.ce.MWReferenceNode.prototype.onUpdate = function () {
+ this.$link.text( this.model.element.text );
+};
+
+ve.ce.MWReferenceNode.prototype.onClick = function ( e ) {
+ e.preventDefault();
+ // edit reference...
+};
+
+/* Registration */
+
+ve.ce.nodeFactory.register( ve.ce.MWReferenceNode );
diff --git a/modules/ve/ce/nodes/ve.ce.MWTemplateNode.js
b/modules/ve/ce/nodes/ve.ce.MWTemplateNode.js
index 59c560c..48e66d4 100644
--- a/modules/ve/ce/nodes/ve.ce.MWTemplateNode.js
+++ b/modules/ve/ce/nodes/ve.ce.MWTemplateNode.js
@@ -1,5 +1,5 @@
/*!
- * VisualEditor ContentEditable MWTemplate class.
+ * VisualEditor ContentEditable MWTemplateNode class.
*
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
diff --git a/modules/ve/ce/ve.ce.ContentBranchNode.js
b/modules/ve/ce/ve.ce.ContentBranchNode.js
index 8c589a7..bc55438 100644
--- a/modules/ve/ce/ve.ce.ContentBranchNode.js
+++ b/modules/ve/ce/ve.ce.ContentBranchNode.js
@@ -114,7 +114,7 @@
// Detach all child nodes from this.$
// We can't use this.$.empty() because that destroys .data() and event
handlers
this.$.contents().each( function () {
- $(this).detach();
+ $( this ).detach();
} );
// Reattach child nodes with the right annotations
diff --git a/modules/ve/dm/nodes/ve.dm.InternalReferenceListNode.js
b/modules/ve/dm/nodes/ve.dm.InternalReferenceListNode.js
new file mode 100644
index 0000000..8d2c740
--- /dev/null
+++ b/modules/ve/dm/nodes/ve.dm.InternalReferenceListNode.js
@@ -0,0 +1,38 @@
+/*!
+ * VisualEditor DataModel InternalReferenceListNode class.
+ *
+ * @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * DataModel internal reference node.
+ *
+ * @class
+ * @extends ve.dm.BranchNode
+ * @constructor
+ * @param {ve.dm.BranchNode[]} [children] Child nodes to attach
+ * @param {Object} [element] Reference to element in linear model
+ */
+ve.dm.InternalReferenceListNode = function VeDmInternalReferenceListNode(
children, element ) {
+ // Parent constructor
+ ve.dm.BranchNode.call( this, children, element );
+};
+
+/* Inheritance */
+
+ve.inheritClass( ve.dm.InternalReferenceListNode, ve.dm.BranchNode );
+
+/* Static members */
+
+ve.dm.InternalReferenceListNode.static.name = 'internalReferenceList';
+
+ve.dm.InternalReferenceListNode.static.childNodeTypes = [ 'internalReference'
];
+
+ve.dm.InternalReferenceListNode.static.matchTagNames = [];
+
+ve.dm.InternalReferenceListNode.static.isInternal = true;
+
+/* Registration */
+
+ve.dm.modelRegistry.register( ve.dm.InternalReferenceListNode );
\ No newline at end of file
diff --git a/modules/ve/dm/nodes/ve.dm.InternalReferenceNode.js
b/modules/ve/dm/nodes/ve.dm.InternalReferenceNode.js
new file mode 100644
index 0000000..7d0cf5c
--- /dev/null
+++ b/modules/ve/dm/nodes/ve.dm.InternalReferenceNode.js
@@ -0,0 +1,38 @@
+/*!
+ * VisualEditor DataModel InternalReferenceNode class.
+ *
+ * @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * DataModel internal reference node.
+ *
+ * @class
+ * @extends ve.dm.BranchNode
+ * @constructor
+ * @param {ve.dm.BranchNode[]} [children] Child nodes to attach
+ * @param {Object} [element] Reference to element in linear model
+ */
+ve.dm.InternalReferenceNode = function VeDmInternalReferenceNode( children,
element ) {
+ // Parent constructor
+ ve.dm.BranchNode.call( this, children, element );
+};
+
+/* Inheritance */
+
+ve.inheritClass( ve.dm.InternalReferenceNode, ve.dm.BranchNode );
+
+/* Static members */
+
+ve.dm.InternalReferenceNode.static.name = 'internalReference';
+
+ve.dm.InternalReferenceNode.static.matchTagNames = [];
+
+ve.dm.InternalReferenceNode.static.handlesOwnChildren = true;
+
+ve.dm.InternalReferenceNode.static.isInternal = true;
+
+/* Registration */
+
+ve.dm.modelRegistry.register( ve.dm.InternalReferenceNode );
\ No newline at end of file
diff --git a/modules/ve/dm/nodes/ve.dm.MWHeadingNode.js
b/modules/ve/dm/nodes/ve.dm.MWHeadingNode.js
index 5fba677..320e331 100644
--- a/modules/ve/dm/nodes/ve.dm.MWHeadingNode.js
+++ b/modules/ve/dm/nodes/ve.dm.MWHeadingNode.js
@@ -6,7 +6,7 @@
*/
/**
- * DataModel MW heading node.
+ * DataModel MediaWiki heading node.
*
* @class
* @extends ve.dm.HeadingNode
diff --git a/modules/ve/dm/nodes/ve.dm.MWPreformattedNode.js
b/modules/ve/dm/nodes/ve.dm.MWPreformattedNode.js
index 210d18f..2585b45 100644
--- a/modules/ve/dm/nodes/ve.dm.MWPreformattedNode.js
+++ b/modules/ve/dm/nodes/ve.dm.MWPreformattedNode.js
@@ -6,7 +6,7 @@
*/
/**
- * DataModel MW preformatted node.
+ * DataModel MediaWiki preformatted node.
*
* @class
* @extends ve.dm.PreformattedNode
diff --git a/modules/ve/dm/nodes/ve.dm.MWReferenceNode.js
b/modules/ve/dm/nodes/ve.dm.MWReferenceNode.js
new file mode 100644
index 0000000..55dc681
--- /dev/null
+++ b/modules/ve/dm/nodes/ve.dm.MWReferenceNode.js
@@ -0,0 +1,69 @@
+/*!
+ * VisualEditor DataModel MWReferenceNode class.
+ *
+ * @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * DataModel MediaWiki reference node.
+ *
+ * @class
+ * @extends ve.dm.GeneratedContentNode
+ * @constructor
+ * @param {number} [length] Length of content data in document; ignored and
overridden to 0
+ * @param {Object} [element] Reference to element in linear model
+ */
+ve.dm.MWReferenceNode = function VeDmMWReferenceNode( length, element ) {
+ // Parent constructor
+ ve.dm.GeneratedContentNode.call( this, 0, element );
+};
+
+/* Inheritance */
+
+ve.inheritClass( ve.dm.MWReferenceNode, ve.dm.GeneratedContentNode );
+
+/* Static members */
+
+ve.dm.MWReferenceNode.static.name = 'MWreference';
+
+ve.dm.MWReferenceNode.static.matchTagNames = null;
+
+// TODO: latest spec has this as mw:Object/Extension/Ref
+ve.dm.MWReferenceNode.static.matchRdfaTypes = [ 'mw:Object/Ext/Ref' ];
+
+ve.dm.MWReferenceNode.static.isContent = true;
+
+ve.dm.MWReferenceNode.static.toDataElement = function ( domElements, converter
) {
+ var dataElement,
+ about = domElements[0].getAttribute( 'about' ),
+ text = $( '<div>', domElements[0].ownerDocument ).append( $(
domElements ).clone() ).text(),
+ // TODO: this is always-present in the new spec, so "|| '{}'"
can be removed later
+ mw = JSON.parse( domElements[0].getAttribute( 'data-mw' ) ||
'{}' ),
+ // TODO: this will be stored in mw.body.html in the new spec
+ body = JSON.parse( domElements[0].getAttribute( 'data-parsoid'
) ).src,
+ // TODO: this will be stored in mw.name in the new spec
+ name = $( body ).attr( 'name' );
+
+ converter.referenceList.addReference( name, body );
+
+ dataElement = {
+ 'type': this.name,
+ 'mw': mw,
+ 'about': about,
+ 'text': text
+ };
+ return dataElement;
+};
+
+ve.dm.MWReferenceNode.static.toDomElements = function ( dataElement, doc ) {
+ var span = doc.createElement( 'span' );
+ span.setAttribute( 'about', dataElement.about );
+ // TODO: latest spec has this as mw:Object/Extension/Ref
+ span.setAttribute( 'typeof', 'mw:Object/Ext/Ref' );
+ span.setAttribute( 'data-mw', JSON.stringify( dataElement.mw ) );
+ return [ span ];
+};
+/* Registration */
+
+ve.dm.modelRegistry.register( ve.dm.MWReferenceNode );
\ No newline at end of file
diff --git a/modules/ve/dm/ve.dm.Converter.js b/modules/ve/dm/ve.dm.Converter.js
index eae715b..da6fe96 100644
--- a/modules/ve/dm/ve.dm.Converter.js
+++ b/modules/ve/dm/ve.dm.Converter.js
@@ -205,6 +205,9 @@
if ( !nodeClass ) {
throw new Error( 'Attempting to convert unknown data element
type ' + dataElement.type );
}
+ if ( nodeClass.static.isInternal ) {
+ return false;
+ }
domElements = nodeClass.static.toDomElements( dataElements, doc, this );
if ( !domElements || !domElements.length ) {
throw new Error( 'toDomElements() failed to return an array
when converting element of type ' + dataElement.type );
@@ -285,26 +288,33 @@
/**
* Convert an HTML document to a linear model.
- * @param {ve.dm.IndexValueStore} store Index-value store
* @param {HTMLDocument} doc HTML document to convert
+ * @param {ve.dm.IndexValueStore} store Index-value store
+ * @param {ve.dm.ReferenceList} referenceList Reference list
* @returns {ve.dm.ElementLinearData} Linear model data
*/
-ve.dm.Converter.prototype.getDataFromDom = function ( store, doc ) {
- var result;
+ve.dm.Converter.prototype.getDataFromDom = function ( doc, store,
referenceList ) {
+ var linearData, refData;
// Set up the converter state
this.doc = doc;
this.store = store;
+ this.referenceList = referenceList;
this.contextStack = [];
// Possibly do things with doc and the head in the future
- result = new ve.dm.ElementLinearData(
+
+ linearData = new ve.dm.ElementLinearData(
store,
this.getDataFromDomRecursion( doc.body )
);
+ refData = this.referenceList.getDataFromDom( this );
+ linearData.batchSplice( linearData.getLength(), 0, refData );
+
// Clear the state
this.doc = null;
this.store = null;
+ this.referenceList = null;
this.contextStack = null;
- return result;
+ return linearData;
};
/**
@@ -1025,59 +1035,61 @@
// Create node from data
dataElementOrSlice = getDataElementOrSlice();
childDomElements =
this.getDomElementsFromDataElement( dataElementOrSlice, doc );
- // Add reference to internal data
- childDomElements[0].veInternal =
ve.extendObject(
- { 'childDomElements': childDomElements
},
- dataElement.internal || {}
- );
- // Add elements
- for ( j = 0; j < childDomElements.length; j++ )
{
- domElement.appendChild(
childDomElements[j] );
- }
- // Descend into the first child node
- parentDomElement = domElement;
- domElement = childDomElements[0];
-
- // Process outer whitespace
- // Every piece of outer whitespace is
duplicated somewhere:
- // each node's outerPost is duplicated as the
next node's
- // outerPre, the first node's outerPre is the
parent's
- // innerPre, and the last node's outerPost is
the parent's
- // innerPost. For each piece of whitespace, we
verify that
- // the duplicate matches. If it doesn't, we
take that to
- // mean the user has messed with it and don't
output any
- // whitespace.
- if ( domElement.veInternal &&
domElement.veInternal.whitespace ) {
- // Process this node's outerPre
- ours =
domElement.veInternal.whitespace[0];
- theirs = undefined;
- if ( domElement.previousSibling ) {
- // Get previous sibling's
outerPost
- theirs =
parentDomElement.lastOuterPost;
- } else if ( parentDomElement ===
container ) {
- // outerPre of the very first
node in the document, this one
- // has no duplicate
- theirs = ours;
- } else {
- // First child, get parent's
innerPre
- if (
-
parentDomElement.veInternal &&
-
parentDomElement.veInternal.whitespace
- ) {
- theirs =
parentDomElement.veInternal.whitespace[1];
- // Clear after use so
it's not used twice
-
parentDomElement.veInternal.whitespace[1] = undefined;
- }
- // else theirs=undefined
+ if ( childDomElements ) {
+ // Add reference to internal data
+ childDomElements[0].veInternal =
ve.extendObject(
+ { 'childDomElements':
childDomElements },
+ dataElement.internal || {}
+ );
+ // Add elements
+ for ( j = 0; j <
childDomElements.length; j++ ) {
+ domElement.appendChild(
childDomElements[j] );
}
- if ( ours && ours === theirs ) {
- // Matches the duplicate,
insert a TextNode
- textNode = doc.createTextNode(
ours );
- textNode.veIsWhitespace = true;
- parentDomElement.insertBefore(
- textNode,
- domElement
- );
+ // Descend into the first child node
+ parentDomElement = domElement;
+ domElement = childDomElements[0];
+
+ // Process outer whitespace
+ // Every piece of outer whitespace is
duplicated somewhere:
+ // each node's outerPost is duplicated
as the next node's
+ // outerPre, the first node's outerPre
is the parent's
+ // innerPre, and the last node's
outerPost is the parent's
+ // innerPost. For each piece of
whitespace, we verify that
+ // the duplicate matches. If it
doesn't, we take that to
+ // mean the user has messed with it and
don't output any
+ // whitespace.
+ if ( domElement.veInternal &&
domElement.veInternal.whitespace ) {
+ // Process this node's outerPre
+ ours =
domElement.veInternal.whitespace[0];
+ theirs = undefined;
+ if ( domElement.previousSibling
) {
+ // Get previous
sibling's outerPost
+ theirs =
parentDomElement.lastOuterPost;
+ } else if ( parentDomElement
=== container ) {
+ // outerPre of the very
first node in the document, this one
+ // has no duplicate
+ theirs = ours;
+ } else {
+ // First child, get
parent's innerPre
+ if (
+
parentDomElement.veInternal &&
+
parentDomElement.veInternal.whitespace
+ ) {
+ theirs =
parentDomElement.veInternal.whitespace[1];
+ // Clear after
use so it's not used twice
+
parentDomElement.veInternal.whitespace[1] = undefined;
+ }
+ // else theirs=undefined
+ }
+ if ( ours && ours === theirs ) {
+ // Matches the
duplicate, insert a TextNode
+ textNode =
doc.createTextNode( ours );
+ textNode.veIsWhitespace
= true;
+
parentDomElement.insertBefore(
+ textNode,
+ domElement
+ );
+ }
}
}
diff --git a/modules/ve/dm/ve.dm.Document.js b/modules/ve/dm/ve.dm.Document.js
index d353473..8b0120a 100644
--- a/modules/ve/dm/ve.dm.Document.js
+++ b/modules/ve/dm/ve.dm.Document.js
@@ -41,6 +41,7 @@
currentNode = this.documentNode;
this.documentNode.setDocument( doc );
this.documentNode.setRoot( root );
+ this.referenceList = new ve.dm.ReferenceList( this );
// Properties
this.parentDocument = parentDocument;
@@ -48,7 +49,7 @@
if ( documentOrData instanceof ve.dm.LinearData ) {
this.data = documentOrData;
} else if ( !ve.isArray( documentOrData ) && typeof documentOrData ===
'object' ) {
- this.data = ve.dm.converter.getDataFromDom( new
ve.dm.IndexValueStore(), documentOrData );
+ this.data = ve.dm.converter.getDataFromDom( documentOrData, new
ve.dm.IndexValueStore(), this.getReferenceList() );
} else {
this.data = new ve.dm.ElementLinearData(
new ve.dm.IndexValueStore(),
@@ -267,6 +268,14 @@
};
/**
+ * Get the document's reference list
+ * @returns {ve.dm.ReferenceList} The document's reference list
+ */
+ve.dm.Document.prototype.getReferenceList = function () {
+ return this.referenceList;
+};
+
+/**
* Splice data into and/or out of the linear model.
*
* `this.metadata` will be updated accordingly.
diff --git a/modules/ve/dm/ve.dm.Model.js b/modules/ve/dm/ve.dm.Model.js
index 550fc83..71eac79 100644
--- a/modules/ve/dm/ve.dm.Model.js
+++ b/modules/ve/dm/ve.dm.Model.js
@@ -65,6 +65,11 @@
ve.dm.Model.static.matchFunction = null;
/**
+ * Set the model to be internal. Internal model items are ignored by the
converter.
+ */
+ve.dm.Model.static.isInternal = false;
+
+/**
* Static function to convert a DOM element or set of sibling DOM elements to
a linear model element
* for this model type.
*
diff --git a/modules/ve/dm/ve.dm.ReferenceList.js
b/modules/ve/dm/ve.dm.ReferenceList.js
new file mode 100644
index 0000000..ec089be
--- /dev/null
+++ b/modules/ve/dm/ve.dm.ReferenceList.js
@@ -0,0 +1,88 @@
+/*!
+ * VisualEditor DataModel ReferenceList class.
+ *
+ * @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * DataModel meta item.
+ *
+ * @class
+ * @extends ve.EventEmitter
+ * @constructor
+ * @param {ve.dm.Document} doc Document model
+ */
+ve.dm.ReferenceList = function VeDmReferenceList(/* doc */) {
+ // Parent constructor
+ ve.EventEmitter.call( this );
+
+ // Properties
+ //this.document = doc;
+ this.store = new ve.dm.IndexValueStore();
+ this.domElements = [];
+ this.dataRanges = [];
+
+ // Event handlers
+ //this.document.on( 'transact', ve.bind( this.onTransact, this ) );
+};
+
+/* Inheritance */
+
+ve.inheritClass( ve.dm.ReferenceList, ve.EventEmitter );
+
+/* Methods */
+
+/**
+ * Add a reference to the list.
+ *
+ * If a reference by this name already exists it will be ignored.
+ *
+ * @param {string|null} name Reference name
+ * @param {string} body Reference contents
+ */
+ve.dm.ReferenceList.prototype.addReference = function ( name, body ) {
+ if ( name === null || this.store.indexOfHash( name ) === null ) {
+ this.domElements.push( this.store.index( body, name ) );
+ }
+};
+
+/**
+ * Gets all the reference DOM elements
+ * @returns {Object} Name-indexed object containing HTMLElements
+ */
+ve.dm.ReferenceList.prototype.getDomElements = function () {
+ return this.store.values( this.domElements );
+};
+
+/**
+ * Gets linear model data for all the stored reference DOM elements.
+ *
+ * Each reference is an internalReference item, and they are wrapped in an
internalReferenceList.
+ * If there are no references an empty array is returned.
+ *
+ * @param {ve.dm.Converter} converter Converter object
+ * @returns {Array} Linear model data
+ */
+ve.dm.ReferenceList.prototype.getDataFromDom = function ( converter ) {
+ var i, length, domElements, refData, endOffset,
+ refList = [], startOffset = 0, refElements =
this.getDomElements();
+
+ if ( !ve.isEmptyObject( refElements ) ) {
+ refList.push( { 'type': 'internalReferenceList' } );
+ domElements = this.getDomElements();
+ for ( i = 0, length = domElements.length; i < length; i++ ) {
+ refData = converter.getDataFromDomRecursion( $(
domElements[i] )[0] );
+ refList = refList.concat(
+ [{ 'type': 'internalReference' }],
+ refData,
+ [{ 'type': '/internalReference' }]
+ );
+ endOffset = startOffset + refData.length + 2;
+ this.dataRanges[i] = new ve.Range( startOffset,
endOffset );
+ startOffset = endOffset;
+ }
+ refList.push( { 'type': '/internalReferenceList' } );
+ }
+ return refList;
+};
\ No newline at end of file
diff --git a/modules/ve/init/mw/ve.init.mw.Target.js
b/modules/ve/init/mw/ve.init.mw.Target.js
index 05abd6f..76820cc 100644
--- a/modules/ve/init/mw/ve.init.mw.Target.js
+++ b/modules/ve/init/mw/ve.init.mw.Target.js
@@ -577,6 +577,7 @@
var now = new Date(),
editedData = this.surface.getDocumentModel().getFullData(),
store = this.surface.getDocumentModel().getStore(),
+ referenceList =
this.surface.getDocumentModel().getReferenceList(),
report = {
'title': this.pageName,
'oldid': this.oldid,
@@ -586,7 +587,7 @@
'originalHtml': this.originalHtml,
'originalData':
// originalHTML only has the body's HTML for
now, see TODO comment in ve.init.mw.ViewPageTarget.prototype.setUpSurface
- ve.dm.converter.getDataFromDom(
ve.createDocumentFromHTML( '<body>' + this.originalHtml + '</body>') ),
+ ve.dm.converter.getDataFromDom(
ve.createDocumentFromHTML( '<body>' + this.originalHtml + '</body>'), store,
referenceList ),
'editedData': editedData,
'editedHtml': ve.dm.converter.getDomFromData( store,
editedData ).body.innerHTML,
'wiki': mw.config.get( 'wgDBname' )
diff --git a/modules/ve/test/dm/ve.dm.Converter.test.js
b/modules/ve/test/dm/ve.dm.Converter.test.js
index 9f63029..a09e9a7 100644
--- a/modules/ve/test/dm/ve.dm.Converter.test.js
+++ b/modules/ve/test/dm/ve.dm.Converter.test.js
@@ -60,7 +60,7 @@
if ( cases[msg].html !== null ) {
ve.dm.example.preprocessAnnotations( cases[msg].data,
store );
assert.deepEqual(
- ve.dm.converter.getDataFromDom( store,
ve.createDocumentFromHTML( cases[msg].html ) ).getData(),
+ ve.dm.converter.getDataFromDom(
ve.createDocumentFromHTML( cases[msg].html ), store, new ve.dm.ReferenceList()
).getData(),
cases[msg].data,
msg
);
diff --git a/modules/ve/test/index.php b/modules/ve/test/index.php
index fe9ccda..0a0596d 100644
--- a/modules/ve/test/index.php
+++ b/modules/ve/test/index.php
@@ -69,6 +69,7 @@
<script src="../../ve/dm/ve.dm.Annotation.js"></script>
<script src="../../ve/dm/ve.dm.MetaItem.js"></script>
<script src="../../ve/dm/ve.dm.MetaList.js"></script>
+ <script src="../../ve/dm/ve.dm.ReferenceList.js"></script>
<script
src="../../ve/dm/ve.dm.TransactionProcessor.js"></script>
<script src="../../ve/dm/ve.dm.Transaction.js"></script>
<script src="../../ve/dm/ve.dm.Surface.js"></script>
@@ -91,6 +92,8 @@
<script src="../../ve/dm/nodes/ve.dm.DocumentNode.js"></script>
<script src="../../ve/dm/nodes/ve.dm.HeadingNode.js"></script>
<script src="../../ve/dm/nodes/ve.dm.ImageNode.js"></script>
+ <script
src="../../ve/dm/nodes/ve.dm.InternalReferenceListNode.js"></script>
+ <script
src="../../ve/dm/nodes/ve.dm.InternalReferenceNode.js"></script>
<script src="../../ve/dm/nodes/ve.dm.ListItemNode.js"></script>
<script src="../../ve/dm/nodes/ve.dm.ListNode.js"></script>
<script src="../../ve/dm/nodes/ve.dm.ParagraphNode.js"></script>
@@ -104,6 +107,7 @@
<script src="../../ve/dm/nodes/ve.dm.MWHeadingNode.js"></script>
<script src="../../ve/dm/nodes/ve.dm.MWImageNode.js"></script>
<script
src="../../ve/dm/nodes/ve.dm.MWPreformattedNode.js"></script>
+ <script
src="../../ve/dm/nodes/ve.dm.MWReferenceNode.js"></script>
<script
src="../../ve/dm/nodes/ve.dm.MWTemplateNode.js"></script>
<script
src="../../ve/dm/annotations/ve.dm.LinkAnnotation.js"></script>
<script
src="../../ve/dm/annotations/ve.dm.MWExternalLinkAnnotation.js"></script>
@@ -135,6 +139,8 @@
<script src="../../ve/ce/nodes/ve.ce.DocumentNode.js"></script>
<script src="../../ve/ce/nodes/ve.ce.HeadingNode.js"></script>
<script src="../../ve/ce/nodes/ve.ce.ImageNode.js"></script>
+ <script
src="../../ve/ce/nodes/ve.ce.InternalReferenceListNode.js"></script>
+ <script
src="../../ve/ce/nodes/ve.ce.InternalReferenceNode.js"></script>
<script src="../../ve/ce/nodes/ve.ce.ListItemNode.js"></script>
<script src="../../ve/ce/nodes/ve.ce.ListNode.js"></script>
<script src="../../ve/ce/nodes/ve.ce.ParagraphNode.js"></script>
@@ -148,6 +154,7 @@
<script src="../../ve/ce/nodes/ve.ce.MWHeadingNode.js"></script>
<script src="../../ve/ce/nodes/ve.ce.MWImageNode.js"></script>
<script
src="../../ve/ce/nodes/ve.ce.MWPreformattedNode.js"></script>
+ <script
src="../../ve/ce/nodes/ve.ce.MWReferenceNode.js"></script>
<script
src="../../ve/ce/nodes/ve.ce.MWTemplateNode.js"></script>
<script
src="../../ve/ce/annotations/ve.ce.LinkAnnotation.js"></script>
<script
src="../../ve/ce/annotations/ve.ce.MWExternalLinkAnnotation.js"></script>
--
To view, visit https://gerrit.wikimedia.org/r/59651
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6daff5c5969e5fdc871f8f346cf790b4302ae080
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Esanders <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits