jenkins-bot has submitted this change and it was merged.

Change subject: ve.ui.Context: Add embedding feature
......................................................................


ve.ui.Context: Add embedding feature

Objectives:

* Make the context menu display in the top right corner of the currently
  focused inspectable node (if there is one)
* Prevent clicking on anything to do with the toolbar or popup from doing
  anything at all, ever

Bonus:

* While we are using the clever feature in jQuery's on method which allows
  passing boolean false to cancel the event - may as well do that in
  ve.ui.Dialog as well

Changes:

ve.ui.FocusableNode
* Add ability to specify the focusable element so that dimensions can be
  derived from it

ve.ce.Surface
* Add quotes to object keys

ve.ui.MediaDialog
* Change association from being MW specific to handling images in general

ve.ui.Context
* Add embedded styles for context
* Add embedded mode, which is triggered when the context is a single
  focusable node, and the node is large enough to fit the context
  reasonably

ve.ui.Dialog
* Inline mousedown handler

ve.ui.Toolbar, ve.ui.PopupWidget
* Cancel stray mousedown events

Change-Id: I4b25d33f64b4bcb8a3ecfd7e9728f54a2d4886f3
---
M modules/ve/ce/ve.ce.FocusableNode.js
M modules/ve/ce/ve.ce.Surface.js
M modules/ve/ui/dialogs/ve.ui.MediaDialog.js
M modules/ve/ui/styles/ve.ui.Context.css
M modules/ve/ui/ve.ui.Context.js
M modules/ve/ui/ve.ui.Dialog.js
M modules/ve/ui/ve.ui.Toolbar.js
M modules/ve/ui/widgets/ve.ui.PopupWidget.js
8 files changed, 71 insertions(+), 23 deletions(-)

Approvals:
  Jforrester: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/modules/ve/ce/ve.ce.FocusableNode.js 
b/modules/ve/ce/ve.ce.FocusableNode.js
index d3ebe49..8175be9 100644
--- a/modules/ve/ce/ve.ce.FocusableNode.js
+++ b/modules/ve/ce/ve.ce.FocusableNode.js
@@ -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 */
diff --git a/modules/ve/ce/ve.ce.Surface.js b/modules/ve/ce/ve.ce.Surface.js
index 0f2f418..87b070f 100644
--- a/modules/ve/ce/ve.ce.Surface.js
+++ b/modules/ve/ce/ve.ce.Surface.js
@@ -177,8 +177,8 @@
                };
        } else {
                return {
-                       start: sel.getStartDocumentPos(),
-                       end: sel.getEndDocumentPos()
+                       'start': sel.getStartDocumentPos(),
+                       'end': sel.getEndDocumentPos()
                };
        }
 };
diff --git a/modules/ve/ui/dialogs/ve.ui.MediaDialog.js 
b/modules/ve/ui/dialogs/ve.ui.MediaDialog.js
index 506a813..ed3983b 100644
--- a/modules/ve/ui/dialogs/ve.ui.MediaDialog.js
+++ b/modules/ve/ui/dialogs/ve.ui.MediaDialog.js
@@ -30,7 +30,9 @@
 
 ve.ui.MediaDialog.static.icon = 'picture';
 
-ve.ui.MediaDialog.static.modelClasses = [ ve.dm.MWInlineImageNode ];
+ve.ui.MediaDialog.static.modelClasses = [ ve.dm.ImageNode ];
+
+/* Methods */
 
 /* Registration */
 
diff --git a/modules/ve/ui/styles/ve.ui.Context.css 
b/modules/ve/ui/styles/ve.ui.Context.css
index 7f2e0c1..096a844 100644
--- a/modules/ve/ui/styles/ve.ui.Context.css
+++ b/modules/ve/ui/styles/ve.ui.Context.css
@@ -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;
+}
diff --git a/modules/ve/ui/ve.ui.Context.js b/modules/ve/ui/ve.ui.Context.js
index 51f1940..68fad32 100644
--- a/modules/ve/ui/ve.ui.Context.js
+++ b/modules/ve/ui/ve.ui.Context.js
@@ -21,6 +21,7 @@
        this.showing = false;
        this.selecting = false;
        this.relocating = false;
+       this.embedded = false;
        this.selection = null;
        this.toolbar = null;
        this.$ = $( '<div>' );
@@ -53,6 +54,8 @@
                'resize': ve.bind( this.update, this ),
                'focus': ve.bind( this.onWindowFocus, this )
        } );
+       this.$.add( this.$menu )
+               .on( 'mousedown', false );
 };
 
 /* Methods */
@@ -246,14 +249,25 @@
  * @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 @@
  * @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 @@
                        }, 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();
                }
 
diff --git a/modules/ve/ui/ve.ui.Dialog.js b/modules/ve/ui/ve.ui.Dialog.js
index d29fbe6..85d8feb 100644
--- a/modules/ve/ui/ve.ui.Dialog.js
+++ b/modules/ve/ui/ve.ui.Dialog.js
@@ -24,7 +24,7 @@
 
        // Initialization
        this.$.addClass( 've-ui-dialog' );
-       this.$.on( 'mousedown', ve.bind( this.onMouseDown, this ) );
+       this.$.on( 'mousedown', false );
 };
 
 /* Inheritance */
@@ -32,16 +32,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.
diff --git a/modules/ve/ui/ve.ui.Toolbar.js b/modules/ve/ui/ve.ui.Toolbar.js
index ac6f15f..f4b802e 100644
--- a/modules/ve/ui/ve.ui.Toolbar.js
+++ b/modules/ve/ui/ve.ui.Toolbar.js
@@ -32,6 +32,7 @@
        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 @@
                '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 @@
                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(
diff --git a/modules/ve/ui/widgets/ve.ui.PopupWidget.js 
b/modules/ve/ui/widgets/ve.ui.PopupWidget.js
index 2db41a3..74f5d45 100644
--- a/modules/ve/ui/widgets/ve.ui.PopupWidget.js
+++ b/modules/ve/ui/widgets/ve.ui.PopupWidget.js
@@ -29,6 +29,11 @@
        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 @@
                        this.$body.addClass( 've-ui-popupWidget-body' )
                );
 
-       // Auto hide popup
-       this.$body.on( 'blur', ve.bind( this.onPopupBlur, this ) );
 };
 
 /* Inheritance */

-- 
To view, visit https://gerrit.wikimedia.org/r/63243
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I4b25d33f64b4bcb8a3ecfd7e9728f54a2d4886f3
Gerrit-PatchSet: 10
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Robmoen <[email protected]>
Gerrit-Reviewer: Jforrester <[email protected]>
Gerrit-Reviewer: Krinkle <[email protected]>
Gerrit-Reviewer: Trevor Parscal <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to