Index: trunk/extensions/VisualEditor/VisualEditor.php |
— | — | @@ -87,6 +87,7 @@ |
88 | 88 | 'es/serializers/es.HtmlSerializer.js', |
89 | 89 | 'es/serializers/es.JsonSerializer.js', |
90 | 90 | 'es/serializers/es.WikitextSerializer.js', |
| 91 | + 'es/views/es.ContextView.js', |
91 | 92 | 'es/views/es.ContentView.js', |
92 | 93 | 'es/views/es.DocumentView.js', |
93 | 94 | 'es/views/es.HeadingView.js', |
Index: trunk/extensions/VisualEditor/demo/index.html |
— | — | @@ -119,6 +119,7 @@ |
120 | 120 | <script src="../modules/es/views/es.SurfaceView.js"></script> |
121 | 121 | <script src="../modules/es/views/es.ToolbarView.js"></script> |
122 | 122 | <script src="../modules/es/views/es.ContentView.js"></script> |
| 123 | + <script src="../modules/es/views/es.ContextView.js"></script> |
123 | 124 | <script src="../modules/es/views/es.DocumentView.js"></script> |
124 | 125 | <script src="../modules/es/views/es.ParagraphView.js"></script> |
125 | 126 | <script src="../modules/es/views/es.PreView.js"></script> |
Index: trunk/extensions/VisualEditor/modules/es/es.Surface.css |
— | — | @@ -35,6 +35,46 @@ |
36 | 36 | -webkit-user-select: none; |
37 | 37 | } |
38 | 38 | |
| 39 | +.es-contextView { |
| 40 | + position: absolute; |
| 41 | + z-index: 2; |
| 42 | +} |
| 43 | + |
| 44 | +.es-contextView-icon { |
| 45 | + position: absolute; |
| 46 | + background-position: top left; |
| 47 | + background-repeat: no-repeat; |
| 48 | + width: 31px; |
| 49 | + height: 31px; |
| 50 | + display: none; |
| 51 | + cursor: pointer; |
| 52 | +} |
| 53 | + |
| 54 | +.es-contextView-position-above .es-contextView-icon { |
| 55 | + background-image: url(images/context-icon-up.png); |
| 56 | + top: -24px; |
| 57 | + left: -15px; |
| 58 | +} |
| 59 | + |
| 60 | +.es-contextView-position-below .es-contextView-icon { |
| 61 | + background-image: url(images/context-icon-down.png); |
| 62 | + top: -7px; |
| 63 | + left: -16px; |
| 64 | +} |
| 65 | + |
| 66 | +.es-contextView-position-above .es-contextView-icon:hover { |
| 67 | + background-image: url(images/context-icon-up-hover.png); |
| 68 | +} |
| 69 | + |
| 70 | +.es-contextView-position-below .es-contextView-icon:hover { |
| 71 | + background-image: url(images/context-icon-down-hover.png); |
| 72 | +} |
| 73 | + |
| 74 | +.es-contextView-menu { |
| 75 | + position: absolute; |
| 76 | + top: 8px; |
| 77 | +} |
| 78 | + |
39 | 79 | .es-contentView { |
40 | 80 | position: relative; |
41 | 81 | z-index: 1; |
— | — | @@ -221,7 +261,7 @@ |
222 | 262 | .es-contentView-range { |
223 | 263 | display: none; |
224 | 264 | position: absolute; |
225 | | - background-color: #bbffcc; |
| 265 | + background-color: #b3d6f6; |
226 | 266 | cursor: text; |
227 | 267 | z-index: -1; |
228 | 268 | } |
Index: trunk/extensions/VisualEditor/modules/es/images/context-icon-up.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/extensions/VisualEditor/modules/es/images/context-icon-up.png |
___________________________________________________________________ |
Added: svn:mime-type |
229 | 269 | + application/octet-stream |
Index: trunk/extensions/VisualEditor/modules/es/images/context-icon.psd |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/extensions/VisualEditor/modules/es/images/context-icon.psd |
___________________________________________________________________ |
Added: svn:mime-type |
230 | 270 | + application/octet-stream |
Index: trunk/extensions/VisualEditor/modules/es/images/context-icon-up-hover.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/extensions/VisualEditor/modules/es/images/context-icon-up-hover.png |
___________________________________________________________________ |
Added: svn:mime-type |
231 | 271 | + application/octet-stream |
Index: trunk/extensions/VisualEditor/modules/es/images/context-icon-down.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/extensions/VisualEditor/modules/es/images/context-icon-down.png |
___________________________________________________________________ |
Added: svn:mime-type |
232 | 272 | + application/octet-stream |
Index: trunk/extensions/VisualEditor/modules/es/images/context-icon-down-hover.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/extensions/VisualEditor/modules/es/images/context-icon-down-hover.png |
___________________________________________________________________ |
Added: svn:mime-type |
233 | 273 | + application/octet-stream |
Index: trunk/extensions/VisualEditor/modules/es/views/es.ContextView.js |
— | — | @@ -0,0 +1,48 @@ |
| 2 | +/** |
| 3 | + * Creates an es.ContextView object. |
| 4 | + * |
| 5 | + * @class |
| 6 | + * @constructor |
| 7 | + * @param {jQuery} $overlay DOM selection to add nodes to |
| 8 | + */ |
| 9 | +es.ContextView = function( surfaceView, $overlay ) { |
| 10 | + this.surfaceView = surfaceView; |
| 11 | + this.$ = $( '<div class="es-contextView"></div>' ).appendTo( $overlay || $( 'body' ) ); |
| 12 | + this.$menu = $( '<div class="es-contextView-menu"></div>' ).appendTo( this.$ ); |
| 13 | + this.$icon = $( '<div class="es-contextView-icon"></div>' ).appendTo( this.$ ); |
| 14 | +}; |
| 15 | + |
| 16 | +/* Methods */ |
| 17 | + |
| 18 | +es.ContextView.prototype.set = function() { |
| 19 | + this.$.removeClass( 'es-contextView-position-below es-contextView-position-above' ); |
| 20 | + var selection = this.surfaceView.getModel().getSelection(), |
| 21 | + position, |
| 22 | + offset, |
| 23 | + bias; |
| 24 | + if ( selection.from < selection.to ) { |
| 25 | + var $lastRange = this.surfaceView.$.find( '.es-contentView-range:visible:last' ); |
| 26 | + if ( $lastRange.length ) { |
| 27 | + offset = $lastRange.offset(); |
| 28 | + position = new es.Position( |
| 29 | + offset.left + $lastRange.width(), offset.top + $lastRange.height() |
| 30 | + ); |
| 31 | + this.$.addClass( 'es-contextView-position-below' ); |
| 32 | + } |
| 33 | + } else if ( selection.from > selection.to ) { |
| 34 | + var $firstRange = this.surfaceView.$.find( '.es-contentView-range:visible:first' ); |
| 35 | + if ( $firstRange.length ) { |
| 36 | + offset = $firstRange.offset(); |
| 37 | + position = new es.Position( offset.left, offset.top ); |
| 38 | + this.$.addClass( 'es-contextView-position-above' ); |
| 39 | + } |
| 40 | + } |
| 41 | + if ( position ) { |
| 42 | + this.$.css( { 'left': position.left, 'top': position.top } ); |
| 43 | + this.$icon.fadeIn( 'fast' ); |
| 44 | + } |
| 45 | +}; |
| 46 | + |
| 47 | +es.ContextView.prototype.clear = function() { |
| 48 | + this.$icon.hide(); |
| 49 | +}; |
Index: trunk/extensions/VisualEditor/modules/es/views/es.SurfaceView.js |
— | — | @@ -19,6 +19,7 @@ |
20 | 20 | this.model = model; |
21 | 21 | this.currentSelection = new es.Range(); |
22 | 22 | this.documentView = new es.DocumentView( this.model.getDocument(), this ); |
| 23 | + this.contextView = new es.ContextView( this ); |
23 | 24 | this.$ = $container |
24 | 25 | .addClass( 'es-surfaceView' ) |
25 | 26 | .append( this.documentView.$ ); |
— | — | @@ -132,6 +133,10 @@ |
133 | 134 | |
134 | 135 | /* Methods */ |
135 | 136 | |
| 137 | +es.SurfaceView.prototype.getModel = function() { |
| 138 | + return this.model; |
| 139 | +}; |
| 140 | + |
136 | 141 | es.SurfaceView.prototype.updateSelection = function( delay ) { |
137 | 142 | if ( delay ) { |
138 | 143 | if ( this.updateSelectionTimeout !== undefined ) { |
— | — | @@ -224,6 +229,8 @@ |
225 | 230 | this.cursor.initialLeft = null; |
226 | 231 | // Apply new selection |
227 | 232 | this.model.select( selection ); |
| 233 | + // Hide the context |
| 234 | + this.contextView.clear(); |
228 | 235 | } |
229 | 236 | // If the inut isn't already focused, focus it and select it's contents |
230 | 237 | if ( !this.$input.is( ':focus' ) ) { |
— | — | @@ -284,6 +291,8 @@ |
285 | 292 | if ( e.button === 0 ) { // left mouse button |
286 | 293 | this.mouse.selectingMode = this.mouse.selectedRange = null; |
287 | 294 | this.model.select( this.currentSelection ); |
| 295 | + // Show the context |
| 296 | + this.contextView.set(); |
288 | 297 | } |
289 | 298 | }; |
290 | 299 | |