- From: Carlos Lopez <notifications@github.com>
- Date: Fri, 23 Aug 2019 08:05:39 -0700
- To: whatwg/xhr <xhr@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/xhr/issues/253@github.com>
So, I'm dealing with an issue with bridging older browsers with the new `manifest.json` spec. Due to the way the pages are served, `manifest.json` is served based on certain server criteria (hostname) while `index.html` is a static file from a CDN. Basically, before the UI events start, and any interaction is possible, I use a `prerender.js` script in <head> to style the document before it's rendered. This could include things like setting different content header padding if the page is rendered on an iOS PWA. Also, I use this pre-render state to set some colors based on `prefers-color-scheme:dark`. Some properties I want to grab straight from `manifest.json`. This means it has to be intentionally synchronous. For example, let's say I want to style the `background-color` of the document (`<html>`) to be the same as what's in `manifest.json`. Let's say I have the color as `#000` (black). When a PWA loads, it will load a black background, but, if I don't use block the render before changing the `background-color` in `<html>`and, instead do this asynchronously, then the background will flash white (browser default), and then go black. Here's some short snippets of this configuration: manifest.json: ```` { "name": "Full App Name", "short_name": "App", "start_url": "/", "background_color": "#000000", "display": "standalone", "theme_color": "#2196F3", } ```` index.html: ```` <html> <head> <link rel="manifest" href="manifest.json" /> <script src="prerender.js"> <!-- Content snip --!> ```` prerender.js ```` import * as Document from '@shortfuse/materialdesignweb/core/document/index'; /** @return {Object} */ function getManifestObject() { let manifestObject = {}; const xhr = new XMLHttpRequest(); xhr.onreadystatechange = () => { if (xhr.readyState === 4) { manifestObject = JSON.parse(xhr.responseText); } }; xhr.open('GET', 'manifest.json', false); try { xhr.send(); } catch (e) { console.error('Could not load manifest.json'); } return manifestObject; } /** * @param {!string} name * @param {string} content * @return {void} */ function setMeta(name, content) { let attr = document.head.getElementsByTagName('meta').namedItem(name); if (attr) { if (content == null) { attr.parentElement.removeChild(attr); } else { attr.setAttribute('content', content); } } else if (content != null) { attr = document.createElement('meta'); attr.setAttribute('content', content); document.head.appendChild(attr); } } /** @return {void} */ function onDOMContentLoaded() { const manifest = getManifestObject(); setMeta('apple-mobile-web-app-title', manifest.short_name); setMeta('apple-mobile-web-app-status-bar-style', manifest.theme_color); setMeta('theme-color', manifest.theme_color); document.documentElement.style.setProperty('background-color', manifest.background_color); document.removeEventListener('DOMContentLoaded', onDOMContentLoaded); } Document.onPrerender(); document.addEventListener('DOMContentLoaded', onDOMContentLoaded); ```` I will add, I already have a service worker in place to serve `manifest.json` from cache, so ideally speaking, there's as little load-up time lag as possible here. (I'd imagine first fetch could experience a slight uptick in delay, but I could always add a check to see if the application is running as a PWA before doing the synchronous request.) Right now, I'm wary about using the synchronous request because of the deprecated nature. The alternative I current have is rewriting the `index.html` file, which complicates the back-end. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/whatwg/xhr/issues/253
Received on Friday, 23 August 2019 15:06:02 UTC