@@ -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