From 2d720bd6d9825d00d0500755809e501716a5e92e Mon Sep 17 00:00:00 2001 From: Ed Sanders Date: Mon, 19 Aug 2013 16:22:29 +0100 Subject: [PATCH] Allow phantoms and focus areas to be overridden And actually use this functionality on MWBlockImage to highlight centred images correctly. FocusableNode * Actually use $focusable to render the highlight correctly ProtectedNode * Allow a $phantomable element to define which element to highlight on mouseenter * As phatoms are built off shields, make sure a shield is given to $phantomable RelocatableNode * Allow a $relocatable element to define which element the relocatable marker is measured against ui.Context * Use $focusable (when available) for positioning the popup Plus some documentation fixes Change-Id: I370337239af4fc935cd86757b3ce03011bae5ba8 --- modules/ve/ce/ve.ce.FocusableNode.js | 10 +++++----- modules/ve/ce/ve.ce.ProtectedNode.js | 14 +++++++++----- modules/ve/ce/ve.ce.RelocatableNode.js | 10 ++++++---- modules/ve/ui/ve.ui.Context.js | 2 +- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/modules/ve/ce/ve.ce.FocusableNode.js b/modules/ve/ce/ve.ce.FocusableNode.js index 1afc40d982..309e781e94 100644 --- a/modules/ve/ce/ve.ce.FocusableNode.js +++ b/modules/ve/ce/ve.ce.FocusableNode.js @@ -6,7 +6,7 @@ */ /** - * ContentEditable resizable node. + * ContentEditable focusable node. * * Focusable elements have a special treatment by ve.ce.Surface. When the user selects only a single * node, if it is focusable, the surface will set the focusable node's focused state. Other systems, @@ -22,7 +22,7 @@ * @abstract * * @constructor - * @param {jQuery} [$focusable] Primary element user is focusing on + * @param {jQuery} [$focusable=this.$] Primary element user is focusing on */ ve.ce.FocusableNode = function VeCeFocusableNode( $focusable ) { // Properties @@ -135,11 +135,11 @@ ve.ce.FocusableNode.prototype.setFocused = function ( value ) { this.focused = value; if ( this.focused ) { this.emit( 'focus' ); - this.$.addClass( 've-ce-node-focused' ); + this.$focusable.addClass( 've-ce-node-focused' ); this.createHighlight(); } else { this.emit( 'blur' ); - this.$.removeClass( 've-ce-node-focused' ); + this.$focusable.removeClass( 've-ce-node-focused' ); this.clearHighlight(); } } @@ -151,7 +151,7 @@ ve.ce.FocusableNode.prototype.setFocused = function ( value ) { * @method */ ve.ce.FocusableNode.prototype.createHighlight = function () { - this.$.find( '*' ).add( this.$ ).each( + this.$focusable.find( '*' ).add( this.$focusable ).each( ve.bind( function( i, element ) { var offset, $element = $( element ); if ( !$element.is( ':visible' ) ) { diff --git a/modules/ve/ce/ve.ce.ProtectedNode.js b/modules/ve/ce/ve.ce.ProtectedNode.js index 5fec0eda09..76826336d8 100644 --- a/modules/ve/ce/ve.ce.ProtectedNode.js +++ b/modules/ve/ce/ve.ce.ProtectedNode.js @@ -6,17 +6,19 @@ */ /** - * ContentEditable relocatable node. + * ContentEditable protected node. * * @class * @abstract * * @constructor + * @param {jQuery} [$phantomable=this.$] Element to show a phantom for */ -ve.ce.ProtectedNode = function VeCeProtectedNode() { +ve.ce.ProtectedNode = function VeCeProtectedNode( $phantomable ) { // Properties this.$phantoms = $( [] ); this.$shields = $( [] ); + this.$phantomable = $phantomable || this.$; this.isSetup = false; // Events @@ -89,7 +91,9 @@ ve.ce.ProtectedNode.prototype.onProtectedSetup = function () { if ( this.nodeType === Node.ELEMENT_NODE ) { if ( ( $this.css( 'float' ) === 'none' || $this.css( 'float' ) === '' ) && - !$this.hasClass( 've-ce-protectedNode' ) + !$this.hasClass( 've-ce-protectedNode' ) && + // Phantoms are built off shields, so make sure $phantomable has a shield + !$this.is( node.$phantomable ) ) { return; } @@ -210,7 +214,7 @@ ve.ce.ProtectedNode.prototype.createPhantoms = function () { var $phantomTemplate = this.constructor.static.$phantomTemplate, surface = this.root.getSurface(); - this.$.find( '.ve-ce-protectedNode-shield' ).each( + this.$phantomable.find( '.ve-ce-protectedNode-shield' ).each( ve.bind( function () { this.$phantoms = this.$phantoms.add( $phantomTemplate.clone().on( 'mousedown', ve.bind( this.onPhantomMouseDown, this ) ) @@ -232,7 +236,7 @@ ve.ce.ProtectedNode.prototype.createPhantoms = function () { * @method */ ve.ce.ProtectedNode.prototype.positionPhantoms = function () { - this.$.find( '.ve-ce-protectedNode-shield' ).each( + this.$phantomable.find( '.ve-ce-protectedNode-shield' ).each( ve.bind( function ( i, element ) { var $shield = $( element ), offset = ve.Element.getRelativePosition( diff --git a/modules/ve/ce/ve.ce.RelocatableNode.js b/modules/ve/ce/ve.ce.RelocatableNode.js index 262518924e..5fa23d34c4 100644 --- a/modules/ve/ce/ve.ce.RelocatableNode.js +++ b/modules/ve/ce/ve.ce.RelocatableNode.js @@ -14,10 +14,12 @@ * @abstract * * @constructor + * @param {jQuery} [$relocatable=this.$] Element which can be relocated */ -ve.ce.RelocatableNode = function VeCeRelocatableNode() { +ve.ce.RelocatableNode = function VeCeRelocatableNode( $relocatable ) { // Properties this.relocatingSurface = null; + this.$relocatable = $relocatable || this.$; this.$relocatableMarker = this.$$( '' ); // Events @@ -125,12 +127,12 @@ ve.ce.RelocatableNode.prototype.onRelocatableDragEnd = function () { */ ve.ce.RelocatableNode.prototype.setRelocatableMarkerSizeAndPosition = function () { var offset = ve.Element.getRelativePosition( - this.$, this.getRoot().getSurface().getSurface().$ + this.$relocatable, this.getRoot().getSurface().getSurface().$ ); this.$relocatableMarker.css( { - 'height': this.$.height(), - 'width': this.$.width(), + 'height': this.$relocatable.height(), + 'width': this.$relocatable.width(), 'top': offset.top, 'left': offset.left } ); diff --git a/modules/ve/ui/ve.ui.Context.js b/modules/ve/ui/ve.ui.Context.js index 077a52ff41..4682ff2c5d 100644 --- a/modules/ve/ui/ve.ui.Context.js +++ b/modules/ve/ui/ve.ui.Context.js @@ -255,7 +255,7 @@ ve.ui.Context.prototype.updateDimensions = function ( transition ) { $container = inspector ? this.inspectors.$ : this.$menu; if ( focusedNode ) { // We're on top of a node - $node = focusedNode.$; + $node = focusedNode.$focusable || focusedNode.$; nodePosition = $node.position(); if ( this.embedded ) { // Get the position relative to the surface it is embedded in