FIX: workaround for Safari on iOS causing crazy composer positioning
see: http://stackoverflow.com/questions/29001977/safari-in-ios8-is-scrolling-screen-when-fixed-elements-get-focus
This commit is contained in:
parent
92e371f0b3
commit
1bdce815e2
|
@ -0,0 +1,61 @@
|
|||
function applicable() {
|
||||
|
||||
// CriOS is Chrome on iPad / iPhone, OPiOS is Opera (they need no patching)
|
||||
// Dolphin has a wierd user agent, rest seem a bit nitch
|
||||
return navigator.userAgent.match(/(iPad|iPhone|iPod)/g) &&
|
||||
navigator.userAgent.match(/Safari/g) &&
|
||||
!navigator.userAgent.match(/CriOS/g) &&
|
||||
!navigator.userAgent.match(/OPiOS/g);
|
||||
}
|
||||
|
||||
// per http://stackoverflow.com/questions/29001977/safari-in-ios8-is-scrolling-screen-when-fixed-elements-get-focus/29064810
|
||||
function positioningWorkaround($fixedElement) {
|
||||
if (!applicable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fixedElement = $fixedElement[0];
|
||||
|
||||
|
||||
var positioningHack = function(evt){
|
||||
|
||||
const self = this;
|
||||
|
||||
if (fixedElement.style.position !== 'absolute') {
|
||||
evt.preventDefault();
|
||||
fixedElement.style.position = 'absolute';
|
||||
fixedElement.style.top = (window.scrollY + $('.d-header').height() + 10) + 'px';
|
||||
}
|
||||
|
||||
var blurred = function() {
|
||||
if (_.include($(document.activeElement).parents(), fixedElement)) {
|
||||
// something in focus so skip
|
||||
return;
|
||||
}
|
||||
fixedElement.style.position = '';
|
||||
fixedElement.style.top = '';
|
||||
self.removeEventListener('blur', blurred);
|
||||
};
|
||||
|
||||
blurred = _.debounce(blurred, 300);
|
||||
|
||||
if (this !== document.activeElement) {
|
||||
self.focus();
|
||||
}
|
||||
|
||||
self.addEventListener('blur', blurred);
|
||||
};
|
||||
|
||||
const checkForInputs = _.debounce(function(){
|
||||
$fixedElement.find('input,textarea').each(function(){
|
||||
if (!$(this).data('listening')) {
|
||||
this.addEventListener('touchstart', positioningHack);
|
||||
$(this).data('listening', true);
|
||||
}
|
||||
});
|
||||
}, 100);
|
||||
|
||||
fixedElement.addEventListener('DOMNodeInserted', checkForInputs);
|
||||
}
|
||||
|
||||
export default positioningWorkaround;
|
|
@ -2,6 +2,7 @@ import userSearch from 'discourse/lib/user-search';
|
|||
import afterTransition from 'discourse/lib/after-transition';
|
||||
import loadScript from 'discourse/lib/load-script';
|
||||
import avatarTemplate from 'discourse/lib/avatar-template';
|
||||
import positioningWorkaround from 'discourse/lib/safari-hacks';
|
||||
|
||||
const ComposerView = Discourse.View.extend(Ember.Evented, {
|
||||
_lastKeyTimeout: null,
|
||||
|
@ -122,6 +123,9 @@ const ComposerView = Discourse.View.extend(Ember.Evented, {
|
|||
afterTransition($replyControl, this.resize.bind(self));
|
||||
this.ensureMaximumDimensionForImagesInPreview();
|
||||
this.set('controller.view', this);
|
||||
|
||||
positioningWorkaround(this.$());
|
||||
|
||||
}.on('didInsertElement'),
|
||||
|
||||
_unlinkView: function() {
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//= require ./discourse/lib/after-transition
|
||||
//= require ./discourse/lib/debounce
|
||||
//= require ./discourse/lib/avatar-template
|
||||
//= require ./discourse/lib/safari-hacks
|
||||
//= require_tree ./discourse/adapters
|
||||
//= require ./discourse/models/model
|
||||
//= require ./discourse/models/user_action
|
||||
|
|
Loading…
Reference in New Issue