Index: trunk/extensions/VisualEditor/modules/ve/ce/ve.ce.Surface.js |
— | — | @@ -28,12 +28,24 @@ |
29 | 29 | this.clipboard = {}; |
30 | 30 | this.autoRender = false; |
31 | 31 | |
32 | | - // Content Observer |
| 32 | + // Surface Observer |
33 | 33 | this.surfaceObserver = new ve.ce.SurfaceObserver( this.documentView ); |
34 | | - this.surfaceObserver.on( 'cursor', function( info ) { |
35 | | - //console.log("cursor", info); |
36 | | - } ) |
| 34 | + this.surfaceObserver.on( 'select', function( selection ) { |
| 35 | + |
| 36 | + if ( selection !== null ) { |
| 37 | + // Keep a copy of the current selection on hand |
| 38 | + _this.currentSelection = selection.clone(); |
| 39 | + // Respond to selection changes |
| 40 | + _this.updateSelection(); |
37 | 41 | |
| 42 | + if ( selection.getLength() ) { |
| 43 | + _this.clearInsertionAnnotations(); |
| 44 | + } else { |
| 45 | + _this.loadInsertionAnnotations(); |
| 46 | + } |
| 47 | + } |
| 48 | + } ); |
| 49 | + |
38 | 50 | // Events |
39 | 51 | this.documentView.$.bind( { |
40 | 52 | 'focus': function( e ) { |
— | — | @@ -100,18 +112,6 @@ |
101 | 113 | document.execCommand("enableObjectResizing", false, false); |
102 | 114 | } catch(e) { |
103 | 115 | } |
104 | | - |
105 | | - this.model.on( 'select', function( selection ) { |
106 | | - // Keep a copy of the current selection on hand |
107 | | - _this.currentSelection = selection.clone(); |
108 | | - // Respond to selection changes |
109 | | - _this.updateSelection(); |
110 | | - if ( selection.getLength() ) { |
111 | | - _this.clearInsertionAnnotations(); |
112 | | - } else { |
113 | | - _this.loadInsertionAnnotations(); |
114 | | - } |
115 | | - } ); |
116 | 116 | }; |
117 | 117 | |
118 | 118 | /* Methods */ |
— | — | @@ -278,11 +278,11 @@ |
279 | 279 | ve.ce.Surface.prototype.updateSelection = function( delay ) { |
280 | 280 | var _this = this; |
281 | 281 | function update() { |
282 | | - if ( _this.currentSelection.getLength() ) { |
| 282 | + if ( _this.surfaceObserver.range.getLength() ) { |
283 | 283 | _this.clearInsertionAnnotations(); |
284 | 284 | } |
285 | 285 | if ( _this.contextView ) { |
286 | | - if ( _this.currentSelection.getLength() ) { |
| 286 | + if ( _this.surfaceObserver.range.getLength() ) { |
287 | 287 | _this.contextView.set(); |
288 | 288 | } else { |
289 | 289 | _this.contextView.clear(); |
— | — | @@ -577,8 +577,11 @@ |
578 | 578 | }; |
579 | 579 | |
580 | 580 | ve.ce.Surface.prototype.getSelectionRect = function() { |
581 | | - var sel = rangy.getSelection(); |
582 | | - return sel.getBoundingClientRect(); |
| 581 | + var rangySel = rangy.getSelection(); |
| 582 | + return { |
| 583 | + start: rangySel.getStartClientPos(), |
| 584 | + end: rangySel.getEndClientPos() |
| 585 | + }; |
583 | 586 | }; |
584 | 587 | |
585 | 588 | ve.ce.Surface.prototype.getDOMNodeAndOffset = function( offset ) { |
— | — | @@ -643,8 +646,6 @@ |
644 | 647 | range.setStart( start.node, start.offset ); |
645 | 648 | range.setEnd( stop.node, stop.offset ); |
646 | 649 | sel.setSingleRange( range ); |
647 | | - // Trigger select event |
648 | | - this.model.select( this.getSelectionRange() ); |
649 | 650 | }; |
650 | 651 | |
651 | 652 | ve.ce.Surface.prototype.getLeafNode = function( elem ) { |
Index: trunk/extensions/VisualEditor/modules/ve/ui/ve.ui.Toolbar.js |
— | — | @@ -16,12 +16,36 @@ |
17 | 17 | this.$groups = $( '<div class="es-toolbarGroups"></div>' ).prependTo( this.$ ); |
18 | 18 | this.tools = []; |
19 | 19 | |
20 | | - this.surfaceView.on( 'cursor', function( annotations, nodes ) { |
21 | | - for( var i = 0; i < _this.tools.length; i++ ) { |
22 | | - _this.tools[i].updateState( annotations, nodes ); |
| 20 | + this.surfaceView.surfaceObserver.on( 'select', function ( selection ) { |
| 21 | + var annotations = _this.surfaceView.getAnnotations(), |
| 22 | + nodes = [], |
| 23 | + model = _this.surfaceView.documentView.model; |
| 24 | + |
| 25 | + if ( selection.from === selection.to ) { |
| 26 | + nodes.push( model.getNodeFromOffset( selection.from ) ); |
| 27 | + } else { |
| 28 | + var startNode = model.getNodeFromOffset( selection.start ), |
| 29 | + endNode = model.getNodeFromOffset( selection.end ); |
| 30 | + if ( startNode === endNode ) { |
| 31 | + nodes.push( startNode ); |
| 32 | + } else { |
| 33 | + model.traverseLeafNodes( function( node ) { |
| 34 | + nodes.push( node ); |
| 35 | + if( node === endNode ) { |
| 36 | + return false; |
| 37 | + } |
| 38 | + }, startNode ); |
| 39 | + } |
23 | 40 | } |
24 | | - } ); |
25 | 41 | |
| 42 | + if ( selection !== null ) { |
| 43 | + for( var i = 0; i < _this.tools.length; i++ ) { |
| 44 | + _this.tools[i].updateState( annotations, nodes ); |
| 45 | + } |
| 46 | + } |
| 47 | + |
| 48 | + }); |
| 49 | + |
26 | 50 | this.config = config || [ |
27 | 51 | { 'name': 'history', 'items' : ['undo', 'redo'] }, |
28 | 52 | { 'name': 'textStyle', 'items' : ['format'] }, |
Index: trunk/extensions/VisualEditor/modules/ve/ui/ve.ui.Context.js |
— | — | @@ -92,16 +92,16 @@ |
93 | 93 | |
94 | 94 | ve.ui.Context.prototype.positionIcon = function() { |
95 | 95 | this.$.removeClass( 'es-contextView-position-start es-contextView-position-end' ); |
96 | | - var selection = this.surfaceView.getModel().getSelection(), |
| 96 | + var selection = this.surfaceView.currentSelection, |
97 | 97 | selectionRect = this.surfaceView.getSelectionRect(); |
98 | 98 | this.position = null; |
99 | 99 | |
100 | 100 | if ( selection.from < selection.to ) { |
101 | | - this.position = new ve.Position( selectionRect.right, selectionRect.bottom ); |
| 101 | + this.position = new ve.Position( selectionRect.end.x, selectionRect.end.y ); |
102 | 102 | this.$.addClass( 'es-contextView-position-end' ); |
103 | 103 | |
104 | 104 | } else if ( selection.from > selection.to ) { |
105 | | - this.position = new ve.Position( selectionRect.left, selectionRect.top ); |
| 105 | + this.position = new ve.Position( selectionRect.start.x, selectionRect.start.y ); |
106 | 106 | this.$.addClass( 'es-contextView-position-start' ); |
107 | 107 | } |
108 | 108 | |