mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-15 10:35:48 +00:00
Merge "ve.ui.Context: Add embedding feature"
This commit is contained in:
commit
0eb2581b64
|
@ -8,14 +8,23 @@
|
|||
/**
|
||||
* ContentEditable resizable 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,
|
||||
* such as the context, may also use a focusable node's $focusable property as a hint of where the
|
||||
* primary element in the node is. Typically, and by default, the primary element is the root
|
||||
* element, but in some cases it may need to be configured to be a specific child element within the
|
||||
* node's DOM rendering.
|
||||
*
|
||||
* @class
|
||||
* @abstract
|
||||
*
|
||||
* @constructor
|
||||
* @param {jQuery} [$focusable] Primary element user is focusing on
|
||||
*/
|
||||
ve.ce.FocusableNode = function VeCeFocusableNode() {
|
||||
ve.ce.FocusableNode = function VeCeFocusableNode( $focusable ) {
|
||||
// Properties
|
||||
this.focused = false;
|
||||
this.$focusable = $focusable || this.$;
|
||||
};
|
||||
|
||||
/* Events */
|
||||
|
|
|
@ -177,8 +177,8 @@ ve.ce.Surface.getSelectionRect = function () {
|
|||
};
|
||||
} else {
|
||||
return {
|
||||
start: sel.getStartDocumentPos(),
|
||||
end: sel.getEndDocumentPos()
|
||||
'start': sel.getStartDocumentPos(),
|
||||
'end': sel.getEndDocumentPos()
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -30,7 +30,9 @@ ve.ui.MediaDialog.static.titleMessage = 'visualeditor-dialog-media-title';
|
|||
|
||||
ve.ui.MediaDialog.static.icon = 'picture';
|
||||
|
||||
ve.ui.MediaDialog.static.modelClasses = [ ve.dm.MWInlineImageNode ];
|
||||
ve.ui.MediaDialog.static.modelClasses = [ ve.dm.ImageNode ];
|
||||
|
||||
/* Methods */
|
||||
|
||||
/* Registration */
|
||||
|
||||
|
|
|
@ -35,3 +35,16 @@
|
|||
.ve-ui-context-menu .ve-ui-buttonTool-active {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
.ve-ui-context-embed .ve-ui-popupWidget-callout {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ve-ui-context-embed .ve-ui-popupWidget-body {
|
||||
margin-top: 0.25em;
|
||||
margin-left: -1.3em;
|
||||
}
|
||||
|
||||
.ve-ui-context-embed .ve-ui-context-menu {
|
||||
right: 0;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ ve.ui.Context = function VeUiContext( surface ) {
|
|||
this.showing = false;
|
||||
this.selecting = false;
|
||||
this.relocating = false;
|
||||
this.embedded = false;
|
||||
this.selection = null;
|
||||
this.toolbar = null;
|
||||
this.$ = $( '<div>' );
|
||||
|
@ -53,6 +54,8 @@ ve.ui.Context = function VeUiContext( surface ) {
|
|||
'resize': ve.bind( this.update, this ),
|
||||
'focus': ve.bind( this.onWindowFocus, this )
|
||||
} );
|
||||
this.$.add( this.$menu )
|
||||
.on( 'mousedown', false );
|
||||
};
|
||||
|
||||
/* Methods */
|
||||
|
@ -246,14 +249,25 @@ ve.ui.Context.prototype.update = function () {
|
|||
* @chainable
|
||||
*/
|
||||
ve.ui.Context.prototype.updateDimensions = function ( transition ) {
|
||||
var position, $container,
|
||||
inspector = this.inspectors.getCurrent();
|
||||
var position, $container, focusableOffset, focusableWidth,
|
||||
inspector = this.inspectors.getCurrent(),
|
||||
focusedNode = this.surface.getView().getFocusedNode();
|
||||
|
||||
// Get cursor position
|
||||
position = ve.ce.Surface.getSelectionRect();
|
||||
position = position && position.end;
|
||||
|
||||
if ( position ) {
|
||||
$container = inspector ? this.inspectors.$ : this.$menu;
|
||||
if ( this.embedded ) {
|
||||
focusableOffset = focusedNode.$focusable.offset();
|
||||
focusableWidth = focusedNode.$focusable.outerWidth();
|
||||
$container = this.$menu;
|
||||
position = { 'x': focusableOffset.left + focusableWidth, 'y': focusableOffset.top };
|
||||
this.popup.align = 'right';
|
||||
} else {
|
||||
position = position && position.end;
|
||||
$container = inspector ? this.inspectors.$ : this.$menu;
|
||||
this.popup.align = 'center';
|
||||
}
|
||||
this.$.css( { 'left': position.x, 'top': position.y } );
|
||||
this.popup.display(
|
||||
position.x,
|
||||
|
@ -274,7 +288,8 @@ ve.ui.Context.prototype.updateDimensions = function ( transition ) {
|
|||
* @chainable
|
||||
*/
|
||||
ve.ui.Context.prototype.show = function ( transition ) {
|
||||
var inspector = this.inspectors.getCurrent();
|
||||
var inspector = this.inspectors.getCurrent(),
|
||||
focusedNode = this.surface.getView().getFocusedNode();
|
||||
|
||||
if ( !this.showing ) {
|
||||
this.showing = true;
|
||||
|
@ -294,6 +309,16 @@ ve.ui.Context.prototype.show = function ( transition ) {
|
|||
}, this ), 200 );
|
||||
} else {
|
||||
this.inspectors.$.hide();
|
||||
if (
|
||||
focusedNode &&
|
||||
focusedNode.$focusable.outerHeight() > this.$menu.outerHeight() * 2
|
||||
) {
|
||||
this.$.addClass( 've-ui-context-embed' );
|
||||
this.embedded = true;
|
||||
} else {
|
||||
this.$.removeClass( 've-ui-context-embed' );
|
||||
this.embedded = false;
|
||||
}
|
||||
this.$menu.show();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ ve.ui.Dialog = function VeUiDialog( surface ) {
|
|||
|
||||
// Initialization
|
||||
this.$.addClass( 've-ui-dialog' );
|
||||
this.$.on( 'mousedown', ve.bind( this.onMouseDown, this ) );
|
||||
this.$.on( 'mousedown', false );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
@ -33,16 +33,6 @@ ve.inheritClass( ve.ui.Dialog, ve.ui.Window );
|
|||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* Handle mouse down events.
|
||||
*
|
||||
* @method
|
||||
* @param {jQuery.Event} e Mouse down event
|
||||
*/
|
||||
ve.ui.Dialog.prototype.onMouseDown = function () {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle close button click events.
|
||||
*
|
||||
|
|
|
@ -32,6 +32,7 @@ ve.ui.Toolbar = function VeUiToolbar( surface, options ) {
|
|||
this.surface = surface;
|
||||
this.$bar = this.$$( '<div>' );
|
||||
this.$tools = this.$$( '<div>' );
|
||||
this.$actions = this.$$( '<div>' );
|
||||
this.floating = false;
|
||||
this.$window = null;
|
||||
this.windowEvents = {
|
||||
|
@ -39,11 +40,15 @@ ve.ui.Toolbar = function VeUiToolbar( surface, options ) {
|
|||
'scroll': ve.bind( this.onWindowScroll, this )
|
||||
};
|
||||
|
||||
// Events
|
||||
this.$
|
||||
.add( this.$bar ).add( this.$tools ).add( this.$actions )
|
||||
.on( 'mousedown', false );
|
||||
|
||||
// Initialization
|
||||
this.$tools.addClass( 've-ui-toolbar-tools' );
|
||||
this.$bar.addClass( 've-ui-toolbar-bar' ).append( this.$tools );
|
||||
if ( options.actions ) {
|
||||
this.$actions = this.$$( '<div>' );
|
||||
this.$actions.addClass( 've-ui-toolbar-actions' );
|
||||
this.$bar.append( this.$actions );
|
||||
}
|
||||
|
@ -160,6 +165,7 @@ ve.ui.Toolbar.prototype.addTools = function ( tools ) {
|
|||
group = tools[i];
|
||||
// Create group
|
||||
$group = this.$$( '<div class="ve-ui-toolbar-group"></div>' )
|
||||
.on( 'mousedown', false )
|
||||
.addClass( 've-ui-toolbar-group-' + group.name );
|
||||
if ( group.label ) {
|
||||
$group.append(
|
||||
|
|
|
@ -29,6 +29,11 @@ ve.ui.PopupWidget = function VeUiPopupWidget( config ) {
|
|||
this.transitionTimeout = null;
|
||||
this.align = config.align || 'center';
|
||||
|
||||
// Events
|
||||
this.$body.on( 'blur', ve.bind( this.onPopupBlur, this ) );
|
||||
this.$.add( this.$body ).add( this.$callout )
|
||||
.on( 'mousedown', false );
|
||||
|
||||
// Initialization
|
||||
this.$
|
||||
.addClass( 've-ui-popupWidget' )
|
||||
|
@ -37,8 +42,6 @@ ve.ui.PopupWidget = function VeUiPopupWidget( config ) {
|
|||
this.$body.addClass( 've-ui-popupWidget-body' )
|
||||
);
|
||||
|
||||
// Auto hide popup
|
||||
this.$body.on( 'blur', ve.bind( this.onPopupBlur, this ) );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
|
Loading…
Reference in a new issue