diff --git a/src/htmlLanguageService.ts b/src/htmlLanguageService.ts index 8ce5bc7..a17bfb4 100644 --- a/src/htmlLanguageService.ts +++ b/src/htmlLanguageService.ts @@ -87,6 +87,8 @@ export function getLanguageService(options: LanguageServiceOptions = defaultLang }; } +export { convertScriptContentToJavaScript } from './parser/htmlScanner.js'; + export function newHTMLDataProvider(id: string, customData: HTMLDataV1): IHTMLDataProvider { return new HTMLDataProvider(id, customData); } diff --git a/src/parser/htmlScanner.ts b/src/parser/htmlScanner.ts index 69cf50c..a2788df 100644 --- a/src/parser/htmlScanner.ts +++ b/src/parser/htmlScanner.ts @@ -429,3 +429,26 @@ export function createScanner(input: string, initialOffset = 0, initialState: Sc getTokenError: () => tokenError }; } + +/** + * Converts HTML comment markers (``) in inline script content + * to JavaScript block comment markers (`/* ` and ` *​/`), only replacing + * matched pairs. Unpaired `-->` (e.g., inside a JS block comment like + * `/* --> *​/`) will not be replaced. + */ +export function convertScriptContentToJavaScript(content: string): string { + const re = //g; + let depth = 0; + return content.replace(re, (match) => { + if (match === '' + if (depth > 0) { + depth--; + return ' */'; + } + return match; + }); +} diff --git a/src/test/scanner.test.ts b/src/test/scanner.test.ts index 0928a12..2c94507 100644 --- a/src/test/scanner.test.ts +++ b/src/test/scanner.test.ts @@ -5,7 +5,7 @@ import { suite, test } from 'node:test'; import * as assert from 'node:assert'; -import { createScanner } from '../parser/htmlScanner.js'; +import { createScanner, convertScriptContentToJavaScript } from '../parser/htmlScanner.js'; import { TokenType, ScannerState } from '../htmlLanguageTypes.js'; suite('HTML Scanner', () => { @@ -876,4 +876,66 @@ suite('HTML Scanner', () => { ]); }); +}); + +suite('convertScriptContentToJavaScript', () => { + + test('replaces matched pairs', () => { + assert.strictEqual( + convertScriptContentToJavaScript(''), + '/* var x = 1; */' + ); + }); + + test('does not replace unpaired -->', () => { + // Issue #151: --> inside a JS block comment should not be replaced + assert.strictEqual( + convertScriptContentToJavaScript('/* --> a b\n */'), + '/* --> a b\n */' + ); + }); + + test('replaces only paired markers when mixed', () => { + assert.strictEqual( + convertScriptContentToJavaScript(' /* --> */'), + '/* code */ /* --> */' + ); + }); + + test('handles multiple pairs', () => { + assert.strictEqual( + convertScriptContentToJavaScript(' '), + '/* a */ /* b */' + ); + }); + + test('handles nested -->'), + '/* /* */ */' + ); + }); + + test('handles empty script content', () => { + assert.strictEqual( + convertScriptContentToJavaScript(''), + '' + ); + }); + + test('handles content with no markers', () => { + assert.strictEqual( + convertScriptContentToJavaScript('var x = 1;'), + 'var x = 1;' + ); + }); + + test('leaves unpaired ', () => { + assert.strictEqual( + convertScriptContentToJavaScript('