Skip to content

Commit

Permalink
Revert "fix: remove ancient image fill-while-zoomable hack"
Browse files Browse the repository at this point in the history
This reverts commit 4a90cd6.

See #17318
  • Loading branch information
mikehardy authored and david-allison committed Oct 31, 2024
1 parent 769a6b6 commit 28f5951
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 3 deletions.
7 changes: 4 additions & 3 deletions AnkiDroid/src/main/assets/flashcard.css
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,11 @@ code#typeans {
}

/*
Use hard-coded max dimensions. Modern webviews are able to zoom into images
correctly even with max dimensions specified
Use hard-coded max dimensions if using Chrome back-end. Chrome is able to
zoom into images correctly even with max dimensions specified, so this way is
preferred over using JavaScript.
*/
img {
.chrome img {
max-width: 100%;
max-height: 90%;
}
Expand Down
79 changes: 79 additions & 0 deletions AnkiDroid/src/main/assets/scripts/card.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,63 @@
var resizeDone = false;

/*
Handle image resizing if the image exceeds the window dimensions.
If we are using the Chrome engine, add the "chrome" class to the
body and defer image resizing to pure CSS. The Chrome engine can
handle image resizing on its own, but for older versions of WebView,
we do it here.
If we are resizing with JavaScript, we also account for the CSS zoom
level applied to the image. If an image is scaled with CSS zoom, the
dimensions given to us by the browser will not be scaled
accordingly, giving us only the original dimensions. We have to
fetch the zoom value and scale the dimensions with it before
checking if the image exceeds the window bounds.
If the WebView loads too early on Android <= 2.3 (which happens on
the first card or regularly with WebView switching enabled), then
the window dimensions returned to us are 0x0. In this case, we skip
image resizing and try again after we know the window has fully
loaded with a method call initiated from Java (onPageFinished).
*/
var resizeImages = function () {
if (navigator.userAgent.indexOf("Chrome") > -1) {
document.body.className = document.body.className + " chrome";
} else {
if (window.innerWidth === 0 || window.innerHeight === 0) {
return;
}
var maxWidth = window.innerWidth * 0.9;
var maxHeight = window.innerHeight * 0.9;
var ratio = 0;
var images = document.getElementsByTagName("img");
for (var i = 0; i < images.length; i++) {
var img = images[i];
var scale = 1;
var zoom = window.getComputedStyle(img).getPropertyValue("zoom");
if (!isNaN(zoom)) {
scale = zoom;
}
var width = img.width * scale;
var height = img.height * scale;
if (width > maxWidth) {
img.width = maxWidth;
img.height = height * (maxWidth / width);
width = img.width;
height = img.height;
img.style.zoom = 1;
}
if (height > maxHeight) {
img.width = width * (maxHeight / height);
img.height = maxHeight;
img.style.zoom = 1;
}
}
}
resizeDone = true;
};

/* Tell the app that we no longer want to focus the WebView and should instead return keyboard
* focus to a native answer input method.
* Naming subject to change.
Expand Down Expand Up @@ -67,6 +127,19 @@ function taKey(itag, e) {
}
}

window.onload = function () {
/* If the WebView loads too early on Android <= 4.3 (which happens
on the first card or regularly with WebView switching enabled),
the window dimensions returned to us will be default built-in
values. In this case, issuing a scroll event will force the
browser to recalculate the dimensions and give us the correct
values, so we do this every time. This lets us resize images
correctly. */
window.scrollTo(0, 0);
resizeImages();
window.location.href = "#answer";
};

function _runHook(arr) {
var promises = [];

Expand All @@ -81,6 +154,12 @@ var onUpdateHook = [];
var onShownHook = [];

var onPageFinished = function () {
if (!resizeDone) {
resizeImages();
/* Re-anchor to answer after image resize since the point changes */
window.location.href = "#answer";
}

var card = document.querySelector(".card");

var typedElement = document.getElementsByName("typed")[0];
Expand Down

0 comments on commit 28f5951

Please sign in to comment.