diff --git a/make.sh b/make.sh
index a6b56ee..19e2233 100755
--- a/make.sh
+++ b/make.sh
@@ -4,7 +4,7 @@
EXTENSION_NAME="PiPer"
-SOURCE_FILES=("main.js" "fix.js" "background.js" "install.js" "localization-bridge.js")
+SOURCE_FILES=("main.js" "fix.js" "background.js" "install.js" "localization-bridge.js" "legacy.js")
# Certifcate paths
LEAF_CERT_PATH="../certs/cert.pem"
@@ -226,24 +226,6 @@ if [[ "${compress_svg}" -eq 1 ]]; then
${SVGO_PATH} -q -f "out/${EXTENSION_NAME}/images"
fi
-# Compress all inline CSS with CSSO
-if [[ "${compress_css}" -eq 1 ]]; then
- function minify_css() {
- echo "$@" | sed -e 's/\\"/"/g' -e 's/\\\$/$/g' | ${CSSO_PATH} --declaration-list
- }
- export -f minify_css
- export CSSO_PATH
- for path in "out/${EXTENSION_NAME}/scripts"/{*,**/*}.js; do
- [[ ! -f "${path}" ]] && continue
- source=$(cat "${path}")
- echo "echo \"$(sed -e 's/\\/\\\\/g' -e 's/\$/\\$/g' -e 's/`/\\`/g' -e 's/\"/\\\"/g' -e 's/\\n/\\\\n/g' <<< "$source" \
- | tr '\n' '\f' \
- | sed -E 's/\/\*\*[[:space:]]+CSS[[:space:]]+\*\/[[:space:]]*\([[:space:]]*\\`([^`]*)\\`[[:space:]]*\)/\\`\$(minify_css '\''\1'\'')\\`/g' \
- | tr '\f' '\n')\"" \
- | sh > "${path}"
- done
-fi
-
# Get current version from git if automatic versioning enabled
if [[ "${update_version}" -eq 1 ]]; then
@@ -344,6 +326,23 @@ for target in "${targets[@]}"; do
# Copy target specific items to target output folder
cp -r "src/${target}"/* "out/${EXTENSION_NAME}-${target}${target_extension}/" 2>/dev/null
+ # Compress all inline CSS with CSSO
+ if [[ "${compress_css}" -eq 1 ]]; then
+ function minify_css() {
+ echo "$@" | sed -e 's/\\"/"/g' -e 's/\\\$/$/g' | ${CSSO_PATH} --declaration-list
+ }
+ export -f minify_css
+ export CSSO_PATH
+ for path in "out/${EXTENSION_NAME}-${target}${target_extension}${common_file_path}/scripts"/{*,**/*}.js; do
+ [[ ! -f "${path}" ]] && continue
+ source=$(cat "${path}")
+ echo "echo \"$(sed -e 's/\\/\\\\/g' -e 's/\$/\\$/g' -e 's/`/\\`/g' -e 's/\"/\\\"/g' -e 's/\\n/\\\\n/g' <<< "$source" \
+ | tr '\n' '\f' \
+ | sed -E 's/\/\*\*[[:space:]]+CSS[[:space:]]+\*\/[[:space:]]*\([[:space:]]*\\`([^`]*)\\`[[:space:]]*\)/\\`\$(minify_css '\''\1'\'')\\`/g' \
+ | tr '\f' '\n')\"" \
+ | sh > "${path}"
+ done
+ fi
# Use closure compiler to compress javascript
function remove_element() {
diff --git a/out/PiPer-chrome.zip b/out/PiPer-chrome.zip
index 46e9013..3f0cb0c 100644
Binary files a/out/PiPer-chrome.zip and b/out/PiPer-chrome.zip differ
diff --git a/out/PiPer-safari-legacy.safariextz b/out/PiPer-safari-legacy.safariextz
index 0335bdb..0bc3608 100644
Binary files a/out/PiPer-safari-legacy.safariextz and b/out/PiPer-safari-legacy.safariextz differ
diff --git a/out/PiPer-safari.pkg b/out/PiPer-safari.pkg
index 3d7d252..24be1ac 100644
Binary files a/out/PiPer-safari.pkg and b/out/PiPer-safari.pkg differ
diff --git a/src/common/scripts/externs.js b/src/common/scripts/externs.js
index 123dd7b..05a5d31 100644
--- a/src/common/scripts/externs.js
+++ b/src/common/scripts/externs.js
@@ -24,16 +24,7 @@ HTMLVideoElement.prototype.webkitSetPresentationMode = function(mode) {};
/** @type {string} */
TextTrack.prototype.label;
-/** @return {undefined} */
-safari.extension.dispatchMessage = function(message, userInfo) {};
-
-/** @const */
-safari.self = {};
-
-/** @return {undefined} */
-safari.self.addEventListener = function(type, listener) {};
-
-/** @constructor */
+/** @interface */
const SafariExtensionMessageEvent = function() {};
/** @type {*} */
@@ -42,6 +33,24 @@ SafariExtensionMessageEvent.prototype.message;
/** @type {string} */
SafariExtensionMessageEvent.prototype.name;
+/** @type {EventTarget} */
+SafariExtensionMessageEvent.prototype.target;
+
+/** @interface */
+const SafariEventTarget = function() {};
+
+/** @return {function(string,function(SafariExtensionMessageEvent),boolean=):undefined} */
+SafariEventTarget.prototype.addEventListener = function(type, listener, capture) {};
+
+/** @return {function(string,function(SafariExtensionMessageEvent),boolean=):undefined} */
+SafariEventTarget.prototype.removeEventListener = function(type, listener, capture) {};
+
+/** @type {!SafariEventTarget} */
+safari.self;
+
+/** @type {function(string,*=):undefined} */
+safari.extension.dispatchMessage = function(message, userInfo) {};
+
/* Legacy Safari Extension */
@@ -51,6 +60,27 @@ safari.extension.settings = {};
/** @return {undefined} */
safari.extension.settings.clear = function() {};
+/** @type {!SafariEventTarget} */
+safari.application;
+
+/** @const */
+safari.self.tab = {};
+
+/** @type {function(string,*=):undefined} */
+safari.self.tab.dispatchMessage = function(message, userInfo) {};
+
+/** @interface */
+const SafariBrowserTab = function() {};
+
+/** @type {SafariWebPageProxy} */
+SafariBrowserTab.prototype.page;
+
+/** @interface */
+const SafariWebPageProxy = function() {};
+
+/** @type {function(string,*=):undefined} */
+SafariWebPageProxy.prototype.dispatchMessage = function(message, userInfo) {};
+
/* Chrome Extension */
diff --git a/src/safari-legacy/Info.plist b/src/safari-legacy/Info.plist
index 9acbb4b..81afd0b 100644
--- a/src/safari-legacy/Info.plist
+++ b/src/safari-legacy/Info.plist
@@ -16,6 +16,11 @@
0.0
CFBundleVersion
0
+ Chrome
+
+ Global Page
+ global.html
+
Content
Scripts
@@ -23,6 +28,7 @@
End
scripts/main.js
+ scripts/legacy.js
diff --git a/src/safari-legacy/global.html b/src/safari-legacy/global.html
new file mode 100644
index 0000000..7751f1e
--- /dev/null
+++ b/src/safari-legacy/global.html
@@ -0,0 +1,9 @@
+
+
+
+ PiPer
+
+
+
+
+
diff --git a/src/safari-legacy/scripts/background.js b/src/safari-legacy/scripts/background.js
new file mode 100644
index 0000000..1d98fc4
--- /dev/null
+++ b/src/safari-legacy/scripts/background.js
@@ -0,0 +1,13 @@
+const messageHandler = function(/** SafariExtensionMessageEvent */ messageEvent) {
+ switch (messageEvent.name) {
+ case 'getUpgradeAlertShown':
+ const setting = /** @type {string|undefined} */ (safari.extension.settings['upgradeAlertShown']);
+ const target = /** @type {SafariBrowserTab} */ (messageEvent.target);
+ target.page.dispatchMessage('upgradeAlertShownResponse', parseInt(setting || '0', 10));
+ break;
+ case 'setUpgradeAlertShown':
+ safari.extension.settings['upgradeAlertShown'] = messageEvent.message;
+ break;
+ }
+}
+safari.application.addEventListener('message', messageHandler, false);
diff --git a/src/safari-legacy/scripts/legacy.js b/src/safari-legacy/scripts/legacy.js
new file mode 100644
index 0000000..ad180ea
--- /dev/null
+++ b/src/safari-legacy/scripts/legacy.js
@@ -0,0 +1,150 @@
+(function () {
+
+ let /** boolean */ upgradeAlertShown = false;
+
+ /**
+ * Returns localized legacy upgrade alert message
+ *
+ * @return {string}
+ */
+ const localizedUpgradeAlertMessage = function() {
+ const language = navigator.language.substring(0, 2);
+ switch (language) {
+ case 'it':
+ return 'Apple finirà presto il supporto per questa versione di PiPer. Esegui l\'upgrade alla versione per [url]Mac App Store[/url] ora';
+ case 'es':
+ return 'Apple terminará el soporte para esta versión de PiPer pronto. Por favor actualice a la versión de [url]Mac App Store[/url] ahora';
+ case 'de':
+ return 'Apple wird den Support für diese Version von PiPer in Kürze beenden. Aktualisieren Sie jetzt auf die [url]Mac App Store-Version[/url]';
+ case 'nl':
+ return 'Apple zal binnenkort de ondersteuning voor deze versie van PiPer beëindigen. Upgrade nu naar de [url]Mac App Store-versie[/url]';
+ case 'fr':
+ return 'Apple va bientôt mettre fin au support de cette version de PiPer. Veuillez passer à la version [url]Mac App Store[/url] maintenant';
+ case 'pt':
+ return 'A Apple encerrará o suporte para esta versão do PiPer em breve. Por favor, atualize para a versão [url]Mac App Store[/url] agora';
+ case 'en':
+ default:
+ return 'Apple will end support for this version of PiPer soon. Please upgrade to the [url]Mac App Store version[/url] now';
+ }
+ };
+
+ /**
+ * Shows alert
+ *
+ * @param {string} message - a message to display
+ * @param {function()} callback - a function called after alert dismissed
+ */
+ const showAlert = function(message, callback) {
+ const alert = document.createElement('div');
+ alert.style.cssText = /** CSS */ (`
+ position: fixed;
+ top: 30px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: calc(100% - 80px);
+ max-width: 600px;
+ border-radius: 5px;
+ background-color: #E66;
+ padding: 10px;
+ z-index: 9999;
+ font-family: -apple-system;
+ line-height: 1.1;
+ color: white;
+ `);
+
+ const image = /** @type {HTMLImageElement} */ (document.createElement('img'));
+ image.src = safari.extension.baseURI + 'images/default.svg';
+ image.style.cssText = /** CSS */ (`
+ float: left;
+ width: 25px;
+ height: 25px;
+ margin: 5px;
+ `);
+ alert.appendChild(image);
+
+ const close = document.createElement('div');
+ close.innerHTML = '×';
+ close.style.cssText = /** CSS */ (`
+ float: right;
+ width: 25px;
+ margin: 0px 5px;
+ font-size: 30px;
+ text-align: center;
+ opacity: 0.6;
+ cursor: pointer;
+ `);
+ alert.appendChild(close);
+
+ const content = document.createElement('div');
+ content.innerHTML = `PiPer${message}`;
+ content.style.cssText = /** CSS */ (`
+ font-size: 16px;
+ margin: 0px 45px;
+ `);
+ alert.appendChild(content);
+
+ close.addEventListener('click', function() {
+ document.body.removeChild(alert);
+ callback();
+ });
+
+ document.body.appendChild(alert);
+ };
+
+ /**
+ * Shows upgrade to Mac App Store alert if needed
+ *
+ * @param {number} dismissedTimestamp - timestamp upgrade alert was last dismissed in milliseconds
+ */
+ const showUpgradeAlertIfNeeded = function(dismissedTimestamp) {
+ const currentTimestamp = Date.now();
+
+ let /** number */ alertInterval;
+ if (currentTimestamp >= 1551398400000) { // 2019-03-01
+ alertInterval = 3.6e+6; // hourly
+ } else if (currentTimestamp >= 1548979200000) { // 2019-02-01
+ alertInterval = 8.64e+7; // daily
+ } else if (currentTimestamp >= 1546300800000) { // 2019-01-01
+ alertInterval = 6.048e+8; // weekly
+ } else {
+ alertInterval = 2.628e+9; // monthly
+ }
+
+ if (upgradeAlertShown || currentTimestamp - dismissedTimestamp < alertInterval) {
+ return;
+ }
+
+ const message = localizedUpgradeAlertMessage()
+ .replace('[url]', '')
+ .replace('[/url]', '');
+
+ showAlert(message, function() {
+ safari.self.tab.dispatchMessage('setUpgradeAlertShown', currentTimestamp);
+ });
+
+ upgradeAlertShown = true;
+ };
+
+ /**
+ * Handles Safari 'upgradeAlertShownResponse' messages from global page and shows alert if needed
+ *
+ * @param {SafariExtensionMessageEvent} messageEvent - a Safari extension message
+ */
+ const messageHandler = function(/** SafariExtensionMessageEvent */ messageEvent) {
+ if (messageEvent.name === 'upgradeAlertShownResponse') {
+ safari.self.removeEventListener('message', messageHandler, false);
+ const dismissedTimestamp = /** @type {number} */ (messageEvent.message);
+ showUpgradeAlertIfNeeded(dismissedTimestamp);
+ }
+ }
+
+ // Listen for entering Picture in Picture mode events and request last upgrade alert shown time
+ document.addEventListener('webkitpresentationmodechanged', function(event){
+ const video = /** @type {HTMLVideoElement} */ (event.target);
+ if (video.webkitPresentationMode == 'picture-in-picture') {
+ safari.self.addEventListener('message', messageHandler, false);
+ safari.self.tab.dispatchMessage('getUpgradeAlertShown');
+ }
+ }, { capture: true });
+
+})();
\ No newline at end of file
diff --git a/src/safari-legacy/update.plist b/src/safari-legacy/update.plist
index fd4ecbf..dcf5a8d 100644
--- a/src/safari-legacy/update.plist
+++ b/src/safari-legacy/update.plist
@@ -10,7 +10,7 @@
CFBundleShortVersionString
CFBundleVersion
- 189
+ 190
Developer Identifier
BQ6Q24MF9X
URL