http://www.mediawiki.org/wiki/Special:Code/MediaWiki/94913

Revision: 94913
Author:   tparscal
Date:     2011-08-18 18:32:18 +0000 (Thu, 18 Aug 2011)
Log Message:
-----------
Moved es.Content.isolate functionality into es.Content.annotate, where it's 
actually needed - not using it prior to annotating can cause nasty hard to find 
bugs, so this is safer and easier

Modified Paths:
--------------
    trunk/parsers/wikidom/lib/es/es.Content.js
    trunk/parsers/wikidom/lib/es/es.Transaction.js

Modified: trunk/parsers/wikidom/lib/es/es.Content.js
===================================================================
--- trunk/parsers/wikidom/lib/es/es.Content.js  2011-08-18 18:22:43 UTC (rev 
94912)
+++ trunk/parsers/wikidom/lib/es/es.Content.js  2011-08-18 18:32:18 UTC (rev 
94913)
@@ -401,26 +401,6 @@
 };
 
 /**
- * Breaks cross references, which occur when content is copied around.
- * 
- * Because content data is an array of characters, or arrays containing a 
character and any
- * number of references to annotation objects, slicing the array still leaves 
annotated characters
- * as references to shared memory. This should be used only when annotations 
are going to be
- * changed because it is rather expensive.
- * 
- * @method
- */
-es.Content.prototype.isolate = function() {
-       var i = 0,
-               length = this.data.length;
-       while ( i < length ) {
-               // The slice method works for array or string character type
-               this.data[i] = this.data[i].slice( 0 );
-               i++;
-       }
-};
-
-/**
  * Inserts content data at a specific position.
  * 
  * Inserted content will inherit annotations from neighboring content.
@@ -550,12 +530,33 @@
  * @emits "change" with type:"annotate" data property
  */
 es.Content.prototype.annotate = function( method, annotation, range ) {
+       // Support calling without a range argument, using the full content 
range as default
        if ( !range ) {
                range = new es.Range( 0, this.data.length );
        } else {
                range.normalize();
        }
-       var i;
+       /*
+        * Because content data is an array of either strings containing a 
single character each or
+        * references to arrays containing a single character string followed 
by a series of references
+        * to annotation objects, making a "copy" by slicing content data will 
cause references to
+        * annotated characters in the content data to be shared between the 
original and the "copy". To
+        * ensure that modifications to annotated characters in the content 
data do not affect the data
+        * of other content objects, annotated characters must be sliced 
individually. This is too
+        * expensive to do on all content on every copy, so we only do it when 
we are going to modify
+        * the annotation information, and on a few annotated characters as 
possible.
+        */
+       for ( var i = range.start; i < range.end; i++ ) {
+               if ( typeof this.data[i] !== 'string' ) {
+                       this.data[i] = this.data[i].slice( 0 );
+               }
+               i++;
+       }
+       /*
+        * Support toggle method by automatically choosing add or remove based 
on the coverage of the 
+        * content being annotated; if the content is not covered or partially 
covered add will be used,
+        * if the content is completely covered, remove will be used.
+        */
        if ( method === 'toggle' ) {
                var coverage = this.coverageOfAnnotation( range, annotation, 
false );
                if ( coverage.length === range.getLength() ) {
@@ -567,7 +568,7 @@
        }
        if ( method === 'add' ) {
                var duplicate;
-               for ( i = range.start; i < range.end; i++ ) {
+               for ( var i = range.start; i < range.end; i++ ) {
                        duplicate = -1;
                        if ( typeof this.data[i] === 'string' ) {
                                // Never annotate new lines
@@ -589,7 +590,7 @@
                        }
                }
        } else if ( method === 'remove' ) {
-               for ( i = range.start; i < range.end; i++ ) {
+               for ( var i = range.start; i < range.end; i++ ) {
                        if ( typeof this.data[i] !== 'string' ) {
                                if ( annotation.type === 'all' ) {
                                        // Remove all annotations by converting 
the annotated character to a plain

Modified: trunk/parsers/wikidom/lib/es/es.Transaction.js
===================================================================
--- trunk/parsers/wikidom/lib/es/es.Transaction.js      2011-08-18 18:22:43 UTC 
(rev 94912)
+++ trunk/parsers/wikidom/lib/es/es.Transaction.js      2011-08-18 18:32:18 UTC 
(rev 94913)
@@ -1,6 +1,9 @@
 /**
- * Creates an operation to be applied to a content object.
+ * Creates a transaction which can be applied to a content object.
  * 
+ * Transactions contain a series of operations, such as retain, insert, 
remove, start and end. Each
+ * operation describes a step that must be taken to construct a new version of 
a content object.
+ * 
  * @class
  * @constructor
  * @param content {es.Content} Content to operate on
@@ -12,13 +15,10 @@
 };
 
 /**
- * List of operation implementations.
+ * List of operation implementations. 
  */
 es.Transaction.operations = ( function() {
        function annotate( con, add, rem ) {
-               // Ensure that modifications to annotated characters do not 
affect other uses of the same
-               // content by isolating it - performing a deep-slice
-               con.isolate();
                for ( var i = 0; i < add.length; i++ ) {
                        con.annotate( 'add', add[i] );
                }
@@ -147,8 +147,7 @@
                adv;
        for ( var i = 0; i < this.operations.length; i++ ) {
                var op = this.operations[i];
-               adv = op.model.commit( op.val, cur, src, dst, add, rem );
-               cur += adv;
+               cur += op.model.commit( op.val, cur, src, dst, add, rem );
        }
        return dst;
 };
@@ -161,8 +160,7 @@
                adv;
        for ( var i = 0; i < this.operations.length; i++ ) {
                var op = this.operations[i];
-               adv = op.model.rollback( op.val, cur, src, dst, add, rem );
-               cur += adv;
+               cur += op.model.rollback( op.val, cur, src, dst, add, rem );
        }
        return dst;
 };


_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to