JGonera has uploaded a new change for review.

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

Change subject: [WIP] Reenable mobile context and style it properly
......................................................................

[WIP] Reenable mobile context and style it properly

Also, attach inspectors to the global surface instead of mobile context.

TODO:
* styling of mobile context
* why do I need to tap references twice?

Change-Id: Ic4f288cdcb248b76ead57c048144c8909a16042d
---
M modules/ve/ui/styles/ve.ui.MobileContext.css
M modules/ve/ui/styles/ve.ui.MobileSurface.css
M modules/ve/ui/ve.ui.Context.js
M modules/ve/ui/ve.ui.DesktopContext.js
M modules/ve/ui/ve.ui.MobileContext.js
M modules/ve/ui/ve.ui.MobileSurface.js
6 files changed, 199 insertions(+), 151 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor 
refs/changes/85/141085/1

diff --git a/modules/ve/ui/styles/ve.ui.MobileContext.css 
b/modules/ve/ui/styles/ve.ui.MobileContext.css
index d68b1f7..5cc3ba8 100644
--- a/modules/ve/ui/styles/ve.ui.MobileContext.css
+++ b/modules/ve/ui/styles/ve.ui.MobileContext.css
@@ -5,16 +5,19 @@
  * @license The MIT License (MIT); see LICENSE.txt
  */
 
