Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.

Commit 3d92fdb

Browse files
committed
Support disabling/enabling extensions in UI.
1 parent 314d7ff commit 3d92fdb

File tree

7 files changed

+605
-98
lines changed

7 files changed

+605
-98
lines changed

src/extensibility/ExtensionManager.js

Lines changed: 122 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,9 @@ define(function (require, exports, module) {
104104
/**
105105
* Requested changes to the installed extensions.
106106
*/
107-
var _idsToRemove = [],
108-
_idsToUpdate = [];
107+
var _idsToRemove = {},
108+
_idsToUpdate = {},
109+
_idsToDisable = {};
109110

110111
PreferencesManager.stateManager.definePreference(FOLDER_AUTOINSTALL, "object", undefined);
111112

@@ -187,8 +188,9 @@ define(function (require, exports, module) {
187188
*/
188189
function _reset() {
189190
exports.extensions = extensions = {};
190-
_idsToRemove = [];
191-
_idsToUpdate = [];
191+
_idsToRemove = {};
192+
_idsToUpdate = {};
193+
_idsToDisable = {};
192194
}
193195

194196
/**
@@ -267,7 +269,7 @@ define(function (require, exports, module) {
267269
metadata: metadata,
268270
path: path,
269271
locationType: locationType,
270-
status: (e.type === "loadFailed" ? START_FAILED : (metadata.disabled ? DISABLED : ENABLED))
272+
status: (e.type === "loadFailed" ? START_FAILED : (e.type === "disabled" ? DISABLED : ENABLED))
271273
};
272274

273275
synchronizeEntry(id);
@@ -406,6 +408,60 @@ define(function (require, exports, module) {
406408
}
407409
return result.promise();
408410
}
411+
412+
/**
413+
* Disables the installed extension with the given id.
414+
*
415+
* @param {string} id The id of the extension to disable.
416+
* @return {$.Promise} A promise that's resolved when the extenion is disabled or
417+
* rejected with an error that prevented the disabling.
418+
*/
419+
function disable(id) {
420+
var result = new $.Deferred(),
421+
extension = extensions[id];
422+
if (extension && extension.installInfo) {
423+
Package.disable(extension.installInfo.path)
424+
.done(function () {
425+
extension.installInfo.status = DISABLED;
426+
extension.installInfo.metadata.disabled = true;
427+
result.resolve();
428+
exports.trigger("statusChange", id);
429+
})
430+
.fail(function (err) {
431+
result.reject(err);
432+
});
433+
} else {
434+
result.reject(StringUtils.format(Strings.EXTENSION_NOT_INSTALLED, id));
435+
}
436+
return result.promise();
437+
}
438+
439+
/**
440+
* Enables the installed extension with the given id.
441+
*
442+
* @param {string} id The id of the extension to enable.
443+
* @return {$.Promise} A promise that's resolved when the extenion is enabled or
444+
* rejected with an error that prevented the enabling.
445+
*/
446+
function enable(id) {
447+
var result = new $.Deferred(),
448+
extension = extensions[id];
449+
if (extension && extension.installInfo) {
450+
Package.enable(extension.installInfo.path)
451+
.done(function () {
452+
extension.installInfo.status = ENABLED;
453+
extension.installInfo.metadata.disabled = false;
454+
result.resolve();
455+
exports.trigger("statusChange", id);
456+
})
457+
.fail(function (err) {
458+
result.reject(err);
459+
});
460+
} else {
461+
result.reject(StringUtils.format(Strings.EXTENSION_NOT_INSTALLED, id));
462+
}
463+
return result.promise();
464+
}
409465

410466
/**
411467
* Updates an installed extension with the given package file.
@@ -460,7 +516,7 @@ define(function (require, exports, module) {
460516
}
461517
exports.trigger("statusChange", id);
462518
}
463-
519+
464520
/**
465521
* Returns true if an extension is marked for removal.
466522
* @param {string} id The id of the extension to check.
@@ -469,7 +525,7 @@ define(function (require, exports, module) {
469525
function isMarkedForRemoval(id) {
470526
return !!(_idsToRemove[id]);
471527
}
472-
528+
473529
/**
474530
* Returns true if there are any extensions marked for removal.
475531
* @return {boolean} true if there are extensions to remove
@@ -478,6 +534,39 @@ define(function (require, exports, module) {
478534
return Object.keys(_idsToRemove).length > 0;
479535
}
480536

537+
/**
538+
* Marks an extension for disabling later, or unmarks an extension previously marked.
539+
*
540+
* @param {string} id The id of the extension
541+
* @param {boolean} mark Whether to mark or unmark the extension.
542+
*/
543+
function markForDisabling(id, mark) {
544+
if (mark) {
545+
_idsToDisable[id] = true;
546+
} else {
547+
delete _idsToDisable[id];
548+
}
549+
exports.trigger("statusChange", id);
550+
}
551+
552+
/**
553+
* Returns true if an extension is mark for disabling.
554+
*
555+
* @param {string} id The id of the extension to check.
556+
* @return {boolean} true if it's been mark for disabling, false otherwise.
557+
*/
558+
function isMarkedForDisabling(id) {
559+
return !!(_idsToDisable[id]);
560+
}
561+
562+
/**
563+
* Returns true if there are any extensions marked for disabling.
564+
* @return {boolean} true if there are extensions to disable
565+
*/
566+
function hasExtensionsToDisable() {
567+
return Object.keys(_idsToDisable).length > 0;
568+
}
569+
481570
/**
482571
* If a downloaded package appears to be an update, mark the extension for update.
483572
* If an extension was previously marked for removal, marking for update will
@@ -550,6 +639,25 @@ define(function (require, exports, module) {
550639
}
551640
);
552641
}
642+
643+
/**
644+
* Disables extensions marked for disabling.
645+
*
646+
* If the return promise is rejected, the argument will contain an array of objects. Each
647+
* element is an object identifying the extension failed with "item" property set to the
648+
* extension id which has failed to be disabled and "error" property set to the error.
649+
*
650+
* @return {$.Promise} A promise that's resolved when all extensions marked for disabling are
651+
* disabled or rejected if one or more extensions can't be disabled.
652+
*/
653+
function disableMarkedExtensions() {
654+
return Async.doInParallel_aggregateErrors(
655+
Object.keys(_idsToDisable),
656+
function (id) {
657+
return disable(id);
658+
}
659+
);
660+
}
553661

554662
/**
555663
* Updates extensions previously marked for update.
@@ -784,24 +892,31 @@ define(function (require, exports, module) {
784892
exports.getExtensionURL = getExtensionURL;
785893
exports.remove = remove;
786894
exports.update = update;
895+
exports.disable = disable;
896+
exports.enable = enable;
787897
exports.extensions = extensions;
788898
exports.cleanupUpdates = cleanupUpdates;
789899
exports.markForRemoval = markForRemoval;
790900
exports.isMarkedForRemoval = isMarkedForRemoval;
791901
exports.unmarkAllForRemoval = unmarkAllForRemoval;
792902
exports.hasExtensionsToRemove = hasExtensionsToRemove;
903+
exports.markForDisabling = markForDisabling;
904+
exports.isMarkedForDisabling = isMarkedForDisabling;
905+
exports.hasExtensionsToDisable = hasExtensionsToDisable;
793906
exports.updateFromDownload = updateFromDownload;
794907
exports.removeUpdate = removeUpdate;
795908
exports.isMarkedForUpdate = isMarkedForUpdate;
796909
exports.hasExtensionsToUpdate = hasExtensionsToUpdate;
797910
exports.removeMarkedExtensions = removeMarkedExtensions;
911+
exports.disableMarkedExtensions = disableMarkedExtensions;
798912
exports.updateExtensions = updateExtensions;
799913
exports.getAvailableUpdates = getAvailableUpdates;
800914
exports.cleanAvailableUpdates = cleanAvailableUpdates;
801915

802916
exports.hasDownloadedRegistry = false;
803917

804918
exports.ENABLED = ENABLED;
919+
exports.DISABLED = DISABLED;
805920
exports.START_FAILED = START_FAILED;
806921

807922
exports.LOCATION_DEFAULT = LOCATION_DEFAULT;

0 commit comments

Comments
 (0)