Robmoen has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/57684


Change subject: Enhance popupWidget with automatic closing when not focused.
......................................................................

Enhance popupWidget with automatic closing when not focused.

Change-Id: I04e7201f7e85be36fca010e6422eeb784acf7757
---
M modules/ve/ui/styles/ve.ui.Widget.css
M modules/ve/ui/widgets/ve.ui.CategoryGroupItemWidget.js
M modules/ve/ui/widgets/ve.ui.CategoryWidget.js
M modules/ve/ui/widgets/ve.ui.PopupWidget.js
4 files changed, 57 insertions(+), 21 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor 
refs/changes/84/57684/1

diff --git a/modules/ve/ui/styles/ve.ui.Widget.css 
b/modules/ve/ui/styles/ve.ui.Widget.css
index f4aeb35..c288c00 100644
--- a/modules/ve/ui/styles/ve.ui.Widget.css
+++ b/modules/ve/ui/styles/ve.ui.Widget.css
@@ -319,6 +319,11 @@
        box-shadow: 0 0.15em 0.5em 0 rgba(0, 0, 0, 0.2);
 }
 
+.ve-ui-popupWidget-body:focus {
+       /* No outline. The body has a tabindex and is focused on show */
+       outline: none;
+}
+
 .ve-ui-popupWidget-transitioning .ve-ui-popupWidget-body {
        -webkit-transition: width 100ms, height 100ms, left 100ms;
        -moz-transition: width 100ms, height 100ms, left 100ms;
@@ -330,7 +335,6 @@
        -ms-transition-timing-function: ease-in-out;
        -o-transition-timing-function: ease-in-out;
        transition-timing-function: ease-in-out;
-       z-index:300;
 }
 
 /* ve.ui.CategoryListWidget */
diff --git a/modules/ve/ui/widgets/ve.ui.CategoryGroupItemWidget.js 
b/modules/ve/ui/widgets/ve.ui.CategoryGroupItemWidget.js
index 74631d7..8430bea 100644
--- a/modules/ve/ui/widgets/ve.ui.CategoryGroupItemWidget.js
+++ b/modules/ve/ui/widgets/ve.ui.CategoryGroupItemWidget.js
@@ -30,7 +30,6 @@
        this.value = config.item.value;
        this.sortKey = config.item.sortKey || '';
        this.metaItem = config.metaItem;
-       this.menuOpen = false;
 
        // Initialization
 
@@ -43,8 +42,8 @@
        // Assemble the widget elements
        this.$.addClass( 've-ui-categoryListItemWidget' ).append( 
this.$categoryItem );
 
-       // Events
-       this.$categoryItem.on( 'click', ve.bind( this.onClick, this ) );
+       // Reacting on mousedown will allow us to check the state prior to the 
blur
+       this.$categoryItem.on( 'mousedown', ve.bind( this.onMouseDown, this ) );
 };
 
 /* Inheritance */
@@ -54,7 +53,7 @@
 
 /* Methods */
 
-ve.ui.CategoryGroupItemWidget.prototype.onClick = function () {
+ve.ui.CategoryGroupItemWidget.prototype.onMouseDown = function () {
        this.emit( 'togglePopupMenu', this );
        return false;
 };
diff --git a/modules/ve/ui/widgets/ve.ui.CategoryWidget.js 
b/modules/ve/ui/widgets/ve.ui.CategoryWidget.js
index 22ac272..6542037 100644
--- a/modules/ve/ui/widgets/ve.ui.CategoryWidget.js
+++ b/modules/ve/ui/widgets/ve.ui.CategoryWidget.js
@@ -28,9 +28,9 @@
        // Properties
        this.categories = {};
        this.$categories = this.$$( '<div>' );
-       this.popup = new ve.ui.PopupWidget( { '$$': this.$$, 'align': 'right' } 
);
-       this.popupOpen = false;
+       this.popup = new ve.ui.PopupWidget( { '$$': this.$$, 'align': 'right' } 
).hide();
        this.popupCategory = null;
+       this.popupOpen = false;
 
        this.categoryInput = new ve.ui.MWCategoryInputWidget( {
                '$$': this.$$, '$overlay': config.$overlay
@@ -69,7 +69,7 @@
 
        // Assemble popup
        this.popup.$body.append( this.$menu );
-       this.$popupMenu = this.$$( '<div>' ).addClass( 
've-ui-categoryPopupMenu' ).hide()
+       this.$popupMenu = this.$$( '<div>' ).addClass( 
've-ui-categoryPopupMenu' )
                .append( this.popup.$.addClass( 've-ui-categoryListItemMenu' ) 
);
 
        // Append popup to window overlay
@@ -79,6 +79,7 @@
        this.removeButton.on( 'click', ve.bind( this.onRemoveCategory, this ) );
        this.$removeButtonLabel.on( 'click', ve.bind( this.onRemoveCategory, 
this ) );
        this.$sortKeyForm.on( 'submit', ve.bind( this.onSortKeySubmit, this ) );
+       this.popup.addListenerMethods( this, { 'hide': 'onPopupHide' } );
 };
 
 /* Inheritance */
@@ -129,7 +130,7 @@
 };
 
 ve.ui.CategoryWidget.prototype.openPopup = function ( item ) {
-       this.$popupMenu.show();
+       this.popup.show();
        this.popupOpen = true;
        this.popupCategory = item.name;
        this.loadCategoryIntoPopup( item );
@@ -141,7 +142,7 @@
 };
 
 ve.ui.CategoryWidget.prototype.closePopup = function () {
-       this.$popupMenu.hide();
+       this.popup.hide();
        this.popupOpen = false;
 };
 
@@ -151,7 +152,6 @@
                        'top': item.$.offset().top + item.$.height()
                };
        this.popup.$.css( { 'left': position.left, 'top': position.top } );