-.ve-ui-mobileContext-visible {
-       position: absolute;
-       top: 0;
-       width: 100%;
-       height: 100%;
+.ve-ui-mobileContext {
+       position: fixed;
+       top: 3.35em;
        background: #fff;
+       width: 100%;
+       -webkit-transform: translate3d(0, -200%, 0);
+       transform: translate3d(0, -200%, 0);
+
+       -webkit-transition: -webkit-transform .3s, opacity .3s;
+       transition: transform .3s, opacity .3s;
 }
 
-/* inspector styles */
-
-.ve-ui-mobileContext .oo-ui-frame {
-       width: 100%;
+.ve-ui-mobileContext-visible {
+       -webkit-transform: none;
+       transform: none;
 }
diff --git a/modules/ve/ui/styles/ve.ui.MobileSurface.css 
b/modules/ve/ui/styles/ve.ui.MobileSurface.css
index d344664..c3064fe 100644
--- a/modules/ve/ui/styles/ve.ui.MobileSurface.css
+++ b/modules/ve/ui/styles/ve.ui.MobileSurface.css
@@ -9,6 +9,7 @@
 /*csslint compatible-vendor-prefixes:false */
 
 .ve-ui-mobileSurface-overlay-global {
+       background: #fff;
        height: 100%;
        -webkit-transform: translate3d(0, -100%, 0);
        transform: translate3d(0, -100%, 0);
@@ -26,3 +27,9 @@
        height: 100%;
        overflow: hidden;
 }
+
+/* inspector styles */
+
+.ve-ui-mobileSurface-overlay-global-visible .oo-ui-frame {
+       width: 100%;
+}
diff --git a/modules/ve/ui/ve.ui.Context.js b/modules/ve/ui/ve.ui.Context.js
index 0274798..a973f1a 100644
--- a/modules/ve/ui/ve.ui.Context.js
+++ b/modules/ve/ui/ve.ui.Context.js
@@ -25,6 +25,20 @@
        this.inspectors = new ve.ui.WindowSet(
                ve.ui.windowFactory, { '$': this.$, '$contextOverlay': 
this.$element }
        );
+       this.context = new ve.ui.ContextWidget( { '$': this.$ } );
+       this.afterModelChangeTimeout = null;
+       this.afterModelChangeRange = null;
+
+       // Events
+       this.surface.getModel().connect( this, {
+               'documentUpdate': 'onModelChange',
+               'select': 'onModelChange'
+       } );
+       this.inspectors.connect( this, {
+               'setup': 'onInspectorSetup',
+               'teardown': 'onInspectorTeardown'
+       } );
+       this.context.connect( this, { 'choose': 'onContextItemChoose' } );
 };
 
 /* Inheritance */
@@ -32,6 +46,109 @@
 OO.inheritClass( ve.ui.Context, OO.ui.Element );
 
 /* Methods */
+
+/**
+ * Handle context item choose events.
+ *
+ * @param {ve.ui.ContextItemWidget} item Chosen item
+ */
+ve.ui.Context.prototype.onContextItemChoose = function ( item ) {
+       if ( item ) {
+               item.getCommand().execute( this.surface );
+       }
+};
+
+/**
+ * @inheritdoc
+ */
+ve.ui.Context.prototype.destroy = function () {
+       // Disconnect events
+       this.surface.getModel().disconnect( this );
+       this.surface.getView().disconnect( this );
+       this.inspectors.disconnect( this );
+
+       // Stop timers
+       clearTimeout( this.afterModelChangeTimeout );
+
+       // Parent method
+       return ve.ui.Context.prototype.destroy.call( this );
+};
+
+/**
+ * Handle selection changes in the model.
+ *
+ * Changes are ignored while the user is selecting text or relocating content, 
apart from closing
+ * the popup if it's open. While an inspector is opening or closing, all 
changes are ignored so as
+ * to prevent inspectors that change the selection from within their 
open/close handlers from
+ * causing issues.
+ *
+ * The response to selection changes is deferred to prevent close handlers 
that process
+ * changes from causing this function to recurse. These responses are also 
batched for efficiency,
+ * so that if there are three selection changes in the same tick, 
afterModelChange() only runs once.
+ *
+ * @method
+ * @param {ve.Range} range Range if triggered by selection change, null 
otherwise
+ * @see #afterModelChange
+ */
+ve.ui.Context.prototype.onModelChange = function ( range ) {
+       var win = this.inspectors.getCurrentWindow();
+
+       if ( this.showing || this.hiding || ( win && ( win.isOpening() || 
win.isClosing() ) ) ) {
+               clearTimeout( this.afterModelChangeTimeout );
+               this.afterModelChangeTimeout = null;
+               this.afterModelChangeRange = null;
+       } else {
+               if ( this.afterModelChangeTimeout === null ) {
+                       this.afterModelChangeTimeout = setTimeout( ve.bind( 
this.afterModelChange, this ) );
+               }
+               if ( range instanceof ve.Range ) {
+                       this.afterModelChangeRange = range;
+               }
+       }
+};
+
+/**
+ * Updates the context menu.
+ *
+ * @method
+ * @param {boolean} [transition=false] Use a smooth transition
+ * @chainable
+ */
+ve.ui.Context.prototype.update = function ( transition ) {
+       var i, len, match, matches,
+               items = [],
+               fragment = this.surface.getModel().getFragment( null, false ),
+               selection = fragment.getRange(),
+               inspector = this.inspectors.getCurrentWindow();
+
+       if ( inspector && selection && selection.equals( this.selection ) ) {
+               // There's an inspector, and the selection hasn't changed, 
update the position
+               this.show( transition );
+       } else {
+               // No inspector is open, or the selection has changed, show a 
menu of available inspectors
+               matches = ve.ui.toolFactory.getToolsForFragment( fragment );
+               if ( matches.length ) {
+                       // There's at least one inspectable annotation, build a 
menu and show it
+                       this.context.clearItems();
+                       for ( i = 0, len = matches.length; i < len; i++ ) {
+                               match = matches[i];
+                               items.push( new ve.ui.ContextItemWidget(
+                                       match.tool.static.name, match.tool, 
match.model, { '$': this.$ }
+                               ) );
+                       }
+                       this.context.addItems( items );
+                       this.show( transition );
+               } else if ( this.visible ) {
+                       // Nothing to inspect
+                       this.hide();
+               }
+       }
+
+       // Remember selection for next time
+       this.selection = selection && selection.clone();
+
+       return this;
+};
 
 /**
  * Get the surface the context is being used in.
@@ -78,6 +195,24 @@
 };
 
 /**
+* Handle an inspector setup event.
+*
+* @method
+*/
+ve.ui.Context.prototype.onInspectorSetup = function () {
+       throw new Error( 've.ui.Context.onInspectorSetup must be overridden in 
subclass' );
+};
+
+/**
+* Handle an inspector teardown event.
+*
+* @method
+*/
+ve.ui.Context.prototype.onInspectorTeardown = function () {
+       throw new Error( 've.ui.Context.onInspectorTeardown must be overridden 
in subclass' );
+};
+
+/**
  * Hide the context.
  *
  * @method
diff --git a/modules/ve/ui/ve.ui.DesktopContext.js 
b/modules/ve/ui/ve.ui.DesktopContext.js
index 70926d1..87d8ca7 100644
--- a/modules/ve/ui/ve.ui.DesktopContext.js
+++ b/modules/ve/ui/ve.ui.DesktopContext.js
@@ -28,9 +28,6 @@
        this.relocating = false;
        this.embedded = false;
        this.selection = null;
-       this.context = new ve.ui.ContextWidget( { '$': this.$ } );
-       this.afterModelChangeTimeout = null;
-       this.afterModelChangeRange = null;
        this.$menu = this.$( '<div>' );
        this.popup = new OO.ui.PopupWidget( {
                '$': this.$,
@@ -38,10 +35,6 @@
        } );
 
        // Events
-       this.surface.getModel().connect( this, {
-               'documentUpdate': 'onModelChange',
-               'select': 'onModelChange'
-       } );
        this.surface.getView().connect( this, {
                'selectionStart': 'onSelectionStart',
                'selectionEnd': 'onSelectionEnd',
@@ -51,11 +44,6 @@
                'blur': 'onSurfaceBlur',
                'position': 'onSurfacePosition'
        } );
-       this.inspectors.connect( this, {
-               'setup': 'onInspectorSetup',
-               'teardown': 'onInspectorTeardown'
-       } );
-       this.context.connect( this, { 'choose': 'onContextItemChoose' } );
 
        this.$element.add( this.$menu )
                .on( 'mousedown', false );
@@ -76,71 +64,11 @@
 /* Methods */
 
 /**
- * Handle context item choose events.
- *
- * @param {ve.ui.ContextItemWidget} item Chosen item
- */
-ve.ui.DesktopContext.prototype.onContextItemChoose = function ( item ) {
-       if ( item ) {
-               item.getCommand().execute( this.surface );
-       }
-};
-
-/**
- * @inheritdoc
- */
-ve.ui.DesktopContext.prototype.destroy = function () {
-       // Disconnect events
-       this.surface.getModel().disconnect( this );
-       this.surface.getView().disconnect( this );
-       this.inspectors.disconnect( this );
-
-       // Stop timers
-       clearTimeout( this.afterModelChangeTimeout );
-
-       // Parent method
-       return ve.ui.Context.prototype.destroy.call( this );
-};
-
-/**
  * Handle window resize events.
  */
 ve.ui.DesktopContext.prototype.onWindowResize = function () {
        // Update, no transition
        this.update( false );
-};
-
-/**
- * Handle selection changes in the model.
- *
- * Changes are ignored while the user is selecting text or relocating content, 
apart from closing
- * the popup if it's open. While an inspector is opening or closing, all 
changes are ignored so as
- * to prevent inspectors that change the selection from within their 
open/close handlers from
- * causing issues.
- *
- * The response to selection changes is deferred to prevent close handlers 
that process
- * changes from causing this function to recurse. These responses are also 
batched for efficiency,
- * so that if there are three selection changes in the same tick, 
afterModelChange() only runs once.
- *
- * @method
- * @param {ve.Range} range Range if triggered by selection change, null 
otherwise
- * @see #afterModelChange
- */
-ve.ui.DesktopContext.prototype.onModelChange = function ( range ) {
-       var win = this.inspectors.getCurrentWindow();
-
-       if ( this.showing || this.hiding || ( win && ( win.isOpening() || 
win.isClosing() ) ) ) {
-               clearTimeout( this.afterModelChangeTimeout );
-               this.afterModelChangeTimeout = null;
-               this.afterModelChangeRange = null;
-       } else {
-               if ( this.afterModelChangeTimeout === null ) {
-                       this.afterModelChangeTimeout = setTimeout( ve.bind( 
this.afterModelChange, this ) );
-               }
-               if ( range instanceof ve.Range ) {
-                       this.afterModelChangeRange = range;
-               }
-       }
 };
 
 /**
@@ -252,11 +180,7 @@
 };
 
 /**
- * Handle an inspector setup event.
- *
- * @method
- * @param {ve.ui.Inspector} inspector Inspector that's been setup
- * @param {Object} [config] Inspector opening information
+ * @inheritdoc
  */
 ve.ui.DesktopContext.prototype.onInspectorSetup = function () {
        this.selection = this.surface.getModel().getSelection();
@@ -264,60 +188,13 @@
 };
 
 /**
- * Handle an inspector teardown event.
- *
- * @method
- * @param {ve.ui.Inspector} inspector Inspector that's been torn down
- * @param {Object} [config] Inspector closing information
+ * @inheritdoc
  */
 ve.ui.DesktopContext.prototype.onInspectorTeardown = function () {
        this.update();
        if ( this.getSurface().getModel().getSelection() ) {
                this.getSurface().getView().focus();
        }
-};
-
-/**
- * Updates the context menu.
- *
- * @method
- * @param {boolean} [transition=false] Use a smooth transition
- * @chainable
- */
-ve.ui.DesktopContext.prototype.update = function ( transition ) {
-       var i, len, match, matches,
-               items = [],
-               fragment = this.surface.getModel().getFragment( null, false ),
-               selection = fragment.getRange(),
-               inspector = this.inspectors.getCurrentWindow();
-
-       if ( inspector && selection && selection.equals( this.selection ) ) {
-               // There's an inspector, and the selection hasn't changed, 
update the position
-               this.show( transition );
-       } else {
-               // No inspector is open, or the selection has changed, show a 
menu of available inspectors
-               matches = ve.ui.toolFactory.getToolsForFragment( fragment );
-               if ( matches.length ) {
-                       // There's at least one inspectable annotation, build a 
menu and show it
-                       this.context.clearItems();
-                       for ( i = 0, len = matches.length; i < len; i++ ) {
-                               match = matches[i];
-                               items.push( new ve.ui.ContextItemWidget(
-                                       match.tool.static.name, match.tool, 
match.model, { '$': this.$ }
-                               ) );
-                       }
-                       this.context.addItems( items );
-                       this.show( transition );
-               } else if ( this.visible ) {
-                       // Nothing to inspect
-                       this.hide();
-               }
-       }
-
-       // Remember selection for next time
-       this.selection = selection && selection.clone();
-
-       return this;
 };
 
 /**
diff --git a/modules/ve/ui/ve.ui.MobileContext.js 
b/modules/ve/ui/ve.ui.MobileContext.js
index 625f3f6..c85e9f5 100644
--- a/modules/ve/ui/ve.ui.MobileContext.js
+++ b/modules/ve/ui/ve.ui.MobileContext.js
@@ -19,15 +19,12 @@
        // Parent constructor
        ve.ui.Context.call( this, surface, config );
 
-       // Events
-       this.inspectors.connect( this, {
-               'setup': 'show',
-               'teardown': 'hide'
-       } );
-
        // Initialization
        this.$element
                .addClass( 've-ui-mobileContext' )
+               .append( this.context.$element );
+
+       this.surface.$globalOverlay
                .append( this.inspectors.$element );
 };
 
@@ -38,6 +35,41 @@
 /* Methods */
 
 /**
+ * Deferred response to one or more select events.
+ *
+ * Update the context menu for the new selection, except if the user is 
selecting or relocating
+ * content. If the popup is open, close it, even while selecting or relocating.
+ */
+ve.ui.MobileContext.prototype.afterModelChange = function () {
+       var win = this.inspectors.getCurrentWindow(),
+               selectionChange = !!this.afterModelChangeRange,
+               moving = selectionChange && !( win && ( win.isOpening() || 
win.isClosing() ) );
+
+       this.afterModelChangeTimeout = null;
+       this.afterModelChangeRange = null;
+
+       // TODO this is the only big difference between MobileContext and 
DesktopContext
+       // merge this code somehow?
+       this.hide();
+
+       this.update( !moving  );
+};
+
+/**
+ * @inheritdoc
+ */
+ve.ui.MobileContext.prototype.onInspectorSetup = function () {
+       this.surface.showGlobalOverlay();
+};
+
+/**
+ * @inheritdoc
+ */
+ve.ui.MobileContext.prototype.onInspectorTeardown = function () {
+       this.surface.hideGlobalOverlay();
+};
+
+/**
  * Shows the context.
  *
  * @method
@@ -45,19 +77,13 @@
  */
 ve.ui.MobileContext.prototype.show = function () {
        this.$element.addClass( 've-ui-mobileContext-visible' );
-       this.surface.showGlobalOverlay();
+       return this;
 };
 
 /**
  * @inheritdoc
  */
 ve.ui.MobileContext.prototype.hide = function () {
-       var self = this;
-
-       this.surface.hideGlobalOverlay();
-       // Make sure that the context is hidden only after the transition
-       // of global overlay finishes (see ve.ui.MobileSurface.css).
-       setTimeout( function () {
-               self.$element.removeClass( 've-ui-mobileContext-visible' );
-       }, 300 );
+       this.$element.removeClass( 've-ui-mobileContext-visible' );
+       return this;
 };
diff --git a/modules/ve/ui/ve.ui.MobileSurface.js 
b/modules/ve/ui/ve.ui.MobileSurface.js
index 0df6f92..8a6fb27 100644
--- a/modules/ve/ui/ve.ui.MobileSurface.js
+++ b/modules/ve/ui/ve.ui.MobileSurface.js
@@ -29,8 +29,8 @@
        } );
 
        // Initialization
-       this.$globalOverlay.append( this.context.$element )
-               .addClass( 've-ui-mobileSurface-overlay 
ve-ui-mobileSurface-overlay-global' );
+       this.$globalOverlay.addClass( 've-ui-mobileSurface-overlay 
ve-ui-mobileSurface-overlay-global' );
+       this.$localOverlay.append( this.context.$element );
 };
 
 /* Inheritance */

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic4f288cdcb248b76ead57c048144c8909a16042d
Gerrit-PatchSet: 1
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: JGonera <[email protected]>

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

Reply via email to