diff --git a/flow-client/src/main/resources/META-INF/resources/frontend/Flow.ts b/flow-client/src/main/resources/META-INF/resources/frontend/Flow.ts index 0cf808cb3c5..96564c44257 100644 --- a/flow-client/src/main/resources/META-INF/resources/frontend/Flow.ts +++ b/flow-client/src/main/resources/META-INF/resources/frontend/Flow.ts @@ -389,8 +389,10 @@ export class Flow { } private async offlineStubAction() { - await import('./OfflineStub'); - const offlineStub = document.createElement('vaadin-offline-stub') as HTMLRouterContainer; + const offlineStub = document.createElement('iframe') as HTMLRouterContainer; + const offlineStubPath = './offline-stub.html'; + offlineStub.setAttribute('src', offlineStubPath); + offlineStub.setAttribute('style', 'width: 100%; height: 100%; border: 0'); this.response = undefined; let onlineListener: ConnectionStateChangeListener | undefined; diff --git a/flow-client/src/main/resources/META-INF/resources/frontend/OfflineStub.ts b/flow-client/src/main/resources/META-INF/resources/frontend/OfflineStub.ts deleted file mode 100644 index 641485bca06..00000000000 --- a/flow-client/src/main/resources/META-INF/resources/frontend/OfflineStub.ts +++ /dev/null @@ -1,87 +0,0 @@ -import {css, html, LitElement } from 'lit-element'; - -export class OfflineStub extends LitElement { - - static get styles() { - return css` - .page { - font-family: -apple-system, BlinkMacSystemFont, "Roboto", "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - font-size: 1rem; - line-height: 1.625; - font-weight: 300; - -webkit-font-smoothing: antialiased; - color: hsla(214, 96%, 96%, 0.9); - background: hsl(214, 35%, 21%); - word-break: break-word; - padding: 0; - margin: 0; - } - .offline { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - z-index: 10000; - padding: 0 24px; - min-height: 100vh; - } - - .offline .content { - width: 100%; - max-width: 50em; - margin: 0 auto; - } - - .offline .content .message { - flex: 1; - box-sizing: border-box; - height: 100%; - } - - .offline .content .message h2 { - text-align: center; - font-size: 1.75rem; - margin-bottom: 0.5em; - font-weight: 600; - color: hsl(214, 100%, 98%); - } - - .offline .content .message p { - margin-top: 0.5em; - margin-bottom: 0.75em; - } - - @media (min-width: 800px) { - .offline { - padding: 0 48px; - } - - .offline .content .title h1, - .offline .content .message h2 { - text-align: left; - } - - .offline .content .message { - height: auto; - } - } - `; - } - - render() { - return html` -
-
-
-
-

You are offline

-

This route requires an internet connection to work. You do not seem to have access to the server right now. Check your internet connection and try reloading the page to use the application.

-
-
-
-
- `; - } -} - -customElements.define('vaadin-offline-stub', OfflineStub); diff --git a/flow-client/src/test/frontend/FlowTests.ts b/flow-client/src/test/frontend/FlowTests.ts index a135b584172..d6a4fc1d144 100644 --- a/flow-client/src/test/frontend/FlowTests.ts +++ b/flow-client/src/test/frontend/FlowTests.ts @@ -19,8 +19,6 @@ const flowRoot = window.document.body as any; const stubVaadinPushSrc = '/src/test/frontend/stubVaadinPush.js'; -const OFFLINE_STUB_NAME = 'vaadin-offline-stub'; - // A `changes` array that adds a div with 'Foo' text to body const changesResponse = `[ { @@ -659,7 +657,8 @@ suite("Flow", () => { search: '' }; const view = await route.action(params); - assert.equal(view.localName, OFFLINE_STUB_NAME); + assert.equal(view.localName, 'iframe'); + assert.equal(view.getAttribute('src'), './offline-stub.html'); // @ts-ignore let onBeforeEnterReturns = view.onBeforeEnter(params, {}); @@ -686,7 +685,8 @@ suite("Flow", () => { const view = await route.action(params); assert.isNotNull(view); - assert.equal(view.localName, OFFLINE_STUB_NAME); + assert.equal(view.localName, 'iframe'); + assert.equal(view.getAttribute('src'), './offline-stub.html'); assert.equal(indicator.getAttribute('style'), 'display: none'); diff --git a/flow-server/src/main/java/com/vaadin/flow/server/PwaRegistry.java b/flow-server/src/main/java/com/vaadin/flow/server/PwaRegistry.java index 9fe59a5a37e..156c4a55efc 100644 --- a/flow-server/src/main/java/com/vaadin/flow/server/PwaRegistry.java +++ b/flow-server/src/main/java/com/vaadin/flow/server/PwaRegistry.java @@ -33,11 +33,14 @@ import java.net.URLConnection; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashSet; import java.util.List; import java.util.stream.Collectors; import org.slf4j.LoggerFactory; +import com.vaadin.flow.server.communication.PwaHandler; import com.vaadin.flow.server.startup.ApplicationRouteRegistry; import elemental.json.Json; @@ -234,16 +237,19 @@ private String initializeRuntimeServiceWorker( ServletContext servletContext) { StringBuilder stringBuilder = new StringBuilder(); - // List of icons for precache - List filesToCache = getIcons().stream() + // List of files to precache + Collection filesToCache = getIcons().stream() .filter(PwaIcon::shouldBeCached).map(PwaIcon::getCacheFormat) - .collect(Collectors.toList()); + .collect(Collectors.toCollection(LinkedHashSet::new)); - // When offlinePath is in use, it is also an offline resource to + // When custom offlinePath is in use, it is also an offline resource to // precache if (pwaConfiguration.isOfflinePathEnabled()) { - filesToCache.add(offlinePageCache()); + filesToCache.add(offlinePageCache(pwaConfiguration.getOfflinePath())); } + // Offline stub to be shown within an