From 0ccdc11c78441342a1e5c440b55df418cfd5f2ac Mon Sep 17 00:00:00 2001 From: Domino Goupil <1er@live.ca> Date: Wed, 2 Jul 2025 04:14:43 -0400 Subject: [PATCH] Make injectIntoFile more reliable. --- src/server/serverUtils/contentLoader.ts | 38 ++++++++++++------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/server/serverUtils/contentLoader.ts b/src/server/serverUtils/contentLoader.ts index 7b3273c4..7c16ca91 100644 --- a/src/server/serverUtils/contentLoader.ts +++ b/src/server/serverUtils/contentLoader.ts @@ -55,7 +55,6 @@ interface IIndexDirEntry { export class ContentLoader extends Disposable { private _scriptInjector: HTMLInjector | undefined; private _servedFiles: Set = new Set(); - private _insertionTags = ['head', 'body', 'html', '!DOCTYPE']; constructor( _extensionUri: vscode.Uri, @@ -345,29 +344,28 @@ export class ContentLoader extends Disposable { * @returns {string} the injected string. */ private _injectIntoFile(contents: string): string { - // order of preference for script placement: - // 1. after - // 2. after - // 3. after - // 4. after - // 5. at the very beginning - - let re: RegExp; - let tagEnd = 0; - for (const tag of this._insertionTags) { - re = new RegExp(`<${tag}[^>]*>`, 'g'); - re.test(contents); - - tagEnd = re.lastIndex; - if (tagEnd != 0) { - break; + let offset = 0; + const consume = (rx: RegExp): void => { + rx.lastIndex = offset; + if (rx.test(contents)) { + offset = rx.lastIndex; } - } + }; + + // whitespace, comments, and xml processor instructions + const misc = /(?:\s+||<\?[^>]*>)*/sy; + + consume(misc); + consume(/]*>/iy); + consume(misc); + consume(/]*)?>/iy); + consume(misc); + consume(/<(?:head|body)(?:\s[^>]*)?>/iy); const newContents = - contents.substring(0, tagEnd) + + contents.substring(0, offset) + this._scriptInjection + - contents.substring(tagEnd); + contents.substring(offset); return newContents; }