diff --git a/src/extensions/default/AutoUpdate/StateHandler.js b/src/extensions/default/AutoUpdate/StateHandler.js index ad59e6feb03..533368890e1 100644 --- a/src/extensions/default/AutoUpdate/StateHandler.js +++ b/src/extensions/default/AutoUpdate/StateHandler.js @@ -55,9 +55,9 @@ define(function (require, exports, module) { _file = FileSystem.getFileForPath(this.path); _file.exists(function (err, exists) { - if(err) { + if (err) { result.reject(); - } else if(exists) { + } else if (exists) { result.resolve(); } else { result.reject(); @@ -189,7 +189,7 @@ define(function (require, exports, module) { self.exists() .fail(function () { writePromise(self.path, content); - }).done(function (){ + }).done(function () { result.reject(); }); } diff --git a/src/extensions/default/AutoUpdate/UpdateInfoBar.js b/src/extensions/default/AutoUpdate/UpdateInfoBar.js index de3551ac89d..b7b689e77dd 100644 --- a/src/extensions/default/AutoUpdate/UpdateInfoBar.js +++ b/src/extensions/default/AutoUpdate/UpdateInfoBar.js @@ -76,7 +76,7 @@ define(function (require, exports, module) { */ function cleanUpdateBar() { var $updateBar = $('#update-bar'); - if($updateBar.length > 0) { + if ($updateBar.length > 0) { $updateBar.remove(); } $(window.document).off("keydown.AutoUpdate"); @@ -103,12 +103,12 @@ define(function (require, exports, module) { $later = $updateBar.find('#update-btn-later'), $closeIcon = $updateBar.find('#close-icon'); - if($updateContent.length > 0) { + if ($updateContent.length > 0) { if ($updateContent[0].scrollWidth > $updateContent.innerWidth()) { //Text has over-flown, show the update content as tooltip message - if($contentContainer.length > 0 && - $heading.length > 0 && - $description.length > 0) { + if ($contentContainer.length > 0 && + $heading.length > 0 && + $description.length > 0) { $contentContainer.attr("title", $heading.text() + $description.text()); } } @@ -117,7 +117,7 @@ define(function (require, exports, module) { //Event handlers on the Update Bar // Click and key handlers on Restart button - if($restart.length > 0) { + if ($restart.length > 0) { $restart.click(function () { cleanUpdateBar(); exports.trigger(exports.RESTART_BTN_CLICKED); @@ -131,7 +131,7 @@ define(function (require, exports, module) { } // Click and key handlers on Later button - if($later.length > 0) { + if ($later.length > 0) { $later.click(function () { cleanUpdateBar(); MainViewManager.focusActivePane(); @@ -146,7 +146,7 @@ define(function (require, exports, module) { } // Click and key handlers on Close button - if($closeIcon.length > 0) { + if ($closeIcon.length > 0) { $closeIcon.click(function () { cleanUpdateBar(); MainViewManager.focusActivePane(); diff --git a/src/extensions/default/AutoUpdate/main.js b/src/extensions/default/AutoUpdate/main.js index 573ce73cfa1..5d062c0eec0 100644 --- a/src/extensions/default/AutoUpdate/main.js +++ b/src/extensions/default/AutoUpdate/main.js @@ -20,6 +20,8 @@ * DEALINGS IN THE SOFTWARE. * */ +/* eslint-disable indent */ +/* eslint-disable max-len */ define(function (require, exports, module) { "use strict"; @@ -75,37 +77,110 @@ define(function (require, exports, module) { /** - * Defines preference to enable/disable Auto Update + * Checks if auto update preference is enabled or disabled + * @private + * @returns {boolean} - true if preference enabled, false otherwise */ - function setupAutoUpdatePreference(){ - PreferencesManager.definePreference("autoUpdate.AutoUpdate", "boolean", true, { - description: Strings.DESCRIPTION_AUTO_UPDATE - }); + function _isAutoUpdateEnabled() { + return (PreferencesManager.get("autoUpdate.AutoUpdate") !== false); + } - // Set or unset the auto update, based on preference state change - PreferencesManager.on("change", "autoUpdate.AutoUpdate", function () { - if(_isAutoUpdateEnabled()) { - setupAutoUpdate(); - UpdateNotification.registerUpdateHandler(_updateProcessHandler); - } else { - unsetAutoUpdate(); - UpdateNotification.resetToDefaultUpdateHandler(); + /** + * Receives messages from node + * @param {object} event - event received from node + * @param {object} msgObj - json containing - { + * fn - function to execute on Brackets side + * args - arguments to the above function + */ + function receiveMessageFromNode(event, msgObj) { + functionMap[msgObj.fn].apply(null, msgObj.args); + } + + /* + * Checks if Brackets version got updated + * @returns {boolean} true if version updated, false otherwise + */ + function checkIfVersionUpdated() { + + var latestBuildNumber = updateJsonHandler.get("latestBuildNumber"), + currentBuildNumber = Number(/-([0-9]+)/.exec(brackets.metadata.version)[1]); + + return latestBuildNumber === currentBuildNumber; + } + + + /** + * Gets the arguments to a function in an array + * @param {object} args - the arguments object + * @returns {Array} - array of actual arguments + */ + function getFunctionArgs(args) { + if (args.length > 1) { + var fnArgs = new Array(args.length - 1), + i; + + for (i = 1; i < args.length; ++i) { + fnArgs[i - 1] = args[i]; } - }); + return fnArgs; + } + return []; } /** - * Checks if auto update preference is enabled or disabled - * @private - * @returns {boolean} - true if preference enabled, false otherwise + * Posts messages to node + * @param {string} messageId - Message to be passed */ - function _isAutoUpdateEnabled() { - return (PreferencesManager.get("autoUpdate.AutoUpdate") !== false); + function postMessageToNode(messageId) { + var msg = { + fn: messageId, + args: getFunctionArgs(arguments) + }; + updateDomain.exec('data', msg); } - /** + /** + * Checks and handles the update success and failure scenarios + */ + function checkUpdateStatus() { + var filesToCache = null, + downloadCompleted = updateJsonHandler.get("downloadCompleted"), + updateInitiatedInPrevSession = updateJsonHandler.get("updateInitiatedInPrevSession"); + + if (downloadCompleted && updateInitiatedInPrevSession) { + var isNewVersion = checkIfVersionUpdated(); + if (isNewVersion) { + // We get here if the update was successful + UpdateInfoBar.showUpdateBar({ + type: "success", + title: Strings.UPDATE_SUCCESSFUL, + description: "" + }); + } else { + // We get here if the update started but failed + filesToCache = ['.logs']; //AUTOUPDATE_PRERELEASE + UpdateInfoBar.showUpdateBar({ + type: "error", + title: Strings.UPDATE_FAILED, + description: Strings.GO_TO_SITE + }); + } + } else if (downloadCompleted && !updateInitiatedInPrevSession) { + // We get here if the download was complete and user selected UpdateLater + if (brackets.platform === "mac") { + filesToCache = ['.dmg', '.json']; + } else if (brackets.platform === "win") { + filesToCache = ['.msi', '.json']; + } + } + + postMessageToNode(MessageIds.PERFORM_CLEANUP, filesToCache); + } + + + /** * Initializes the state of parsed content from updateHelper.json */ function initState() { @@ -133,6 +208,8 @@ define(function (require, exports, module) { }); } + + /** * Sets up the Auto Update environment */ @@ -149,45 +226,38 @@ define(function (require, exports, module) { } - /** - * Unsets the Auto Update environment - */ - function unsetAutoUpdate() { - updateJsonHandler = null; - updateDomain.off('data'); - resetAppQuitHandler(); - } - - /** - * Overriding the appReady for Auto update + /** + * Generates the extension for installer file, based on platform + * @returns {object} - json containing platform Info : { + * extension - installer file extension, + * OS - current OS } */ + function getPlatformInfo() { + var ext = "", + OS = ""; - AppInit.appReady(function () { - - // Auto Update is supported on Win and Mac, as of now - if(brackets.platform === "linux" || !(brackets.app.setUpdateParams)) { - return; + if (/Windows|Win32|WOW64|Win64/.test(window.navigator.userAgent)) { + OS = "WIN"; + ext = ".msi"; + } else if (/Mac/.test(window.navigator.userAgent)) { + OS = "OSX"; + ext = ".dmg"; + } else if (/Linux|X11/.test(window.navigator.userAgent)) { + OS = "LINUX32"; + ext = ".32-bit.deb"; + if (/x86_64/.test(window.navigator.appVersion + window.navigator.userAgent)) { + OS = "LINUX64"; + ext = ".64-bit.deb"; + } } - setupAutoUpdateDomain(); - //Bail out if update domain could not be created - if(!updateDomain) { - return; - } + return { + extension: ext, + OS: OS + }; + } + - // Check if the update domain is properly initialised - updateDomain.promise() - .done(function() { - setupAutoUpdatePreference(); - if(_isAutoUpdateEnabled()) { - setupAutoUpdate(); - UpdateNotification.registerUpdateHandler(_updateProcessHandler); - } - }) - .fail(function() { - return; - }); - }); /** * Generates the download URL for the update installer, based on platform @@ -206,7 +276,7 @@ define(function (require, exports, module) { installerName = "Brackets." + buildName.split(" ").join(".") + ext, downloadURL; - downloadURL = brackets.config.update_download_url + tag + "/" + installerName; + downloadURL = brackets.config.update_download_url + tag + "/" + installerName; downloadInfo = { installerName: installerName, @@ -219,35 +289,60 @@ define(function (require, exports, module) { return downloadInfo; } + /** - * Generates the extension for installer file, based on platform - * @returns {object} - json containing platform Info : { - * extension - installer file extension, - * OS - current OS } + * Initializes the state for AutoUpdate process + * @returns {$.Deferred} - a jquery promise, + * that is resolved with success or failure + * of state initialization */ - function getPlatformInfo() { - var ext = "", - OS = ""; + function initializeState() { + var result = $.Deferred(); - if (/Windows|Win32|WOW64|Win64/.test(window.navigator.userAgent)) { - OS = "WIN"; - ext = ".msi"; - } else if (/Mac/.test(window.navigator.userAgent)) { - OS = "OSX"; - ext = ".dmg"; - } else if (/Linux|X11/.test(window.navigator.userAgent)) { - OS = "LINUX32"; - ext = ".32-bit.deb"; - if (/x86_64/.test(window.navigator.appVersion + window.navigator.userAgent)) { - OS = "LINUX64"; - ext = ".64-bit.deb"; + FileSystem.resolve(updateDir, function (err) { + if (!err) { + result.resolve(); + } else { + var directory = FileSystem.getDirectoryForPath(updateDir); + directory.create(function (error) { + if (error) { + console.error('AutoUpdate : Error in creating update directory in Appdata'); + result.reject(); + } else { + result.resolve(); + } + }); } - } + }); - return { - extension: ext, - OS: OS - }; + return result.promise(); + } + + + + /** + * Handles the auto update event, which is triggered when user clicks GetItNow in UpdateNotification dialog + * @param {object} updateParams - json object containing update information { + * installerName - name of the installer + * downloadURL - download URL + * latestBuildNumber - build number + * checksum - checksum } + */ + function initiateAutoUpdate(updateParams) { + _updateParams = updateParams; + downloadAttemptsRemaining = MAX_DOWNLOAD_ATTEMPTS; + + initializeState() + .done(function () { + postMessageToNode(MessageIds.INITIALIZE_STATE, _updateParams); + }) + .fail(function () { + UpdateInfoBar.showUpdateBar({ + type: "error", + title: Strings.INITIALISATION_FAILED, + description: "" + }); + }); } @@ -264,127 +359,93 @@ define(function (require, exports, module) { checksum = (updates[0].checksums) ? updates[0].checksums[platformInfo.OS] : 0; var updateParams = getDownloadInfo(buildName, platformInfo.extension); - updateParams.latestBuildNumber = updates[0].buildNumber; ; + updateParams.latestBuildNumber = updates[0].buildNumber; updateParams.checksum = checksum; //Initiate the auto update, with update params initiateAutoUpdate(updateParams); } - /** - * Creates the Node Domain for Auto Update - */ - function setupAutoUpdateDomain() { - updateDomain = new NodeDomain("AutoUpdate", _domainPath); - } - /* - * Checks if Brackets version got updated - * @returns {boolean} true if version updated, false otherwise + /** + * Unregisters the App Quit event handler */ - function checkIfVersionUpdated() { + function resetAppQuitHandler() { + DocumentCommandHandlers.off(APP_QUIT_CANCELLED); + } - var latestBuildNumber = updateJsonHandler.get("latestBuildNumber"), - currentBuildNumber = Number(/-([0-9]+)/.exec(brackets.metadata.version)[1]); - return latestBuildNumber === currentBuildNumber; + /** + * Unsets the Auto Update environment + */ + function unsetAutoUpdate() { + updateJsonHandler = null; + updateDomain.off('data'); + resetAppQuitHandler(); } + /** - * Gets the arguments to a function in an array - * @param {object} args - the arguments object - * @returns {Array} - array of actual arguments + * Defines preference to enable/disable Auto Update */ - function getFunctionArgs(args) { - if (args.length > 1) { - var fnArgs = new Array(args.length - 1), - i; + function setupAutoUpdatePreference() { + PreferencesManager.definePreference("autoUpdate.AutoUpdate", "boolean", true, { + description: Strings.DESCRIPTION_AUTO_UPDATE + }); - for (i = 1; i < args.length; ++i) { - fnArgs[i - 1] = args[i]; + // Set or unset the auto update, based on preference state change + PreferencesManager.on("change", "autoUpdate.AutoUpdate", function () { + if (_isAutoUpdateEnabled()) { + setupAutoUpdate(); + UpdateNotification.registerUpdateHandler(_updateProcessHandler); + } else { + unsetAutoUpdate(); + UpdateNotification.resetToDefaultUpdateHandler(); } - return fnArgs; - } - return []; + }); } + /** - * Posts messages to node - * @param {string} messageId - Message to be passed + * Creates the Node Domain for Auto Update */ - function postMessageToNode(messageId) { - var msg = { - fn: messageId, - args: getFunctionArgs(arguments) - }; - updateDomain.exec('data', msg); + function setupAutoUpdateDomain() { + updateDomain = new NodeDomain("AutoUpdate", _domainPath); } + /** - * Checks and handles the update success and failure scenarios + * Overriding the appReady for Auto update */ - function checkUpdateStatus() { - var filesToCache = null, - downloadCompleted = updateJsonHandler.get("downloadCompleted"), - updateInitiatedInPrevSession = updateJsonHandler.get("updateInitiatedInPrevSession"); - if (downloadCompleted && updateInitiatedInPrevSession) { - var isNewVersion = checkIfVersionUpdated(); - if (isNewVersion) { - // We get here if the update was successful - UpdateInfoBar.showUpdateBar({ - type: "success", - title: Strings.UPDATE_SUCCESSFUL, - description: "" - }); - } else { - // We get here if the update started but failed - filesToCache = ['.logs']; //AUTOUPDATE_PRERELEASE - UpdateInfoBar.showUpdateBar({ - type: "error", - title: Strings.UPDATE_FAILED, - description: Strings.GO_TO_SITE - }); - } - } else if (downloadCompleted && !updateInitiatedInPrevSession) { - // We get here if the download was complete and user selected UpdateLater - if (brackets.platform === "mac") { - filesToCache = ['.dmg', '.json']; - } else if (brackets.platform === "win") { - filesToCache = ['.msi', '.json']; - } - } + AppInit.appReady(function () { - postMessageToNode(MessageIds.PERFORM_CLEANUP, filesToCache); - } + // Auto Update is supported on Win and Mac, as of now + if (brackets.platform === "linux" || !(brackets.app.setUpdateParams)) { + return; + } + setupAutoUpdateDomain(); - /** - * Initializes the state for AutoUpdate process - * @returns {$.Deferred} - a jquery promise, - * that is resolved with success or failure - * of state initialization - */ - function initializeState() { - var result = $.Deferred(); + //Bail out if update domain could not be created + if (!updateDomain) { + return; + } - FileSystem.resolve(updateDir, function (err) { - if (!err) { - result.resolve(); - } else { - var directory = FileSystem.getDirectoryForPath(updateDir); - directory.create(function (error) { - if (error) { - console.error('AutoUpdate : Error in creating update directory in Appdata'); - result.reject(); - } else { - result.resolve(); - } - }); - } - }); + // Check if the update domain is properly initialised + updateDomain.promise() + .done(function () { + setupAutoUpdatePreference(); + if (_isAutoUpdateEnabled()) { + setupAutoUpdate(); + UpdateNotification.registerUpdateHandler(_updateProcessHandler); + } + }) + .fail(function (err) { + console.error("AutoUpdate : node domain could not be initialized."); + return; + }); + }); - return result.promise(); - } /** * Enables/disables the state of "Check For Updates" menu entry under Help Menu @@ -447,7 +508,8 @@ define(function (require, exports, module) { function handleSafeToDownload() { var downloadFn = function () { if (isFirstIterationDownload()) { - // For the first iteration of download, show download status info in Status bar, and pass download to node + // For the first iteration of download, show download + //status info in Status bar, and pass download to node UpdateStatus.showUpdateStatus("initial-download"); postMessageToNode(MessageIds.DOWNLOAD_INSTALLER, true); } else { @@ -560,21 +622,30 @@ define(function (require, exports, module) { }); } + /** - * Registers the App Quit event handler, in case of dirty file save cancelled scenario, while Auto Update is scheduled to run on quit + * Handles the Cancel button click by user in + * Unsaved changes prompt, which would come up if user + * has dirty files and he/she clicked UpdateNow */ - function setAppQuitHandler() { - resetAppQuitHandler(); - DocumentCommandHandlers.on(APP_QUIT_CANCELLED, dirtyFileSaveCancelled); + function dirtyFileSaveCancelled() { + UpdateInfoBar.showUpdateBar({ + type: "warning", + title: Strings.WARNING_TYPE, + description: Strings.UPDATE_ON_NEXT_LAUNCH + }); } /** - * Unregisters the App Quit event handler + * Registers the App Quit event handler, in case of dirty + * file save cancelled scenario, while Auto Update is scheduled to run on quit */ - function resetAppQuitHandler() { - DocumentCommandHandlers.off(APP_QUIT_CANCELLED); + function setAppQuitHandler() { + resetAppQuitHandler(); + DocumentCommandHandlers.on(APP_QUIT_CANCELLED, dirtyFileSaveCancelled); } + /** * Initiates the update process, when user clicks UpdateNow in the update popup * @param {string} formattedInstallerPath - formatted path to the latest installer @@ -611,19 +682,20 @@ define(function (require, exports, module) { }; if (brackets.platform === "mac") { - var additionalParams = getAdditionalParams(); + var additionalParams = getAdditionalParams(), + key; - for (var key in additionalParams) { - if(additionalParams.hasOwnProperty(key)) { + for (key in additionalParams) { + if (additionalParams.hasOwnProperty(key)) { infoObj[key] = additionalParams[key]; } } } // Set update parameters for app update - if(brackets.app.setUpdateParams) { + if (brackets.app.setUpdateParams) { brackets.app.setUpdateParams(JSON.stringify(infoObj), function (err) { - if(err) { + if (err) { resetStateInFailure("AutoUpdate : Update parameters could not be set for the installer. Error encountered: " + err); } else { setAppQuitHandler(); @@ -757,30 +829,6 @@ define(function (require, exports, module) { } - /** - * Handles the auto update event, which is triggered when user clicks GetItNow in UpdateNotification dialog - * @param {object} updateParams - json object containing update information { - * installerName - name of the installer - * downloadURL - download URL - * latestBuildNumber - build number - * checksum - checksum } - */ - function initiateAutoUpdate(updateParams) { - _updateParams = updateParams; - downloadAttemptsRemaining = MAX_DOWNLOAD_ATTEMPTS; - - initializeState() - .done(function () { - postMessageToNode(MessageIds.INITIALIZE_STATE, _updateParams); - }) - .fail(function () { - UpdateInfoBar.showUpdateBar({ - type: "error", - title: Strings.INITIALISATION_FAILED, - description: "" - }); - }); - } /** * Handles the completion of node state initialization @@ -790,18 +838,6 @@ define(function (require, exports, module) { getLatestInstaller(); } - /** - * Handles the Cancel button click by user in - * Unsaved changes prompt, which would come up if user - * has dirty files and he/she clicked UpdateNow - */ - function dirtyFileSaveCancelled() { - UpdateInfoBar.showUpdateBar({ - type: "warning", - title: Strings.WARNING_TYPE, - description: Strings.UPDATE_ON_NEXT_LAUNCH - }); - } /** * Handles Download completion callback from Node @@ -811,16 +847,6 @@ define(function (require, exports, module) { validateChecksum(); } - /** - * Receives messages from node - * @param {object} event - event received from node - * @param {object} msgObj - json containing - { - * fn - function to execute on Brackets side - * args - arguments to the above function - */ - function receiveMessageFromNode(event, msgObj) { - functionMap[msgObj.fn].apply(null, msgObj.args); - } /** * Generates a map for brackets side functions diff --git a/src/extensions/default/AutoUpdate/node/package.json b/src/extensions/default/AutoUpdate/node/package.json index cf70b60103b..6bf7cd06622 100644 --- a/src/extensions/default/AutoUpdate/node/package.json +++ b/src/extensions/default/AutoUpdate/node/package.json @@ -1,22 +1,8 @@ { - "name": "autoupdatedomain", - "version": "1.0.0", - "description": "Node Domain For Auto Update", - "main": "AutoUpdateDomain.js", + "name": "brackets-auto-update", "dependencies": { "request": "^2.83.0", "request-progress": "^3.0.0", "fs-extra": "^5.0.0" - }, - "devDependencies": {}, - "scripts": { - "test": "none" - }, - "keywords": [ - "Brackets", - "Auto", - "Update" - ], - "author": "Adobe", - "license": "MIT" + } }