How can I know if my Safari extension code is running for the first time after the user has installed the extension?
I would like to differentiate between a new installation of the extension vs. an update of the extension.
I am looking for something very similar to this answer, but for Safari, instead of for Chrome. I haven't been able to "translate" the code from the answer in that link to Safari.
If you can live without the update check, this script should work (compare with the Chrome related answer):
// In background page
function onInstall() {
console.log('Extension installed');
}
var firstRun = typeof localStorage['extensionHasPreviouslyRun'] === 'undefined' ||
!JSON.parse(localStorage['extensionHasPreviouslyRun']);
if (firstrun) {
onInstall();
localStorage['extensionHasPreviouslyRun'] = JSON.stringify(true);
}
If you want to check for updates also, you need to asynchronously get the version from the plist file, as so:
// In background page
function onInstall() {
console.log('Extension installed');
}
function onUpdate() {
console.log('Extension update');
}
function requestVersion(callback) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', 'info.plist');
xmlhttp.onload = function () {
var infoFile = xmlhttp.responseXML;
var keys = infoFile.getElementsByTagName('key');
for (var i = 0; i < keys.length; i++){
if (keys[i].firstChild.data === 'CFBundleShortVersionString'){
var version = keys[i].nextElementSibling.firstChild.data;
callback(version);
break;
}
}
}
xmlhttp.send();
}
requestVersion(function(version) {
var storedVersion = localStorage['version'];
if (storedVersion !== version) {
// Check if we just installed this extension.
if (typeof storedVersion === 'undefined') {
onInstall();
} else {
onUpdate();
}
localStorage['version'] = version;
}
});
we can get version from safari.extension.displayVersion
var storedVersion = safari.extension.settings.version;
var currentVersion = safari.extension.displayVersion + '.' + safari.extension.bundleVersion;
if (typeof storedVersion === 'undefined') {
console.log('Extension installed');
safari.extension.settings.version = currentVersion
} else if (currentVersion != storedVersion) {
console.log('Extension update');
safari.extension.settings.version = currentVersion
}
do not forget to add hidden setting item in Extension Builder
Took @Claudijo's answer above and worked it into a small class:
/**
* ExtensionState
*
* @abstract
*/
var ExtensionState = (function() {
/**
* __configFilePath
*
* @access private
* @return String (default: '../Info.plist')
*/
var __configFilePath = '../Info.plist';
/**
* __getConfigVersion
*
* @access private
* @param Function callback
* @return void
*/
var __getConfigVersion = function(callback) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', __configFilePath);
xmlhttp.onload = function () {
var infoFile = xmlhttp.responseXML,
keys = infoFile.getElementsByTagName('key');
for (var i = 0; i < keys.length; i++){
if (keys[i].firstChild.data === 'CFBundleShortVersionString') {
var version = keys[i].nextElementSibling.firstChild.data;
callback(version);
break;
}
}
};
xmlhttp.send();
};
/**
* __getLocalVersion
*
* @access private
* @return String
*/
var __getLocalVersion = function() {
return localStorage['version'];
};
/**
* __putLocalVersion
*
* @access private
* @param String version
* @return void
*/
var __putLocalVersion = function(version) {
localStorage['version'] = version;
};
// Public
return {
/**
* installed
*
* @access public
* @param Function callback
* @return void
*/
installed: function(callback) {
var localVersion = __getLocalVersion();
if (typeof localVersion === 'undefined') {
__getConfigVersion(function(version) {
callback(version);
__putLocalVersion(version);
});
}
},
/**
* updated
*
* @access public
* @param Function callback
* @return void
*/
updated: function(callback) {
var localVersion = __getLocalVersion();
if (typeof localVersion !== 'undefined') {
__getConfigVersion(function(version) {
if (localVersion !== version) {
callback(version);
__putLocalVersion(version);
}
});
}
}
};
})()
ExtensionState.installed(function(version) {
console.log('(global.html): Installed');
});
ExtensionState.updated(function(version) {
console.log('(global.html): Updated');
});