4

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.

Community
  • 1
  • 1
user1292512
  • 163
  • 1
  • 5

3 Answers3

4

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;
  }
});
Claudijo
  • 1,321
  • 1
  • 10
  • 15
  • Oops. I missed that localStorage only handles strings, so we have to compensate for that when working with booleans in the topmost example, for instance by introducing JSON.parse and JSON.stringify. Answer has been updated. – Claudijo Jul 17 '12 at 10:34
0

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

DelGod
  • 17
  • 3
0

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');
});
onassar
  • 3,313
  • 7
  • 36
  • 58