r96861 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r96860‎ | r96861 | r96862 >
Date:16:39, 12 September 2011
Author:tparscal
Status:deferred
Tags:
Comment:
* Added es.Location and es.Position to support code being moved from the old es.Surface
* Added more methods to es.SurfaceController, mostly with todo's
Modified paths:
  • /trunk/parsers/wikidom/lib/synth/controllers/es.SurfaceController.js (modified) (history)
  • /trunk/parsers/wikidom/lib/synth/es.Location.js (added) (history)
  • /trunk/parsers/wikidom/lib/synth/es.Position.js (added) (history)
  • /trunk/parsers/wikidom/lib/synth/views/es.BlockView.js (modified) (history)
  • /trunk/parsers/wikidom/lib/synth/views/es.SurfaceView.js (modified) (history)

Diff [purge]

Index: trunk/parsers/wikidom/lib/synth/es.Position.js
@@ -0,0 +1,171 @@
 2+/**
 3+ * Pixel position.
 4+ *
 5+ * This can also support an optional bottom field, to represent a vertical line, such as a cursor.
 6+ *
 7+ * @class
 8+ * @constructor
 9+ * @param left {Integer} Horizontal position
 10+ * @param top {Integer} Vertical top position
 11+ * @param bottom {Integer} Vertical bottom position of bottom (optional, default: top)
 12+ * @param line {Integer} Rendered line index (optional, default: undefined)
 13+ * @property left {Integer} Horizontal position
 14+ * @property top {Integer} Vertical top position
 15+ * @property bottom {Integer} Vertical bottom position of bottom
 16+ * @property line {Integer} Rendered line index
 17+ */
 18+es.Position = function( left, top, bottom, line ) {
 19+ this.left = left || 0;
 20+ this.top = top || 0;
 21+ this.bottom = bottom || this.top;
 22+ this.line = line;
 23+};
 24+
 25+/* Static Methods */
 26+
 27+/**
 28+ * Creates position object from the screen position data in an Event object.
 29+ *
 30+ * @static
 31+ * @method
 32+ * @param event {Event} Event to get position data from
 33+ * @returns {es.Position} Position with event data applied
 34+ */
 35+es.Position.newFromEventScreenPosition = function( event ) {
 36+ return new es.Position( event.screenX, event.screenY );
 37+};
 38+
 39+/**
 40+ * Creates position object from the page position data in an Event object.
 41+ *
 42+ * @static
 43+ * @method
 44+ * @param event {Event} Event to get position data from
 45+ * @returns {es.Position} Position with event data applied
 46+ */
 47+es.Position.newFromEventPagePosition = function( event ) {
 48+ return new es.Position( event.pageX, event.pageY );
 49+};
 50+
 51+/**
 52+ * Creates position object from the layer position data in an Event object.
 53+ *
 54+ * @static
 55+ * @method
 56+ * @param event {Event} Event to get position data from
 57+ * @returns {es.Position} Position with event data applied
 58+ */
 59+es.Position.newFromEventLayerPosition = function( event ) {
 60+ return new es.Position( event.layerX, event.layerY );
 61+};
 62+
 63+/* Methods */
 64+
 65+/**
 66+ * Checks if this position is the same as another one.
 67+ *
 68+ * @method
 69+ * @param position {es.Position} Position to compare with
 70+ * @returns {Boolean} If positions have the same left and top values
 71+ */
 72+es.Position.prototype.at = function( position ) {
 73+ return this.left === position.left && this.top === position.top;
 74+};
 75+
 76+/**
 77+ * Checks if this position perpendicular with another one, sharing either a top or left value.
 78+ *
 79+ * @method
 80+ * @param position {es.Position} Position to compare with
 81+ * @returns {Boolean} If positions share a top or a left value
 82+ */
 83+es.Position.prototype.perpendicularWith = function( position ) {
 84+ return this.left === position.left || this.top === position.top;
 85+};
 86+
 87+/**
 88+ * Checks if this position is level with another one, having the same top value.
 89+ *
 90+ * @method
 91+ * @param position {es.Position} Position to compare with
 92+ * @returns {Boolean} If positions have the same top value
 93+ */
 94+es.Position.prototype.levelWith = function( position ) {
 95+ return this.top === position.top;
 96+};
 97+
 98+/**
 99+ * Checks if this position is plumb with another one, having the same left value.
 100+ *
 101+ * @method
 102+ * @param position {es.Position} Position to compare with
 103+ * @returns {Boolean} If positions have the same left value
 104+ */
 105+es.Position.prototype.plumbWith = function( position ) {
 106+ return this.left === position.left;
 107+};
 108+
 109+/**
 110+ * Checks if this position is nearby another one.
 111+ *
 112+ * Distance is measured radially.
 113+ *
 114+ * @method
 115+ * @param position {es.Position} Position to compare with
 116+ * @param radius {Integer} Pixel distance from this position to consider "near-by"
 117+ * @returns {Boolean} If positions are near-by each other
 118+ */
 119+es.Position.prototype.near = function( position, radius ) {
 120+ return Math.sqrt(
 121+ Math.pow( this.left - position.left, 2 ),
 122+ Math.pow( this.top - position.top )
 123+ ) <= radius;
 124+};
 125+
 126+/**
 127+ * Checks if this position is above another one.
 128+ *
 129+ * This method utilizes the bottom property.
 130+ *
 131+ * @method
 132+ * @param position {es.Position} Position to compare with
 133+ * @returns {Boolean} If this position is above the other
 134+ */
 135+es.Position.prototype.above = function( position ) {
 136+ return this.bottom < position.top;
 137+};
 138+
 139+/**
 140+ * Checks if this position is below another one.
 141+ *
 142+ * This method utilizes the bottom property.
 143+ *
 144+ * @method
 145+ * @param position {es.Position} Position to compare with
 146+ * @returns {Boolean} If this position is below the other
 147+ */
 148+es.Position.prototype.below = function( position ) {
 149+ return this.top > position.bottom;
 150+};
 151+
 152+/**
 153+ * Checks if this position is to the left of another one.
 154+ *
 155+ * @method
 156+ * @param position {es.Position} Position to compare with
 157+ * @returns {Boolean} If this position is the left the other
 158+ */
 159+es.Position.prototype.leftOf = function( left ) {
 160+ return this.left < left;
 161+};
 162+
 163+/**
 164+ * Checks if this position is to the right of another one.
 165+ *
 166+ * @method
 167+ * @param position {es.Position} Position to compare with
 168+ * @returns {Boolean} If this position is the right the other
 169+ */
 170+es.Position.prototype.rightOf = function( left ) {
 171+ return this.left > left;
 172+};