-
        // Set popup position and dimensions
        this.popup.display(
                position.left,
@@ -162,16 +162,16 @@
        );
 };
 
+ve.ui.CategoryWidget.prototype.onPopupHide = function () {
+       this.popupOpen = false;
+};
+
 ve.ui.CategoryWidget.prototype.onTogglePoupupMenu = function ( item ) {
-       // Close open popup.
-       if ( this.popupCategory === item.name ) {
-               this.closePopup();
-               this.popupCategory = null;
-       } else if ( this.popupOpen ) {
-               this.closePopup();
+       if ( this.popupOpen === false || item.name !== this.popupCategory ) {
                this.openPopup( item );
        } else {
-               this.openPopup( item );
+               // Handles toggle
+               this.closePopup();
        }
 };
 
diff --git a/modules/ve/ui/widgets/ve.ui.PopupWidget.js 
b/modules/ve/ui/widgets/ve.ui.PopupWidget.js
index 8d960cf..3caf05e 100644
--- a/modules/ve/ui/widgets/ve.ui.PopupWidget.js
+++ b/modules/ve/ui/widgets/ve.ui.PopupWidget.js
@@ -24,7 +24,8 @@
        // Properties
        this.visible = false;
        this.$callout = this.$$( '<div>' );
-       this.$body = this.$$( '<div>' );
+       // Tab index on body so that it may blur
+       this.$body = this.$$( '<div>' ).attr( 'tabindex', 1 );
        this.transitionTimeout = null;
        this.align = config.align || 'center';
 
@@ -35,6 +36,8 @@
                        this.$callout.addClass( 've-ui-popupWidget-callout' ),
                        this.$body.addClass( 've-ui-popupWidget-body' )
                );
+       // Auto hide popup
+       this.$body.on( 'blur', ve.bind( this.onPopupBlur, this ) );
 };
 
 /* Inheritance */
@@ -52,8 +55,38 @@
 ve.ui.PopupWidget.prototype.show = function () {
        this.$.show();
        this.visible = true;
-
+       // Focus body so that it may blur.
+       this.$body.focus();
        return this;
+};
+
+ve.ui.PopupWidget.prototype.getFocusedChild = function () {
+       return this.$body.find( ':focus' );
+};
+
+ve.ui.PopupWidget.prototype.onPopupBlur = function () {
+       // Find out what is focused after blur
+       setTimeout( ve.bind( function () {
+               var $focused = this.getFocusedChild();
+               // Is there a focused child element?
+               if ( $focused.length > 0 ) {
+                       // Bind a one off blur event to that focused child 
element
+                       $focused.one( 'blur', ve.bind( function () {
+                               setTimeout( ve.bind( function () {
+                                       if ( this.getFocusedChild().length === 
0 ) {
+                                               // Be sure focus is not the 
popup itself.
+                                               if ( this.$.find( ':focus' 
).is( this.$body ) ){
+                                                       return;
+                                               }
+                                               // Not a child and not the 
popup itself, so hide.
+                                               this.hide();
+                                       }
+                               }, this ), 0 );
+                       }, this ) );
+               } else {
+                       this.hide();
+               }
+       }, this ), 0 );
 };
 
 /**
@@ -65,7 +98,7 @@
 ve.ui.PopupWidget.prototype.hide = function () {
        this.$.hide();
        this.visible = false;
-
+       this.emit( 'hide' );
        return this;
 };
 

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I04e7201f7e85be36fca010e6422eeb784acf7757
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Robmoen <[email protected]>

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

Reply via email to