diff --git a/resources/ext.neowiki/src/neowiki.ts b/resources/ext.neowiki/src/neowiki.ts index a734025f..08d58693 100644 --- a/resources/ext.neowiki/src/neowiki.ts +++ b/resources/ext.neowiki/src/neowiki.ts @@ -34,6 +34,13 @@ export function registerSubjectCreatorClickHandler( pinia: Pinia, signal?: Abort }, { signal } ); } +function fireRegistrationHook(): void { + const ext = NeoWikiExtension.getInstance(); + mw.hook( 'neowiki.registration' ).fire( + new FrontendRegistrar( ext.getTypeSpecificComponentRegistry(), ext.getPropertyTypeRegistry() ), + ); +} + function initializeNeoWikiApp(): void { queueMicrotask( () => { const neowikiApp = document.querySelector( '#mw-content-text > #ext-neowiki-app' ); @@ -46,9 +53,6 @@ function initializeNeoWikiApp(): void { const pageHasMainSubject = ( neowikiApp as HTMLElement ).dataset.mwNeowikiPageHasMainSubject === 'true'; const ext = NeoWikiExtension.getInstance(); - mw.hook( 'neowiki.registration' ).fire( - new FrontendRegistrar( ext.getTypeSpecificComponentRegistry(), ext.getPropertyTypeRegistry() ), - ); const app = createMwApp( NeoWikiApp, { showSubjectCreator, @@ -70,10 +74,6 @@ function initializeSchemaView(): void { if ( viewSchema !== null ) { const ext = NeoWikiExtension.getInstance(); - mw.hook( 'neowiki.registration' ).fire( - new FrontendRegistrar( ext.getTypeSpecificComponentRegistry(), ext.getPropertyTypeRegistry() ), - ); - const revisionId = mw.config.get( 'wgRevisionId' ); const schemaName = mw.config.get( 'wgTitle' ) as SchemaName; @@ -107,9 +107,6 @@ function initializeSchemasPage(): void { if ( schemasPage !== null ) { const ext = NeoWikiExtension.getInstance(); - mw.hook( 'neowiki.registration' ).fire( - new FrontendRegistrar( ext.getTypeSpecificComponentRegistry(), ext.getPropertyTypeRegistry() ), - ); const app = createMwApp( SchemasPage ); app.use( ext.getPinia() ); @@ -126,10 +123,6 @@ function initializeLayoutView(): void { if ( viewLayout !== null ) { const ext = NeoWikiExtension.getInstance(); - mw.hook( 'neowiki.registration' ).fire( - new FrontendRegistrar( ext.getTypeSpecificComponentRegistry(), ext.getPropertyTypeRegistry() ), - ); - const revisionId = mw.config.get( 'wgRevisionId' ); const layoutName = mw.config.get( 'wgTitle' ) as LayoutName; @@ -159,9 +152,6 @@ function initializeLayoutsPage(): void { if ( layoutsPage !== null ) { const ext = NeoWikiExtension.getInstance(); - mw.hook( 'neowiki.registration' ).fire( - new FrontendRegistrar( ext.getTypeSpecificComponentRegistry(), ext.getPropertyTypeRegistry() ), - ); const app = createMwApp( LayoutsPage ); app.use( ext.getPinia() ); @@ -178,10 +168,6 @@ function initializeSubjectsManagerPage(): void { if ( subjectsManager !== null ) { const ext = NeoWikiExtension.getInstance(); - mw.hook( 'neowiki.registration' ).fire( - new FrontendRegistrar( ext.getTypeSpecificComponentRegistry(), ext.getPropertyTypeRegistry() ), - ); - const app = createMwApp( SubjectsManagerPage ).directive( 'tooltip', CdxTooltip ); const pinia = ext.getPinia(); app.use( pinia ); @@ -196,6 +182,7 @@ const isTestEnvironment = typeof window !== 'undefined' && ( window as unknown as { neoWikiTestMode?: boolean } ).neoWikiTestMode === true; if ( !isTestEnvironment ) { + fireRegistrationHook(); initializeNeoWikiApp(); initializeSchemaView(); initializeLayoutView(); diff --git a/resources/ext.neowiki/tests/integration/HookRegistration.spec.ts b/resources/ext.neowiki/tests/integration/HookRegistration.spec.ts index d6cfa242..2459c155 100644 --- a/resources/ext.neowiki/tests/integration/HookRegistration.spec.ts +++ b/resources/ext.neowiki/tests/integration/HookRegistration.spec.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, expect, it } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { markRaw } from 'vue'; import { FrontendRegistrar } from '@/presentation/FrontendRegistrar'; import { TypeSpecificComponentRegistry } from '@/TypeSpecificComponentRegistry'; @@ -79,3 +79,30 @@ describe( 'neowiki.registration hook end-to-end', () => { expect( typeRegistry.getTypeNames() ).toContain( 'late' ); } ); } ); + +describe( 'ext.neowiki module load', () => { + beforeEach( () => setupMwHook() ); + + afterEach( () => { + ( window as unknown as { neoWikiTestMode?: boolean } ).neoWikiTestMode = true; + } ); + + it( 'fires neowiki.registration with a registrar wired to the live extension registries', async () => { + ( window as unknown as { neoWikiTestMode?: boolean } ).neoWikiTestMode = false; + + vi.resetModules(); + await import( '@/neowiki' ); + const { NeoWikiExtension } = await import( '@/NeoWikiExtension' ); + + let receivedRegistrar: FrontendRegistrar | null = null; + ( globalThis as any ).mw.hook( 'neowiki.registration' ).add( ( r: FrontendRegistrar ) => { + receivedRegistrar = r; + } ); + + receivedRegistrar!.registerPropertyType( fakeRegistration( 'boot-fake' ) ); + + const ext = NeoWikiExtension.getInstance(); + expect( ext.getPropertyTypeRegistry().getTypeNames() ).toContain( 'boot-fake' ); + expect( ext.getTypeSpecificComponentRegistry().getPropertyTypes() ).toContain( 'boot-fake' ); + } ); +} ); diff --git a/tests/RedHerb/resources/subjectFinder/init.js b/tests/RedHerb/resources/subjectFinder/init.js index 9a271749..b403fc56 100644 --- a/tests/RedHerb/resources/subjectFinder/init.js +++ b/tests/RedHerb/resources/subjectFinder/init.js @@ -12,15 +12,7 @@ return; } - var ext = nw.NeoWikiExtension.getInstance(); - mw.hook( 'neowiki.registration' ).fire( - new nw.FrontendRegistrar( - ext.getTypeSpecificComponentRegistry(), - ext.getPropertyTypeRegistry() - ) - ); - - var pinia = ext.getPinia(); + var pinia = nw.NeoWikiExtension.getInstance().getPinia(); var app = Vue.createMwApp( SubjectFinderPanel ) .directive( 'tooltip', codex.CdxTooltip ); app.use( pinia );