Index: trunk/parsers/wikidom/lib/synth/controllers/es.SurfaceController.js
@@ -1,4 +1,200 @@
2 -es.SurfaceController = function() {
 2+es.SurfaceController = function( surfaceView ) {
 3+ this.view = surfaceView;
 4+ this.mouse = {
 5+ 'selecting': false,
 6+ 'clicks': 0,
 7+ 'clickDelay': 500,
 8+ 'clickTimeout': null,
 9+ 'clickPosition': null,
 10+ 'hotSpotRadius': 1
 11+ };
 12+ this.keyboard = {
 13+ 'selecting': false,
 14+ 'cursorAnchor': null,
 15+ 'keydownTimeout': null,
 16+ 'keys': {
 17+ 'shift': false,
 18+ 'control': false,
 19+ 'command': false,
 20+ 'alt': false
 21+ }
 22+ };
323
 24+ // MouseDown on surface
 25+ this.view.$.bind( {
 26+ 'mousedown' : function(e) {
 27+ return surface.onMouseDown( e );
 28+ }
 29+ } );
 30+
 31+ // Hidden input
 32+ var controller = this,
 33+ $document = $(document);
 34+ this.$input = $( '<input class="editSurface-input" />' )
 35+ .prependTo( this.view.$ )
 36+ .bind( {
 37+ 'focus' : function() {
 38+ $(document).bind({
 39+ 'mousemove.editSurface' : function(e) {
 40+ return controller.onMouseMove( e );
 41+ },
 42+ 'mouseup.editSurface' : function(e) {
 43+ return controller.onMouseUp( e );
 44+ },
 45+ 'keydown.editSurface' : function( e ) {
 46+ return controller.onKeyDown( e );
 47+ },
 48+ 'keyup.editSurface' : function( e ) {
 49+ return controller.onKeyUp( e );
 50+ }
 51+ });
 52+ },
 53+ 'blur': function( e ) {
 54+ $document.unbind('.editSurface');
 55+ controller.hideCursor();
 56+ },
 57+ 'cut': function( e ) {
 58+ return controller.onCut( e );
 59+ },
 60+ 'copy': function( e ) {
 61+ return controller.onCopy( e );
 62+ },
 63+ 'paste': function( e ) {
 64+ return controller.onPaste( e );
 65+ }
 66+ } );
 67+
 68+ $(window).resize( function() {
 69+ controller.view.hideCursor();
 70+ controller.view.renderContent();
 71+ } );
472 };
573
 74+es.SurfaceController.prototype.onKeyDown = function( e ) {
 75+ switch ( e.keyCode ) {
 76+ case 16: // Shift
 77+ this.keyboard.keys.shift = true;
 78+ break;
 79+ case 17: // Control
 80+ this.keyboard.keys.control = true;
 81+ break;
 82+ case 18: // Alt
 83+ this.keyboard.keys.alt = true;
 84+ break;
 85+ case 91: // Command
 86+ this.keyboard.keys.command = true;
 87+ break;
 88+ case 36: // Home
 89+ break;
 90+ case 35: // End
 91+ break;
 92+ case 37: // Left arrow
 93+ break;
 94+ case 38: // Up arrow
 95+ break;
 96+ case 39: // Right arrow
 97+ break;
 98+ case 40: // Down arrow
 99+ break;
 100+ case 8: // Backspace
 101+ break;
 102+ case 46: // Delete
 103+ break;
 104+ default: // Insert content (maybe)
 105+ break;
 106+ }
 107+ return true;
 108+};
 109+
 110+es.SurfaceController.prototype.onKeyUp = function( e ) {
 111+ switch ( e.keyCode ) {
 112+ case 16: // Shift
 113+ this.keyboard.keys.shift = false;
 114+ if ( this.keyboard.selecting ) {
 115+ this.keyboard.selecting = false;
 116+ }
 117+ break;
 118+ case 17: // Control
 119+ this.keyboard.keys.control = false;
 120+ break;
 121+ case 18: // Alt
 122+ this.keyboard.keys.alt = false;
 123+ break;
 124+ case 91: // Command
 125+ this.keyboard.keys.command = false;
 126+ break;
 127+ default:
 128+ break;
 129+ }
 130+ return true;
 131+};
 132+
 133+es.SurfaceController.prototype.onMouseDown = function( e ) {
 134+ // TODO: Respond to mouse down event, moving cursor and possibly beginning selection painting
 135+ return false;
 136+};
 137+
 138+es.SurfaceController.prototype.onMouseMove = function( e ) {
 139+ // TODO: Respond to mouse move event, updating selection while painting
 140+};
 141+
 142+es.SurfaceController.prototype.onMouseUp = function( e ) {
 143+ // TODO: Respond to mouse up event, possibly ending selection painting
 144+};
 145+
 146+es.SurfaceController.prototype.onCut = function( e ) {
 147+ // TODO: Keep a Content object copy of the selection
 148+};
 149+
 150+es.SurfaceController.prototype.onCopy = function( e ) {
 151+ // TODO: Keep a Content object copy of the selection
 152+};
 153+
 154+es.SurfaceController.prototype.onPaste = function( e ) {
 155+ // TODO: Respond to paste event, using the object copy if possible
 156+};
 157+
 158+es.SurfaceController.prototype.handleBackspace = function() {
 159+ // TODO: Respond to backspace event
 160+};
 161+
 162+es.SurfaceController.prototype.handleDelete = function() {
 163+ // TODO: Respond to delete event
 164+};
 165+
 166+es.SurfaceController.prototype.getInputContent = function() {
 167+ // TODO: Get content from this.$input
 168+};
 169+
 170+es.SurfaceController.prototype.setInputContent = function( content ) {
 171+ // TODO: Set the value of this.$input
 172+};
 173+
 174+es.SurfaceController.prototype.getLocationFromEvent = function( e ) {
 175+ var $target = $( e.target ),
 176+ $block = $target.is( '.editSurface-block' )
 177+ ? $target : $target.closest( '.editSurface-block' );
 178+ // Not a block or child of a block? Find the nearest block...
 179+ if( !$block.length ) {
 180+ var $blocks = this.$.find( '> .editSurface-document .editSurface-block' );
 181+ $block = $blocks.first();
 182+ $blocks.each( function() {
 183+ // Stop looking when mouse is above top
 184+ if ( e.pageY <= $(this).offset().top ) {
 185+ return false;
 186+ }
 187+ $block = $(this);
 188+ } );
 189+ }
 190+ var block = $block.data( 'block' ),
 191+ blockPosition = $block.offset();
 192+ return new es.Location(
 193+ block,
 194+ block.getOffset(
 195+ new es.Position(
 196+ e.pageX - blockPosition.left,
 197+ e.pageY - blockPosition.top
 198+ )
 199+ )
 200+ );
 201+};
Index: trunk/parsers/wikidom/lib/synth/es.Location.js
@@ -0,0 +1,42 @@
 2+/**
 3+ * Creates an es.Location object.
 4+ *
 5+ * Locations describe an offset within an aggregate target, including a reference to the target.
 6+ *
 7+ * @class
 8+ * @constructor
 9+ * @param target {Object} Target offset is within
 10+ * @param offset {Integer} Offset within target
 11+ * @property target {Object} Target offset is within
 12+ * @property offset {Integer} Offset within target (optional, default: 0)
 13+ */
 14+es.Location = function( target, offset ) {
 15+ this.target = target;
 16+ this.offset = offset || 0;
 17+};
 18+
 19+/**
 20+ * Compares location with another.
 21+ *
 22+ * This method expects targets to support a getIndex method, which returns an integer representing
 23+ * the target's offset within a container.
 24+ *
 25+ * @method
 26+ * @param location {es.Location} Location to compare with
 27+ * @returns {Integer} -1 if this is before the argument, 0 if at the same place or 1 if after
 28+ */
 29+es.Location.prototype.compareWith = function( location ) {
 30+ var a = this,
 31+ b = location;
 32+ if ( a === b ) {
 33+ return 0;
 34+ }
 35+ var aIndex = this.block.getIndex(),
 36+ bIndex = location.block.getIndex();
 37+ if ( aIndex < bIndex || ( aIndex === bIndex && a.offset < b.offset ) ) {
 38+ return -1;
 39+ } else if ( aIndex > bIndex || ( aIndex === bIndex && a.offset > b.offset ) ) {
 40+ return 1;
 41+ }
 42+ return 0;
 43+};
Index: trunk/parsers/wikidom/lib/synth/views/es.SurfaceView.js
@@ -8,6 +8,16 @@
99 this.$.append( this.documentView.$ );
1010 this.width = null;
1111
 12+ // Selection
 13+ this.$ranges = $( '<div class="editSurface-ranges"></div>' ).prependTo( this.$ );
 14+ this.$rangeStart = $( '<div class="editSurface-range"></div>' ).appendTo( this.$ranges );
 15+ this.$rangeFill = $( '<div class="editSurface-range"></div>' ).appendTo( this.$ranges );
 16+ this.$rangeEnd = $( '<div class="editSurface-range"></div>' ).appendTo( this.$ranges );
 17+
 18+ // Cursor
 19+ this.blinkInterval = null;
 20+ this.$cursor = $( '<div class="editSurface-cursor"></div>' ).appendTo( this.$ );
 21+
1222 var surface = this;
1323 $(window).resize( function() {
1424 var width = surface.$.width();
@@ -20,3 +30,47 @@
2131 // First render
2232 this.documentView.renderContent();
2333 };
 34+
 35+/**
 36+ * Shows the cursor in a new position.
 37+ *
 38+ * @method
 39+ * @param position {Position} Position to show the cursor at
 40+ * @param offset {Position} Offset to be added to position
 41+ */
 42+es.SurfaceView.prototype.showCursor = function( position, offset ) {
 43+ if ( position ) {
 44+ if ( $.isPlainObject( offset ) ) {
 45+ position.left += offset.left;
 46+ position.top += offset.top;
 47+ position.bottom += offset.top;
 48+ }
 49+ this.$cursor.css( {
 50+ 'left': position.left,
 51+ 'top': position.top,
 52+ 'height': position.bottom - position.top
 53+ } ).show();
 54+ } else {
 55+ this.$cursor.show();
 56+ }
 57+
 58+ if ( this.blinkInterval ) {
 59+ clearInterval( this.blinkInterval );
 60+ }
 61+ var $cursor = this.$cursor;
 62+ this.blinkInterval = setInterval( function() {
 63+ $cursor.$.css( 'display' ) === 'block' ? $cursor.$.hide() : $cursor.$.show();
 64+ }, 500 );
 65+};
 66+
 67+/**
 68+ * Hides the cursor.
 69+ *
 70+ * @method
 71+ */
 72+es.SurfaceView.prototype.hideCursor = function() {
 73+ if( this.blinkInterval ) {
 74+ clearInterval( this.blinkInterval );
 75+ }
 76+ this.$cursor.hide();
 77+};
Index: trunk/parsers/wikidom/lib/synth/views/es.BlockView.js
@@ -41,4 +41,11 @@
4242 throw 'BlockView.getRenderedLineIndex not implemented in this subclass.';
4343 };
4444
 45+/**
 46+ * Gets rendered line index of offset within content.
 47+ */
 48+es.BlockView.getRenderedLineRange = function( offset ) {
 49+ throw 'BlockView.getRenderedLineRange not implemented in this subclass.';
 50+};
 51+
4552 es.extend( es.BlockView, es.ViewContainerItem );

Status & tagging log