r94913 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r94912‎ | r94913 | r94914 >
Date:18:32, 18 August 2011
Author:tparscal
Status:deferred
Tags:
Comment:
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 (modified) (history)
  • /trunk/parsers/wikidom/lib/es/es.Transaction.js (modified) (history)

Diff [purge]

Index: trunk/parsers/wikidom/lib/es/es.Content.js
@@ -401,26 +401,6 @@
402402 };
403403
404404 /**
405 - * Breaks cross references, which occur when content is copied around.
406 - *
407 - * Because content data is an array of characters, or arrays containing a character and any
408 - * number of references to annotation objects, slicing the array still leaves annotated characters
409 - * as references to shared memory. This should be used only when annotations are going to be
410 - * changed because it is rather expensive.
411 - *
412 - * @method
413 - */
414 -es.Content.prototype.isolate = function() {
415 - var i = 0,
416 - length = this.data.length;
417 - while ( i < length ) {
418 - // The slice method works for array or string character type
419 - this.data[i] = this.data[i].slice( 0 );
420 - i++;
421 - }
422 -};
423 -
424 -/**
425405 * Inserts content data at a specific position.
426406 *
427407 * Inserted content will inherit annotations from neighboring content.
@@ -550,12 +530,33 @@
551531 * @emits "change" with type:"annotate" data property
552532 */
553533 es.Content.prototype.annotate = function( method, annotation, range ) {
 534+ // Support calling without a range argument, using the full content range as default
554535 if ( !range ) {
555536 range = new es.Range( 0, this.data.length );
556537 } else {
557538 range.normalize();
558539 }
559 - var i;
 540+ /*
 541+ * Because content data is an array of either strings containing a single character each or
 542+ * references to arrays containing a single character string followed by a series of references
 543+ * to annotation objects, making a "copy" by slicing content data will cause references to
 544+ * annotated characters in the content data to be shared between the original and the "copy". To
 545+ * ensure that modifications to annotated characters in the content data do not affect the data
 546+ * of other content objects, annotated characters must be sliced individually. This is too
 547+ * expensive to do on all content on every copy, so we only do it when we are going to modify
 548+ * the annotation information, and on a few annotated characters as possible.
 549+ */
 550+ for ( var i = range.start; i < range.end; i++ ) {
 551+ if ( typeof this.data[i] !== 'string' ) {
 552+ this.data[i] = this.data[i].slice( 0 );
 553+ }
 554+ i++;
 555+ }
 556+ /*
 557+ * Support toggle method by automatically choosing add or remove based on the coverage of the
 558+ * content being annotated; if the content is not covered or partially covered add will be used,
 559+ * if the content is completely covered, remove will be used.
 560+ */
560561 if ( method === 'toggle' ) {
561562 var coverage = this.coverageOfAnnotation( range, annotation, false );
562563 if ( coverage.length === range.getLength() ) {
@@ -567,7 +568,7 @@
568569 }
569570 if ( method === 'add' ) {
570571 var duplicate;
571 - for ( i = range.start; i < range.end; i++ ) {
 572+ for ( var i = range.start; i < range.end; i++ ) {
572573 duplicate = -1;
573574 if ( typeof this.data[i] === 'string' ) {
574575 // Never annotate new lines
@@ -589,7 +590,7 @@
590591 }
591592 }
592593 } else if ( method === 'remove' ) {
593 - for ( i = range.start; i < range.end; i++ ) {
 594+ for ( var i = range.start; i < range.end; i++ ) {
594595 if ( typeof this.data[i] !== 'string' ) {
595596 if ( annotation.type === 'all' ) {
596597 // Remove all annotations by converting the annotated character to a plain
Index: trunk/parsers/wikidom/lib/es/es.Transaction.js
@@ -1,6 +1,9 @@
22 /**
3 - * Creates an operation to be applied to a content object.
 3+ * Creates a transaction which can be applied to a content object.
44 *
 5+ * Transactions contain a series of operations, such as retain, insert, remove, start and end. Each
 6+ * operation describes a step that must be taken to construct a new version of a content object.
 7+ *
58 * @class
69 * @constructor
710 * @param content {es.Content} Content to operate on
@@ -12,13 +15,10 @@
1316 };
1417
1518 /**
16 - * List of operation implementations.
 19+ * List of operation implementations.
1720 */
1821 es.Transaction.operations = ( function() {
1922 function annotate( con, add, rem ) {
20 - // Ensure that modifications to annotated characters do not affect other uses of the same
21 - // content by isolating it - performing a deep-slice
22 - con.isolate();
2323 for ( var i = 0; i < add.length; i++ ) {
2424 con.annotate( 'add', add[i] );
2525 }
@@ -147,8 +147,7 @@
148148 adv;
149149 for ( var i = 0; i < this.operations.length; i++ ) {
150150 var op = this.operations[i];
151 - adv = op.model.commit( op.val, cur, src, dst, add, rem );
152 - cur += adv;
 151+ cur += op.model.commit( op.val, cur, src, dst, add, rem );
153152 }
154153 return dst;
155154 };
@@ -161,8 +160,7 @@
162161 adv;
163162 for ( var i = 0; i < this.operations.length; i++ ) {
164163 var op = this.operations[i];
165 - adv = op.model.rollback( op.val, cur, src, dst, add, rem );
166 - cur += adv;
 164+ cur += op.model.rollback( op.val, cur, src, dst, add, rem );
167165 }
168166 return dst;
169167 };

Status & tagging log