Skip to content

Commit

Permalink
HFP-3956 Compensate scrollbar gap on different browser engines
Browse files Browse the repository at this point in the history
  • Loading branch information
otacke committed Aug 7, 2024
1 parent d60a85c commit e6aa178
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 5 deletions.
49 changes: 44 additions & 5 deletions src/scripts/h5p-crossword-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,21 @@ export default class CrosswordInput {
this.content = document.createElement('div');
this.content.classList.add('h5p-crossword-input-container');

const safariFirefoxWapper = document.createElement('div');
safariFirefoxWapper.classList.add('h5p-crossword-safari-firefox-wrapper');
this.content.appendChild(safariFirefoxWapper);

const fieldsAcross = this.buildInputFieldsGroup({
words: this.params.words.filter((word) => word.orientation === 'across'),
title: params.l10n.across
});
this.content.appendChild(fieldsAcross);
safariFirefoxWapper.appendChild(fieldsAcross);

const fieldsDown = this.buildInputFieldsGroup({
words: this.params.words.filter((word) => word.orientation === 'down'),
title: params.l10n.down
});
this.content.appendChild(fieldsDown);
safariFirefoxWapper.appendChild(fieldsDown);

this.overlay = new Overlay(
{
Expand Down Expand Up @@ -646,9 +650,12 @@ export default class CrosswordInput {
*/
resize(params = {}) {
if (params.height) {
this.content.style.setProperty('--h5p-crossword-input-container-height', `${params.height}px`);
this.content.classList.toggle(
'has-scrollbar', this.content.scrollHeight > this.content.clientHeight
this.content.style.setProperty(
'--h5p-crossword-input-container-height', `${params.height}px`
);

this.compensateForScrollbar(
this.content.scrollHeight > this.content.clientHeight
);
}

Expand All @@ -658,6 +665,38 @@ export default class CrosswordInput {
this.overlay.resize();
}

/*
* Browsers handle scrollbars differently :-/
* Firefox, Safari and Chrome on MacOS do not (fully) reduce the width of
* the inner container when a scrollbar is present, but only let it appear
* when interacted with and put it on top of the content.
* Looks slick, but I wonder where this would be the expected outcome.
* Worked around here. Not using CSS, because it cannot reliably detect
* Safari in all its versions and I wanted to keep the logic in one place.
*/
compensateForScrollbar(hasScrollbar) {
this.content.classList.toggle('has-scrollbar', hasScrollbar);

if (!hasScrollbar) {
this.content.style.removeProperty('--scrollbar-width');
return;
}

// Reduce width of wrapper by scrollbar width
if (Util.isSafari()) {
this.content.style.setProperty('--scrollbar-width', '7px');
}
else if (Util.isChrome() && Util.isMacOS()) {
this.content.style.setProperty('--scrollbar-width', '16px');
}
else if (Util.isFirefox()) {
this.content.style.setProperty('--scrollbar-width', '12px');
}
else {
this.content.style.removeProperty('--scrollbar-width');
}
}

/**
* Enable input fields.
* @param {boolean} [noListeners] If true, no listeners will be active.
Expand Down
34 changes: 34 additions & 0 deletions src/scripts/services/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,40 @@ class Util {
static isControlKey(event = {}) {
return Util.CONTROL_KEY_VALUES.includes(event.key);
}

/**
* Test whether current browser is Safari.
* @returns {boolean} True if the browser is Safari, else false.
*/
static isSafari() {
return /WebKit/.test(navigator.userAgent) &&
!/Chrome/.test(navigator.userAgent) &&
!/CriOS/.test(navigator.userAgent);
};

/**
* Test whether current browser is Chrome.
* @returns {boolean} True if the browser is Chrome, else false.
*/
static isChrome() {
return !!window.chrome;
}

/**
* Test whether current browser is Firefox.
* @returns {boolean} True if the browser is Firefox, else false.
*/
static isFirefox() {
return navigator.userAgent.toLowerCase().includes('firefox');
}

/**
* Test whether OS is MacOS.
* @returns {boolean} True if the OS is MacOS, else false.
*/
static isMacOS() {
return navigator.userAgent.includes('Mac OS');
}
}

/** @constant {string[]} KeyEventListener key values of control symbols */
Expand Down
6 changes: 6 additions & 0 deletions src/styles/h5p-crossword.scss
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@
}

.h5p-crossword-input-container {
box-sizing: border-box;
display: flex;
flex-direction: column;
height: var(--h5p-crossword-input-container-height);
Expand All @@ -258,6 +259,11 @@
}
}

.h5p-crossword-safari-firefox-wrapper {
box-sizing: border-box;
width: calc(100% - var(--scrollbar-width, 0px));
}

.h5p-crossword-input-fields-group {
margin-top: 1em;
}
Expand Down

0 comments on commit e6aa178

Please sign in to comment.