extensionSystem: Rebase the extension order list to help prevent conflicts

When two extensions monkey-patch the same area, enable() and disable() may
behave badly and completely wreck things. To solve this, when disabling
an extension, "rebase" the extension list so that monkey patches should be
added and removed in order.

https://bugzilla.gnome.org/show_bug.cgi?id=661815
This commit is contained in:
Jasper St. Pierre 2011-10-14 18:06:03 -04:00
parent 4ae2a0b2a5
commit fd1b3b4fee

View File

@ -64,6 +64,8 @@ const extensions = {};
const extensionStateObjs = {};
// Maps uuid -> [GFile to the extension directory, Extension type]
const extensionDirs = {};
// Contains the order that extensions were enabled in.
const extensionOrder = [];
// Arrays of uuids
var enabledExtensions;
@ -215,6 +217,27 @@ function disableExtension(uuid) {
let extensionState = extensionStateObjs[uuid];
// "Rebase" the extension order by disabling and then enabling extensions
// in order to help prevent conflicts.
// Example:
// order = [A, B, C, D, E]
// user disables C
// this should: disable E, disable D, disable C, enable D, enable E
let orderIdx = extensionOrder.indexOf(uuid);
let order = extensionOrder.slice(orderIdx + 1);
let orderReversed = order.slice().reverse();
for (let i = 0; i < orderReversed.length; i++) {
let uuid = orderReversed[i];
try {
extensionStateObjs[uuid].disable();
} catch(e) {
logExtensionError(uuid, e.toString());
}
}
try {
extensionState.disable();
} catch(e) {
@ -222,6 +245,15 @@ function disableExtension(uuid) {
return;
}
for (let i = 0; i < order.length; i++) {
let uuid = order[i];
try {
extensionStateObjs[uuid].enable();
} catch(e) {
logExtensionError(uuid, e.toString());
}
}
meta.state = ExtensionState.DISABLED;
_signals.emit('extension-state-changed', meta);
}
@ -241,6 +273,8 @@ function enableExtension(uuid) {
let extensionState = extensionStateObjs[uuid];
extensionOrder.push(uuid);
try {
extensionState.enable();
} catch(e) {