1
0
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:
Sami Mazouz
2023-10-10 21:36:08 +01:00
committed by GitHub
parent 24d13e33bb
commit 5ab5257ff5
174 changed files with 2671 additions and 2056 deletions

View File

@@ -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');
}
}
}
);