Fix viewport size calculation on Firefox first load#1271
Fix viewport size calculation on Firefox first load#1271BuildPushkar wants to merge 5 commits intokiwix:mainfrom
Conversation
There was a problem hiding this comment.
@BuildPushkar Thank you for your PR, without pre-judging any other feedback from my fellow reviewers, can you please first ensure a proper code formatting (spacing, indentation, lining)?
Please also update appropriate cache busting ID to fix the test. All the necessary information is in the README.md, at https://github.com/kiwix/libkiwix
Thank you for the feedback! @kelson42 |
|
@BuildPushkar thx |
static/skin/index.js
Outdated
| let zoom = 1; | ||
|
|
||
| if (window.innerWidth) { | ||
| zoom = Math.floor((width / window.innerWidth) * 100) || 1; | ||
| } |
There was a problem hiding this comment.
What is the meaning of the zoom variable? The presence of * 100 in the calculation implies that it is measured in % which is in contradiction with the default value of 1.
There was a problem hiding this comment.
Thanks for pointing this out.
I’ve updated the logic to use a zoom ratio instead of a percentage and removed the *100 factor, so it now reflects the actual layout to viewport ratio.
static/skin/index.js
Outdated
| const rows = Math.floor(height / (3 * zoom) + 1); | ||
| const cols = Math.floor(width / (2.5 * zoom) + 1); |
There was a problem hiding this comment.
I don't understand the logic of this calculation. IMHO, the formula for the number of rows/columns should involve the height/width of the items being laid out in a grid (and maybe vertical/horizontal spacing between them), but there are some magic numbers 3 and 2.5 which bear no meaning to me.
I see that it is carried over from the previous implementation, but I think that we should strive to bring more clarity into code that we have to modify for any reason.
There was a problem hiding this comment.
Good point, thanks.
These values were inherited from the previous implementation, but I’ve now extracted them into named constants with comments to make their purpose clearer. Let me know if you’d prefer a different approach.
There was a problem hiding this comment.
Introduction of CARD_HEIGHT_FACTOR/CARD_WIDTH_FACTOR doesn't help much if at all. I'd rather want to see a formula that makes geometrical sense (something like height/(cardHeight + verticalSpacing).
There was a problem hiding this comment.
Thank you, I get your point.
The constants were mainly to keep the existing behavi0r for now. i agree that a formula based on actual card height and spacing would make more sense. I’ll try to rework this part using a geometry based approach
There was a problem hiding this comment.
Please don't take too much pain pursuing this improvement. If it doesn't come easy, just clean-up this PR so that the addressed bug is fixed with minimal changes to the existing code and the CI is green (unit tests pass).
There was a problem hiding this comment.
Got it, thank you
I’ll keep this PR focused on fixing the Firefox viewport issue with minimal changes and make sure everything is clean.
Yes it does 👍 |
| function viewPortToCount(){ | ||
| const zoom = Math.floor((( window.outerWidth - 10 ) / window.innerWidth) * 100); | ||
| return Math.floor((window.innerHeight/(3*zoom) + 1)*(window.innerWidth/(2.5*zoom) + 1)); | ||
| function viewPortToCount() { | ||
| // Use stable viewport size instead of outerWidth (Firefox devtools issue) | ||
| const width = | ||
| document.documentElement.clientWidth || window.innerWidth; | ||
|
|
||
| const height = | ||
| document.documentElement.clientHeight || window.innerHeight; | ||
|
|
||
| // Zoom ratio btw layout width and viewport width | ||
| let zoomRatio = 1; | ||
|
|
||
| if (window.innerWidth) { | ||
| zoomRatio = width / window.innerWidth || 1; | ||
| } | ||
|
|
||
| // Estimated card size (in viewport units) | ||
| const CARD_HEIGHT_FACTOR = 3; | ||
| const CARD_WIDTH_FACTOR = 2.5; | ||
|
|
||
| const rows = Math.floor( | ||
| height / (CARD_HEIGHT_FACTOR * zoomRatio) + 1 | ||
| ); | ||
|
|
||
| const cols = Math.floor( | ||
| width / (CARD_WIDTH_FACTOR * zoomRatio) + 1 | ||
| ); |
There was a problem hiding this comment.
I think this won't work. Before this change zoom used to be percentage, but the formulas for rows and cols have been actually preserved in spite of the fact that zoomRatio is now being used instead.
There was a problem hiding this comment.
Thanks for pointing this out, I see what you mean.
The goal was to switch to a ratio while keeping the existing behavior stable but I agree this may not fully preserve the original scaling.
I’ll revisit the calculation and see how we can better align it with the new zoomRatio semantics.
|
@kelson42 are there any updates regarding this PR? i noticed the “changes requested” badge is still present. |
|
@BuildPushkar I was kind of waiting to you ;) |
Sorry for the waiting. My lap stopped working, so I had to borrow a friend’s lap to continue my work. |
|
@kelson42 whenever you free, let me know should i make changes? i’ll be happy to address them. |
I'm a kind of facilitator here. Hard core reviewer is @veloman-yunkan. But please remove the main merges. There are kind of taboo by us because they make the revision log really dirty. Once the PR review over, we will do a rebase on main. Can you please do that? |
|
@veloman-yunkan AFAIK we are read here for a new review pass |
| function viewPortToCount(){ | ||
| const zoom = Math.floor((( window.outerWidth - 10 ) / window.innerWidth) * 100); | ||
| return Math.floor((window.innerHeight/(3*zoom) + 1)*(window.innerWidth/(2.5*zoom) + 1)); | ||
| function viewPortToCount() { | ||
| // Use stable viewport size instead of outerWidth (Firefox devtools issue) | ||
| const width = | ||
| document.documentElement.clientWidth || window.innerWidth; | ||
|
|
||
| const height = | ||
| document.documentElement.clientHeight || window.innerHeight; | ||
|
|
||
| // Zoom ratio btw layout width and viewport width | ||
| let zoomRatio = 1; | ||
|
|
||
| if (window.innerWidth) { | ||
| zoomRatio = width / window.innerWidth || 1; | ||
| } | ||
|
|
||
| // Estimated card size (in viewport units) | ||
| const CARD_HEIGHT_FACTOR = 3; | ||
| const CARD_WIDTH_FACTOR = 2.5; | ||
|
|
||
| const rows = Math.floor( | ||
| height / (CARD_HEIGHT_FACTOR * zoomRatio) + 1 | ||
| ); | ||
|
|
||
| const cols = Math.floor( | ||
| width / (CARD_WIDTH_FACTOR * zoomRatio) + 1 | ||
| ); |
There was a problem hiding this comment.
Has this code been tested? The concern raised during the previous has not been addressed, and therefore it looks like the functionality should be utterly broken unless the return value of viewPortToCount() (which is now ~10000 larger than before the change) doesn't matter at all (which would mean a different kind of defect of the implementation).
|
Actually, it looks like no changes other than bringing updates from the |
|
Apologies the branch update was accidental and did not include functional changes. I’m currently re-evaluating the viewport calculation logic based on the review comments and will push an actual fix shortly.
yes, i’ll clean up the branch history and remove the merge commits. i’ll rebase properly once the review changes are addressed. |
i mistakenly updated the branch without functional changes that wasn’t intentional and re-requested the review for the understading where im doing wrong |
|
i've reworked the function to derive rows and columns from actual card dimensions and margins instead of using zoombased scaling. |
|
@BuildPushkar That code makes sense, but please test it for various window sizes and zoom ratios. |
yeah sure |
|
sorry for the delay, my life is giving me a lot of trouble :) i'm having trouble reproducing the exact testing setup locally. Thanks! |
|
@BuildPushkar I am not sure that I understand the problems that you are having and the advice that you are seeking. The simple flow is to build If you have to do changes in the JS code during testing there is a more efficient flow eliminating the need to build |

Fixes #1192
This fix a issue where the initial viewport size was calculated
incorrectly in Firefox when DevTools is open, resulting in fewer results.
The calculation is now based on clientWidth/clientHeight rather than
outerWidth for greater consistency.