Skip to content

Commit cad8633

Browse files
committed
Update spa-router dependency to v1.11.4 and refactor layout to use DOM fragments
1 parent cccb3ff commit cad8633

File tree

2 files changed

+117
-31
lines changed

2 files changed

+117
-31
lines changed

public/js/deps.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
// Import and re-export spa-router
10-
export { Router, transitions, renderer, componentLoader } from 'https://esm.sh/@profullstack/[email protected].3';
10+
export { Router, transitions, renderer, componentLoader } from 'https://esm.sh/@profullstack/[email protected].4';
1111

1212
// Import and re-export state-manager
1313
export { createStore, StoreConnector } from 'https://esm.sh/@profullstack/[email protected]';

public/js/router.js

Lines changed: 116 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,40 @@ import {
1212
initResetPasswordPage
1313
} from './page-initializers.js';
1414

15-
// Default page layout with header and footer
16-
const DEFAULT_LAYOUT = (content) => `
17-
<pf-header></pf-header>
18-
<div class="content">${content}</div>
19-
<pf-footer></pf-footer>
20-
`;
15+
// Create a DOM fragment with the default layout
16+
function createLayoutFragment(content) {
17+
// Create a document fragment
18+
const fragment = document.createDocumentFragment();
19+
20+
// Create header
21+
const header = document.createElement('pf-header');
22+
fragment.appendChild(header);
23+
24+
// Create content container
25+
const contentDiv = document.createElement('div');
26+
contentDiv.className = 'content';
27+
28+
// If content is a string, use createContextualFragment to parse it
29+
if (typeof content === 'string') {
30+
const range = document.createRange();
31+
const parsedContent = range.createContextualFragment(content);
32+
contentDiv.appendChild(parsedContent);
33+
} else if (content instanceof DocumentFragment) {
34+
// If it's already a fragment, append it directly
35+
contentDiv.appendChild(content);
36+
} else if (content instanceof Node) {
37+
// If it's a DOM node, append it directly
38+
contentDiv.appendChild(content);
39+
}
40+
41+
fragment.appendChild(contentDiv);
42+
43+
// Create footer
44+
const footer = document.createElement('pf-footer');
45+
fragment.appendChild(footer);
46+
47+
return fragment;
48+
}
2149

2250
/**
2351
* Load a page from the server
@@ -47,25 +75,56 @@ async function loadPage(url) {
4775
// Execute any inline scripts
4876
await componentLoader.executeInlineScripts(doc);
4977

50-
// Filter out script tags, but keep them for views
51-
const contentWithoutScripts = componentLoader.filterScriptTags(doc.body, true); // Keep script tags
52-
const content = contentWithoutScripts.innerHTML;
78+
// We want to keep script tags, so we'll use DOM methods to clone the content
79+
// Create a fragment to hold the content
80+
const contentFragment = document.createDocumentFragment();
5381

54-
// Pre-translate the content
82+
// Clone all children from the body, including script tags
83+
Array.from(doc.body.children).forEach(child => {
84+
contentFragment.appendChild(child.cloneNode(true));
85+
});
86+
87+
// Create a wrapper for translation
5588
const wrapper = document.createElement('div');
56-
wrapper.innerHTML = content;
89+
wrapper.appendChild(contentFragment.cloneNode(true));
90+
91+
// Pre-translate the content
5792
localizer.translateContainer(wrapper);
5893

59-
// Return the content wrapped in the default layout
60-
return DEFAULT_LAYOUT(wrapper.innerHTML);
94+
// Create a new fragment with the translated content
95+
const translatedFragment = document.createDocumentFragment();
96+
while (wrapper.firstChild) {
97+
translatedFragment.appendChild(wrapper.firstChild);
98+
}
99+
100+
// Return the content wrapped in the default layout as a DOM fragment
101+
return createLayoutFragment(translatedFragment);
61102
} catch (error) {
62103
console.error('Error loading page:', error);
63-
return `
64-
<div class="error">
65-
<h1 data-i18n="errors.error_loading_page">Error Loading Page</h1>
66-
<p>${error.message}</p>
67-
</div>
68-
`;
104+
105+
// Create an error fragment
106+
const errorFragment = document.createDocumentFragment();
107+
108+
// Create error container
109+
const errorDiv = document.createElement('div');
110+
errorDiv.className = 'error';
111+
112+
// Create error heading
113+
const heading = document.createElement('h1');
114+
heading.setAttribute('data-i18n', 'errors.error_loading_page');
115+
heading.textContent = 'Error Loading Page';
116+
errorDiv.appendChild(heading);
117+
118+
// Create error message
119+
const message = document.createElement('p');
120+
message.textContent = error.message;
121+
errorDiv.appendChild(message);
122+
123+
// Add to fragment
124+
errorFragment.appendChild(errorDiv);
125+
126+
// Return the error wrapped in the default layout
127+
return createLayoutFragment(errorFragment);
69128
}
70129
}
71130

@@ -151,17 +210,44 @@ export function createRouter(options = {}) {
151210
console.log('Safety interval cleared');
152211
}, 3000);
153212

154-
return `
155-
<pf-header></pf-header>
156-
<div class="content-container" style="display: flex; justify-content: center; align-items: center; min-height: 60vh;">
157-
<div class="error-page">
158-
<h1>404 - Page Not Found</h1>
159-
<p>The page "${path}" could not be found.</p>
160-
<a href="/" class="back-link">Go back to home</a>
161-
</div>
162-
</div>
163-
<pf-footer></pf-footer>
164-
`;
213+
// Create error content fragment
214+
const contentFragment = document.createDocumentFragment();
215+
216+
// Create content container
217+
const contentContainer = document.createElement('div');
218+
contentContainer.className = 'content-container';
219+
contentContainer.style.display = 'flex';
220+
contentContainer.style.justifyContent = 'center';
221+
contentContainer.style.alignItems = 'center';
222+
contentContainer.style.minHeight = '60vh';
223+
224+
// Create error page div
225+
const errorPage = document.createElement('div');
226+
errorPage.className = 'error-page';
227+
228+
// Create heading
229+
const heading = document.createElement('h1');
230+
heading.textContent = '404 - Page Not Found';
231+
errorPage.appendChild(heading);
232+
233+
// Create message
234+
const message = document.createElement('p');
235+
message.textContent = `The page "${path}" could not be found.`;
236+
errorPage.appendChild(message);
237+
238+
// Create back link
239+
const backLink = document.createElement('a');
240+
backLink.href = '/';
241+
backLink.className = 'back-link';
242+
backLink.textContent = 'Go back to home';
243+
errorPage.appendChild(backLink);
244+
245+
// Assemble the fragment
246+
contentContainer.appendChild(errorPage);
247+
contentFragment.appendChild(contentContainer);
248+
249+
// Return the error wrapped in the default layout
250+
return createLayoutFragment(contentFragment);
165251
}
166252
});
167253

0 commit comments

Comments
 (0)