remove safari-hacks file
This commit is contained in:
parent
7e9a21c520
commit
9157ce9303
|
@ -1,167 +0,0 @@
|
|||
import $ from "jquery";
|
||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { helperContext } from "discourse-common/lib/helpers";
|
||||
import discourseLater from "discourse-common/lib/later";
|
||||
|
||||
let workaroundActive = false;
|
||||
|
||||
export function isWorkaroundActive() {
|
||||
return workaroundActive;
|
||||
}
|
||||
|
||||
// per http://stackoverflow.com/questions/29001977/safari-in-ios8-is-scrolling-screen-when-fixed-elements-get-focus/29064810
|
||||
function positioningWorkaround(fixedElement) {
|
||||
let caps = helperContext().capabilities;
|
||||
if (!caps.isIOS) {
|
||||
return;
|
||||
}
|
||||
|
||||
document.addEventListener("scroll", () => {
|
||||
if (!caps.isIpadOS && workaroundActive) {
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
});
|
||||
|
||||
let originalScrollTop = 0;
|
||||
let lastTouchedElement = null;
|
||||
|
||||
positioningWorkaround.blur = function (evt) {
|
||||
if (workaroundActive) {
|
||||
document.body.classList.remove("ios-safari-composer-hacks");
|
||||
window.scrollTo(0, originalScrollTop);
|
||||
evt?.target?.removeEventListener("blur", blurred);
|
||||
|
||||
workaroundActive = false;
|
||||
}
|
||||
};
|
||||
|
||||
let blurredNow = function (evt) {
|
||||
// we cannot use evt.relatedTarget to get the last focused element in safari iOS
|
||||
// document.activeElement is also unreliable (iOS does not mark buttons as focused)
|
||||
// so instead, we store the last touched element and check against it
|
||||
|
||||
// cancel blur event when:
|
||||
// - switching to another iOS app
|
||||
// - displaying title field
|
||||
// - invoking a select-kit dropdown
|
||||
// - invoking mentions
|
||||
// - invoking emoji dropdown via : and hitting return
|
||||
// - invoking a button in the editor toolbar
|
||||
// - tapping on emoji in the emoji modal
|
||||
// - tapping on the upload button
|
||||
// - tapping on the edit reason icon/input
|
||||
|
||||
if (
|
||||
lastTouchedElement &&
|
||||
(document.visibilityState === "hidden" ||
|
||||
fixedElement.classList.contains("edit-title") ||
|
||||
lastTouchedElement.classList.contains("select-kit-header") ||
|
||||
lastTouchedElement.closest(".autocomplete") ||
|
||||
(lastTouchedElement.nodeName === "TEXTAREA" &&
|
||||
document.activeElement === lastTouchedElement) ||
|
||||
lastTouchedElement.closest(".d-editor-button-bar") ||
|
||||
lastTouchedElement.classList.contains("emoji") ||
|
||||
lastTouchedElement.closest(".mobile-file-upload") ||
|
||||
lastTouchedElement.closest(".display-edit-reason"))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
positioningWorkaround.blur(evt);
|
||||
};
|
||||
|
||||
let blurred = function (evt) {
|
||||
discourseDebounce(this, blurredNow, evt, INPUT_DELAY);
|
||||
};
|
||||
|
||||
let positioningHack = function (evt) {
|
||||
if (evt === undefined) {
|
||||
evt = new CustomEvent("no-op");
|
||||
}
|
||||
|
||||
// we need this, otherwise changing focus means we never clear
|
||||
this.addEventListener("blur", blurred);
|
||||
|
||||
// resets focus out of select-kit elements
|
||||
// might become redundant after select-kit refactoring
|
||||
fixedElement
|
||||
.querySelectorAll(".select-kit.is-expanded > button")
|
||||
.forEach((el) => el.click());
|
||||
fixedElement
|
||||
.querySelectorAll(".select-kit > button.is-focused")
|
||||
.forEach((el) => el.classList.remove("is-focused"));
|
||||
|
||||
if (window.pageYOffset > 0) {
|
||||
originalScrollTop = window.pageYOffset;
|
||||
}
|
||||
|
||||
let delay = caps.isIpadOS ? 350 : 150;
|
||||
|
||||
discourseLater(() => {
|
||||
if (caps.isIpadOS) {
|
||||
// disable hacks when using a hardware keyboard
|
||||
// by default, a hardware keyboard will show the keyboard accessory bar
|
||||
// whose height is currently 55px (using 75 for a bit of a buffer)
|
||||
let heightDiff = window.innerHeight - window.visualViewport.height;
|
||||
if (heightDiff < 75) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// don't trigger keyboard on disabled element (happens when a category is required)
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
document.body.classList.add("ios-safari-composer-hacks");
|
||||
window.scrollTo(0, 0);
|
||||
|
||||
evt.preventDefault();
|
||||
this.focus();
|
||||
workaroundActive = true;
|
||||
}, delay);
|
||||
};
|
||||
|
||||
let lastTouched = function (evt) {
|
||||
if (evt && evt.target) {
|
||||
lastTouchedElement = evt.target;
|
||||
}
|
||||
};
|
||||
|
||||
function attachTouchStart(elem, fn) {
|
||||
if (!$(elem).data("listening")) {
|
||||
elem.addEventListener("touchstart", fn);
|
||||
$(elem).data("listening", true);
|
||||
}
|
||||
}
|
||||
|
||||
function checkForInputs() {
|
||||
attachTouchStart(fixedElement, lastTouched);
|
||||
|
||||
fixedElement
|
||||
.querySelectorAll("input[type=text], textarea")
|
||||
.forEach((el) => {
|
||||
attachTouchStart(el, positioningHack);
|
||||
});
|
||||
}
|
||||
|
||||
function debouncedCheckForInputs() {
|
||||
discourseDebounce(checkForInputs, 100);
|
||||
}
|
||||
|
||||
positioningWorkaround.touchstartEvent = function (element) {
|
||||
let triggerHack = positioningHack.bind(element);
|
||||
triggerHack();
|
||||
};
|
||||
|
||||
const observer = new MutationObserver(debouncedCheckForInputs);
|
||||
observer.observe(fixedElement, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
attributes: false,
|
||||
characterData: false,
|
||||
});
|
||||
}
|
||||
|
||||
export default positioningWorkaround;
|
Loading…
Reference in New Issue