Fix iframe scrolling in iOS (#87)

Also some other small fixes for iOS/Android.
pull/5742/merge
Aleksander Machniak 7 years ago
parent d04d0a3078
commit aa542a35c1

@ -57,7 +57,7 @@ destination system.
RULES:
------
- Supported browsers: IE11+, Edge, Last 2 versions for Chrome/Firefox/Safari,
Android Browser 5+, iOS Safari 7+.
Android Browser 5+, iOS Safari 9+.
- Minimum supported screen width is 240px (note that even if the device screen
resolution is e.g.320x372 changing the text size in device settings will reduce

@ -38,7 +38,6 @@ html {
body {
min-width: @page-min-width;
height: 100%;
overflow: hidden;
color: @color-font;
}
@ -65,15 +64,24 @@ body > #layout {
background-color: @color-layout-content-background;
& > .formcontent, // e.g. Help plugin
& > iframe,
& > .content,
& > .content > iframe {
& > .content {
height: 100%;
width: 100%;
overflow: auto;
border: 0;
flex: 1;
}
.iframe-wrapper {
width: 100%;
height: 100%;
flex: 1;
iframe {
width: 100%;
height: 100%;
border: 0;
}
}
}
&.sidebar {
@ -92,6 +100,9 @@ body > #layout {
&.menu {
width: @layout-menu-width;
// FIXME: we set background color here not in taskmenu.less, because
// otherwise background is partially white on Android/iOS
background-color: @color-taskmenu-background;
}
& > .scroller {

@ -240,6 +240,17 @@ fieldset.image-attachment {
bottom: @layout-header-height;
}
// iOS: Fix scrolling of iframe, display scrollbars on scrollable elements
.ios-scroll {
padding: 0;
-webkit-overflow-scrolling: touch !important;
overflow: scroll !important;
&.iframe-wrapper {
margin-top: 1px; // FIXME: without this scrolling hides the wrapper neighbours' border
}
}
.quota-widget {
width: 5rem;
max-width: 8rem;

@ -311,7 +311,6 @@ html.ms .propform {
flex-direction: column;
justify-content:flex-start;
overflow-y: hidden !important;
height: 100%;
.formcontent {
overflow-x: hidden;
@ -325,17 +324,28 @@ html.ms .propform {
margin-right: .5rem;
}
}
}
html.layout-small,
html.layout-phone {
.formcontainer {
// FIXME: iOS/Android frames have some problem with form buttons element
// when the form height is bigger than the iframe height
// We got rid of the floating buttons effect to fix that,
// which is not perfect because Save button are visible only after
// the page is scrolled to the bottom
.webkit.tablet &,
.iframe.ipad &,
.iframe.iphone & {
display: block;
}
// We don't need buttons element on small devices
html.layout-small &,
html.layout-phone & {
.formbuttons {
display: none;
}
}
}
.formcontent {
padding: 1rem;

@ -97,17 +97,18 @@
}
}
}
}
.ui-dialog iframe,
.ui-dialog-content.iframe {
padding: 0 !important;
overflow: hidden !important;
iframe,
.ui-dialog-content.iframe {
padding: 0;
width: 100% !important;
height: 100%;
border: 0;
overflow: hidden;
}
}
/* FIXME: why do I need !important here? */
@media screen and (max-width: @screen-width-xs) {

@ -12,7 +12,6 @@
/*** Taskmenu ***/
#taskmenu {
background-color: @color-taskmenu-background;
height: 100%;
a {

@ -84,8 +84,10 @@
</div>
</div>
<h2 id="aria-label-contact-frame" class="voice"><roundcube:label name="contactproperties" /></h2>
<div class="iframe-wrapper">
<roundcube:object name="addressframe" id="contact-frame" src="/watermark.html" title="contactproperties"
aria-labelledby="aria-label-contact-frame" />
</div>
</div>
<!-- popup menus -->

@ -19,7 +19,7 @@
<div class="formbuttons">
<roundcube:button command="edit" class="btn btn-primary edit" label="edit" condition="!ENV:readonly" />
<roundcube:if condition="env:qrcode" />
<roundcube:button command="qrcode" class="btn qrcode" label="qrcode" />
<roundcube:button command="qrcode" class="btn btn-secondary qrcode" label="qrcode" />
<roundcube:endif />
</div>

@ -47,7 +47,9 @@
label="empty" title="empty" innerclass="inner" />
</div>
</div>
<div class="iframe-wrapper">
<roundcube:object name="folderframe" id="preferences-frame" src="/watermark.html" />
</div>
</div>
<div id="search-filter" class="popupmenu form nolist toolbarmenu" data-editable="true">

@ -37,7 +37,9 @@
condition="config:identities_level:0<2" />
</div>
</div>
<div class="iframe-wrapper">
<roundcube:object name="identityframe" id="preferences-frame" src="/watermark.html" title="arialabelidentityeditfrom" />
</div>
</div>
<roundcube:include file="includes/footer.html" />

@ -69,12 +69,14 @@
<roundcube:include file="includes/mail-menu.html" />
</div>
<h2 id="aria-label-mailpreviewframe" class="voice"><roundcube:label name="arialabelmailpreviewframe" /></h2>
<div class="iframe-wrapper">
<roundcube:object name="messagecontentframe"
id="messagecontframe"
aria-labelledby="aria-label-mailpreviewframe"
src="/watermark.html"
title="arialabelmailpreviewframe"
/>
</div>
</div>
<!-- popup menus -->

@ -53,8 +53,10 @@
</div>
</div>
<h2 id="aria-label-messagepart" class="voice"><roundcube:label name="arialabelattachmentpreview" /></h2>
<div class="iframe-wrapper">
<roundcube:object name="messagePartFrame" id="messagepartframe" title="arialabelattachmentpreview"
role="main" aria-labelledby="aria-label-messagepart" />
</div>
</div>
<roundcube:if condition="env:is_message" />

@ -35,7 +35,9 @@
class="button delete disabled" classAct="button delete" />
</div>
</div>
<div class="iframe-wrapper">
<roundcube:object name="responseframe" id="preferences-frame" src="/watermark.html" title="arialabelresonseeditfrom" />
</div>
</div>
<roundcube:include file="includes/footer.html" />

@ -21,7 +21,9 @@
<a class="button icon back-list-button" href="#back"><span class="inner"><roundcube:label name="back" /></span></a>
<span class="header-title"></span>
</div>
<div class="iframe-wrapper">
<roundcube:object name="prefsframe" id="preferences-frame" src="/watermark.html" title="arialabelpreferencesform" />
</div>
</div>
<roundcube:include file="includes/footer.html" />

@ -18,6 +18,7 @@ function rcube_elastic_ui()
var ref = this,
mode = 'normal', // one of: large, normal, small, phone
touch = false,
ios = false,
is_framed = rcmail.is_framed(),
env = {
config: {
@ -288,6 +289,10 @@ function rcube_elastic_ui()
// move "Download all attachments" button into a better location
$('#attachment-list + a.zipdownload').appendTo('.header-links');
if (ios = $('html').is('.ipad,.iphone')) {
$('.iframe-wrapper, .scroller').addClass('ios-scroll');
}
};
/**
@ -728,6 +733,10 @@ function rcube_elastic_ui()
// when loading content-frame in small-screen mode display it
layout.content.find('iframe').on('load', function(e) {
var href = '', show = true;
// Reset the scroll position of the iframe-wrapper
$(this).parent('.iframe-wrapper').scrollTop(0);
try {
href = e.target.contentWindow.location.href;
show = !href.endsWith(rcmail.env.blankpage);
@ -1015,6 +1024,16 @@ function rcube_elastic_ui()
}
screen_resize_headers();
// On iOS and Android the content frame height is never correct, fix it
if (bw.webkit) {
$('.iframe-wrapper').each(function() {
var h = $(this).height();
if (h) {
$(this).children('iframe').height(h);
}
});
}
};
/**
@ -2489,6 +2508,11 @@ function rcube_elastic_ui()
setTimeout(function() { loader.remove(); }, 500);
})
.parent().append(loader);
// fix scrolling in iOS
if (ios) {
frame.parent().addClass('ios-scroll');
}
}
};

Loading…
Cancel
Save