GoogleChromeLabs / pwacompat

PWACompat to bring Web App Manifest to older browsers

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

data uri for manifest

riegel opened this issue · comments

Doesn't recognize the data uri for my manifest and attempts to get using XMLHttpRequest

I modified your setup() function to support data uri's in the manifest. It depends on an external decodeBase64() see below for the one I am using. Since I can reasaonably expect the manifest file to be non binary the base64 decoding can be more simplistic than would be required if the data uri contained binary data.

 function setup() {
    const manifestEl = document.head.querySelector('link[rel="manifest"]');
    const manifestHref = manifestEl ? manifestEl.href : '';
    if (!manifestHref) {
      throw `can't find <link rel="manifest" href=".." />'`;
    }

    const hrefFactory = buildHrefFactory([manifestHref, window.location]);
    const datauri=decodeBase64(manifestHref.split(',')[1]);
    if(datauri){
     try {
       const data = (JSON.parse(datauri));
       process(data, hrefFactory);
     } catch (err) {
       console.warn('pwacompat.js error', err)
     }
    } else {
     const xhr = new XMLHttpRequest();
     xhr.open('GET', manifestHref);

     // nb. use getAttribute for older brower safety
     xhr.withCredentials = (manifestEl.getAttribute('crossorigin') === 'use-credentials');

     // this is IE10+
     xhr.onload = () => {
       try {
         const data = /** @type {!Object<string, *>} */ (JSON.parse(xhr.responseText));
         process(data, hrefFactory);
       } catch (err) {
         console.warn('pwacompat.js error', err)
       }
     };
     xhr.send(null);
    }
  }

This is the decodeBase64 I am using, might be appropriate to include it in the pwacompat function.

    decodeBase64=function(f){var g={},b=65,d=0,a,c=0,h,e="",k=String.fromCharCode,l=f.length;for(a="";91>b;)a+=k(b++);a+=a.toLowerCase()+"0123456789+/";for(b=0;64>b;b++)g[a.charAt(b)]=b;for(a=0;a<l;a++)for(b=g[f.charAt(a)],d=(d<<6)+b,c+=6;8<=c;)((h=d>>>(c-=8)&255)||a<l-2)&&(e+=k(h));return e};

I'm not sure what thisline is for but I am guessing it is to add the manifest url to an href list somewhere?

const hrefFactory = buildHrefFactory([manifestHref, window.location]);

If so then it probably should be moved to the XHR block.

by the way, the reason I am using a dataURI is my goal is to make my web app a single file. With no external file dependencies. That was I can hash that file and I know if the client is running the same version. Also it seems to make sense with the whole idea of an app being a single file.

Actually—the code should support this. I use it in the test suite. The format should look like:

  <link rel="manifest" href="data:application/json;base64,eyJpY29ucyI6W3sic3JjIjoibG9nby0xOTIucG5nIiwic2l6ZXMiOiIxOTJ4MTkyIn0seyJzcmMiOiJsb2dvLTEyOC5wbmciLCJzaXplcyI6IjEyOHgxMjgifV19" />

Admittedly, I've only tested this in Chromium-based browsers. Maybe IE11 or older browsers don't support the GET operation on that href? Are you using another browser?