Skip to content

Commit

Permalink
ScriptLoader: only execute scripts from actually updated snippets (on…
Browse files Browse the repository at this point in the history
… snippet's afterUpdate)
  • Loading branch information
jiripudil committed Nov 28, 2023
1 parent b3974ea commit 648246b
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 37 deletions.
77 changes: 43 additions & 34 deletions src/core/ScriptLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,51 +15,60 @@ export class ScriptLoader {
});
});

naja.addEventListener('success', (event) => {
const {payload} = event.detail;
if (payload.snippets) {
this.loadScripts(payload.snippets);
}
naja.snippetHandler.addEventListener('afterUpdate', (event) => {
const {content} = event.detail;
this.loadScripts(content);
});
});
}

public loadScripts(snippets: Record<string, string>): void {
Object.keys(snippets).forEach((id) => {
const content = snippets[id];
if ( ! /<script/i.test(content)) {
return;
}
public loadScripts(content: string): void;
public loadScripts(snippets: Record<string, string>): void;
public loadScripts(snippetsOrSnippet: Record<string, string> | string): void {
if (typeof snippetsOrSnippet === 'string') {
this.loadScriptsInSnippet(snippetsOrSnippet);
return;
}

const el = window.document.createElement('div');
el.innerHTML = content;
Object.keys(snippetsOrSnippet).forEach((id) => {
const content = snippetsOrSnippet[id];
this.loadScriptsInSnippet(content);
});
}

const scripts = el.querySelectorAll('script');
for (let i = 0; i < scripts.length; i++) {
const script = scripts.item(i);
const scriptId = script.getAttribute('data-naja-script-id');
if (scriptId !== null && scriptId !== '' && this.loadedScripts.has(scriptId)) {
continue;
}
private loadScriptsInSnippet(content: string) {
if (!/<script/i.test(content)) {
return;
}

const scriptEl = window.document.createElement('script');
scriptEl.innerHTML = script.innerHTML;
const el = window.document.createElement('div');
el.innerHTML = content;

if (script.hasAttributes()) {
const attrs = script.attributes;
for (let j = 0; j < attrs.length; j++) {
const attrName = attrs[j].name;
scriptEl.setAttribute(attrName, attrs[j].value);
}
}
const scripts = el.querySelectorAll('script');
for (let i = 0; i < scripts.length; i++) {
const script = scripts.item(i);
const scriptId = script.getAttribute('data-naja-script-id');
if (scriptId !== null && scriptId !== '' && this.loadedScripts.has(scriptId)) {
continue;
}

window.document.head.appendChild(scriptEl)
.parentNode!.removeChild(scriptEl);
const scriptEl = window.document.createElement('script');
scriptEl.innerHTML = script.innerHTML;

if (scriptId !== null && scriptId !== '') {
this.loadedScripts.add(scriptId);
if (script.hasAttributes()) {
const attrs = script.attributes;
for (let j = 0; j < attrs.length; j++) {
const attrName = attrs[j].name;
scriptEl.setAttribute(attrName, attrs[j].value);
}
}
});

window.document.head.appendChild(scriptEl)
.parentNode!.removeChild(scriptEl);

if (scriptId !== null && scriptId !== '') {
this.loadedScripts.add(scriptId);
}
}
}
}
14 changes: 11 additions & 3 deletions tests/Naja.ScriptLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {assert} from 'chai';
import sinon from 'sinon';

import {ScriptLoader} from '../src/core/ScriptLoader';

import {SnippetHandler} from '../src/core/SnippetHandler';

describe('ScriptLoader', function () {
fakeFetch();
Expand All @@ -22,18 +22,26 @@ describe('ScriptLoader', function () {
});

it('loads scripts in snippets', function () {
const naja = mockNaja();
const naja = mockNaja({
snippetHandler: SnippetHandler,
});

const foo = document.createElement('div');
foo.id = 'snippet--foo';
document.body.appendChild(foo);

const scriptLoader = new ScriptLoader(naja);
naja.initialize();

const mock = sinon.mock(scriptLoader);
mock.expects('loadScripts')
.withExactArgs({'snippet--foo': 'foo'})
.withExactArgs('foo')
.once();

this.fetchMock.respond(200, {'Content-Type': 'application/json'}, {snippets: {'snippet--foo': 'foo'}});
return naja.makeRequest('GET', '/ScriptLoader/loadScripts').then(() => {
mock.verify();
document.body.removeChild(foo);
});
});

Expand Down

0 comments on commit 648246b

Please sign in to comment.