Trevor Parscal has uploaded a new change for review.

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


Change subject: New popup widget
......................................................................

New popup widget

This will make the popup with callout functionality easy to reuse elsewhere - 
in the first case most likely the popup menus for the category widget.

*.php
* Added links to the new widget

ve.ui.Context.css, ve.ui.Widget.css
* Moved styles to the widget stylesheet

ve.ui.Context.js, ve.ui.PopupWidget
* Moved "popup" specific stuff to the new popup widget

Change-Id: I823c6e2c5e1ec11088898e9621d93e983c3b76f3
---
M VisualEditor.php
M demos/ve/index.php
M modules/ve/test/index.php
M modules/ve/ui/styles/ve.ui.Context.css
M modules/ve/ui/styles/ve.ui.Widget.css
M modules/ve/ui/ve.ui.Context.js
A modules/ve/ui/widgets/ve.ui.PopupWidget.js
7 files changed, 164 insertions(+), 90 deletions(-)


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

diff --git a/VisualEditor.php b/VisualEditor.php
index cfb634f..d13ba64 100644
--- a/VisualEditor.php
+++ b/VisualEditor.php
@@ -324,6 +324,7 @@
 
                        've/ui/widgets/ve.ui.LabeledWidget.js',
                        've/ui/widgets/ve.ui.FlaggableWidget.js',
+                       've/ui/widgets/ve.ui.PopupWidget.js',
                        've/ui/widgets/ve.ui.GroupWidget.js',
                        've/ui/widgets/ve.ui.SelectWidget.js',
                        've/ui/widgets/ve.ui.OptionWidget.js',
diff --git a/demos/ve/index.php b/demos/ve/index.php
index 0712330..40e516b 100644
--- a/demos/ve/index.php
+++ b/demos/ve/index.php
@@ -208,6 +208,7 @@
                <script 
src="../../modules/ve/ui/layouts/ve.ui.PanelLayout.js"></script>
                <script 
src="../../modules/ve/ui/widgets/ve.ui.LabeledWidget.js"></script>
                <script 
src="../../modules/ve/ui/widgets/ve.ui.FlaggableWidget.js"></script>
+               <script 
src="../../modules/ve/ui/widgets/ve.ui.PopupWidget.js"></script>
                <script 
src="../../modules/ve/ui/widgets/ve.ui.GroupWidget.js"></script>
                <script 
src="../../modules/ve/ui/widgets/ve.ui.SelectWidget.js"></script>
                <script 
src="../../modules/ve/ui/widgets/ve.ui.OptionWidget.js"></script>
diff --git a/modules/ve/test/index.php b/modules/ve/test/index.php
index faa446e..e07d08c 100644
--- a/modules/ve/test/index.php
+++ b/modules/ve/test/index.php
@@ -153,6 +153,7 @@
                <script src="../../ve/ui/layouts/ve.ui.PanelLayout.js"></script>
                <script 
src="../../ve/ui/widgets/ve.ui.LabeledWidget.js"></script>
                <script 
src="../../ve/ui/widgets/ve.ui.FlaggableWidget.js"></script>
+               <script src="../../ve/ui/widgets/ve.ui.PopupWidget.js"></script>
                <script src="../../ve/ui/widgets/ve.ui.GroupWidget.js"></script>
                <script 
src="../../ve/ui/widgets/ve.ui.SelectWidget.js"></script>
                <script 
src="../../ve/ui/widgets/ve.ui.OptionWidget.js"></script>
diff --git a/modules/ve/ui/styles/ve.ui.Context.css 
b/modules/ve/ui/styles/ve.ui.Context.css
index 3b1fe4e..e542b32 100644
--- a/modules/ve/ui/styles/ve.ui.Context.css
+++ b/modules/ve/ui/styles/ve.ui.Context.css
@@ -10,40 +10,6 @@
        z-index: 2;
 }
 
