[Pkg-mozext-commits] [tabmixplus] 05/10: Incompatibility with new TabGroup extension that replaced Firefox build-in panorama

David Prévot taffit at moszumanska.debian.org
Tue Dec 29 19:03:19 UTC 2015


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to tag 0.4.2.1pre.151226a1
in repository tabmixplus.

commit a85a7898350d559bedb4d5690ed8ac46b2852753
Author: onemen <tabmix.onemen at gmail.com>
Date:   Sat Dec 26 14:40:41 2015 +0200

    Incompatibility with new TabGroup extension that replaced Firefox build-in panorama
---
 chrome/content/minit/minit.js       |  19 ++++-
 chrome/content/minit/tabView.js     | 162 ++++++++++++++++++++----------------
 chrome/content/session/session.js   |  21 +++--
 chrome/content/tabmix.js            |   9 +-
 modules/extensions/AddonManager.jsm |  29 +++++++
 5 files changed, 150 insertions(+), 90 deletions(-)

diff --git a/chrome/content/minit/minit.js b/chrome/content/minit/minit.js
index 0aa3644..680cc59 100644
--- a/chrome/content/minit/minit.js
+++ b/chrome/content/minit/minit.js
@@ -907,13 +907,24 @@ Tabmix.hidePopup = function TMP_hidePopup(aPopupMenu) {
   }
 };
 
-var TMP_TabView = { /* jshint ignore: line */
+var TMP_TabView = {
+  subScriptLoaded: false,
+  init: function() {
+    try {
+      if (this.installed) {
+        this._patchBrowserTabview();
+      }
+    } catch (ex) {
+      Tabmix.assert(ex);
+    }
+  },
+
   get installed() {
-    delete this.installed;
     let installed = typeof TabView == "object";
-    if (installed)
+    if (installed && !this.subScriptLoaded) {
       Services.scriptloader.loadSubScript("chrome://tabmixplus/content/minit/tabView.js", window);
-    return (this.installed = installed);
+    }
+    return installed;
   },
 
   exist: function(id) {
diff --git a/chrome/content/minit/tabView.js b/chrome/content/minit/tabView.js
index 149bf47..0e28047 100644
--- a/chrome/content/minit/tabView.js
+++ b/chrome/content/minit/tabView.js
@@ -1,5 +1,8 @@
+  /* globals TabItems */
   "use strict";
 
+  TMP_TabView.subScriptLoaded = true;
+
   TMP_TabView.handleEvent = function(aEvent) {
     switch (aEvent.type) {
       case "tabviewshown":
@@ -30,6 +33,9 @@
           }, 0, aEvent);
         }
         break;
+      case "willshowtabview":
+        Tabmix.slideshow.cancel();
+        break;
     }
   };
 
