diff --git a/patches/@ionic+core+7.8.6.patch b/patches/@ionic+core+7.8.6.patch new file mode 100644 index 000000000..b88976d43 --- /dev/null +++ b/patches/@ionic+core+7.8.6.patch @@ -0,0 +1,154 @@ +diff --git a/node_modules/@ionic/core/components/popover.js b/node_modules/@ionic/core/components/popover.js +index 21fb3e3..52ea4a6 100644 +--- a/node_modules/@ionic/core/components/popover.js ++++ b/node_modules/@ionic/core/components/popover.js +@@ -763,8 +763,10 @@ const iosEnterAnimation = (baseEl, opts) => { + const { event: ev, size, trigger, reference, side, align } = opts; + const doc = baseEl.ownerDocument; + const isRTL = doc.dir === 'rtl'; +- const bodyWidth = doc.defaultView.innerWidth; +- const bodyHeight = doc.defaultView.innerHeight; ++ // Patched: use document.body.clientXXX instead of doc.defaultView.innerXXXX because the latter doesn't return the correct ++ // dimensions when the `zoom` CSS property is being used. ++ const bodyWidth = document.body.clientWidth; ++ const bodyHeight = document.body.clientHeight; + const root = getElementRoot(baseEl); + const contentEl = root.querySelector('.popover-content'); + const arrowEl = root.querySelector('.popover-arrow'); +@@ -884,8 +886,10 @@ const mdEnterAnimation = (baseEl, opts) => { + const { event: ev, size, trigger, reference, side, align } = opts; + const doc = baseEl.ownerDocument; + const isRTL = doc.dir === 'rtl'; +- const bodyWidth = doc.defaultView.innerWidth; +- const bodyHeight = doc.defaultView.innerHeight; ++ // Patched: use document.body.clientXXX instead of doc.defaultView.innerXXXX because the latter doesn't return the correct ++ // dimensions when the `zoom` CSS property is being used. ++ const bodyWidth = document.body.clientWidth; ++ const bodyHeight = document.body.clientHeight; + const root = getElementRoot(baseEl); + const contentEl = root.querySelector('.popover-content'); + const referenceSizeEl = trigger || ((_a = ev === null || ev === void 0 ? void 0 : ev.detail) === null || _a === void 0 ? void 0 : _a.ionShadowTarget) || (ev === null || ev === void 0 ? void 0 : ev.target); +diff --git a/node_modules/@ionic/core/dist/cjs/ion-popover.cjs.entry.js b/node_modules/@ionic/core/dist/cjs/ion-popover.cjs.entry.js +index 68a908b..050e544 100644 +--- a/node_modules/@ionic/core/dist/cjs/ion-popover.cjs.entry.js ++++ b/node_modules/@ionic/core/dist/cjs/ion-popover.cjs.entry.js +@@ -768,8 +768,10 @@ const iosEnterAnimation = (baseEl, opts) => { + const { event: ev, size, trigger, reference, side, align } = opts; + const doc = baseEl.ownerDocument; + const isRTL = doc.dir === 'rtl'; +- const bodyWidth = doc.defaultView.innerWidth; +- const bodyHeight = doc.defaultView.innerHeight; ++ // Patched: use document.body.clientXXX instead of doc.defaultView.innerXXXX because the latter doesn't return the correct ++ // dimensions when the `zoom` CSS property is being used. ++ const bodyWidth = document.body.clientWidth; ++ const bodyHeight = document.body.clientHeight; + const root = helpers.getElementRoot(baseEl); + const contentEl = root.querySelector('.popover-content'); + const arrowEl = root.querySelector('.popover-arrow'); +@@ -889,8 +891,10 @@ const mdEnterAnimation = (baseEl, opts) => { + const { event: ev, size, trigger, reference, side, align } = opts; + const doc = baseEl.ownerDocument; + const isRTL = doc.dir === 'rtl'; +- const bodyWidth = doc.defaultView.innerWidth; +- const bodyHeight = doc.defaultView.innerHeight; ++ // Patched: use document.body.clientXXX instead of doc.defaultView.innerXXXX because the latter doesn't return the correct ++ // dimensions when the `zoom` CSS property is being used. ++ const bodyWidth = document.body.clientWidth; ++ const bodyHeight = document.body.clientHeight; + const root = helpers.getElementRoot(baseEl); + const contentEl = root.querySelector('.popover-content'); + const referenceSizeEl = trigger || ((_a = ev === null || ev === void 0 ? void 0 : ev.detail) === null || _a === void 0 ? void 0 : _a.ionShadowTarget) || (ev === null || ev === void 0 ? void 0 : ev.target); +diff --git a/node_modules/@ionic/core/dist/collection/components/popover/animations/ios.enter.js b/node_modules/@ionic/core/dist/collection/components/popover/animations/ios.enter.js +index 84b30ff..528af87 100644 +--- a/node_modules/@ionic/core/dist/collection/components/popover/animations/ios.enter.js ++++ b/node_modules/@ionic/core/dist/collection/components/popover/animations/ios.enter.js +@@ -14,8 +14,10 @@ export const iosEnterAnimation = (baseEl, opts) => { + const { event: ev, size, trigger, reference, side, align } = opts; + const doc = baseEl.ownerDocument; + const isRTL = doc.dir === 'rtl'; +- const bodyWidth = doc.defaultView.innerWidth; +- const bodyHeight = doc.defaultView.innerHeight; ++ // Patched: use document.body.clientXXX instead of doc.defaultView.innerXXXX because the latter doesn't return the correct ++ // dimensions when the `zoom` CSS property is being used. ++ const bodyWidth = document.body.clientWidth; ++ const bodyHeight = document.body.clientHeight; + const root = getElementRoot(baseEl); + const contentEl = root.querySelector('.popover-content'); + const arrowEl = root.querySelector('.popover-arrow'); +diff --git a/node_modules/@ionic/core/dist/collection/components/popover/animations/md.enter.js b/node_modules/@ionic/core/dist/collection/components/popover/animations/md.enter.js +index 603923a..ff10a25 100644 +--- a/node_modules/@ionic/core/dist/collection/components/popover/animations/md.enter.js ++++ b/node_modules/@ionic/core/dist/collection/components/popover/animations/md.enter.js +@@ -14,8 +14,10 @@ export const mdEnterAnimation = (baseEl, opts) => { + const { event: ev, size, trigger, reference, side, align } = opts; + const doc = baseEl.ownerDocument; + const isRTL = doc.dir === 'rtl'; +- const bodyWidth = doc.defaultView.innerWidth; +- const bodyHeight = doc.defaultView.innerHeight; ++ // Patched: use document.body.clientXXX instead of doc.defaultView.innerXXXX because the latter doesn't return the correct ++ // dimensions when the `zoom` CSS property is being used. ++ const bodyWidth = document.body.clientWidth; ++ const bodyHeight = document.body.clientHeight; + const root = getElementRoot(baseEl); + const contentEl = root.querySelector('.popover-content'); + const referenceSizeEl = trigger || ((_a = ev === null || ev === void 0 ? void 0 : ev.detail) === null || _a === void 0 ? void 0 : _a.ionShadowTarget) || (ev === null || ev === void 0 ? void 0 : ev.target); +diff --git a/node_modules/@ionic/core/dist/esm/ion-popover.entry.js b/node_modules/@ionic/core/dist/esm/ion-popover.entry.js +index 839e91c..abcd28f 100644 +--- a/node_modules/@ionic/core/dist/esm/ion-popover.entry.js ++++ b/node_modules/@ionic/core/dist/esm/ion-popover.entry.js +@@ -764,8 +764,10 @@ const iosEnterAnimation = (baseEl, opts) => { + const { event: ev, size, trigger, reference, side, align } = opts; + const doc = baseEl.ownerDocument; + const isRTL = doc.dir === 'rtl'; +- const bodyWidth = doc.defaultView.innerWidth; +- const bodyHeight = doc.defaultView.innerHeight; ++ // Patched: use document.body.clientXXX instead of doc.defaultView.innerXXXX because the latter doesn't return the correct ++ // dimensions when the `zoom` CSS property is being used. ++ const bodyWidth = document.body.clientWidth; ++ const bodyHeight = document.body.clientHeight; + const root = getElementRoot(baseEl); + const contentEl = root.querySelector('.popover-content'); + const arrowEl = root.querySelector('.popover-arrow'); +@@ -885,8 +887,10 @@ const mdEnterAnimation = (baseEl, opts) => { + const { event: ev, size, trigger, reference, side, align } = opts; + const doc = baseEl.ownerDocument; + const isRTL = doc.dir === 'rtl'; +- const bodyWidth = doc.defaultView.innerWidth; +- const bodyHeight = doc.defaultView.innerHeight; ++ // Patched: use document.body.clientXXX instead of doc.defaultView.innerXXXX because the latter doesn't return the correct ++ // dimensions when the `zoom` CSS property is being used. ++ const bodyWidth = document.body.clientWidth; ++ const bodyHeight = document.body.clientHeight; + const root = getElementRoot(baseEl); + const contentEl = root.querySelector('.popover-content'); + const referenceSizeEl = trigger || ((_a = ev === null || ev === void 0 ? void 0 : ev.detail) === null || _a === void 0 ? void 0 : _a.ionShadowTarget) || (ev === null || ev === void 0 ? void 0 : ev.target); +diff --git a/node_modules/@ionic/core/hydrate/index.js b/node_modules/@ionic/core/hydrate/index.js +index 7f898c7..a3a7669 100644 +--- a/node_modules/@ionic/core/hydrate/index.js ++++ b/node_modules/@ionic/core/hydrate/index.js +@@ -29254,8 +29254,10 @@ const iosEnterAnimation$1 = (baseEl, opts) => { + const { event: ev, size, trigger, reference, side, align } = opts; + const doc = baseEl.ownerDocument; + const isRTL = doc.dir === 'rtl'; +- const bodyWidth = doc.defaultView.innerWidth; +- const bodyHeight = doc.defaultView.innerHeight; ++ // Patched: use document.body.clientXXX instead of doc.defaultView.innerXXXX because the latter doesn't return the correct ++ // dimensions when the `zoom` CSS property is being used. ++ const bodyWidth = document.body.clientWidth; ++ const bodyHeight = document.body.clientHeight; + const root = getElementRoot(baseEl); + const contentEl = root.querySelector('.popover-content'); + const arrowEl = root.querySelector('.popover-arrow'); +@@ -29375,8 +29377,10 @@ const mdEnterAnimation$1 = (baseEl, opts) => { + const { event: ev, size, trigger, reference, side, align } = opts; + const doc = baseEl.ownerDocument; + const isRTL = doc.dir === 'rtl'; +- const bodyWidth = doc.defaultView.innerWidth; +- const bodyHeight = doc.defaultView.innerHeight; ++ // Patched: use document.body.clientXXX instead of doc.defaultView.innerXXXX because the latter doesn't return the correct ++ // dimensions when the `zoom` CSS property is being used. ++ const bodyWidth = document.body.clientWidth; ++ const bodyHeight = document.body.clientHeight; + const root = getElementRoot(baseEl); + const contentEl = root.querySelector('.popover-content'); + const referenceSizeEl = trigger || ((_a = ev === null || ev === void 0 ? void 0 : ev.detail) === null || _a === void 0 ? void 0 : _a.ionShadowTarget) || (ev === null || ev === void 0 ? void 0 : ev.target); diff --git a/src/core/services/utils/dom.ts b/src/core/services/utils/dom.ts index e73338425..47a37c03d 100644 --- a/src/core/services/utils/dom.ts +++ b/src/core/services/utils/dom.ts @@ -14,7 +14,7 @@ import { Injectable, SimpleChange, KeyValueChanges } from '@angular/core'; import { IonContent } from '@ionic/angular'; -import { ModalOptions, PopoverOptions, AlertOptions, AlertButton, TextFieldTypes, getMode, ToastOptions } from '@ionic/core'; +import { ModalOptions, PopoverOptions, AlertOptions, AlertButton, TextFieldTypes, ToastOptions } from '@ionic/core'; import { Md5 } from 'ts-md5'; import { CoreApp } from '@services/app'; @@ -46,7 +46,6 @@ import { CoreNetworkError } from '@classes/errors/network-error'; import { CoreBSTooltipComponent } from '@components/bs-tooltip/bs-tooltip'; import { CoreViewerImageComponent } from '@features/viewer/components/image/image'; import { CoreModalLateralTransitionEnter, CoreModalLateralTransitionLeave } from '@classes/modal-lateral-transition'; -import { CoreZoomLevel } from '@features/settings/services/settings-helper'; import { CoreSites } from '@services/sites'; import { NavigationStart } from '@angular/router'; import { filter } from 'rxjs/operators'; @@ -1594,22 +1593,9 @@ export class CoreDomUtilsProvider { */ async openPopoverWithoutResult(options: Omit): Promise { const popover = await PopoverController.create(options); - const zoomLevel = await CoreConfig.get(CoreConstants.SETTINGS_ZOOM_LEVEL, CoreConstants.CONFIG.defaultZoomLevel); await popover.present(); - // Fix popover position if zoom is applied. - if (zoomLevel !== CoreZoomLevel.NONE) { - switch (getMode()) { - case 'ios': - fixIOSPopoverPosition(popover, options.event); - break; - case 'md': - fixMDPopoverPosition(popover, options.event); - break; - } - } - this.fixAriaHidden(popover); return popover; @@ -1819,159 +1805,6 @@ export class CoreDomUtilsProvider { } -/** - * Fix the position of a popover that was created with a zoom level applied in iOS. - * - * This is necessary because Ionic's implementation gets the body dimensions from `element.ownerDocument.defaultView.innerXXX`, - * which doesn't return the correct dimensions when the `zoom` CSS property is being used. This is specially necessary - * in iOS because Android already respects system font sizes. Eventually, we should find an alternative implementation for iOS - * that doesn't require this workaround (also because the `zoom` CSS property is not standard and its usage is discouraged for - * production). - * - * This function has been copied in its entirety from Ionic's source code, only changing the aforementioned calculation - * of the body dimensions with `document.body.clientXXX`. - * - * @see https://github.com/ionic-team/ionic-framework/blob/v5.6.6/core/src/components/popover/animations/ios.enter.ts - */ -function fixIOSPopoverPosition(baseEl: HTMLElement, ev?: Event): void { - let originY = 'top'; - let originX = 'left'; - - const POPOVER_IOS_BODY_PADDING = 5; - const contentEl = baseEl.querySelector('.popover-content') as HTMLElement; - const contentDimentions = contentEl.getBoundingClientRect(); - const contentWidth = contentDimentions.width; - const contentHeight = contentDimentions.height; - const bodyWidth = document.body.clientWidth; - const bodyHeight = document.body.clientHeight; - const targetDim = ev && ev.target && (ev.target as HTMLElement).getBoundingClientRect(); - const targetTop = targetDim != null && 'top' in targetDim ? targetDim.top : bodyHeight / 2 - contentHeight / 2; - const targetLeft = targetDim != null && 'left' in targetDim ? targetDim.left : bodyWidth / 2; - const targetWidth = (targetDim && targetDim.width) || 0; - const targetHeight = (targetDim && targetDim.height) || 0; - const arrowEl = baseEl.querySelector('.popover-arrow') as HTMLElement; - const arrowDim = arrowEl.getBoundingClientRect(); - const arrowWidth = arrowDim.width; - const arrowHeight = arrowDim.height; - - if (targetDim == null) { - arrowEl.style.display = 'none'; - } - - const arrowCSS = { - top: targetTop + targetHeight, - left: targetLeft + targetWidth / 2 - arrowWidth / 2, - }; - - const popoverCSS: { top: number; left: number } = { - top: targetTop + targetHeight + (arrowHeight - 1), - left: targetLeft + targetWidth / 2 - contentWidth / 2, - }; - - let checkSafeAreaLeft = false; - let checkSafeAreaRight = false; - - if (popoverCSS.left < POPOVER_IOS_BODY_PADDING + 25) { - checkSafeAreaLeft = true; - popoverCSS.left = POPOVER_IOS_BODY_PADDING; - } else if ( - contentWidth + POPOVER_IOS_BODY_PADDING + popoverCSS.left + 25 > bodyWidth - ) { - checkSafeAreaRight = true; - popoverCSS.left = bodyWidth - contentWidth - POPOVER_IOS_BODY_PADDING; - originX = 'right'; - } - - if (targetTop + targetHeight + contentHeight > bodyHeight && targetTop - contentHeight > 0) { - arrowCSS.top = targetTop - (arrowHeight + 1); - popoverCSS.top = targetTop - contentHeight - (arrowHeight - 1); - - baseEl.className = baseEl.className + ' popover-bottom'; - originY = 'bottom'; - } else if (targetTop + targetHeight + contentHeight > bodyHeight) { - contentEl.style.bottom = POPOVER_IOS_BODY_PADDING + '%'; - } - - arrowEl.style.top = arrowCSS.top + 'px'; - arrowEl.style.left = arrowCSS.left + 'px'; - - contentEl.style.top = popoverCSS.top + 'px'; - contentEl.style.left = popoverCSS.left + 'px'; - - if (checkSafeAreaLeft) { - contentEl.style.left = `calc(${popoverCSS.left}px + var(--ion-safe-area-left, 0px))`; - } - - if (checkSafeAreaRight) { - contentEl.style.left = `calc(${popoverCSS.left}px - var(--ion-safe-area-right, 0px))`; - } - - contentEl.style.transformOrigin = originY + ' ' + originX; -} - -/** - * Fix the position of a popover that was created with a zoom level applied in Android. - * - * This is necessary because Ionic's implementation gets the body dimensions from `element.ownerDocument.defaultView.innerXXX`, - * which doesn't return the correct dimensions when the `zoom` CSS property is being used. This is only a temporary solution - * in Android because system zooming is already supported, so it won't be necessary to do it at an app level. - * - * @todo MOBILE-3790 remove the ability to zoom in Android. - * - * This function has been copied in its entirety from Ionic's source code, only changing the aforementioned calculation - * of the body dimensions with `document.body.clientXXX`. - * - * @see https://github.com/ionic-team/ionic-framework/blob/v5.6.6/core/src/components/popover/animations/md.enter.ts - */ -function fixMDPopoverPosition(baseEl: HTMLElement, ev?: Event): void { - const POPOVER_MD_BODY_PADDING = 12; - const isRTL = document.dir === 'rtl'; - - let originY = 'top'; - let originX = isRTL ? 'right' : 'left'; - - const contentEl = baseEl.querySelector('.popover-content') as HTMLElement; - const contentDimentions = contentEl.getBoundingClientRect(); - const contentWidth = contentDimentions.width; - const contentHeight = contentDimentions.height; - const bodyWidth = document.body.clientWidth; - const bodyHeight = document.body.clientHeight; - const targetDim = ev && ev.target && (ev.target as HTMLElement).getBoundingClientRect(); - const targetTop = targetDim != null && 'bottom' in targetDim - ? targetDim.bottom - : bodyHeight / 2 - contentHeight / 2; - const targetLeft = targetDim != null && 'left' in targetDim - ? isRTL - ? targetDim.left - contentWidth + targetDim.width - : targetDim.left - : bodyWidth / 2 - contentWidth / 2; - const targetHeight = (targetDim && targetDim.height) || 0; - const popoverCSS: { top: number; left: number } = { - top: targetTop, - left: targetLeft, - }; - - if (popoverCSS.left < POPOVER_MD_BODY_PADDING) { - popoverCSS.left = POPOVER_MD_BODY_PADDING; - originX = 'left'; - } else if (contentWidth + POPOVER_MD_BODY_PADDING + popoverCSS.left > bodyWidth) { - popoverCSS.left = bodyWidth - contentWidth - POPOVER_MD_BODY_PADDING; - originX = 'right'; - } - - if (targetTop + targetHeight + contentHeight > bodyHeight && targetTop - contentHeight > 0) { - popoverCSS.top = targetTop - contentHeight - targetHeight; - baseEl.className = baseEl.className + ' popover-bottom'; - originY = 'bottom'; - } else if (targetTop + targetHeight + contentHeight > bodyHeight) { - contentEl.style.bottom = POPOVER_MD_BODY_PADDING + 'px'; - } - - contentEl.style.top = popoverCSS.top + 'px'; - contentEl.style.left = popoverCSS.left + 'px'; - contentEl.style.transformOrigin = originY + ' ' + originX; -} - export const CoreDomUtils = makeSingleton(CoreDomUtilsProvider); /**