diff --git a/tests/utils.test.js b/tests/utils.test.js index 3374fa6..0469e6e 100644 --- a/tests/utils.test.js +++ b/tests/utils.test.js @@ -10,6 +10,7 @@ describe('replaceI18nPlaceholders', () => { dom = new JSDOM(`

__MSG_world__

`); global.document = dom.window.document; global.Node = dom.window.Node; + global.NodeFilter = dom.window.NodeFilter; global.browser = { i18n: { getMessage: (key) => ({ title: 'Title', hello: 'Hello', world: 'World' }[key]) @@ -20,6 +21,7 @@ describe('replaceI18nPlaceholders', () => { dom.window.close(); delete global.document; delete global.Node; + delete global.NodeFilter; delete global.browser; }); test('replaces placeholders in elements and text nodes', () => { diff --git a/utils/utils.js b/utils/utils.js index 98dd95d..1b4702e 100644 --- a/utils/utils.js +++ b/utils/utils.js @@ -65,17 +65,24 @@ function replaceI18nPlaceholders() { }); // Replace __MSG_...__ patterns in common attributes (e.g., placeholder, title, aria-label) - document.querySelectorAll('*').forEach(el => { - if (!el.attributes) return; - Array.from(el.attributes).forEach(attr => { - if (typeof attr.value === 'string' && attr.value.includes('__MSG_')) { - const newVal = replaceTokens(attr.value); - if (newVal !== attr.value) { - el.setAttribute(attr.name, newVal); + if (document.documentElement) { + const walker = document.createTreeWalker(document.documentElement, NodeFilter.SHOW_ELEMENT); + let el = walker.currentNode; + while (el) { + if (el.hasAttributes()) { + for (let i = 0; i < el.attributes.length; i++) { + const attr = el.attributes[i]; + if (typeof attr.value === 'string' && attr.value.includes('__MSG_')) { + const newVal = replaceTokens(attr.value); + if (newVal !== attr.value) { + el.setAttribute(attr.name, newVal); + } + } } } - }); - }); + el = walker.nextNode(); + } + } // Replace __MSG_...__ patterns in the document title if (document.title && document.title.includes('__MSG_')) {