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