From fd1b3b4fee271108794ca4150c84cce7e56a6243 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 14 Oct 2011 18:06:03 -0400 Subject: [PATCH] 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 --- js/ui/extensionSystem.js | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js index c30da01cc..95c3a29ed 100644 --- a/js/ui/extensionSystem.js +++ b/js/ui/extensionSystem.js @@ -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) {