+
+
+ `;
+ });
+
+ beforeAll(async () => {
+ ({ addFullScreenModeControl, getFullScreenModeStatus } =
+ await importModule());
+ addFullScreenModeControl(getEnterFullScreenButtons());
+ });
+
+ beforeAll(async () => {
+ // eventListener functions
+ ({ onPressEscape, onPopstate } = await importModule());
+ });
+
+ it('starts in non-fullscreen mode', testNonFullScreen);
+
+ it('enters fullscreen mode on click', () => {
+ const goFullScreenButtons = getEnterFullScreenButtons();
+ const spyDoc = jest.spyOn(document.body, 'addEventListener');
+ const spyWindow = jest.spyOn(window, 'addEventListener');
+
+ goFullScreenButtons[0].click();
+
+ testFullScreen();
+ expect(spyDoc).toHaveBeenCalledWith('keyup', onPressEscape);
+ expect(spyWindow).toHaveBeenCalledWith('popstate', onPopstate);
+ });
+
+ it('exits fullscreen mode on Escape key', () => {
+ const spyDocRemove = jest.spyOn(document.body, 'removeEventListener');
+ const spyWindowRemove = jest.spyOn(window, 'removeEventListener');
+
+ testFullScreen();
+ document.body.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' }));
+ testNonFullScreen();
+
+ expect(spyDocRemove).toHaveBeenCalledWith('keyup', onPressEscape);
+ expect(spyWindowRemove).toHaveBeenCalledWith('popstate', onPopstate);
+ });
+
+ it('re-enters fullscreen mode on click', () => {
+ const goFullScreenButtons = getEnterFullScreenButtons();
+ const spyDoc = jest.spyOn(document.body, 'addEventListener');
+ const spyWindow = jest.spyOn(window, 'addEventListener');
+
+ testNonFullScreen();
+ goFullScreenButtons[0].click();
+ testFullScreen();
+
+ expect(spyDoc).toHaveBeenCalledWith('keyup', onPressEscape);
+ expect(spyWindow).toHaveBeenCalledWith('popstate', onPopstate);
+ });
+
+ it('exits fullscreen mode on popstate event', () => {
+ const spyDocRemove = jest.spyOn(document.body, 'removeEventListener');
+ const spyWindowRemove = jest.spyOn(window, 'removeEventListener');
+
+ testFullScreen();
+ window.dispatchEvent(new PopStateEvent('popstate', { state: { key: '' } }));
+ testNonFullScreen();
+
+ expect(spyDocRemove).toHaveBeenCalledWith('keyup', onPressEscape);
+ expect(spyWindowRemove).toHaveBeenCalledWith('popstate', onPopstate);
+ });
+});
diff --git a/app/javascript/utilities/codeFullscreenModeSwitcher.js b/app/javascript/utilities/codeFullscreenModeSwitcher.js
index 14d6a3526..5e42a6404 100644
--- a/app/javascript/utilities/codeFullscreenModeSwitcher.js
+++ b/app/javascript/utilities/codeFullscreenModeSwitcher.js
@@ -4,6 +4,10 @@ const fullScreenWindow =
document.getElementsByClassName('js-fullscreen-code')[0];
const { body } = document;
+export function getFullScreenModeStatus() {
+ return isFullScreenModeCodeOn;
+}
+
function setAfterFullScreenScrollPosition() {
window.scrollTo(0, screenScroll);
}
@@ -12,7 +16,7 @@ function getBeforeFullScreenScrollPosition() {
screenScroll = window.scrollY;
}
-function onPressEscape(event) {
+export function onPressEscape(event) {
if (event.key == 'Escape') {
fullScreenModeControl(event);
}
@@ -26,6 +30,18 @@ function listenToKeyboardForEscape(listen) {
}
}
+export function onPopstate() {
+ fullScreenModeControl();
+}
+
+function listenToWindowForPopstate(listen) {
+ if (listen) {
+ window.addEventListener('popstate', onPopstate);
+ } else {
+ window.removeEventListener('popstate', onPopstate);
+ }
+}
+
function toggleOverflowForDocument(overflow) {
if (overflow) {
body.style.overflow = 'hidden';
@@ -51,7 +67,7 @@ function removeFullScreenModeControl(elements) {
}
function fullScreenModeControl(event) {
- const codeBlock = event.currentTarget.closest('.js-code-highlight')
+ const codeBlock = event?.currentTarget.closest('.js-code-highlight')
? event.currentTarget.closest('.js-code-highlight').cloneNode(true)
: null;
const codeBlockControls = codeBlock
@@ -62,6 +78,7 @@ function fullScreenModeControl(event) {
toggleOverflowForDocument(false);
setAfterFullScreenScrollPosition();
listenToKeyboardForEscape(false);
+ listenToWindowForPopstate(false);
removeFullScreenModeControl(codeBlockControls);
fullScreenWindow.classList.remove('is-open');
@@ -72,6 +89,8 @@ function fullScreenModeControl(event) {
toggleOverflowForDocument(true);
getBeforeFullScreenScrollPosition();
listenToKeyboardForEscape(true);
+ listenToWindowForPopstate(true);
+
codeBlock.classList.add('is-fullscreen');
fullScreenWindow.appendChild(codeBlock);
fullScreenWindow.classList.add('is-open');