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

Revision: 90094
Author:   tparscal
Date:     2011-06-14 22:03:06 +0000 (Tue, 14 Jun 2011)
Log Message:
-----------
Added rough-sketch of planned API for an edit surface and it's related 
components.

Added Paths:
-----------
    trunk/parsers/wikidom/lib/editSurface.js

Added: trunk/parsers/wikidom/lib/editSurface.js
===================================================================
--- trunk/parsers/wikidom/lib/editSurface.js                            (rev 0)
+++ trunk/parsers/wikidom/lib/editSurface.js    2011-06-14 22:03:06 UTC (rev 
90094)
@@ -0,0 +1,379 @@
+/**
+ * Pixel position, a 2D position within a rendered document.
+ * 
+ * @param x {Integer} Horizontal position
+ * @param y {Integer} Vertical position
+ * @returns {Position}
+ */
+function Position( x, y ) {
+       this.x = x || 0;
+       this.y = y || 0;
+}
+
+/**
+ * Content location, an offset within a block.
+ * 
+ * @param block {Block} Location target
+ * @param offset {Integer} Location offset
+ * @returns {Location}
+ */
+function Location( block, offset ) {
+       this.block = block;
+       this.offset = offset || 0;
+}
+
+/**
+ * Content selection, a pair of locations.
+ * 
+ * @param from {Location} Starting location
+ * @param to {Location} Ending location
+ * @returns {Selection}
+ */
+function Selection( from, to ) {
+       this.from = from;
+       this.to = to;
+}
+
+/**
+ * Ensures that "from" is before "to".
+ */
+Selection.prototype.normalize = function() {
+       if ( this.from.block.index() > this.to.block.index()
+                       || ( this.from.block.index() === this.to.block.index()
+                                       && this.from.offset > this.to.offset ) 
) {
+               var from = sel.from;
+               this.from = to;
+               this.to = from;
+       }
+};
+
+/**
+ * Gets all blocks selected completely, between from and to.
+ * 
+ * If from and to are adjacent blocks, or the same block, the result will 
always be an empty array.
+ * 
+ * @returns {Array} List of blocks
+ */
+Selection.prototype.through = function() {
+       var through = [];
+       if ( this.from !== this.to && this.from.nextBlock() !== this.to ) {
+               var next = this.from.nextBlock()
+               while ( next && next !== this.to ) {
+                       through.push( next );
+                       next = next.nextBlock();
+               }
+       }
+       return through;
+};
+
+/**
+ * 
+ * @param blocks {Array} List of blocks
+ * @returns {Document}
+ */
+function Document( blocks ) {
+       this.blocks = blocks || [];
+}
+
+/**
+ * Gets the first block in the document.
+ * 
+ * @returns {Block}
+ */
+Document.prototype.firstBlock = function() {
+       return this.blocks.length ? this.blocks[0] : null;
+};
+
+/**
+ * Gets the last block in the document.
+ * 
+ * @returns {Block}
+ */
+Document.prototype.lastBlock = function() {
+       return this.blocks.length ? this.blocks[this.blocks.length - 1] : null;
+};
+
+/**
+ * Adds a block to the end of the document.
+ * 
+ * @param {Block} Block to append
+ */
+Document.prototype.appendBlock = function( block ) {
+       block.document = this;
+       this.blocks.push( block );
+};
+
+/**
+ * Adds a block to the beginning of the document.
+ * 
+ * @param {Block} Block to prepend
+ */
+Document.prototype.prependBlock = function( block ) {
+       block.document = this;
+       this.blocks.unshift( block );
+};
+
+/**
+ * Adds a block to the document after an existing block.
+ * 
+ * @param {Block} Block to insert
+ */
+Document.prototype.insertBlockBefore = function( block, before ) {
+       block.document = this;
+       if ( before ) {
+               this.blocks.splice( before.index(), 0, block );
+       } else {
+               this.blocks.push( block );
+       }
+};
+
+/**
+ * Removes a block from the document.
+ * 
+ * @param {Block} Block to remove
+ */
+Document.prototype.removeBlock = function( block ) {
+       this.blocks.splice( block.index(), 1 );
+       block.document = null;
+};
+
+/**
+ * 
+ * @param document
+ * @returns {Block}
+ */
+function Block( document ) {
+       this.document = document;
+}
+
+/**
+ * Gets the index of the block within it's document.
+ * 
+ * @returns {Integer} Index of block
+ */
+Block.prototype.index = function() {
+       return this.document.blocks.indexOf( this );
+};
+
+/**
+ * Gets the next block in the document.
+ * 
+ * @returns {Block|Null} Block directly proceeding this one, or null if none 
exists
+ */
+Block.prototype.nextBlock = function() {
+       var index = this.index() + 1;
+       return this.document.blocks.length < index ? 
this.document.blocks[index] : null;
+};
+
+/**
+ * Gets the previous block in the document.
+ * 
+ * @returns {Block|Null} Block directly preceding this one, or null if none 
exists
+ */
+Block.prototype.previousBlock = function() {
+       var index = this.index() - 1;
+       return index >= 0 ? this.document.blocks[index] : null;
+};
+
+/**
+ * Inserts content into a block at an offset.
+ * 
+ * @param offset {Integer} Position to insert content at
+ * @param content {Object} Content to insert
+ */
+Block.prototype.insertContent = function( offset, content ) {
+       // block-type dependent implementation
+};
+
+/**
+ * Deletes content in a block within a range.
+ * 
+ * @param offset {Integer} Position to start removing content from
+ * @param length {Integer} Length of content to remove
+ */
+Block.prototype.deleteContent = function( offset, length ) {
+       // block-type dependent implementation
+};
+
+/**
+ * Replaces a range of content in a block with new content.
+ * 
+ * @param offset {Integer} Position to start removing content from
+ * @param length {Integer} Length of content to remove
+ * @param content {Object} Content to insert
+ */
+Block.prototype.replaceContent = function( offset, length, content ) {
+       // block-type dependent implementation
+};
+
+/**
+ * 
+ * @param $container
+ * @param document
+ * @returns {Surface}
+ */
+function Surface( $container, document ) {
+       this.$container = $container;
+       this.document = document;
+}
+
+/**
+ * Moves the cursor to a new location.
+ * 
+ * @param location {Location} Location to move the cursor to
+ */
+Surface.prototype.setCursor = function( location ) {
+       //
+};
+
+/**
+ * Gets the current location of the cursor.
+ * 
+ * @returns {Location}
+ */
+Surface.prototype.getCursor = function() {
+       // return location
+};
+
+/**
+ * Sets the selection to a new range.
+ * 
+ * @param from {Location} Start of selection
+ * @param to {Location} End of selection
+ */
+Surface.prototype.setSelection = function( from, to ) {
+       //
+};
+
+/**
+ * Sets the selection to a new range.
+ * 
+ * @param from {Selection} Selection to apply
+ */
+Surface.prototype.setSelection = function( selection ) {
+       //
+};
+
+/**
+ * Gets the current document selection.
+ * 
+ * @returns {Selection}
+ */
+Surface.prototype.getSelection = function() {
+       // return selection
+};
+
+/**
+ * Gets the location of a position.
+ * 
+ * @param position {Position} Position to translate
+ * @returns {Location}
+ */
+Surface.prototype.getLocation = function( position ) {
+       // return location
+};
+
+/**
+ * Gets the position of a location.
+ * 
+ * @param location {Location} Location to translate
+ * @returns {Position}
+ */
+Surface.prototype.getPosition = function( location ) {
+       // return position
+};
+
+/**
+ * Moves the cursor to the nearest location directly above the current flowed 
line.
+ */
+Surface.prototype.moveCursorUp = function() {
+       var location = this.getCursor();
+       var below = this.getPosition( location );
+       var minDistance;
+       while ( location.block.previous() && location.offset > 0 ) {
+               location.offset--;
+               if ( location.offset === -1 ) {
+                       location.block = block.previous();
+               }
+               var above = this.getPosition( location );
+               if ( above.y < below.y ) {
+                       var distance = below.x - above.x;
+                       if ( minDistance > distance ) {
+                               location.offset++;
+                               break;
+                       } else {
+                               minDistance = distance;
+                       }
+               }
+       }
+       this.setCursor( location );
+};
+
+/**
+ * Moves the cursor to the nearest location directly below the current flowed 
line.
+ */
+Surface.prototype.moveCursorDown = function() {
+       var location = this.getCursor();
+       var above = this.getPosition( location );
+       var minDistance;
+       while ( location.block.next() && location.offset < 
location.block.length ) {
+               location.offset++;
+               if ( location.offset = location.block.length ) {
+                               location.block = block.next();
+               }
+               var below = this.getPosition( location );
+               if ( above.y < below.y ) {
+                       var distance = below.x - above.x;
+                       if ( minDistance > distance ) {
+                               location.offset++;
+                               break;
+                       } else {
+                               minDistance = distance;
+                       }
+               }
+       }
+       this.setCursor( location );
+};
+
+/**
+ * Moves the cursor backward of the current position.
+ */
+Surface.prototype.moveCursorRight = function() {
+       var location = this.getCursor();
+       if ( location.block.length < location.offset + 1 ) {
+               location.offset++;
+       } else {
+               var next = location.block.next();
+               if ( next ) {
+                       location.block = next;
+                       location.offset = 0;
+               }
+       }
+       this.setCursor( location );
+};
+
+/**
+ * Moves the cursor forward of the current position.
+ */
+Surface.prototype.moveCursorLeft = function() {
+       var location = this.getCursor();
+       if ( location.offset > 0 ) {
+               location.offset--;
+       } else {
+               var previous = location.block.previous();
+               if ( previous ) {
+                       location.block = previous;
+                       location.offset = location.block.length - 1;
+               }
+       }
+       this.setCursor( location );
+};
+
+/**
+ * Updates the rendered view.
+ * 
+ * @param from Location: Where to start re-flowing from (optional)
+ */
+Surface.prototype.reflow = function( from ) {
+       //
+};


Property changes on: trunk/parsers/wikidom/lib/editSurface.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to