mirror of
https://github.com/flarum/core.git
synced 2025-08-06 08:27:42 +02:00
feat: theming and extensibility improvements (#3876)
* feat: make page structure customizable across different pages (#3867) * feat: create `PageStructure` component * feat: apply to `DiscussionPage` * feat: apply to `UserPage` * feat: apply to `TagsPage` * fix: adapt subscriptions ext * chore: cleanup * chore: use grid & flexbox for the discussion list item (#3868) * chore: rename `DiscussionPage-list` to `DiscussionListPane` * chore: itemlistify `DiscussionListItem` * chore: use flex and grid for `DiscussionListItem` * chore: use flexbox for `App-header` (#3869) * chore: use flex and grid for `App-header` * chore: drop search floats * fix: adapt admin styles * chore: use flexbox in dropdowns and SplitDropdown for subscriptions (#3874) * chore: flexbox dropdown menu items * chore: normalize subscriptions menu (use slit dropdown) * chore: cleanup * chore: misc flexbox/grid changes (#3875) * chore: `TagsPage` to tsx * chore: `TagsPage` flexbox/grid * chore: `IndexPage-toolbar` flexbox * chore: `UserCard` flexbox & itemlists * fix: `Post` improve spacing logic * chore: `Post` grid and proper spacing * fix: avatar editor hover layer layout * chore: `Button` flex * chore: normalize form semantics (#3877) * chore: normalize fieldsets * fix: `LinkButton` spacing * chore: consistent form semantics * fix: styling regressions (#3878) * fix: post spacing goes off in other pages * fix: regression * feat: extract reusable components from `NotificationsDropdown` (#3879) * feat: extensible global notices (#3880) * fix: js error on null item list * feat: extensible global notices * chore: housekeeping (#3881) * chore: use CSS variables where still not using * chore: cleanup suspension modal * chore: cleanup post flag * fix: badge vertical align * chore: use CSS variables for custom coloring * chore: `icon` helper to `Icon` component * chore: `avatar` helper to `Avatar` component * fix: chunk loading fails on admin frontend * chore: format * feat: reusable `UploadImageButton` component (#3882) * chore: convert `UploadImageButton` to tsx * feat: reusable `UploadImageButton` component * feat: add `image-upload` setting type * feat: extensible default footer component (#3883) * chore: yarn format
This commit is contained in:
@@ -20,86 +20,91 @@ class RegisterAsyncChunksPlugin {
|
||||
alreadyOptimized = true;
|
||||
|
||||
const chunks = Array.from(compilation.chunks);
|
||||
const chunkModuleMemory = [];
|
||||
|
||||
const modulesToCheck = [];
|
||||
const chunkModuleMemory = {};
|
||||
const modulesToCheck = {};
|
||||
|
||||
for (const chunk of chunks) {
|
||||
for (const module of compilation.chunkGraph.getChunkModulesIterable(chunk)) {
|
||||
modulesToCheck[chunk.id] = modulesToCheck[chunk.id] || [];
|
||||
|
||||
// A normal module.
|
||||
if (module?.resource && module.resource.split(path.sep).includes('src') && module._source?._value.includes("webpackChunkName: ")) {
|
||||
modulesToCheck.push(module);
|
||||
modulesToCheck[chunk.id].push(module);
|
||||
}
|
||||
|
||||
// A ConcatenatedModule.
|
||||
if (module?.modules) {
|
||||
module.modules.forEach((module) => {
|
||||
if (module.resource && module.resource.split(path.sep).includes('src') && module._source?._value.includes("webpackChunkName: ")) {
|
||||
modulesToCheck.push(module);
|
||||
modulesToCheck[chunk.id].push(module);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const module of modulesToCheck) {
|
||||
// If the module source has an async webpack chunk, add the chunk id to flarum.reg
|
||||
// at the end of the module source.
|
||||
for (const sourceChunkId in modulesToCheck) {
|
||||
for (const module of modulesToCheck[sourceChunkId]) {
|
||||
// If the module source has an async webpack chunk, add the chunk id to flarum.reg
|
||||
// at the end of the module source.
|
||||
|
||||
const reg = [];
|
||||
const reg = [];
|
||||
|
||||
// Each line that has a webpackChunkName comment.
|
||||
[...module._source._value.matchAll(/.*\/\* webpackChunkName: .* \*\/.*/gm)].forEach(([match]) => {
|
||||
[...match.matchAll(/(.*?) webpackChunkName: '([^']*)'.*? \*\/ '([^']+)'.*?/gm)]
|
||||
.forEach(([match, _, urlPath, importPath]) => {
|
||||
// Import path is relative to module.resource, so we need to resolve it
|
||||
const importPathResolved = path.resolve(path.dirname(module.resource), importPath);
|
||||
const thisComposerJson = require(path.resolve(process.cwd(), '../composer.json'));
|
||||
const namespace = extensionId(thisComposerJson.name);
|
||||
// Each line that has a webpackChunkName comment.
|
||||
[...module._source._value.matchAll(/.*\/\* webpackChunkName: .* \*\/.*/gm)].forEach(([match]) => {
|
||||
[...match.matchAll(/(.*?) webpackChunkName: '([^']*)'.*? \*\/ '([^']+)'.*?/gm)]
|
||||
.forEach(([match, _, urlPath, importPath]) => {
|
||||
// Import path is relative to module.resource, so we need to resolve it
|
||||
const importPathResolved = path.resolve(path.dirname(module.resource), importPath);
|
||||
const thisComposerJson = require(path.resolve(process.cwd(), '../composer.json'));
|
||||
const namespace = extensionId(thisComposerJson.name);
|
||||
|
||||
const chunkModules = (c) => Array.from(compilation.chunkGraph.getChunkModulesIterable(c));
|
||||
const chunkModules = (c) => Array.from(compilation.chunkGraph.getChunkModulesIterable(c));
|
||||
|
||||
const relevantChunk = chunks.find(
|
||||
(chunk) => chunkModules(chunk)?.find(
|
||||
(module) => module.resource?.split('.')[0] === importPathResolved || module.rootModule?.resource?.split('.')[0] === importPathResolved
|
||||
)
|
||||
);
|
||||
const relevantChunk = chunks.find(
|
||||
(chunk) => chunkModules(chunk)?.find(
|
||||
(module) => module.resource?.split('.')[0] === importPathResolved || module.rootModule?.resource?.split('.')[0] === importPathResolved
|
||||
)
|
||||
);
|
||||
|
||||
if (! relevantChunk) {
|
||||
console.error(`Could not find chunk for ${importPathResolved}`);
|
||||
return match;
|
||||
}
|
||||
if (! relevantChunk) {
|
||||
console.error(`Could not find chunk for ${importPathResolved}`);
|
||||
return match;
|
||||
}
|
||||
|
||||
let concatenatedModule = chunkModules(relevantChunk)[0];
|
||||
const moduleId = compilation.chunkGraph.getModuleId(concatenatedModule);
|
||||
const registrableModulesUrlPaths = new Map();
|
||||
registrableModulesUrlPaths.set(urlPath, [relevantChunk.id, moduleId, namespace, urlPath]);
|
||||
let concatenatedModule = chunkModules(relevantChunk)[0];
|
||||
const moduleId = compilation.chunkGraph.getModuleId(concatenatedModule);
|
||||
const registrableModulesUrlPaths = new Map();
|
||||
registrableModulesUrlPaths.set(urlPath, [relevantChunk.id, moduleId, namespace, urlPath]);
|
||||
|
||||
if (concatenatedModule?.rootModule) {
|
||||
// This is a chunk with many modules, we need to register all of them.
|
||||
concatenatedModule.modules?.forEach((module) => {
|
||||
// The path right after the src/ directory, without the extension.
|
||||
const regPathSep = `\\${path.sep}`;
|
||||
const urlPath = module.resource.replace(`/.*${regPathSep}src(.*)${regPathSep}\..*/`, '$1');
|
||||
if (concatenatedModule?.rootModule) {
|
||||
// This is a chunk with many modules, we need to register all of them.
|
||||
concatenatedModule.modules?.forEach((module) => {
|
||||
// The path right after the src/ directory, without the extension.
|
||||
const regPathSep = `\\${path.sep}`;
|
||||
const urlPath = module.resource.replace(`/.*${regPathSep}src(.*)${regPathSep}\..*/`, '$1');
|
||||
|
||||
if (! registrableModulesUrlPaths.has(urlPath)) {
|
||||
registrableModulesUrlPaths.set(urlPath, [relevantChunk.id, moduleId, namespace, urlPath]);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (! registrableModulesUrlPaths.has(urlPath)) {
|
||||
registrableModulesUrlPaths.set(urlPath, [relevantChunk.id, moduleId, namespace, urlPath]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
registrableModulesUrlPaths.forEach(([chunkId, moduleId, namespace, urlPath]) => {
|
||||
if (! chunkModuleMemory.includes(urlPath)) {
|
||||
reg.push(`flarum.reg.addChunkModule('${chunkId}', '${moduleId}', '${namespace}', '${urlPath}');`);
|
||||
chunkModuleMemory.push(urlPath);
|
||||
}
|
||||
registrableModulesUrlPaths.forEach(([chunkId, moduleId, namespace, urlPath]) => {
|
||||
chunkModuleMemory[sourceChunkId] = chunkModuleMemory[sourceChunkId] || [];
|
||||
|
||||
if (! chunkModuleMemory[sourceChunkId].includes(urlPath)) {
|
||||
reg.push(`flarum.reg.addChunkModule('${chunkId}', '${moduleId}', '${namespace}', '${urlPath}');`);
|
||||
chunkModuleMemory[sourceChunkId].push(urlPath);
|
||||
}
|
||||
});
|
||||
|
||||
return match;
|
||||
});
|
||||
});
|
||||
|
||||
return match;
|
||||
});
|
||||
});
|
||||
|
||||
module._source._value += reg.join('\n');
|
||||
module._source._value += reg.join('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
Reference in New Issue
Block a user