@@ -41,6 +47,11 @@
    */
 
   TMP_TabView._patchBrowserTabview = function SM__patchBrowserTabview() {
+    if (TabView.hasOwnProperty("tabmixInitialized")) {
+      return;
+    }
+    TabView.tabmixInitialized = true;
+
     var tabView = document.getElementById("tab-view-deck");
     if (tabView) {
       tabView.addEventListener("tabviewhidden", this, true);
@@ -50,14 +61,20 @@
     }
 
     // we need to stop tabs slideShow before Tabview starts
-    let $LF = '\n      ';
-    Tabmix.changeCode(TabView, "TabView.toggle")._replace(
-      'this.show();',
-      '{' + $LF +
-      '  Tabmix.slideshow.cancel();' + $LF +
-      '  $&' + $LF +
-      '}'
-    ).toCode(true);
+    if (window.hasOwnProperty("tabGroups")) {
+      // Tab Groups extension by Quicksaver
+      // https://addons.mozilla.org/en-US/firefox/addon/tab-groups-panorama/
+      window.addEventListener("willshowtabview", this, true);
+    } else {
+      let $LF = '\n      ';
+      Tabmix.changeCode(TabView, "TabView.toggle")._replace(
+        'this.show();',
+        '{' + $LF +
+        '  Tabmix.slideshow.cancel();' + $LF +
+        '  $&' + $LF +
+        '}'
+      ).toCode();
+    }
 
     // don't do anything if Session Manager extension installed
     if (Tabmix.extensions.sessionManager)
@@ -83,41 +100,51 @@
   TMP_TabView._patchInitialized = false;
   TMP_TabView._patchTabviewFrame = function SM__patchTabviewFrame() {
     this._patchInitialized = true;
-    // Firefox 8.0 use strict mode - we need to map global variable
     TabView._window.GroupItems._original_reconstitute = TabView._window.GroupItems.reconstitute;
-    Tabmix.changeCode(TabView._window.GroupItems, "TabView._window.GroupItems.reconstitute")._replace(
-      '"use strict";',
-      '$&' +
-      'let win = TabView._window;' +
-      'let GroupItem = win.GroupItem;' +
-      'let iQ = win.iQ;' +
-      'let UI = win.UI;' +
-      'let Utils = win.Utils;' +
-      'let GroupItems = win.GroupItems;' +
-      'let Storage = win.Storage;', {silent: true}
-    )._replace(
-      'this.',
-      'GroupItems.', {flags: "g"}
-    )._replace(
-      // This group is re-used by session restore
-      // make sure all of its children still belong to this group.
-      // Do it before setBounds trigger data save that will overwrite
-      // session restore data.
-      // We call TabItems.resumeReconnecting later to reconnect the tabItem.
-      'groupItem.userSize = data.userSize;',
-      'groupItem.getChildren().forEach(function TMP_GroupItems_reconstitute_groupItem_forEach(tabItem) {' +
-      '  var tabData = TabmixSessionData.getTabValue(tabItem.tab, "tabview-tab", true);' +
-      '  if (!tabData || tabData.groupID != data.id) {' +
-      '    tabItem._reconnected = false;' +
-      '  }' +
-      '});' +
-      '$&'
-    ).toCode();
+    TabView._window.GroupItems.reconstitute = function(groupItemsData, groupItemData) {
+      let validate = function(groupItem, data) {
+        // This group is re-used by session restore
+        // make sure all of its children still belong to this group.
+        // Do it before setBounds trigger data save that will overwrite
+        // session restore data.
+        // TabView will use TabItems.resumeReconnecting or UI.reset to reconnect the tabItem.
+        groupItem.getChildren().forEach(tabItem => {
+          let tabData = TabmixSessionData.getTabValue(tabItem.tab, "tabview-tab", true);
+          if (!tabData || tabData.groupID != data.id) {
+            tabItem._reconnected = false;
+          }
+        });
+      };
+      if (groupItemData) {
+        let storageSanity = this.groupItemStorageSanity || this.storageSanityGroupItem;
+        let ids = Object.keys(groupItemData);
+        for (let id of ids) {
+          let data = groupItemData[id];
+          if (storageSanity(data)) {
+            let groupItem = this.groupItem(data.id);
+            if (groupItem && !groupItem.hidden) {
+              validate(groupItem, data);
+            }
+          }
+        }
+      }
+      this._original_reconstitute.apply(this, arguments);
+    };
+
+    let fn = TabView._window.UI._original_reset = TabView._window.UI.reset;
+    if (window.hasOwnProperty("tabGroups")) {
+      // reconnect tabs that we disconnected in reconstitute
+      TabView._window.UI.reset = function() {
+        TabItems.resumeReconnecting();
+        this._original_reset.apply(this, arguments);
+      };
+      return;
+    }
 
     // add tab to the new group on tabs order not tabItem order
-    TabView._window.UI._original_reset = TabView._window.UI.reset;
+    let isStrict = (f) => f.toString().indexOf('"use strict";') > -1;
     Tabmix.changeCode(TabView._window.UI, "TabView._window.UI.reset")._replace(
-      '"use strict";',
+      isStrict(fn) ? '"use strict";' : '{',
       '$&' +
       'let win = TabView._window;' +
       'let Trenches = win.Trenches;' +
@@ -139,36 +166,10 @@
        if (tab.pinned) return;\
        let item = tab._tabViewTabItem;'
     )._replace(
-      'groupItem.add(item, {immediately: true});',
+      /groupItem.add\(.*\);/,
       'item._reconnected = true; \
        $&'
-    )._replace(
-      /(\})(\)?)$/,
-      '  GroupItems.groupItems.forEach(function(group) {' +
-      '    if (group != groupItem)' +
-      '      group.close();' +
-      '  });' +
-      ' $1$2'
     ).toCode();
