docbrown/app/javascript/packs/application.jsx
Mac Siri afa73e06e3
Replace Webpacker with Esbuild (#20470)
* Migrate to esbuild WIP

* Add exclude

* Remove redundant file

* Move file

* Move to javascript_include_tag

* Lint fix

* WIP

* WIP

* Add watch mode to esbuild WIP

* Get jest working

* Remove babel

* Revert "Remove babel"

This reverts commit 6da35260aa19d6f97f586deb66c0ecaf48433b73.

* More WIP

* Got image to load

* WIP

* Resolve audit

* Lint fix

* WIP

* Fix jest spec

* [CI] Remove asset-restore for test build stage

* Production compliant

* Temp disable sourcemap

* Update glob

* Add esbuild helper to stimulus

* Import fragment

* Temp disable coverage to see failing tests

* Fix broken spec

* Address lint

* Set proper es6 target

* Use esbuild for everything

* wait what

* Revert "Set proper es6 target"

This reverts commit 98f5278093421baa8ffe2ca580845b01c1a1eadf.

* Revert "Use esbuild for everything"

This reverts commit 0ac46738f07ffcb6af095ccb1ffa5e439b7fefa3.

* Replace uglifier with terser

* New compiled assets version

* Remvoe honeybadger-io/webpack

* Remove cypress coverage checks for now

* Update jsconfig.json

* Update docker-compose

* Remove public/packs-test from ci cache
2024-01-25 20:29:21 +00:00

190 lines
5.8 KiB
JavaScript

import 'focus-visible';
import {
initializeMobileMenu,
setCurrentPageIconLink,
initializeMemberMenu,
} from '../topNavigation/utilities';
import { waitOnBaseData } from '../utilities/waitOnBaseData';
import { initializePodcastPlayback } from '../utilities/podcastPlayback';
import { initializeVideoPlayback } from '../utilities/videoPlayback';
import { createRootFragment } from '../shared/preact/preact-root-fragment';
import { initializeDashboardSort } from './initializers/initializeDashboardSort';
import { trackCreateAccountClicks } from '@utilities/ahoy/trackEvents';
import { showWindowModal, closeWindowModal } from '@utilities/showModal';
import * as Runtime from '@utilities/runtime';
Document.prototype.ready = new Promise((resolve) => {
if (document.readyState !== 'loading') {
return resolve();
}
document.addEventListener('DOMContentLoaded', () => resolve());
return null;
});
// Namespace for functions which need to be accessed in plain JS initializers
window.Forem = {
audioInitialized: false,
preactImport: undefined,
getPreactImport() {
if (!this.preactImport) {
this.preactImport = import('preact');
}
return this.preactImport;
},
enhancedCommentTextAreaImport: undefined,
getEnhancedCommentTextAreaImports() {
if (!this.enhancedCommentTextAreaImport) {
this.enhancedCommentTextAreaImport = import(
'./CommentTextArea/CommentTextArea'
);
}
return Promise.all([
this.enhancedCommentTextAreaImport,
this.getPreactImport(),
]);
},
initializeEnhancedCommentTextArea: async (originalTextArea) => {
const parentContainer = originalTextArea.parentElement;
const alreadyInitialized =
parentContainer.classList.contains('c-autocomplete');
if (alreadyInitialized) {
return;
}
const [{ CommentTextArea }, { render, h }] =
await window.Forem.getEnhancedCommentTextAreaImports();
render(
<CommentTextArea vanillaTextArea={originalTextArea} />,
createRootFragment(parentContainer, originalTextArea),
);
},
showModal: showWindowModal,
closeModal: () => closeWindowModal(),
Runtime,
};
initializeDashboardSort();
initializePodcastPlayback();
initializeVideoPlayback();
InstantClick.on('change', () => {
initializeDashboardSort();
initializePodcastPlayback();
initializeVideoPlayback();
});
// Initialize data-runtime context to the body data-attribute
document.body.dataset.runtime = window.Forem.Runtime.currentContext();
function getPageEntries() {
return Object.entries({
'notifications-index': document.getElementById('notifications-link'),
'moderations-index': document.getElementById('moderation-link'),
'articles_search-index': document.getElementById('search-link'),
});
}
/**
* Initializes the left hand side hamburger menu
*/
function initializeNav() {
const { currentPage } = document.getElementById('page-content').dataset;
const menuTriggers = [
...document.querySelectorAll('.js-hamburger-trigger, .hamburger a'),
];
setCurrentPageIconLink(currentPage, getPageEntries());
initializeMobileMenu(menuTriggers);
}
const memberMenu = document.getElementById('crayons-header__menu');
const menuNavButton = document.getElementById('member-menu-button');
if (memberMenu) {
initializeMemberMenu(memberMenu, menuNavButton);
}
/**
* Fetches the html for the navigation_links from an endpoint and dynamically insterts it in the DOM.
*/
async function getNavigation() {
const placeholderElement = document.getElementsByClassName(
'js-navigation-links-container',
)[0];
if (placeholderElement.innerHTML.trim() === '') {
const response = await window.fetch(`/async_info/navigation_links`);
const htmlContent = await response.text();
const generatedElement = document.createElement('div');
generatedElement.innerHTML = htmlContent;
placeholderElement.appendChild(generatedElement);
}
}
// Initialize when asset pipeline (sprockets) initializers have executed
waitOnBaseData()
.then(() => {
InstantClick.on('change', () => {
initializeNav();
});
if (Runtime.currentMedium() === 'ForemWebView') {
// Dynamic import of the namespace
import('../mobile/foremMobile.js').then((module) => {
// Load the namespace
window.ForemMobile = module.foremMobileNamespace();
// Run the first session
window.ForemMobile.userSessionBroadcast();
});
}
})
.catch((error) => {
Honeybadger.notify(error);
});
// we need to call initializeNav here for the initial page load
initializeNav();
async function loadCreatorSettings() {
try {
const [{ LogoUploadController }, { Application }] = await Promise.all([
import('@admin/controllers/logo_upload_controller'),
import('@hotwired/stimulus'),
]);
const application = Application.start();
application.register('logo-upload', LogoUploadController);
} catch (error) {
Honeybadger.notify(
`Error loading the creator settings controller: ${error.message}`,
);
}
}
if (document.location.pathname === '/admin/creator_settings/new') {
loadCreatorSettings();
}
document.ready.then(() => {
// Our infinite scroll pattern causes problems with the browser's back button:
// specifically, if you've scrolled into page 2+, click into a post, then back
// to the feed, the browser scroll position will not be where you had previously
// scrolled. This seems to fix it, even though it seems like it should have
// the opposite effect.
setTimeout(() => {
history.scrollRestoration = 'manual';
}, 0);
const hamburgerTrigger = document.getElementsByClassName(
'js-hamburger-trigger',
)[0];
hamburgerTrigger.addEventListener('click', getNavigation);
});
trackCreateAccountClicks('authentication-hamburger-actions');
trackCreateAccountClicks('authentication-top-nav-actions');
trackCreateAccountClicks('comments-locked-cta');