https://www.mediawiki.org/wiki/Special:Code/MediaWiki/103357
Revision: 103357
Author: catrope
Date: 2011-11-16 19:17:58 +0000 (Wed, 16 Nov 2011)
Log Message:
-----------
Fix breakage in prepareRemoval() from r103271 and demonstrated by the tests in
r103356. Also add, in a comment, a somewhat functional rewrite of
prepareRemoval() to be used after we drop droppability
Modified Paths:
--------------
trunk/extensions/VisualEditor/modules/es/models/es.DocumentModel.js
Modified: trunk/extensions/VisualEditor/modules/es/models/es.DocumentModel.js
===================================================================
--- trunk/extensions/VisualEditor/modules/es/models/es.DocumentModel.js
2011-11-16 19:07:17 UTC (rev 103356)
+++ trunk/extensions/VisualEditor/modules/es/models/es.DocumentModel.js
2011-11-16 19:17:58 UTC (rev 103357)
@@ -832,12 +832,13 @@
*/
function strip( tx, node, range, offset ) {
var childNodes = node.getChildren(),
- selectedNodes = node.selectNodes( range ),
+ selectedNodes = node.selectNodes( range, true ),
rules = es.DocumentModel.nodeRules,
left = offset || 0,
right,
elementLength,
selectedNode;
+ offset = offset || 0;
for ( var i = 0; i < childNodes.length; i++ ) {
if ( selectedNodes.length && childNodes[i] ===
selectedNodes[0].node ) {
for ( var j = 0; j < selectedNodes.length; j++
) {
@@ -867,8 +868,8 @@
if (
selectedNode.globalRange.getLength() ) {
tx.pushRemove(
doc.data.slice(
-
selectedNode.globalRange.start,
-
selectedNode.globalRange.end
+
selectedNode.globalRange.start + offset,
+
selectedNode.globalRange.end + offset
)
);
}
@@ -901,21 +902,9 @@
// So you can merge adjacent paragraphs, or listitems. And you can't
merge a paragraph into
// a table row. There may be other rules we will want in here later,
for instance, special
// casing merging a listitem into a paragraph.
- if (
- // [<p>a</p><p>b</p>]
- (
- node1 &&
- node2 &&
- node1.getElementType() === node2.getElementType() &&
- node1.getParent() === node2.getParent()
- ) ||
- // [<p>a</p>]<p>b</p>
- (
- node1 &&
- node2 &&
- node1 === node2 &&
- range.start < range.end
- )
+ if ( node1 && node2 &&
+ node1.getElementType() === node2.getElementType() &&
+ node1.getParent() === node2.getParent()
) {
// Retain to the start of the range
if ( range.start > 0 ) {
@@ -936,6 +925,101 @@
};
/**
+ * Generates a transaction which removes data from a given range.
+ *
+ * When removing data inside an element, the data is simply discarded and the
node's length is
+ * adjusted accordingly. When removing data across elements, there are two
situations that can cause
+ * added complexity:
+ * 1. A range spans between nodes of different levels or types
+ * 2. A range only partially covers one or two nodes
+ *
+ * To resolve these issues in a predictable way the following rules must be
obeyed:
+ * 1. Structural elements are retained unless the range being removed
covers the entire element
+ * 2. Elements can only be merged if they are of the same time and share a
common parent
+ *
+ * @method
+ * @param {es.Range} range
+ * @returns {es.Transaction}
+ */
+/*
+es.DocumentModel.prototype.prepareRemovalRoan = function( range ) {
+ var tx = new es.Transaction(), selectedNodes, selectedNode, startNode,
endNode, i;
+ range.normalize();
+ if ( range.start === range.end ) {
+ // Empty range, return empty transaction
+ return tx;
+ }
+
+ selectedNodes = this.selectNodes( range );
+ startNode = selectedNodes[0].node;
+ endNode = selectedNodes[selectedNodes.length - 1].node;
+
+ // If a selection is painted across two paragraphs, and then the text
is deleted, the two
+ // paragraphs can become one paragraph. However, if the selection
crosses into a table, those
+ // cannot be merged. To make this simple, we are follow a basic rule:
+ // can merge = ( same type ) && ( same parent )
+ // So you can merge adjacent paragraphs, or listitems. And you can't
merge a paragraph into
+ // a table row. There may be other rules we will want in here later,
for instance, special
+ // casing merging a listitem into a paragraph.
+ if ( startNode && endNode &&
+ startNode.getParent() === endNode.getParent() &&
+ startNode.getElementType() === endNode.getElementType()
+ ) {
+ // This is the simple case. node1 and node2 are either the same
node, or can be merged
+ // So we can just remove all the data in the range and call it
a day, no fancy
+ // processing necessary
+ // FIXME we're not accounting for droppability here, should we?
+
+ // Retain to the start of the range
+ if ( range.start > 0 ) {
+ tx.pushRetain( range.start );
+ }
+ // Remove all data in a given range.
+ tx.pushRemove( this.data.slice( range.start, range.end ) );
+ // Retain up to the end of the document. Why do we do this?
Because Trevor said so!
+ if ( range.end < this.data.length ) {
+ tx.pushRetain( this.data.length - range.end );
+ }
+ } else {
+ //if ( range.start > 0 ) {
+ // tx.pushRetain( range.start );
+ //}
+
+ for ( i = 0; i < selectedNodes.length; i++ ) {
+ selectedNode = selectedNodes[i];
+ if ( !selectedNode.range ) {
+ // Remove the entire node
+ // TODO accounting for droppability will suck
+ tx.pushRemove( this.data.slice(
selectedNode.globalRange.start, selectedNode.globalRange.end ) );
+ } else {
+ // Remove part of the node
+ // TODO account for droppability
+ // TODO need to descend, rawr
+ tx.pushRetain( 1 + selectedNode.range.start );
+ if ( selectedNode.globalRange.getLength() ) {
+ tx.pushRemove(
+ this.data.slice(
+
selectedNode.globalRange.start,
+
selectedNode.globalRange.end
+ )
+ );
+ }
+ tx.pushRetain(
selectedNode.node.getElementLength() - selectedNode.range.end - 1 );
+ }
+ }
+
+ // Retain up to the end of the document. Why do we do this?
Because Trevor said so!
+ if ( range.end < this.data.length ) {
+ tx.pushRetain( this.data.length - range.end );
+ }
+ }
+
+ tx.optimize();
+ return tx;
+};
+*/
+
+/**
* Generates a transaction which annotates content within a given range.
*
* @method
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs