r92021 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r92020‎ | r92021 | r92022 >
Date:23:42, 12 July 2011
Author:tparscal
Status:deferred
Tags:
Comment:
Added clearing and methods: add, remove and toggle are supported.
Modified paths:
  • /trunk/parsers/wikidom/demos/es/index.html (modified) (history)
  • /trunk/parsers/wikidom/lib/es/es.Block.js (modified) (history)
  • /trunk/parsers/wikidom/lib/es/es.Content.js (modified) (history)
  • /trunk/parsers/wikidom/lib/es/es.ParagraphBlock.js (modified) (history)
  • /trunk/parsers/wikidom/lib/es/es.Surface.js (modified) (history)
  • /trunk/parsers/wikidom/lib/es/es.js (modified) (history)

Diff [purge]

Index: trunk/parsers/wikidom/lib/es/es.js
@@ -66,18 +66,21 @@
6767 function Selection( from, to ) {
6868 this.from = from;
6969 this.to = to;
 70+ this.start = from;
 71+ this.end = to;
7072 }
7173
7274 /**
7375 * Ensures that "from" is before "to".
7476 */
7577 Selection.prototype.normalize = function() {
76 - if ( this.from.block.index() > this.to.block.index()
77 - || ( this.from.block.index() === this.to.block.index()
78 - && this.from.offset > this.to.offset ) ) {
79 - var from = sel.from;
80 - this.from = to;
81 - this.to = from;
 78+ if ( this.from.block.getIndex() < this.to.block.getIndex()
 79+ || ( this.from.block === this.to.block && this.from.offset < this.to.offset ) ) {
 80+ this.start = this.from;
 81+ this.end = this.to;
 82+ } else {
 83+ this.start = this.to;
 84+ this.end = this.from;
8285 }
8386 };
8487
Index: trunk/parsers/wikidom/lib/es/es.Surface.js
@@ -197,13 +197,14 @@
198198 */
199199 Surface.prototype.drawSelection = function() {
200200 if ( this.selection.from && this.selection.to ) {
 201+ this.selection.normalize();
201202 var from = {
202 - 'location': this.selection.from,
203 - 'position': this.selection.from.block.getPosition( this.selection.from.offset )
 203+ 'location': this.selection.start,
 204+ 'position': this.selection.start.block.getPosition( this.selection.start.offset )
204205 },
205206 to = {
206 - 'location': this.selection.to,
207 - 'position': this.selection.to.block.getPosition( this.selection.to.offset )
 207+ 'location': this.selection.end,
 208+ 'position': this.selection.end.block.getPosition( this.selection.end.offset )
208209 };
209210 if ( from.location.block === to.location.block ) {
210211 var block = from.location.block,
@@ -214,12 +215,6 @@
215216 this.$rangeFill.hide();
216217 this.$rangeEnd.hide();
217218 } else if ( from.position.line === to.position.line ) {
218 - // Normalize from/to
219 - if ( from.location.offset > to.location.offset ) {
220 - var temp = to;
221 - to = from;
222 - from = temp;
223 - }
224219 // Single line selection
225220 this.$rangeStart
226221 .css( {
@@ -232,12 +227,6 @@
233228 this.$rangeFill.hide();
234229 this.$rangeEnd.hide();
235230 } else {
236 - // Normalize from/to
237 - if ( from.position.line > to.position.line ) {
238 - var temp = to;
239 - to = from;
240 - from = temp;
241 - }
242231 // Multiple line selection
243232 var blockWidth = block.$.width();
244233 this.$rangeStart
@@ -270,12 +259,6 @@
271260 }
272261 }
273262 } else {
274 - // Normalize from/to
275 - if ( from.location.block.getIndex() > to.location.block.getIndex() ) {
276 - var temp = to;
277 - to = from;
278 - from = temp;
279 - }
280263 // Multiple block selection
281264 var blockWidth = Math.max(
282265 from.location.block.$.width(),
@@ -449,3 +432,46 @@
450433 this.document.updateBlocks();
451434 }
452435 };
 436+
 437+/**
 438+ * Applies an annotation to a given selection.
 439+ *
 440+ * If a selection argument is not provided, the current selection will be annotated.
 441+ *
 442+ * @param annotation {Object} Annotation to apply
 443+ * @param selection {Selection} Range to apply annotation to
 444+ */
 445+Surface.prototype.annotateContent= function( annotation, selection ) {
 446+ if ( selection === undefined ) {
 447+ selection = this.selection;
 448+ }
 449+ if ( selection.from && selection.to ) {
 450+ selection.normalize();
 451+ var from = selection.start,
 452+ to = selection.end;
 453+ if ( from.block === to.block ) {
 454+ // Single block annotation
 455+ from.block.annotateContent( annotation, from.offset, to.offset );
 456+ from.block.renderContent();
 457+ } else {
 458+ // Multiple block annotation
 459+ for ( var i = from.block.getIndex(), end = to.block.getIndex(); i <= end; i++ ) {
 460+ var block = this.document.blocks[i];
 461+ if ( block === from.block ) {
 462+ // From offset to length
 463+ block.annotateContent( annotation, from.offset, block.getLength() );
 464+ block.renderContent();
 465+ } else if ( block === to.block ) {
 466+ // From 0 to offset
 467+ block.annotateContent( annotation, 0, to.offset );
 468+ block.renderContent();
 469+ } else {
 470+ // Full coverage
 471+ block.annotateContent( annotation, 0, block.getLength() );
 472+ block.renderContent();
 473+ }
 474+ }
 475+ }
 476+ }
 477+ this.drawSelection();
 478+};
Index: trunk/parsers/wikidom/lib/es/es.Block.js
@@ -70,23 +70,12 @@
7171
7272 /**
7373 * Renders content into a container.
74 - *
75 - * @param $container {jQuery Selection} Container to render into
7674 */
77 -Block.prototype.renderContent = function( $container ) {
 75+Block.prototype.renderContent = function() {
7876 throw 'Block.renderContent not implemented in this subclass.';
7977 };
8078
8179 /**
82 - * Updates the rendered content in a container.
83 - *
84 - * @param $container {jQuery Selection} Container to update content in
85 - */
86 -Block.prototype.updateContent = function( $container ) {
87 - throw 'Block.updateContent not implemented in this subclass.';
88 -};
89 -
90 -/**
9180 * Gets the offset of a position.
9281 *
9382 * @param position {Integer} Offset to translate
@@ -103,3 +92,16 @@
10493 Block.prototype.getPosition = function( offset ) {
10594 throw 'Block.getPosition not implemented in this subclass.';
10695 };
 96+
 97+/**
 98+ * Applies an annotation to a given range.
 99+ *
 100+ * If a range arguments are not provided, all content will be annotated.
 101+ *
 102+ * @param annotation {Object} Annotation to apply
 103+ * @param start {Integer} Offset to begin annotating from
 104+ * @param end {Integer} Offset to stop annotating to
 105+ */
 106+Block.prototype.annotateContent = function( annotation, start, end ) {
 107+ throw 'Block.annotateContent not implemented in this subclass.';
 108+};
Index: trunk/parsers/wikidom/lib/es/es.Content.js
@@ -2,6 +2,23 @@
33 this.data = content || [];
44 };
55
 6+Content.compareObjects = function( a, b ) {
 7+ for ( var key in a ) {
 8+ if ( typeof a[key] !== typeof b[key] ) {
 9+ return false
 10+ } else if ( typeof a[key] === 'string' || typeof a[key] === 'number' ) {
 11+ if ( a[key] !== b[key] ) {
 12+ return false;
 13+ }
 14+ } else if ( $.isPlainObject( a[key] ) ) {
 15+ if ( !Content.compareObjects( a[key], b[key] ) ) {
 16+ return false;
 17+ }
 18+ }
 19+ }
 20+ return true;
 21+};
 22+
623 Content.copyObject = function( src ) {
724 var dst = {};
825 for ( var key in src ) {
@@ -163,6 +180,70 @@
164181 return out;
165182 };
166183
 184+/**
 185+ * Applies an annotation to a given range.
 186+ *
 187+ * If a range arguments are not provided, all content will be annotated.
 188+ *
 189+ * @param annotation {Object} Annotation to apply
 190+ * @param start {Integer} Offset to begin annotating from
 191+ * @param end {Integer} Offset to stop annotating to
 192+ */
 193+Content.prototype.annotate = function( annotation, start, end ) {
 194+ start = Math.max( start, 0 );
 195+ end = Math.min( end, this.data.length );
 196+ for ( var i = start; i < end; i++ ) {
 197+ switch ( annotation.method ) {
 198+ case 'add':
 199+ if ( typeof this.data[i] === 'string' ) {
 200+ this.data[i] = [this.data[i]];
 201+ }
 202+ this.data[i].push( annotation );
 203+ break;
 204+ case 'remove':
 205+ if ( typeof this.data[i] !== 'string' ) {
 206+ if ( annotation.type === 'all' ) {
 207+ this.data[i] = this.data[i][0];
 208+ } else {
 209+ for ( var j = 1; j < this.data[i].length; j++ ) {
 210+ if ( this.data[i][j].type === annotation.type
 211+ && Content.compareObjects(
 212+ this.data[i][j].data, annotation.data
 213+ )
 214+ ) {
 215+ this.data[i].splice( j, 1 );
 216+ j--;
 217+ }
 218+ }
 219+ }
 220+ }
 221+ break;
 222+ case 'toggle':
 223+ var on = true;
 224+ if ( typeof this.data[i] !== 'string' ) {
 225+ for ( var j = 1; j < this.data[i].length; j++ ) {
 226+ if ( this.data[i][j].type === annotation.type
 227+ && Content.compareObjects(
 228+ this.data[i][j].data, annotation.data
 229+ )
 230+ ) {
 231+ this.data[i].splice( j, 1 );
 232+ j--;
 233+ on = false;
 234+ }
 235+ }
 236+ }
 237+ if ( on ) {
 238+ if ( typeof this.data[i] === 'string' ) {
 239+ this.data[i] = [this.data[i]];
 240+ }
 241+ this.data[i].push( annotation );
 242+ }
 243+ break;
 244+ }
 245+ }
 246+};
 247+
167248 Content.htmlCharacters = {
168249 '&': '&amp;',
169250 '<': '&lt;',
Index: trunk/parsers/wikidom/lib/es/es.ParagraphBlock.js
@@ -85,4 +85,17 @@
8686 return this.flow.getPosition( offset );
8787 };
8888
 89+/**
 90+ * Applies an annotation to a given range.
 91+ *
 92+ * If a range arguments are not provided, all content will be annotated.
 93+ *
 94+ * @param annotation {Object} Annotation to apply
 95+ * @param start {Integer} Offset to begin annotating from
 96+ * @param end {Integer} Offset to stop annotating to
 97+ */
 98+Block.prototype.annotateContent = function( annotation, start, end ) {
 99+ this.content.annotate( annotation, start, end );
 100+};
 101+
89102 extend( ParagraphBlock, Block );
Index: trunk/parsers/wikidom/demos/es/index.html
@@ -40,6 +40,7 @@
4141 <div class="es-toolbarTool" id="es-toolbar-bold"><img src="images/bold.png"></div>
4242 <div class="es-toolbarTool" id="es-toolbar-italic"><img src="images/italic.png"></div>
4343 <div class="es-toolbarTool" id="es-toolbar-link"><img src="images/link.png"></div>
 44+ <div class="es-toolbarTool" id="es-toolbar-clear"><img src="images/clear.png"></div>
4445 <div style="clear:both"></div>
4546 </div>
4647 <div id="es-editor"></div>
@@ -89,6 +90,32 @@
9091 ]);
9192 var surface = new Surface( $('#es-editor'), doc );
9293
 94+ $( '#es-toolbar-bold' ).click( function() {
 95+ surface.annotateContent( {
 96+ 'method': 'toggle',
 97+ 'type': 'bold'
 98+ } );
 99+ } );
 100+ $( '#es-toolbar-italic' ).click( function() {
 101+ surface.annotateContent( {
 102+ 'method': 'toggle',
 103+ 'type': 'italic'
 104+ } );
 105+ } );
 106+ $( '#es-toolbar-link' ).click( function() {
 107+ surface.annotateContent( {
 108+ 'method': 'toggle',
 109+ 'type': 'xlink',
 110+ 'data': { 'href': '#' }
 111+ } );
 112+ } );
 113+ $( '#es-toolbar-clear' ).click( function() {
 114+ surface.annotateContent( {
 115+ 'method': 'remove',
 116+ 'type': 'all'
 117+ } );
 118+ } );
 119+
93120 $(window).resize( function() {
94121 surface.render();
95122 } );

Status & tagging log