-
-    TabView._window.TabItems._original_resumeReconnecting = TabView._window.TabItems.resumeReconnecting;
-    TabView._window.TabItems.resumeReconnecting = function TabItems_resumeReconnecting() {
-      let TabItems = TabView._window.TabItems;
-      let Utils = TabView._window.Utils;
-      Utils.assertThrow(TabItems._reconnectingPaused, "should already be paused");
-      TabItems._reconnectingPaused = false;
-      Array.forEach(gBrowser.tabs, function(tab) {
-        if (tab.pinned)
-          return;
-        let item = tab._tabViewTabItem;
-        if ("__tabmix_reconnected" in item && !item.__tabmix_reconnected) {
-          item._reconnected = false;
-          delete item.__tabmix_reconnected;
-        }
-        if (!item._reconnected)
-          item._reconnect();
-      });
-    };
   };
 
   TMP_TabView._resetTabviewFrame = function SM__resetTabviewFrame() {
@@ -179,14 +180,13 @@
       gBrowser.tabContainer.removeEventListener("TabShow", this, true);
       gBrowser.tabContainer.removeEventListener("TabHide", this, true);
     }
+    window.removeEventListener("willshowtabview", this, true);
 
     if (this._patchInitialized && TabView._window) {
       TabView._window.GroupItems.reconstitute = TabView._window.GroupItems._original_reconstitute;
       delete TabView._window.GroupItems._original_reconstitute;
       TabView._window.UI.reset = TabView._window.UI._original_reset;
-      TabView._window.TabItems.resumeReconnecting = TabView._window.TabItems._original_resumeReconnecting;
       delete TabView._window.UI._original_reset;
-      delete TabView._window.TabItems._original_resumeReconnecting;
     }
   };
 
