From 1e1e9295d8a69e8707f09e56b42df9c61ff9b9bf Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Fri, 29 Nov 2024 13:19:18 +0000 Subject: [PATCH 01/14] Fix dark styles --- www/-/s/style-dark.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/www/-/s/style-dark.css b/www/-/s/style-dark.css index d4b1e7c6c..daf6e37fb 100644 --- a/www/-/s/style-dark.css +++ b/www/-/s/style-dark.css @@ -1,4 +1,4 @@ - + /* Wikipedia Dark Theme v1.0.23 (1/17/2017) * https://github.com/StylishThemes/Wikipedia-Dark * http://userstyles.org/styles/ @@ -14,7 +14,7 @@ */ /* transparent background */ -div, span:not(.legend-color):not([class*="wikEd"]):not([style*="background"]), .MainPageBG, .navbox-list, +div:not(.kiwixtooltip), span:not(.legend-color):not([class*="wikEd"]):not([style*="background"]), .MainPageBG, .navbox-list, div#mw-head, .mw-wsmfinal-content, #bodyContent, .referencetooltip > li + li, div.vectorTabs ul li, tr[style*="background:#F5FFFA"], th[style*="background-color: #fff"], .mw-echo-notifications-badge, @@ -24,7 +24,7 @@ th[style*="background-color: #fff"], .mw-echo-notifications-badge, } /*** Overall ***/ -p, li, td:not([style*="background"]), th:not([style*="background"]), caption, div { +p, li, td:not([style*="background"]), th:not([style*="background"]), caption, div:not(.kiwixtooltip) { color: lightgray !important; background-image: none !important; } @@ -170,7 +170,7 @@ tr[style*="background: antiquewhite"], tr[style*="background-color:#ee"], tr[sty .mw-ui-button[style*="background"], .mw-ui-button[style*="background"] *, .wikiEditor-ui, table.navbox.collapsible tr:nth-child(2) > td, div.menu, div.NavHead, .oo-ui-popupWidget-popup, .oo-ui-buttonElement-button, .mw-notification, .mwe-popups, .mwe-popups-is-not-tall, .mwe-popups-is-tall, -.ui-widget-content, .oo-ui-window-body, #pagehistory li.selected, .tracklist tr, .dataTable tr, div.kiwixtooltip { +.ui-widget-content, .oo-ui-window-body, #pagehistory li.selected, .tracklist tr, .dataTable tr { background-color: #222 !important; } From bde095bef0f699c766406d87a89a87964b3e3bfc Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Fri, 29 Nov 2024 13:19:27 +0000 Subject: [PATCH 02/14] Cleanup --- www/js/app.js | 75 +++++++++++++++++++++++---------------------------- 1 file changed, 34 insertions(+), 41 deletions(-) diff --git a/www/js/app.js b/www/js/app.js index fd8e846c8..4d4cbb974 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -688,38 +688,40 @@ document.getElementById('btnForward').addEventListener('click', function () { history.forward(); }); document.getElementById('btnZoomin').addEventListener('click', function () { - params.relativeFontSize += 5; - var doc = document.getElementById('articleContent').contentDocument; - var docElStyle = doc.documentElement.style; - // IE11 and Firefox need to use fontSize on the body style - var zoomProp = '-ms-zoom' in docElStyle ? 'fontSize' : 'zoom' in docElStyle ? 'zoom' : 'fontSize'; - docElStyle = zoomProp === 'fontSize' ? doc.body.style : docElStyle; - docElStyle[zoomProp] = /-\/static\/main\.css|statc\/css\/sotoki.css/.test(doc.head.innerHTML) && zoomProp === 'fontSize' ? params.relativeFontSize * 1.5 + '%' : params.relativeFontSize + '%'; - var lblZoom = document.getElementById('lblZoom'); - lblZoom.innerHTML = params.relativeFontSize + '%'; - lblZoom.style.cssText = 'position:absolute;right:' + window.innerWidth / 5 + 'px;bottom:50px;z-index:50;'; - setTimeout(function () { - lblZoom.innerHTML = ''; - }, 2000); - settingsStore.setItem('relativeFontSize', params.relativeFontSize, Infinity); - document.getElementById('articleContent').contentWindow.focus(); + params.relativeFontSize = Math.min(200, params.relativeFontSize + 5); + setArticleZoom(params.relativeFontSize, true); }); document.getElementById('btnZoomout').addEventListener('click', function () { - params.relativeFontSize -= 5; - var doc = document.getElementById('articleContent').contentDocument; - var docElStyle = doc.documentElement.style; - var zoomProp = '-ms-zoom' in docElStyle ? 'fontSize' : 'zoom' in docElStyle ? 'zoom' : 'fontSize'; - docElStyle = zoomProp === 'fontSize' ? doc.body.style : docElStyle; - docElStyle[zoomProp] = /-\/static\/main\.css|statc\/css\/sotoki.css/.test(doc.head.innerHTML) && zoomProp === 'fontSize' ? params.relativeFontSize * 1.5 + '%' : params.relativeFontSize + '%'; - var lblZoom = document.getElementById('lblZoom'); - lblZoom.innerHTML = params.relativeFontSize + '%'; - lblZoom.style.cssText = 'position:absolute;right:' + window.innerWidth / 4 + 'px;bottom:50px;z-index:50;'; - setTimeout(function () { - lblZoom.innerHTML = ''; - }, 2000); - settingsStore.setItem('relativeFontSize', params.relativeFontSize, Infinity); - document.getElementById('articleContent').contentWindow.focus(); + params.relativeFontSize = Math.max(50, params.relativeFontSize - 5); + setArticleZoom(params.relativeFontSize, true); }); +let zoomLabelTimeout; +function setArticleZoom (zoomLevel, set) { + const doc = document.getElementById('articleContent').contentDocument; + const root = doc.documentElement; + const percentageFontSize = zoomLevel + '%'; + // Set CSS fontSize and zoom if supported + // Note that the zoom property is supported in Firefox since May 2024, but it doesn't + // scale the font size at least in Wikipedia pages, so we need to set fontSize as well + root.style.fontSize = percentageFontSize; + if ('zoom' in root.style) { + root.style.zoom = percentageFontSize; + } + // If we are setting a value from the UI, update the display and settings + if (set) { + // Update zoom label + const lblZoom = document.getElementById('lblZoom'); + lblZoom.innerHTML = percentageFontSize; + lblZoom.style.cssText = 'position:absolute;right:' + window.innerWidth / 4 + 'px;bottom:50px;z-index:50;'; + // Clear and set timeout to hide zoom label + if (zoomLabelTimeout) clearTimeout(zoomLabelTimeout); + zoomLabelTimeout = setTimeout(function () { + lblZoom.innerHTML = ''; + }, 2500); + settingsStore.setItem('relativeFontSize', zoomLevel, Infinity); + document.getElementById('articleContent').contentWindow.focus(); + } +} setRelativeUIFontSize(params.relativeUIFontSize); document.getElementById('relativeUIFontSizeSlider').addEventListener('change', function () { setRelativeUIFontSize(this.value); @@ -5427,13 +5429,7 @@ var articleLoadedSW = function (dirEntry, container) { if (!appstate.isReplayWorkerAvailable) switchCSSTheme(); // Gets called in articleLoader for replay_iframe if (appstate.selectedArchive.zimType === 'open') { // Set relative font size + Stackexchange-family multiplier - var zimType = /-\/s\/style\.css/i.test(doc.head.innerHTML) ? 'desktop' : 'mobile'; - zimType = /-\/static\/main\.css|statc\/css\/sotoki.css/i.test(doc.head.innerHTML) ? 'desktop-stx' : zimType; // Support stackexchange - zimType = /minerva|mobile[^"']*\.css/i.test(doc.head.innerHTML) ? 'mobile' : zimType; - var docElStyle = doc.documentElement.style; - var zoomProp = '-ms-zoom' in docElStyle ? 'fontSize' : 'zoom' in docElStyle ? 'zoom' : 'fontSize'; - docElStyle = zoomProp === 'fontSize' ? docBody.style : docElStyle; - docElStyle[zoomProp] = ~zimType.indexOf('stx') && zoomProp === 'fontSize' ? params.relativeFontSize * 1.5 + '%' : params.relativeFontSize + '%'; + setArticleZoom(params.relativeFontSize); if (!params.isLandingPage) openAllSections(); } checkToolbar(); @@ -6626,11 +6622,8 @@ function displayArticleContentInContainer (dirEntry, htmlArticle) { if (params.lockDisplayOrientation) articleWindow.addEventListener('mousedown', refreshFullScreen, true); setupTableOfContents(); } - // Set relative font size + Stackexchange-family multiplier - var docElStyle = articleDocument.style; - var zoomProp = '-ms-zoom' in docElStyle ? 'fontSize' : 'zoom' in docElStyle ? 'zoom' : 'fontSize'; - docElStyle = zoomProp === 'fontSize' ? docBody.style : docElStyle; - docElStyle[zoomProp] = zimType && ~zimType.indexOf('stx') && zoomProp === 'fontSize' ? params.relativeFontSize * 1.5 + '%' : params.relativeFontSize + '%'; + // Set relative font size + setArticleZoom(params.relativeFontSize); // Set page width according to user preference removePageMaxWidth(); setupHeadings(); From aec69c090b8f5b423cac43f601f21d12f5086f38 Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Fri, 29 Nov 2024 13:19:56 +0000 Subject: [PATCH 03/14] Fix for new functionality of getBoundingClient --- www/js/lib/popovers.js | 44 ++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/www/js/lib/popovers.js b/www/js/lib/popovers.js index b48b09e89..e88b8f00b 100644 --- a/www/js/lib/popovers.js +++ b/www/js/lib/popovers.js @@ -178,9 +178,9 @@ function getImageHTMLFromNode (node, baseURL, pathPrefix) { * @param {Boolean} dark An optional parameter to adjust the background colour for dark themes (generally not needed for inversion-based themes) */ function attachKiwixPopoverCss (doc, dark) { - const colour = dark && !/invert/i.test(params.cssTheme) ? 'darkgray' : 'black'; - const backgroundColour = dark && !/invert/i.test(params.cssTheme) ? '#111' : '#ebf4fb'; - const borderColour = dark ? 'darkslategray' : 'skyblue'; + const colour = dark && !/invert/i.test(params.cssTheme) ? 'lightgray' : 'black'; + const backgroundColour = dark && !/invert/i.test(params.cssTheme) ? '#121e1e' : '#ebf4fb'; + const borderColour = 'skyblue !important'; // DEV: Firefox OS blocks loading stylesheet files into iframe DOM content even if it is same origin, so we are forced to insert a style element instead uiUtil.insertLinkElement(doc, ` .kiwixtooltip { @@ -333,6 +333,7 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { div.popoverisloading = true; const screenWidth = win.innerWidth - 40; const screenHeight = document.documentElement.clientHeight; + const zoomFactor = params.relativeFontSize / 100; let margin = 40; let divWidth = 512; if (screenWidth <= divWidth) { @@ -352,40 +353,49 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { // DEV: We need to insert the div into the target document before we can obtain its computed dimensions accurately currentDocument.body.appendChild(div); // Calculate the position of the link that is being hovered - const linkRect = anchor.getBoundingClientRect(); + const linkRect = anchor.getBoundingClientRect().toJSON(); + // Note that since Chromium 128 getBoundingClientRect() now returns zoom-adjusted values, but if this is the case, + // then currentCSSZoom will be defined as well, so we can adjust for this. Note that UWP also requires adjustment. + if (/UWP/.test(params.appType) || anchor.currentCSSZoom) { + linkRect.top = linkRect.top / zoomFactor; + linkRect.bottom = linkRect.bottom / zoomFactor; + linkRect.left = linkRect.left / zoomFactor; + linkRect.right = linkRect.right / zoomFactor; + linkRect.width = linkRect.width / zoomFactor; + } // Initially position the div 20px above the link + const spacing = 20; let triangleDirection = 'top'; - const divOffsetHeight = /UWP/.test(params.appType) ? div.offsetHeight * params.relativeFontSize / 100 + 20 : div.offsetHeight + 20; + const divOffsetHeight = /UWP/.test(params.appType) ? div.offsetHeight / zoomFactor + spacing : div.offsetHeight + spacing; let divRectY = linkRect.top - divOffsetHeight; if (/UWP/.test(params.appType)) divRectY = divRectY * 100 / params.relativeFontSize; let triangleY = divHeight + 6; // If we're less than half margin from the top, move the div below the link if (divRectY < margin / 2) { triangleDirection = 'bottom'; - divRectY = linkRect.bottom + 20; + divRectY = linkRect.bottom + spacing; triangleY = -16; - if (/UWP/.test(params.appType)) divRectY = divRectY * 100 / params.relativeFontSize; } // Position it horizontally in relation to the pointer position let divRectX, triangleX; if (event.type === 'touchstart') { divRectX = event.touches[0].clientX - divWidth / 2; - triangleX = event.touches[0].clientX - divRectX - 20; + triangleX = event.touches[0].clientX - divRectX - spacing; } else if (event.type === 'focus') { - divRectX = linkRect.left + linkRect.width / 2 - divWidth / 2; - triangleX = linkRect.left + linkRect.width / 2 - divRectX - 20; + divRectX = linkRect.left * zoomFactor + linkRect.width / 2 - divWidth / 2; + triangleX = linkRect.left * zoomFactor + linkRect.width / 2 - divRectX - spacing; } else { divRectX = event.clientX - divWidth / 2; - triangleX = event.clientX - divRectX - 20; + triangleX = event.clientX - divRectX - spacing; } // If right edge of div is greater than margin from the right side of window, shift it to margin - if (divRectX + divWidth * params.relativeFontSize / 100 > screenWidth - margin) { + if (divRectX + divWidth * zoomFactor > screenWidth - margin) { triangleX += divRectX; - divRectX = screenWidth - divWidth * params.relativeFontSize / 100 - margin; + divRectX = screenWidth - divWidth * zoomFactor - margin; triangleX -= divRectX; } // If we're less than margin to the left, shift it to margin px from left - if (divRectX * params.relativeFontSize / 100 < margin) { + if (divRectX * zoomFactor < margin) { triangleX += divRectX; divRectX = margin; triangleX -= divRectX; @@ -394,9 +404,9 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { if (triangleX < 10) triangleX = 10; if (triangleX > divWidth - 10) triangleX = divWidth - 10; // Adjust positions to take into account the font zoom factor - divRectX = divRectX * 100 / params.relativeFontSize; - triangleX = triangleX * 100 / params.relativeFontSize; - const adjustedScrollY = win.scrollY * 100 / params.relativeFontSize; + const adjustedScrollY = win.scrollY / zoomFactor; + divRectX = divRectX / zoomFactor; + triangleX = triangleX / zoomFactor; // Now set the calculated x and y positions div.style.top = divRectY + adjustedScrollY + 'px'; div.style.left = divRectX + 'px'; From 0c55db65afc4081efc8c1b67e89b68536f3ebb44 Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Sat, 30 Nov 2024 06:58:34 +0000 Subject: [PATCH 04/14] Set zoom level when printing Fixes #676. --- www/js/app.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/www/js/app.js b/www/js/app.js index 4d4cbb974..32027d397 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -414,6 +414,7 @@ function printCleanup () { // We don't need a radical cleanup because there was no printIntercept removePageMaxWidth(); setTab(); + setArticleZoom(params.relativeFontSize); params.cssTheme = settingsStore.getItem('cssTheme') || 'light'; if (document.getElementById('cssWikiDarkThemeDarkReaderCheck').checked) { // It seems darkReader has been auto-turned on, so we need to respect that @@ -522,6 +523,8 @@ function printIntercept () { removePageMaxWidth(); params.removePageMaxWidth = tempPageMaxWidth; } + // Reset zoom level to 100% + setArticleZoom(100); // Put doc into light mode params.cssTheme = 'light'; switchCSSTheme(); @@ -697,8 +700,7 @@ document.getElementById('btnZoomout').addEventListener('click', function () { }); let zoomLabelTimeout; function setArticleZoom (zoomLevel, set) { - const doc = document.getElementById('articleContent').contentDocument; - const root = doc.documentElement; + const root = articleDocument.documentElement || articleDocument; const percentageFontSize = zoomLevel + '%'; // Set CSS fontSize and zoom if supported // Note that the zoom property is supported in Firefox since May 2024, but it doesn't From 8af5642ff8c85421dbe4e888a38bf701084d5ff9 Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Sat, 30 Nov 2024 11:09:05 +0000 Subject: [PATCH 05/14] Fix for browsers with no zoom --- www/js/lib/popovers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/js/lib/popovers.js b/www/js/lib/popovers.js index e88b8f00b..dcb735e60 100644 --- a/www/js/lib/popovers.js +++ b/www/js/lib/popovers.js @@ -333,7 +333,7 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { div.popoverisloading = true; const screenWidth = win.innerWidth - 40; const screenHeight = document.documentElement.clientHeight; - const zoomFactor = params.relativeFontSize / 100; + const zoomFactor = 'zoom' in currentDocument.documentElement.style ? params.relativeFontSize / 100 : 1; let margin = 40; let divWidth = 512; if (screenWidth <= divWidth) { From 1aa1c91a0f9a52fbca479891fc6f1cfb359e95a2 Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Sat, 30 Nov 2024 12:53:46 +0000 Subject: [PATCH 06/14] Support for Edge legay --- www/js/lib/popovers.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/www/js/lib/popovers.js b/www/js/lib/popovers.js index dcb735e60..facf25c52 100644 --- a/www/js/lib/popovers.js +++ b/www/js/lib/popovers.js @@ -353,7 +353,14 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { // DEV: We need to insert the div into the target document before we can obtain its computed dimensions accurately currentDocument.body.appendChild(div); // Calculate the position of the link that is being hovered - const linkRect = anchor.getBoundingClientRect().toJSON(); + const rect = anchor.getBoundingClientRect(); + const linkRect = { + top: rect.top, + bottom: rect.bottom, + left: rect.left, + right: rect.right, + width: rect.width + }; // Note that since Chromium 128 getBoundingClientRect() now returns zoom-adjusted values, but if this is the case, // then currentCSSZoom will be defined as well, so we can adjust for this. Note that UWP also requires adjustment. if (/UWP/.test(params.appType) || anchor.currentCSSZoom) { From 74b2d5a3537c115fa1c4a1c5a194708f22ee6731 Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Sat, 30 Nov 2024 14:12:38 +0000 Subject: [PATCH 07/14] Remove redundant UWP code --- www/js/lib/popovers.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/www/js/lib/popovers.js b/www/js/lib/popovers.js index facf25c52..24e30f92e 100644 --- a/www/js/lib/popovers.js +++ b/www/js/lib/popovers.js @@ -373,9 +373,8 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { // Initially position the div 20px above the link const spacing = 20; let triangleDirection = 'top'; - const divOffsetHeight = /UWP/.test(params.appType) ? div.offsetHeight / zoomFactor + spacing : div.offsetHeight + spacing; + let divOffsetHeight = div.offsetHeight + spacing; let divRectY = linkRect.top - divOffsetHeight; - if (/UWP/.test(params.appType)) divRectY = divRectY * 100 / params.relativeFontSize; let triangleY = divHeight + 6; // If we're less than half margin from the top, move the div below the link if (divRectY < margin / 2) { From b415309da5a8571f8d2b862ff77760996143816d Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Sat, 30 Nov 2024 14:23:35 +0000 Subject: [PATCH 08/14] Fix for Edge Legacy --- www/js/lib/popovers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/js/lib/popovers.js b/www/js/lib/popovers.js index 24e30f92e..70286599b 100644 --- a/www/js/lib/popovers.js +++ b/www/js/lib/popovers.js @@ -363,7 +363,7 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { }; // Note that since Chromium 128 getBoundingClientRect() now returns zoom-adjusted values, but if this is the case, // then currentCSSZoom will be defined as well, so we can adjust for this. Note that UWP also requires adjustment. - if (/UWP/.test(params.appType) || anchor.currentCSSZoom) { + if (/UWP/.test(params.appType) || 'MSBlobBuilder' in window || anchor.currentCSSZoom) { linkRect.top = linkRect.top / zoomFactor; linkRect.bottom = linkRect.bottom / zoomFactor; linkRect.left = linkRect.left / zoomFactor; @@ -373,7 +373,7 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { // Initially position the div 20px above the link const spacing = 20; let triangleDirection = 'top'; - let divOffsetHeight = div.offsetHeight + spacing; + const divOffsetHeight = div.offsetHeight + spacing; let divRectY = linkRect.top - divOffsetHeight; let triangleY = divHeight + 6; // If we're less than half margin from the top, move the div below the link From 605ee721fa1d9a4023281e035216f2bbbf00032b Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Sat, 30 Nov 2024 15:34:17 +0000 Subject: [PATCH 09/14] Add Safari --- www/js/lib/popovers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/js/lib/popovers.js b/www/js/lib/popovers.js index 70286599b..e1dd54a75 100644 --- a/www/js/lib/popovers.js +++ b/www/js/lib/popovers.js @@ -363,7 +363,7 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { }; // Note that since Chromium 128 getBoundingClientRect() now returns zoom-adjusted values, but if this is the case, // then currentCSSZoom will be defined as well, so we can adjust for this. Note that UWP also requires adjustment. - if (/UWP/.test(params.appType) || 'MSBlobBuilder' in window || anchor.currentCSSZoom) { + if (/UWP/.test(params.appType) || 'MSBlobBuilder' in window || anchor.currentCSSZoom || window.safari) { linkRect.top = linkRect.top / zoomFactor; linkRect.bottom = linkRect.bottom / zoomFactor; linkRect.left = linkRect.left / zoomFactor; From 80770cc708d4eca7069247114e8bfb0af0818f31 Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Sat, 30 Nov 2024 16:02:35 +0000 Subject: [PATCH 10/14] Add test for Safari --- www/js/lib/popovers.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/www/js/lib/popovers.js b/www/js/lib/popovers.js index e1dd54a75..9317c0dc2 100644 --- a/www/js/lib/popovers.js +++ b/www/js/lib/popovers.js @@ -363,7 +363,7 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { }; // Note that since Chromium 128 getBoundingClientRect() now returns zoom-adjusted values, but if this is the case, // then currentCSSZoom will be defined as well, so we can adjust for this. Note that UWP also requires adjustment. - if (/UWP/.test(params.appType) || 'MSBlobBuilder' in window || anchor.currentCSSZoom || window.safari) { + if (/UWP/.test(params.appType) || 'MSBlobBuilder' in window || anchor.currentCSSZoom || needsZoomAdjustment()) { linkRect.top = linkRect.top / zoomFactor; linkRect.bottom = linkRect.bottom / zoomFactor; linkRect.left = linkRect.left / zoomFactor; @@ -434,6 +434,20 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { return { div: div, span: span }; } +function needsZoomAdjustment () { + // Create a test element + const test = document.createElement('div'); + test.style.width = '100px'; + test.style.position = 'absolute'; + test.style.visibility = 'hidden'; + document.body.appendChild(test); + // Compare getBoundingClientRect() with offsetWidth + const rect = test.getBoundingClientRect(); + const needsAdjustment = Math.round(rect.width) !== test.offsetWidth; + document.body.removeChild(test); + return needsAdjustment; +}; + /** * Adds event listeners to the popover's control icons * @param {Element} anchor The anchor which launched the popover From d6b0c1fdeb2cfefc74336a73839c6a543539e977 Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Sat, 30 Nov 2024 16:09:16 +0000 Subject: [PATCH 11/14] Try test for Safari --- www/js/lib/popovers.js | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/www/js/lib/popovers.js b/www/js/lib/popovers.js index 9317c0dc2..240bea346 100644 --- a/www/js/lib/popovers.js +++ b/www/js/lib/popovers.js @@ -363,7 +363,7 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { }; // Note that since Chromium 128 getBoundingClientRect() now returns zoom-adjusted values, but if this is the case, // then currentCSSZoom will be defined as well, so we can adjust for this. Note that UWP also requires adjustment. - if (/UWP/.test(params.appType) || 'MSBlobBuilder' in window || anchor.currentCSSZoom || needsZoomAdjustment()) { + if (/UWP/.test(params.appType) || 'MSBlobBuilder' in window || anchor.currentCSSZoom || isSafari()) { linkRect.top = linkRect.top / zoomFactor; linkRect.bottom = linkRect.bottom / zoomFactor; linkRect.left = linkRect.left / zoomFactor; @@ -434,18 +434,10 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { return { div: div, span: span }; } -function needsZoomAdjustment () { - // Create a test element - const test = document.createElement('div'); - test.style.width = '100px'; - test.style.position = 'absolute'; - test.style.visibility = 'hidden'; - document.body.appendChild(test); - // Compare getBoundingClientRect() with offsetWidth - const rect = test.getBoundingClientRect(); - const needsAdjustment = Math.round(rect.width) !== test.offsetWidth; - document.body.removeChild(test); - return needsAdjustment; +function isSafari () { + return typeof navigator !== 'undefined' && + /^((?!chrome|android).)*safari/i.test(navigator.userAgent) && + CSS.supports('-webkit-backdrop-filter', 'blur(1px)'); }; /** From 8521ca18cdc0bcaff2eb68b1dda7b5fc90284cd0 Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Sat, 30 Nov 2024 16:16:17 +0000 Subject: [PATCH 12/14] Try again with iOS / Safari --- www/js/lib/popovers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/js/lib/popovers.js b/www/js/lib/popovers.js index 240bea346..f25371854 100644 --- a/www/js/lib/popovers.js +++ b/www/js/lib/popovers.js @@ -333,7 +333,7 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { div.popoverisloading = true; const screenWidth = win.innerWidth - 40; const screenHeight = document.documentElement.clientHeight; - const zoomFactor = 'zoom' in currentDocument.documentElement.style ? params.relativeFontSize / 100 : 1; + const zoomFactor = 'zoom' in currentDocument.documentElement.style && !isSafari() ? params.relativeFontSize / 100 : 1; let margin = 40; let divWidth = 512; if (screenWidth <= divWidth) { @@ -363,7 +363,7 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { }; // Note that since Chromium 128 getBoundingClientRect() now returns zoom-adjusted values, but if this is the case, // then currentCSSZoom will be defined as well, so we can adjust for this. Note that UWP also requires adjustment. - if (/UWP/.test(params.appType) || 'MSBlobBuilder' in window || anchor.currentCSSZoom || isSafari()) { + if (/UWP/.test(params.appType) || 'MSBlobBuilder' in window || anchor.currentCSSZoom) { linkRect.top = linkRect.top / zoomFactor; linkRect.bottom = linkRect.bottom / zoomFactor; linkRect.left = linkRect.left / zoomFactor; From d1bf56b1f3a40eef86a65314b07c5ee1a24b6dbc Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Sat, 30 Nov 2024 16:25:41 +0000 Subject: [PATCH 13/14] Final go with Safari, sigh --- www/js/lib/popovers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/js/lib/popovers.js b/www/js/lib/popovers.js index f25371854..a98e91b16 100644 --- a/www/js/lib/popovers.js +++ b/www/js/lib/popovers.js @@ -363,7 +363,7 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { }; // Note that since Chromium 128 getBoundingClientRect() now returns zoom-adjusted values, but if this is the case, // then currentCSSZoom will be defined as well, so we can adjust for this. Note that UWP also requires adjustment. - if (/UWP/.test(params.appType) || 'MSBlobBuilder' in window || anchor.currentCSSZoom) { + if (/UWP/.test(params.appType) || 'MSBlobBuilder' in window || anchor.currentCSSZoom || isSafari()) { linkRect.top = linkRect.top / zoomFactor; linkRect.bottom = linkRect.bottom / zoomFactor; linkRect.left = linkRect.left / zoomFactor; From 4f56594e77d8ce2f94109e23b21bdee2cf2ef0f7 Mon Sep 17 00:00:00 2001 From: Jaifroid Date: Sat, 30 Nov 2024 17:11:32 +0000 Subject: [PATCH 14/14] Yet another Safari fix --- www/js/lib/popovers.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/www/js/lib/popovers.js b/www/js/lib/popovers.js index a98e91b16..c02362ff2 100644 --- a/www/js/lib/popovers.js +++ b/www/js/lib/popovers.js @@ -333,7 +333,7 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { div.popoverisloading = true; const screenWidth = win.innerWidth - 40; const screenHeight = document.documentElement.clientHeight; - const zoomFactor = 'zoom' in currentDocument.documentElement.style && !isSafari() ? params.relativeFontSize / 100 : 1; + let zoomFactor = 'zoom' in currentDocument.documentElement.style && !isSafari() ? params.relativeFontSize / 100 : 1; let margin = 40; let divWidth = 512; if (screenWidth <= divWidth) { @@ -411,6 +411,10 @@ function createNewKiwixPopoverCointainer (win, anchor, event) { if (triangleX > divWidth - 10) triangleX = divWidth - 10; // Adjust positions to take into account the font zoom factor const adjustedScrollY = win.scrollY / zoomFactor; + if (isSafari()) { + // We have to reinstate zoomFactor as it is only applied to horizontal positioning in Safari + zoomFactor = params.relativeFontSize / 100; + } divRectX = divRectX / zoomFactor; triangleX = triangleX / zoomFactor; // Now set the calculated x and y positions