Link inspector menu not appearing in the right place

ve.ui.Widget.css
* Adjust menu up a few pixels to match other uses of ve.ui.MenuWidget (the format drop down)

ve.ui.LinkInspector.js
* Moved the form value initialization to a timeout that fires well after the animation of the inspector - this is only important because the first element has a menu that pops up and the menu was rendering in the wrong location

ve.ui.Frame.js
* Added reference to frame within this.$$ by passing it to get$$

ve.ui.Inspector.js
* Removed auto-focus on open from inspector base class - this will be done in a more specific and controlled way instead

ve.ui.js
* Added optional frame argument to get$$ so that it's easy to get the frame from any $$ that's bound to an iframe document

ve.ui.Window.js
* Removed duplicate static member assignments
* Added auto-focus on the window's frame before calling onOpen
* Added auto-blur of anything focused within the iframe after calling onClose

ve.ui.MWLinkTargetInputWidget.js
* Auto-highlight the selected item when populating a menu so that pressing enter always keeps the currently selected item selected

ve.ui.TextInputMenuWidget.js
* Take the frame's position into account when positioning a menu below an input

Change-Id: I334f7db29af6b821bcfc8dc3c0ccba2636d4d9b1
This commit is contained in:
Trevor Parscal 2013-03-14 16:56:04 -07:00
parent 949722c392
commit ec912dc2d1
8 changed files with 49 additions and 54 deletions

View file

@ -111,14 +111,13 @@ ve.ui.LinkInspector.prototype.onOpen = function () {
// Call parent method
ve.ui.Inspector.prototype.onOpen.call( this );
// Setup annotation
this.initialAnnotationHash = annotation && annotation.getHash();
this.targetInput.setAnnotation( annotation );
// Set focus on the location input
// Wait for animation to complete
setTimeout( ve.bind( function () {
this.targetInput.$.focus().select();
}, this ) );
// Setup annotation
this.initialAnnotationHash = annotation && annotation.getHash();
this.targetInput.setAnnotation( annotation );
this.targetInput.$input.focus().select();
}, this ), 200 );
};
/**

View file

@ -257,6 +257,7 @@
.ve-ui-mwLinkTargetInputWidget-menu.ve-ui-menuWidget {
width: 20em;
margin-top: -7px;
}
.ve-ui-mwLinkTargetInputWidget-menu .ve-ui-menuWidget-item {

View file

@ -61,9 +61,8 @@ ve.ui.Frame.prototype.onLoad = function () {
doc.close();
// Properties
this.$$ = ve.ui.get$$( doc );
this.$$ = ve.ui.get$$( doc, this );
this.$content = this.$$( '.ve-ui-frame-content' );
// Add stylesheets
$head = this.$$( 'head' );
function embedCss( css ) {

View file

@ -130,7 +130,6 @@ ve.ui.Inspector.prototype.onFormKeyDown = function ( e ) {
*/
ve.ui.Inspector.prototype.onOpen = function () {
this.initialSelection = this.surface.getModel().getSelection();
this.$form.find( ':input:visible:first' ).focus();
};
/**

View file

@ -48,6 +48,21 @@ ve.ui.Window = function VeUiWindow( surface ) {
ve.inheritClass( ve.ui.Window, ve.EventEmitter );
/* Events */
/**
* @event setup
*/
/**
* @event open
*/
/**
* @event close
* @param {Boolean} accept Changes have been accepted
*/
/* Static Properties */
/**
@ -91,41 +106,6 @@ ve.ui.Window.static.icon = 'window';
*/
ve.ui.Window.static.titleMessage = null;
/* Events */
/**
* @event setup
*/
/**
* @event open
*/
/**
* @event close
* @param {Boolean} accept Changes have been accepted
*/
/* Static Properties */
/**
* Symbolic name of icon.
*
* @static
* @property
* @type {string}
*/
ve.ui.Window.static.icon = 'window';
/**
* Localized message for title.
*
* @static
* @property
* @type {string}
*/
ve.ui.Window.static.titleMessage = null;
/* Methods */
/**
@ -260,6 +240,7 @@ ve.ui.Window.prototype.open = function () {
this.$.show();
this.visible = true;
this.frame.run( ve.bind( function () {
this.frame.$.focus();
this.onOpen();
this.opening = false;
this.emit( 'open' );
@ -284,6 +265,7 @@ ve.ui.Window.prototype.close = function ( remove ) {
this.visible = false;
this.onClose( remove );
this.closing = false;
this.frame.$content.find( ':focus' ).blur();
this.surface.getView().getDocument().getDocumentNode().$.focus();
this.emit( 'close', remove );
}

View file

@ -19,10 +19,15 @@ ve.ui = {
* Gets a jQuery function within a specific document.
*
* @param {jQuery|HTMLDocument} context Context to bind the function to
* @param {ve.ui.Frame} [frame] Frame of the document context
* @returns {Function} Bound jQuery function
*/
ve.ui.get$$ = function ( context ) {
return function ( selector ) {
ve.ui.get$$ = function ( context, frame ) {
function $$( selector ) {
return $( selector, context instanceof jQuery ? context.context : context );
};
}
if ( frame ) {
$$.frame = frame;
}
return $$;
};

View file

@ -203,8 +203,13 @@ ve.ui.MWLinkTargetInputWidget.prototype.populateMenu = function () {
// Auto-select
this.menu.selectItem( this.menu.getItemFromData( this.annotation ), true );
if ( !this.menu.getSelectedItem() ) {
if ( this.menu.getSelectedItem() ) {
this.menu.highlightItem( this.menu.getSelectedItem() );
} else {
this.menu.selectItem( this.menu.getItemFromIndex( 0 ), true );
if ( this.menu.getSelectedItem() ) {
this.menu.highlightItem( this.menu.getItemFromIndex( 0 ) );
}
}
return this;

View file

@ -37,16 +37,21 @@ ve.inheritClass( ve.ui.TextInputMenuWidget, ve.ui.MenuWidget );
* @chainable
*/
ve.ui.TextInputMenuWidget.prototype.show = function () {
var $input = this.input.$input;
var dim, offset,
$input = this.input.$input;
// Call parent method
ve.ui.MenuWidget.prototype.show.call( this );
// Position under input
this.$.css( {
'left': $input.offset().left,
'top': $input.offset().top + $input.outerHeight( true )
} );
dim = $input.offset();
dim.top += $input.outerHeight( true );
if ( this.input.$$.frame ) {
offset = this.input.$$.frame.$.offset();
dim.left += offset.left;
dim.top += offset.top;
}
this.$.css( dim );
return this;
};