FIX: Quick-quote on Safari (#15631)
Some safari-specific logic was inadvertently removed during the refactoring in b2d45c59
. This commit restores it. The logic requires some state, so the getRangeBoundaryRect helper has to be moved back into the Component class. The functional change in this commit is the three lines enclosed by `if (this.capabilities.isSafari) {`.
This commit is contained in:
parent
eb4ad958c1
commit
b725b7f1fa
|
@ -46,37 +46,6 @@ function regexSafeStr(str) {
|
|||
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
|
||||
function getRangeBoundaryRect(range, atEnd) {
|
||||
// Don't mess with the original range as it results in weird behaviours
|
||||
// where certain browsers will deselect the selection
|
||||
const clone = range.cloneRange(range);
|
||||
|
||||
// create a marker element containing a single invisible character
|
||||
const markerElement = document.createElement("span");
|
||||
markerElement.appendChild(document.createTextNode("\ufeff"));
|
||||
|
||||
// on mobile, collapse the range at the end of the selection
|
||||
if (atEnd) {
|
||||
clone.collapse();
|
||||
}
|
||||
// insert the marker
|
||||
clone.insertNode(markerElement);
|
||||
|
||||
// retrieve the position of the marker
|
||||
const boundaryRect = markerElement.getBoundingClientRect();
|
||||
boundaryRect.x += document.documentElement.scrollLeft;
|
||||
boundaryRect.y += document.documentElement.scrollTop;
|
||||
|
||||
// remove the marker
|
||||
const parent = markerElement.parentNode;
|
||||
parent.removeChild(markerElement);
|
||||
|
||||
// merge back all text nodes so they don't get messed up
|
||||
parent.normalize();
|
||||
|
||||
return boundaryRect;
|
||||
}
|
||||
|
||||
export default Component.extend(KeyEnterEscape, {
|
||||
classNames: ["quote-button"],
|
||||
classNameBindings: [
|
||||
|
@ -113,6 +82,44 @@ export default Component.extend(KeyEnterEscape, {
|
|||
this.set("_fastEditNewSelection", null);
|
||||
},
|
||||
|
||||
_getRangeBoundaryRect(range, atEnd) {
|
||||
// Don't mess with the original range as it results in weird behaviours
|
||||
// where certain browsers will deselect the selection
|
||||
const clone = range.cloneRange(range);
|
||||
|
||||
// create a marker element containing a single invisible character
|
||||
const markerElement = document.createElement("span");
|
||||
markerElement.appendChild(document.createTextNode("\ufeff"));
|
||||
|
||||
// on mobile, collapse the range at the end of the selection
|
||||
if (atEnd) {
|
||||
clone.collapse();
|
||||
}
|
||||
// insert the marker
|
||||
clone.insertNode(markerElement);
|
||||
|
||||
// retrieve the position of the marker
|
||||
const boundaryRect = markerElement.getBoundingClientRect();
|
||||
boundaryRect.x += document.documentElement.scrollLeft;
|
||||
boundaryRect.y += document.documentElement.scrollTop;
|
||||
|
||||
// remove the marker
|
||||
const parent = markerElement.parentNode;
|
||||
parent.removeChild(markerElement);
|
||||
|
||||
// merge back all text nodes so they don't get messed up
|
||||
parent.normalize();
|
||||
|
||||
// work around Safari that would sometimes lose the selection
|
||||
if (this.capabilities.isSafari) {
|
||||
this._reselected = true;
|
||||
window.getSelection().removeAllRanges();
|
||||
window.getSelection().addRange(range);
|
||||
}
|
||||
|
||||
return boundaryRect;
|
||||
},
|
||||
|
||||
_selectionChanged() {
|
||||
if (this._displayFastEditInput) {
|
||||
return;
|
||||
|
@ -218,7 +225,7 @@ export default Component.extend(KeyEnterEscape, {
|
|||
const { isIOS, isAndroid, isOpera } = this.capabilities;
|
||||
const showAtEnd = isMobileDevice || isIOS || isAndroid || isOpera;
|
||||
|
||||
const boundaryPosition = getRangeBoundaryRect(firstRange, showAtEnd);
|
||||
const boundaryPosition = this._getRangeBoundaryRect(firstRange, showAtEnd);
|
||||
|
||||
// change the position of the button
|
||||
schedule("afterRender", () => {
|
||||
|
@ -273,7 +280,10 @@ export default Component.extend(KeyEnterEscape, {
|
|||
let clearOfStartHandle = true;
|
||||
if (isAndroid) {
|
||||
// On android, the start-selection handle extends below the line, so we need to avoid it as well:
|
||||
const startHandlePosition = getRangeBoundaryRect(firstRange, false);
|
||||
const startHandlePosition = this._getRangeBoundaryRect(
|
||||
firstRange,
|
||||
false
|
||||
);
|
||||
|
||||
clearOfStartHandle =
|
||||
pos.top - startHandlePosition.bottom >= safeRadius ||
|
||||
|
|
Loading…
Reference in New Issue