Index: trunk/extensions/VisualEditor/modules/es/es.Range.js |
— | — | @@ -16,7 +16,6 @@ |
17 | 17 | this.normalize(); |
18 | 18 | }; |
19 | 19 | |
20 | | - |
21 | 20 | /** |
22 | 21 | * Creates a new es.Range object that's a translated version of another. |
23 | 22 | * |
— | — | @@ -32,6 +31,16 @@ |
33 | 32 | /* Methods */ |
34 | 33 | |
35 | 34 | /** |
| 35 | + * Gets a clone of this object. |
| 36 | + * |
| 37 | + * @method |
| 38 | + * @returns {es.Range} Clone of range |
| 39 | + */ |
| 40 | +es.Range.prototype.clone = function() { |
| 41 | + return new es.Range( this.from, this.to ); |
| 42 | +}; |
| 43 | + |
| 44 | +/** |
36 | 45 | * Checks if an offset is within this range. |
37 | 46 | * |
38 | 47 | * @method |
Index: trunk/extensions/VisualEditor/modules/es/views/es.SurfaceView.js |
— | — | @@ -7,10 +7,34 @@ |
8 | 8 | * @param {es.SurfaceModel} model Surface model to view |
9 | 9 | */ |
10 | 10 | es.SurfaceView = function( $container, model ) { |
| 11 | + var _this = this; |
| 12 | + |
| 13 | + es.EventEmitter.call( this ); |
| 14 | + |
11 | 15 | this.$ = $container.addClass( 'es-surfaceView' ); |
12 | 16 | this.$window = $( window ); |
13 | 17 | this.model = model; |
14 | | - |
| 18 | + this.selection = new es.Range(); |
| 19 | + this.previousSelection = null; |
| 20 | + |
| 21 | + this.model.getDocument().on( 'update', function() { |
| 22 | + _this.emit( 'update' ); |
| 23 | + } ); |
| 24 | + this.emitSelect = function() { |
| 25 | + if ( _this.previousSelection ) { |
| 26 | + if ( |
| 27 | + _this.previousSelection.from !== _this.selection.from || |
| 28 | + _this.previousSelection.to !== _this.selection.to |
| 29 | + ) { |
| 30 | + _this.emit( 'select', _this.selection.clone() ); |
| 31 | + _this.previousSelection = _this.selection.clone(); |
| 32 | + } |
| 33 | + // Mouse movement that doesn't change selection points will terminate here |
| 34 | + } else { |
| 35 | + _this.previousSelection = _this.selection.clone(); |
| 36 | + } |
| 37 | + }; |
| 38 | + |
15 | 39 | // Initialize document view |
16 | 40 | this.documentView = new es.DocumentView( this.model.getDocument(), this ); |
17 | 41 | this.$.append( this.documentView.$ ); |
— | — | @@ -37,7 +61,6 @@ |
38 | 62 | alt: false |
39 | 63 | } |
40 | 64 | }; |
41 | | - this.selection = new es.Range(); |
42 | 65 | |
43 | 66 | // References for use in closures |
44 | 67 | var surfaceView = this, |
— | — | @@ -113,7 +136,7 @@ |
114 | 137 | this.mouse.selectingMode = 1; |
115 | 138 | |
116 | 139 | this.selection.to = this.documentView.getOffsetFromEvent( e ); |
117 | | - console.log(this.selection.to); |
| 140 | + //console.log(this.selection.to); |
118 | 141 | if ( this.keyboard.keys.shift ) { |
119 | 142 | this.documentView.drawSelection( this.selection ); |
120 | 143 | this.hideCursor(); |
— | — | @@ -154,15 +177,17 @@ |
155 | 178 | this.$input.focus().select(); |
156 | 179 | } |
157 | 180 | this.cursor.initialLeft = null; |
| 181 | + this.emitSelect(); |
158 | 182 | return false; |
159 | 183 | }; |
160 | 184 | |
161 | 185 | es.SurfaceView.prototype.onMouseMove = function( e ) { |
| 186 | + var wordBoundaries; |
162 | 187 | if ( e.button === 0 /* left mouse button */ && this.mouse.selectingMode ) { |
163 | 188 | if ( this.mouse.selectingMode === 1 ) { |
164 | 189 | this.selection.to = this.documentView.getOffsetFromEvent( e ); |
165 | 190 | } else if ( this.mouse.selectingMode === 2 ) { |
166 | | - var wordBoundaries = this.documentView.model.getWordBoundaries( |
| 191 | + wordBoundaries = this.documentView.model.getWordBoundaries( |
167 | 192 | this.documentView.getOffsetFromEvent( e ) |
168 | 193 | ); |
169 | 194 | if ( wordBoundaries.to <= this.mouse.selectedRange.from ) { |
— | — | @@ -193,7 +218,6 @@ |
194 | 219 | this.hideCursor(); |
195 | 220 | } |
196 | 221 | } |
197 | | - return; |
198 | 222 | |
199 | 223 | if ( e.button === 0 /* left mouse button */ && this.mouse.selected ) { |
200 | 224 | |
— | — | @@ -201,7 +225,7 @@ |
202 | 226 | if ( this.mouse.selected.containsOffset( offset ) ) { |
203 | 227 | //return; |
204 | 228 | } |
205 | | - var wordBoundaries = this.documentView.model.getWordBoundaries( offset ); |
| 229 | + wordBoundaries = this.documentView.model.getWordBoundaries( offset ); |
206 | 230 | if ( wordBoundaries.to <= this.mouse.selected.from ) { |
207 | 231 | this.selection.to = wordBoundaries.from; |
208 | 232 | this.selection.from = this.mouse.selected.to; |
— | — | @@ -226,8 +250,8 @@ |
227 | 251 | |
228 | 252 | } else if ( e.button === 0 /* left mouse button */ && this.mouse.selecting ) { |
229 | 253 | this.selection.to = this.documentView.getOffsetFromEvent( e ); |
230 | | - |
231 | 254 | } |
| 255 | + this.emitSelect(); |
232 | 256 | }; |
233 | 257 | |
234 | 258 | es.SurfaceView.prototype.onMouseUp = function( e ) { |
— | — | @@ -237,6 +261,7 @@ |
238 | 262 | }; |
239 | 263 | |
240 | 264 | es.SurfaceView.prototype.onKeyDown = function( e ) { |
| 265 | + var tx; |
241 | 266 | switch ( e.keyCode ) { |
242 | 267 | case 16: // Shift |
243 | 268 | this.keyboard.keys.shift = true; |
— | — | @@ -280,14 +305,18 @@ |
281 | 306 | this.moveCursor( 'down' ); |
282 | 307 | break; |
283 | 308 | case 8: // Backspace |
284 | | - var transaction = this.documentView.model.prepareRemoval( new es.Range( this.selection.to, this.selection.to - 1 ) ); |
285 | | - this.documentView.model.commit ( transaction ); |
| 309 | + tx = this.documentView.model.prepareRemoval( |
| 310 | + new es.Range( this.selection.to, this.selection.to - 1 ) |
| 311 | + ); |
| 312 | + this.documentView.model.commit( tx ); |
286 | 313 | this.selection.from = this.selection.to -= 1; |
287 | 314 | this.showCursor(); |
288 | 315 | break; |
289 | 316 | case 46: // Delete |
290 | | - var transaction = this.documentView.model.prepareRemoval( new es.Range( this.selection.to, this.selection.to + 1 ) ); |
291 | | - this.documentView.model.commit ( transaction ); |
| 317 | + tx = this.documentView.model.prepareRemoval( |
| 318 | + new es.Range( this.selection.to, this.selection.to + 1 ) |
| 319 | + ); |
| 320 | + this.documentView.model.commit( tx ); |
292 | 321 | break; |
293 | 322 | default: // Insert content (maybe) |
294 | 323 | if ( this.keyboard.keydownTimeout ) { |
— | — | @@ -445,6 +474,7 @@ |
446 | 475 | this.selection.from = this.selection.to = newTo; |
447 | 476 | this.showCursor(); |
448 | 477 | } |
| 478 | + this.emitSelect(); |
449 | 479 | }; |
450 | 480 | |
451 | 481 | /** |
— | — | @@ -489,3 +519,7 @@ |
490 | 520 | } |
491 | 521 | this.cursor.$.hide(); |
492 | 522 | }; |
| 523 | + |
| 524 | +/* Inheritance */ |
| 525 | + |
| 526 | +es.extendClass( es.SurfaceView, es.EventEmitter ); |
\ No newline at end of file |
Index: trunk/extensions/VisualEditor/demo/es.js |
— | — | @@ -294,4 +294,24 @@ |
295 | 295 | window.doc = es.DocumentModel.newFromPlainObject( window.wikiDom ); |
296 | 296 | window.surfaceModel = new es.SurfaceModel( window.doc ); |
297 | 297 | window.surfaceView = new es.SurfaceView( $( '#es-editor' ), window.surfaceModel ); |
| 298 | + |
| 299 | + var tools = { |
| 300 | + 'textStyle/bold': $( '#es-toolbar-bold' ), |
| 301 | + 'textStyle/italic': $( '#es-toolbar-italic' ) |
| 302 | + }; |
| 303 | + surfaceView.on( 'select', function( range ) { |
| 304 | + for ( var key in tools ) { |
| 305 | + tools[key].removeClass( 'es-toolbarTool-down' ); |
| 306 | + } |
| 307 | + if ( range.start == range.end ) { |
| 308 | + var annotations = doc.getAnnotationsFromOffset( range.start ); |
| 309 | + if ( annotations.length ) { |
| 310 | + for ( var i = 0; i < annotations.length; i++ ) { |
| 311 | + if ( annotations[i].type in tools ) { |
| 312 | + tools[annotations[i].type].addClass( 'es-toolbarTool-down' ); |
| 313 | + } |
| 314 | + } |
| 315 | + } |
| 316 | + } |
| 317 | + } ); |
298 | 318 | } ); |