Skip to content

Instantly share code, notes, and snippets.

@marcoscaceres
Last active March 13, 2017 14:23
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcoscaceres/7906456 to your computer and use it in GitHub Desktop.
Save marcoscaceres/7906456 to your computer and use it in GitHub Desktop.
(function(exports) {
'use strict';
implementRequestBookmark();
/**
* Expose requestBookmark() on navigator
* @return {void}
*/
function implementRequestBookmark(){
var property = {
writable: true,
enumerable: true,
configurable: true,
value: requestManifest
};
Object.defineProperty(exports, "requestBookmark", property);
}
/**
* [requestManifest description]
* @return {[type]} [description]
*/
function requestManifest(){
return new Promise(
function resolver(resolve,reject){
var manifestElem = document.querySelector('link[rel="manifest"]');
//No element? Try to get the manifest from the Web
if (!manifestElem) {
//check if it's served using Link header
findLinkBasedManifest()
.then(fetchManifest, checkForWellKnownManifest)
.then(processManifest);
return;
}
fetchManifest(manifestElem.href).then(processManifest, console.log);
}
);
}
//HEAD this document to see if it has a Link: header
function findLinkBasedManifest() {
return new Promise(
function resolver(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', checkHeaders);
xhr.open('HEAD', document.location.href);
xhr.send();
function checkHeaders() {
var rawLinkHeader = xhr.getResponseHeader('Link'),
parsedLink = parseLinkHeader(rawLinkHeader),
hasManifest = !!parsedLink.rels.manifest;
if (hasManifest) {
return resolve(parsedLink.rels.manifest.href);
}
reject('no Link: manifest found');
}
}
);
}
/*
Adapted from:
http://bill.burkecentral.com/2009/10/15/parsing-link-headers-with-javascript-and-java/
*/
function parseLinkHeader(value) {
const linkexp = /<[^>]*>\s*(\s*;\s*[^\(\)<>@,;:"\/\[\]\?={} \t]+=(([^\(\)<>@,;:"\/\[\]\?={} \t]+)|("[^"]*")))*(,|$)/g;
const paramexp = /[^\(\)<>@,;:"\/\[\]\?={} \t]+=(([^\(\)<>@,;:"\/\[\]\?={} \t]+)|("[^"]*"))/g;
var matches,
rels = {},
titles = {},
linkheader = {
rels: rels,
titles: titles
};
function processMatches(item) {
var split = item.split('>'),
ps = split[1],
s = ps.match(paramexp),
href = split[0].substring(1),
link = {
href: href
};
function processParams(param) {
function dequote(value) {
var isQuoted = value.charAt(0) + value.charAt(value.length - 1) === '""';
return (isQuoted) ? value.substring(1, value.length - 1) : value;
}
var paramsplit = param.split('='),
name = paramsplit[0];
link[name] = dequote(paramsplit[1]);
}
s.forEach(processParams);
if (link.rel !== undefined) {
rels[link.rel] = link;
}
if (link.title !== undefined) {
titles[link.title] = link;
}
}
if (value !== null) {
matches = value.match(linkexp);
if (matches) {
matches.forEach(processMatches);
}
}
return linkheader;
}
function fetchManifest(manifestURL) {
return new Promise(
function resolver(resolve, reject) {
var xhr = new XMLHttpRequest(),
url = (manifestURL.href) ? manifestURL.href : manifestURL;
//Type error
if (typeof url !== 'string') {
return reject(new TypeError('Manifest URL is invalid'));
}
//resolve once we load
xhr.addEventListener('load', function() {
if (this.status === 200) {
resolve(this.responseText);
}
});
xhr.addEventListener('error', reject);
xhr.open('GET', url);
xhr.send();
}
);
}
function processManifest(text) {
return new Promise(
function resolver(resolve,reject) {
var json;
try {
json = JSON.parse(text);
resolve(json);
} catch (e) {
reject(e);
}
}
);
}
function checkForWellKnownManifest() {
const wellKnownURI = '/.well-known/manifest.json';
return new Promise(
function resolver(resolve, reject) {
var url = new URL(wellKnownURI, document.location);
fetchManifest(url).then(resolve, reject);
}
);
}
}(window.navigator));
@kenchris
Copy link

manfiest? :) I guess you mean manifest!

@marcoscaceres
Copy link
Author

Fixed :)

@marcoscaceres
Copy link
Author

funny, I had misspelled it my test too... so my tests passed :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment