(function(globals, setup, isMobile, localforage){
'use strict';
var PRIVATE_NAME = '__wp-add-to-homescreen';
var window = globals;
var navigator = window.navigator;
var document = window.document;
var wpAddToHomescreen = globals.wpAddToHomescreen = {
storage: localforage.createInstance({ name: PRIVATE_NAME }),
init: function (overlayContainer, buttonContainer) {
if (this.isPlatformSupported()) {
this.overlay.init(overlayContainer, document.body);
this.installAddToHomescreenButton(buttonContainer);
window.addEventListener('beforeinstallprompt', this._onBeforeInstall.bind(this));
}
},
installAddToHomescreenButton: function (container) {
var button = document.createElement('BUTTON');
button.id = 'wp-add-to-homescreen-button';
button.onclick = wpAddToHomescreen.overlay.show;
button.style.backgroundImage = 'url(' + setup.add2homeIconUrl + ')';
container.appendChild(button);
window.addEventListener('scroll', function () {
if (window.scrollY > 0) {
button.classList.add('hidden');
}
else {
button.classList.remove('hidden');
}
});
return button;
},
_onBeforeInstall: function (event) {
wpAddToHomescreen.stats.logOnce('prompted');
event.userChoice.then(function (choice) {
if (choice.outcome === 'accepted') {
wpAddToHomescreen.stats.logOnce('installed');
}
}.bind(this));
},
isPlatformSupported: function () {
return isMobile.any && this.detectBrowser();
},
detectBrowser: function () {
if (/Gecko\/[\d\.]+ Firefox\/[\d\.]+/.test(navigator.userAgent)) {
return 'fennec';
}
else if (/OPR\/[\d\.]+/.test(navigator.userAgent)) {
return 'opera';
}
else if (/Chrome\/[\d\.]+/.test(navigator.userAgent)) {
return 'chrome';
}
else if (/AppleWebKit\/[\d\.]+/.test(navigator.userAgent)) {
return 'safari';
}
else {
return null;
}
},
detectPlatform: function () {
return 'android';
}
};
wpAddToHomescreen.stats = {
logOnce: function (event, data) {
var lock = 'done-log-once-' + event;
return wpAddToHomescreen.storage.getItem(lock)
.then(function (isDone) {
if (!isDone) {
this.sendEvent(event, data);
}
return wpAddToHomescreen.storage.setItem(lock, true);
}.bind(this));
},
sendEvent: function (event, data) {
data = data || {};
data.event = event;
var encodedData = (function () {
var form = new FormData();
Object.keys(data).forEach(function (key) { form.append(key, data[key]); });
return form;
})();
var xhr = new XMLHttpRequest();
xhr.open('POST', setup.statsEndPoint, true);
xhr.send(encodedData);
}
};
wpAddToHomescreen.overlay = {
container: null,
element: null,
body: null,
init: function (overlayContainer, bodyElement) {
this.show = this.show.bind(this);
this.hide = this.hide.bind(this);
this.body = bodyElement;
this.container = overlayContainer;
this.element = this.installOverlay(overlayContainer);
},
installOverlay: function (container) {
var browser = wpAddToHomescreen.detectBrowser();
var platform = wpAddToHomescreen.detectPlatform();
var overlay = this.buildOverlay(browser, platform);
container.appendChild(overlay);
return overlay;
},
buildOverlay: function (browser, platform) {
var themeColor = document.querySelector('meta[name=theme-color]').getAttribute('content');
var contrastedColor = this.getContrastedColor(themeColor);
var overlay = document.createElement('SECTION');
overlay.id = 'wp-add-to-homescreen-overlay';
overlay.style.backgroundColor = themeColor;
overlay.style.color = contrastedColor;
var wrapper = document.createElement('DIV');
var title = document.createElement('H2');
title.textContent = setup.title;
var instructions = this.getInstructions(browser);
var explanation = instructions[0];
var arrowHint = { vertical: instructions[1], horizontal: instructions[2] };
var arrow = document.createElement('DIV');
arrow.classList.add('arrow');
arrow.classList.add(arrowHint.vertical);
arrow.classList.add(arrowHint.horizontal);
arrow.textContent = "▲";
arrow.style.color = contrastedColor;
var instructionsSection = document.createElement('SECTION');
instructionsSection.classList.add('instructions');
instructionsSection.appendChild(explanation);
var dismissButton = document.createElement('BUTTON');
dismissButton.classList.add('dismiss');
dismissButton.textContent = setup.dismissText;
dismissButton.style.color = themeColor;
dismissButton.style.backgroundColor = contrastedColor;
dismissButton.onclick = this.hide;
wrapper.appendChild(arrow);
wrapper.appendChild(title);
wrapper.appendChild(instructionsSection);
wrapper.appendChild(dismissButton);
overlay.appendChild(wrapper);
return overlay;
},
// http://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color#answer-3943023
getContrastedColor: function (color) {
color = this.normalizeColor(color);
var red = parseInt(color.substr(1,2), 16) / 255.0;
var green = parseInt(color.substr(3,2), 16) / 255.0;
var blue = parseInt(color.substr(5,2), 16) / 255.0;
var colors = [red, green, blue].map(function (color) {
return (color <= 0.03928) ? (color / 12.92) : Math.pow((color + 0.055)/1.055, 2.4);
});
var luminance = colors[0] * 0.2126 + colors[1] * 0.7152 + colors[2] * 0.0722;
return (luminance > 0.179) ? '#000000' : '#FFFFFF';
},
normalizeColor: function (color) {
if (color.length === 4) {
color = ['#', color[1], color[1], color[2], color[2], color[3], color[3]].join('');
}
return color;
},
show: function () {
this.element.classList.add('shown');
this.body.classList.add('noscroll');
this.preventScroll();
wpAddToHomescreen.stats.logOnce('instructions-shown');
},
hide: function () {
this.element.classList.remove('shown');
this.body.classList.remove('noscroll');
this.restoreScroll();
},
getInstructions: function (browser) {
return this.instructionsByBrowser[browser].call(this, setup);
},
instructionsByBrowser: {
fennec: function (setup) {
var buffer = document.createDocumentFragment();
var p = document.createElement('P');
p.innerHTML = 'Long press the navigation bar and tap ' +
'on Add to Home Screen
.';
buffer.appendChild(p);
return [buffer, 'top', 'right'];
},
chrome: function (setup) {
var buffer = document.createDocumentFragment();
var p = document.createElement('P');
p.innerHTML = 'Tap on ⋮ and then tap on Add to ' +
'Home screen
.';
buffer.appendChild(p);
return [buffer, 'top', 'right'];
},
opera: function (setup) {
var buffer = document.createDocumentFragment();
var p = document.createElement('P');
p.innerHTML = 'Tap on the + icon, then tap on Add to ' +
'home screen
.';
buffer.appendChild(p);
return [buffer, 'top', 'left'];
},
safari: function (setup) {
var buffer = document.createDocumentFragment();
var p = document.createElement('P');
p.innerHTML = 'Tap on the share icon, then tap on Add to ' +
'Home Screen
.';
buffer.appendChild(p);
return [buffer, 'bottom', 'center'];
}
},
preventScroll: function () {
['scroll', 'touchmove', 'mousewheel'].forEach(function (event) {
this.container.addEventListener(event, this.noScroll, true);
}.bind(this));
},
restoreScroll: function () {
['scroll', 'touchmove', 'mousewheel'].forEach(function (event) {
this.container.removeEventListener(event, this.noScroll, true);
}.bind(this));
},
noScroll: function (evt) {
evt.preventDefault();
}
};
})(window, wpAddToHomescreenSetup, isMobile, localforage);