@@ -195,6 +195,10 @@
   // aWindow: rdfNodeWindow to read from
   TabmixSessionManager._setWindowStateBusy = function SM__setWindowStateBusy(aWindow) {
     TabmixSvc.SessionStore._setWindowStateBusy(window);
+    if (!this.tabViewInstalled) {
+      return;
+    }
+
     TMP_SessionStore.initService();
     this._getSessionTabviewData(aWindow);
 
@@ -208,6 +212,10 @@
     if (Tabmix.isVersion(350)) {
       TabmixSvc.SessionStore._setWindowStateReady(window);
     }
+    if (!this.tabViewInstalled) {
+      this.notifyAboutMissingTabView(showNotification);
+      return;
+    }
 
     if (!aOverwriteTabs)
       this._groupItems = this._tabviewData["tabview-group"];
@@ -261,6 +269,10 @@
   };
 
   TabmixSessionManager._saveTabviewData = function SM__saveTabviewData() {
+    if (!this.tabViewInstalled) {
+      return;
+    }
+
     for (let id of Object.keys(this._tabviewData)) {
       this._setTabviewData(id, this._tabviewData[id]);
     }
@@ -279,7 +291,7 @@
   };
 
   TabmixSessionManager._setTabviewTab = function SM__setTabviewTab(aTab, tabdata, activeGroupId) {
-    if (tabdata.pinned)
+    if (!this.tabViewInstalled || tabdata.pinned)
       return;
 
     let parsedData;
@@ -409,6 +421,10 @@
   * blankTabs: remaining blank tabs in this windows
   */
   TabmixSessionManager._preperTabviewData = function SM__preperTabviewData(loadOnStartup, blankTabs) {
+    if (!this.tabViewInstalled) {
+      return;
+    }
+
     let newGroupItems = this._tabviewData["tabview-group"];
     let groupItems = TabmixSessionData.getWindowValue(window, "tabview-group", true);
     let newGroupItemsIsEmpty = this.isEmptyObject(newGroupItems);
@@ -540,13 +556,15 @@
   // update page bounds when we overwrite tabs
   TabmixSessionManager._setUIpageBounds = function SM__setUIpageBounds() {
     if (TabView._window) {
-      let data = TabView._window.Storage.readUIData(window);
+      let data = TabmixSessionData.getWindowValue(window, "tabview-ui", true);
       if (this.isEmptyObject(data))
         return;
 
-      TabView._window.UI._storageSanity(data);
-      if (data && data.pageBounds)
+      let UI = TabView._window.UI;
+      let storageSanity = UI._storageSanity || UI.storageSanity;
+      if (storageSanity(data) && data.pageBounds) {
         TabView._window.UI._pageBounds = data.pageBounds;
+      }
     }
   };
 
diff --git a/chrome/content/session/session.js b/chrome/content/session/session.js
index c72e7ec..388e8d6 100644
--- a/chrome/content/session/session.js
+++ b/chrome/content/session/session.js
@@ -271,8 +271,9 @@ var TabmixSessionManager = { // jshint ignore:line
 
     if (Tabmix.isVersion(250, 250) && !TabmixSvc.sm.promiseInitialized) {
       Tabmix.ssPromise = aPromise || TabmixSvc.ss.promiseInitialized;
-      Tabmix.ssPromise.then(initializeSM)
-        .then(null, Tabmix.reportError);
+      Tabmix.ssPromise.then(() => TMP_TabView.init())
+                      .then(initializeSM)
+                      .then(null, Tabmix.reportError);
     }
     else
       initializeSM();
@@ -2539,14 +2540,14 @@ var TabmixSessionManager = { // jshint ignore:line
       return;
     let tabview = this.tabViewInstalled && TabView._window;
     if (tabview) {
-      // update all tabs when we exit panorama (tabviewhidden)
       if (aBackup) {
+        // update all tabs when we enter/exit panorama
         Array.forEach(gBrowser.tabs, function SM_saveTabViewData_forEach(tab) {
           this.saveTabviewTab(this.getNodeForTab(tab), tab);
         }, this);
       } else {
-        // we don't need to save again when we exit panorama (tabviewhidden event)
         // force Tabview to save when we save all window data
+        // we will collect the data from SessionStore
         tabview.UI._save();
         tabview.GroupItems.saveAll();
         tabview.TabItems.saveAll();
@@ -3802,18 +3803,24 @@ var TabmixSessionManager = { // jshint ignore:line
   /* ............... TabView Data ............... */
 
   get tabViewInstalled() {
-    delete this.tabViewInstalled;
-    return (this.tabViewInstalled = TMP_TabView.installed);
+    return TMP_TabView.installed;
   },
 
+  notifyAboutMissingTabView: function() {
+    // TODO: notify the user when TabView is missing and the restored session
+    // contains groups
+  },
+
+  // we override these functions when TabView exist
   _setWindowStateBusy: function() {
     TabmixSvc.SessionStore._setWindowStateBusy(window);
   },
 
-  _setWindowStateReady: function() {
+  _setWindowStateReady: function(aOverwriteTabs, showNotification) {
     if (Tabmix.isVersion(350)) {
       TabmixSvc.SessionStore._setWindowStateReady(window);
     }
+    this.notifyAboutMissingTabView(showNotification);
   },
 
   _saveTabviewData: function() { },
diff --git a/chrome/content/tabmix.js b/chrome/content/tabmix.js
index fe71988..0cda856 100644
--- a/chrome/content/tabmix.js
+++ b/chrome/content/tabmix.js
@@ -178,6 +178,8 @@ Tabmix.getAfterTabsButtonsWidth = function TMP_getAfterTabsButtonsWidth() {
 Tabmix.delayedStartup = function TMP_delayedStartup() {
   TabmixTabbar._enablePositionCheck = true;
 
+  TMP_TabView.init();
+
   if (this.isVersion(250) && this.ssPromise && !TabmixSvc.sm.promiseInitialized)
     this.ssPromise.then(this.sessionInitialized.bind(this), Tabmix.reportError);
   else
@@ -400,13 +402,6 @@ var TMP_eventListener = {
     // url-fixer also prevent the use of eval changes by using closure in the replcaed function
     Tabmix.navToolbox.initializeURLBar();
     Tabmix.navToolbox.initializeSearchbar();
-
-    try {
-      if (TMP_TabView.installed)
-        TMP_TabView._patchBrowserTabview();
-    } catch (ex) {
-      Tabmix.assert(ex);
-    }
   },
 
   onWindowOpen: function TMP_EL_onWindowOpen() {
diff --git a/modules/extensions/AddonManager.jsm b/modules/extensions/AddonManager.jsm
index 02f9d2e..dbcba61 100644
--- a/modules/extensions/AddonManager.jsm
+++ b/modules/extensions/AddonManager.jsm
@@ -15,6 +15,31 @@ const GOOGLE_REGEXP = /http(s)?:\/\/((www|encrypted|news|images)\.)?google\.(.*?
 const GOOGLE_IMGRES_REGEXP = /http(s)?:\/\/(.*?\.)?google\.(.*?)\/imgres\?/;
 const GOOGLE_PLUS_REGEXP = /http(s)?:\/\/plus.url.google.com\/url\?/;
 
+// https://addons.mozilla.org/en-US/firefox/addon/tab-groups-panorama/
+// check if TabView exist in a window and update our code if not initialized
+// since more than one extension can replace panorama we check if we need to
+// update the code after every extensions change
+var TabGroups = {
+  tabViewState: false,
+  isUpdateNeeded: function() {
+    let win = TabmixSvc.topWin();
+    let needUpdate = typeof win.TabView == "object" &&
+        !win.TabView.hasOwnProperty("tabmixInitialized");
+    let currentState = this.tabViewState;
+    this.tabViewState = needUpdate;
+    return needUpdate && !currentState;
+  },
+  onEnabled: function() {
+    if (this.isUpdateNeeded()) {
+      TabmixSvc.forEachBrowserWindow(function(aWindow) {
+        aWindow.TMP_TabView.init();
+      });
+    }
+  },
+  onDisabled: function() {
+  },
+};
+
 // https://addons.mozilla.org/en-US/firefox/addon/google-no-tracking-url/
 var GoogleNoTrackingUrl = {
   id: "jid1-zUrvDCat3xoDSQ at jetpack",
@@ -95,6 +120,8 @@ var TabmixListener = {
       SessionManager.init();
     } else if (id == GoogleNoTrackingUrl.id) {
       GoogleNoTrackingUrl.onEnabled();
+    } else {
+      TabGroups.onEnabled();
     }
   },
   onChange: function(aAddon, aAction) {
@@ -105,6 +132,8 @@ var TabmixListener = {
       PrivateTab[aAction]();
     } else if (id == GoogleNoTrackingUrl.id) {
       GoogleNoTrackingUrl[aAction]();
+    } else {
+      TabGroups[aAction]();
     }
   },
   onEnabled: function(aAddon) {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/tabmixplus.git



More information about the Pkg-mozext-commits mailing list