-.ve-ui-context-callout {
-       position: absolute;
-       /* @embed */
-       background-image: url(images/callout.svg);
-       background-repeat: no-repeat;
-       width: 15px;
-       height: 8px;
-       margin-left: -7px;
-       z-index: 4;
-}
-
-.ve-ui-context-body {
-       margin-top: 7px;
-       position: absolute;
-       overflow: hidden;
-       border: solid 1px #ccc;
-       border-radius: 0.25em;
-       background-color: #fff;
-       box-shadow: 0 0.15em 0.5em 0 rgba(0, 0, 0, 0.2);
-}
-
-.ve-ui-context-body-transition {
-       -webkit-transition: width 100ms, height 100ms, left 100ms;
-       -moz-transition: width 100ms, height 100ms, left 100ms;
-       -ms-transition: width 100ms, height 100ms, left 100ms;
-       -o-transition: width 100ms, height 100ms, left 100ms;
-       transition: width 100ms, height 100ms, left 100ms;
-       -webkit-transition-timing-function: ease-in-out;
-       -moz-transition-timing-function: ease-in-out;
-       -ms-transition-timing-function: ease-in-out;
-       -o-transition-timing-function: ease-in-out;
-       transition-timing-function: ease-in-out;
-}
-
 .ve-ui-context-inspectors, .ve-ui-context-menu {
        position: absolute;
        z-index: 2;
diff --git a/modules/ve/ui/styles/ve.ui.Widget.css 
b/modules/ve/ui/styles/ve.ui.Widget.css
index 137be49..7a8fbf4 100644
--- a/modules/ve/ui/styles/ve.ui.Widget.css
+++ b/modules/ve/ui/styles/ve.ui.Widget.css
@@ -300,3 +300,39 @@
 .ve-ui-mwLinkTargetInputWidget-menu .ve-ui-menuItemWidget[rel=externalLink] {
        color: #0645AD;
 }
+
+/* ve.ui.PopupWidget */
+
+.ve-ui-popupWidget-callout {
+       position: absolute;
+       /* @embed */
+       background-image: url(images/callout.svg);
+       background-repeat: no-repeat;
+       width: 15px;
+       height: 8px;
+       margin-left: -7px;
+       z-index: 4;
+}
+
+.ve-ui-popupWidget-body {
+       margin-top: 7px;
+       position: absolute;
+       overflow: hidden;
+       border: solid 1px #ccc;
+       border-radius: 0.25em;
+       background-color: #fff;
+       box-shadow: 0 0.15em 0.5em 0 rgba(0, 0, 0, 0.2);
+}
+
+.ve-ui-popupWidget-transitioning .ve-ui-popupWidget-body {
+       -webkit-transition: width 100ms, height 100ms, left 100ms;
+       -moz-transition: width 100ms, height 100ms, left 100ms;
+       -ms-transition: width 100ms, height 100ms, left 100ms;
+       -o-transition: width 100ms, height 100ms, left 100ms;
+       transition: width 100ms, height 100ms, left 100ms;
+       -webkit-transition-timing-function: ease-in-out;
+       -moz-transition-timing-function: ease-in-out;
+       -ms-transition-timing-function: ease-in-out;
+       -o-transition-timing-function: ease-in-out;
+       transition-timing-function: ease-in-out;
+}
diff --git a/modules/ve/ui/ve.ui.Context.js b/modules/ve/ui/ve.ui.Context.js
index 6a03782..1c2bda1 100644
--- a/modules/ve/ui/ve.ui.Context.js
+++ b/modules/ve/ui/ve.ui.Context.js
@@ -22,21 +22,15 @@
        this.selecting = false;
        this.selection = null;
        this.toolbar = null;
-       this.inspectors = new ve.ui.WindowSet( surface, ve.ui.inspectorFactory 
);
        this.$ = $( '<div>' );
-       this.$callout = $( '<div>' );
-       this.$body = $( '<div>' );
+       this.popup = new ve.ui.PopupWidget();
        this.$menu = $( '<div>' );
+       this.inspectors = new ve.ui.WindowSet( surface, ve.ui.inspectorFactory 
);
 
        // Initialization
+       this.$.addClass( 've-ui-context' ).append( this.popup.$ );
        this.inspectors.$.addClass( 've-ui-context-inspectors' );
-       this.$
-               .addClass( 've-ui-context' )
-               .append(
-                       this.$callout.addClass( 've-ui-context-callout' ),
-                       this.$body.addClass( 've-ui-context-body' )
-               );
-       this.$body.append(
+       this.popup.$body.append(
                this.$menu.addClass( 've-ui-context-menu' ),
                this.inspectors.$.addClass( 've-ui-context-inspectors' )
        );
@@ -127,9 +121,7 @@
  */
 ve.ui.Context.prototype.onInspectorOpen = function () {
        // Transition between menu and inspector
-       this.$body.addClass( 've-ui-context-body-transition' );
-
-       this.show();
+       this.show( true );
 };
 
 /**
@@ -140,14 +132,7 @@
  * @param {boolean} accept Changes have been accepted
  */
 ve.ui.Context.prototype.onInspectorClose = function () {
-       var $body = this.$body;
-
        this.update();
-
-       // Disable transitioning after transition completes
-       setTimeout( function () {
-               $body.removeClass( 've-ui-context-body-transition' );
-       }, 200 );
 };
 
 /**
@@ -184,11 +169,6 @@
                selection = fragment.getRange(),
                inspector = this.inspectors.getCurrent();
 
-       // If the context about to be moved to a new location, don't transition 
it's size
-       if ( this.selection && this.selection.end !== selection.end ) {
-               this.$body.removeClass( 've-ui-context-body-transition' );
-       }
-
        if ( inspector && selection.equals( this.selection ) ) {
                // There's an inspector, and the selection hasn't changed, 
update the position
                this.show();
@@ -223,40 +203,22 @@
  * @method
  * @chainable
  */
-ve.ui.Context.prototype.updateDimensions = function () {
-       var position, $container, width, height, bodyWidth, buffer, center, 
overlapRight, overlapLeft,
+ve.ui.Context.prototype.updateDimensions = function ( transition ) {
+       var position, $container,
                inspector = this.inspectors.getCurrent();
 
                // Get cursor position
                position = this.surface.getView().getSelectionRect().end;
                if ( position ) {
-                       // Get additional dimensions
                        $container = inspector ? this.inspectors.$ : this.$menu;
-                       width = $container.outerWidth( true );
-                       height = $container.outerHeight( true );
-                       bodyWidth = $( 'body' ).width();
-                       buffer = ( width / 2 ) + 20;
-                       overlapRight = bodyWidth - ( position.x + buffer );
-                       overlapLeft = position.x - buffer;
-                       center = -( width / 2 );
-
-                       // Prevent body from displaying off-screen
-                       if ( overlapRight < 0 ) {
-                               center += overlapRight;
-                       } else if ( overlapLeft < 0 ) {
-                               center -= overlapLeft;
-                       }
-
-                       // Move to just below the cursor
-                       this.$.css( { 'left': position.x, 'width': width, 
'top': position.y } );
-
-                       if ( !this.visible ) {
-                               this.$body
-                                       .css( { 'width': 0, 'height': 0, 
'left': 0 } )
-                                       .addClass( 
've-ui-context-body-transition' );
-                       }
-
-                       this.$body.css( { 'left': center, 'width': width, 
'height': height } );
+                       this.$.css( { 'left': position.x, 'top': position.y } );
+                       this.popup.display(
+                               position.x,
+                               position.y,
+                               $container.outerWidth( true ),
+                               $container.outerHeight( true ),
+                               transition
+                       );
                }
 
        return this;
@@ -268,7 +230,7 @@
  * @method
  * @chainable
  */
-ve.ui.Context.prototype.show = function () {
+ve.ui.Context.prototype.show = function ( transition ) {
        var inspector = this.inspectors.getCurrent();
 
        if ( !this.showing ) {
@@ -284,7 +246,7 @@
                        // Update size and fade the inspector in after 
animation is complete
                        setTimeout( ve.bind( function () {
                                inspector.fitHeightToContents();
-                               this.updateDimensions();
+                               this.updateDimensions( transition );
                                inspector.$.css( 'opacity', 1 );
                        }, this ), 200 );
                } else {
@@ -292,7 +254,7 @@
                        this.$menu.show();
                }
 
-               this.updateDimensions();
+               this.updateDimensions( transition );
 
                this.visible = true;
                this.showing = false;
diff --git a/modules/ve/ui/widgets/ve.ui.PopupWidget.js 
b/modules/ve/ui/widgets/ve.ui.PopupWidget.js
new file mode 100644
index 0000000..fc1f3d8
--- /dev/null
+++ b/modules/ve/ui/widgets/ve.ui.PopupWidget.js
@@ -0,0 +1,107 @@
+/*!
+ * VisualEditor UserInterface PopupWidget class.
+ *
+ * @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * Creates an ve.ui.PopupWidget object.
+ *
+ * @class
+ * @extends ve.ui.Widget
+ *
+ * @constructor
+ * @param {Object} [config] Config options
+ */
+ve.ui.PopupWidget = function VeUiButtonWidget( config ) {
+       // Parent constructor
+       ve.ui.Widget.call( this, config );
+
+       // Properties
+       this.visible = false;
+       this.$callout = $( '<div>' );
+       this.$body = $( '<div>' );
+       this.transitionTimeout = null;
+
+       // Initialization
+       this.$
+               .addClass( 've-ui-popupWidget' )
+               .append(
+                       this.$callout.addClass( 've-ui-popupWidget-callout' ),
+                       this.$body.addClass( 've-ui-popupWidget-body' )
+               );
+};
+
+/* Inheritance */
+
+ve.inheritClass( ve.ui.PopupWidget, ve.ui.Widget );
+
+/* Methods */
+
+/**
+ * Show the context.
+ *
+ * @method
+ * @chainable
+ */
+ve.ui.PopupWidget.prototype.show = function () {
+       this.$.show();
+       this.visible = true;
+
+       return this;
+};
+
+/**
+ * Hide the context.
+ *
+ * @method
+ * @chainable
+ */
+ve.ui.PopupWidget.prototype.hide = function () {
+       this.$.hide();
+       this.visible = false;
+
+       return this;
+};
+
+/**
+ * Updates the position and size.
+ *
+ * @method
+ * @chainable
+ */
+ve.ui.PopupWidget.prototype.display = function ( x, y, width, height, 
transition ) {
+       var buffer = ( width / 2 ) + 20,
+               center = -( width / 2 ),
+               overlapRight = this.$$( 'body' ).width() - ( x + buffer ),
+               overlapLeft = x - buffer;
+
+       // Prevent viewport clipping
+       if ( overlapRight < 0 ) {
+               center += overlapRight;
+       } else if ( overlapLeft < 0 ) {
+               center -= overlapLeft;
+       }
+
+       // Prevent transition from being interrupted
+       clearTimeout( this.transitionTimeout );
+       if ( transition ) {
+               // Enable transition
+               this.$.addClass( 've-ui-popupWidget-transitioning' );
+               // Prevent transitioning after transition is complete
+               this.transitionTimeout = setTimeout( ve.bind( function () {
+                       this.$.removeClass( 've-ui-popupWidget-transitioning' );
+               }, this ), 200 );
+       } else {
+               // Prevent transitioning immediately
+               this.$.removeClass( 've-ui-popupWidget-transitioning' );
+       }
+
+       // Position body relative to anchor and adjust size
+       this.$body.css( {
+               'left': center, 'width': width, 'height': height === undefined 
? 'auto' : height
+       } );
+
+       return this;
+};

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

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

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

Reply via email to