diff --git a/modules/ve-mw/init/styles/ve.init.mw.MobileArticleTarget.less b/modules/ve-mw/init/styles/ve.init.mw.MobileArticleTarget.less index 15d2d699a1..09e2e5ff2d 100644 --- a/modules/ve-mw/init/styles/ve.init.mw.MobileArticleTarget.less +++ b/modules/ve-mw/init/styles/ve.init.mw.MobileArticleTarget.less @@ -171,3 +171,11 @@ .ve-init-mw-mobileArticleTarget-pageToolbar-hidden { display: none; } + +.ve-init-mw-mobileArticleTarget-iosScreenMeasure { + position: absolute; + top: 0; + left: 0; + height: 100vh; + width: 1px; +} diff --git a/modules/ve-mw/init/targets/ve.init.mw.MobileArticleTarget.js b/modules/ve-mw/init/targets/ve.init.mw.MobileArticleTarget.js index 9a5dcf1dc8..e83cc09d1d 100644 --- a/modules/ve-mw/init/targets/ve.init.mw.MobileArticleTarget.js +++ b/modules/ve-mw/init/targets/ve.init.mw.MobileArticleTarget.js @@ -117,6 +117,34 @@ ve.init.mw.MobileArticleTarget.prototype.activateSurfaceForToolbar = function () } }; +ve.init.mw.MobileArticleTarget.prototype.updateIosContextPadding = function () { + var browserMenuCollapsedHeight, currentHeight; + + if ( !this.$screenMeasure ) { + this.$screenMeasure = $( '
' ).addClass( 've-init-mw-mobileArticleTarget-iosScreenMeasure' ); + } + + this.$screenMeasure.appendTo( document.body ); + // This element is sized using 'vh' units, which iOS does not actually update to match the + // viewport when viewport size changes due to browser menu bar collapsing/expanding. + browserMenuCollapsedHeight = this.$screenMeasure.height(); + this.$screenMeasure.detach(); + + currentHeight = window.innerHeight; + + if ( browserMenuCollapsedHeight === currentHeight ) { + // Looks like the browser menu bar is collapsed. Tapping near the bottom of the screen will not + // trigger any events on our widgets, but instead it will expand the browser menu bar. Reserve + // some space where the browser menu bar will appear. + this.surface.getContext().$element.css( 'padding-bottom', 44 ); + } else { + // Looks like the browser menu is expanded, so we can remove the silly padding. Even if our + // check here breaks in future versions of iOS, that's okay, the user will just need to tap + // things in this area twice. + this.surface.getContext().$element.css( 'padding-bottom', 0 ); + } +}; + /** * @inheritdoc */ @@ -126,6 +154,10 @@ ve.init.mw.MobileArticleTarget.prototype.onContainerScroll = function () { surfaceView = this.surface && this.surface.getView(); isActiveWithKeyboard = surfaceView && surfaceView.isFocused() && !surfaceView.isDeactivated(); + if ( ve.init.platform.constructor.static.isIos() && ve.newMobileContext ) { + this.updateIosContextPadding(); + } + $header = this.overlay.$el.find( '.overlay-header-container' ); $overlaySurface = this.$overlaySurface;