How to programmatically move a tab to another window in a firefox Addon-SDK extension?

删除回忆录丶 提交于 2020-01-02 06:30:33

问题


While it looks like you can change the order of a tab within a window by updating the tab .index property, it doesn't look like the tabs api directly supports the move of a tab to another window.

Am I missing something? Is there a viable workaround?


回答1:


It is possible through the low level module window/utils. The example below duplicates the active tab across every open window

const { getMostRecentBrowserWindow, windows: getWindows } = require("sdk/window/utils");

const { ActionButton } = require("sdk/ui/button/action");

var button = ActionButton({
  id: "duplicatetab-button",
  label: "Duplicate tab",
  icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACUElEQVQ4jaWTTWtTURCGjzc33CCpbVKN4kexC9EUY1Hov+iqPyDrbgtuCrViKUERqsWVguBGQaW4UiKiaEVxoShFGgnuBMUqNW3zce49Z+ZxUWtwoRR8YXbzPswM7xj+JgVEiXGsYVknxgII4Ltt5p8AB8RArOAUVQfqQJNtAFA8QgvF6i9PR1Dt0KbVBTjncM4hIni/OZv3HsRB+wvefiP2LcQnJIkQe49FEJFNQLPZZHh4mEwmQyqVoqenh3K5TGvlK1dOlageH+HG4DFar1/S0A6Lr99xdN8QxWKRXC6HGR0dJZvNMjk5Sb1ep1gskk6nuTo/D+/ec7dvkBdhP9cKeX7UXxEZQ2/YRxRFLC8vY+bm5qhUKnjvsdYyPj5OFEWcnTnHujiS5TfcPDbAw50h9w7u5f7UadLZFLVaDRHBiGzuY61lbGyMXC5HoVBgrbGGWAW/TvvxHR7s7udFKs/1oyfZ+PSRTqeDqm7eoFqtEoYhmUyG2dlZVJU4iREfI/WP3Nt9iMUdu7jdf5Anly5i0oaVlRWazSZmYWGBIAiIoohyucz09DQTExPMnJli9dlT5vcM8Kh3gFsHDuNqb9mb7yXMRBhjWFpawpRKJVKpFMYYgiAgDEOCIOD81BkunBjh8pEhKqUhGkvP6bQ/U//wgUP5/YRhSDabxbTbbVQV5xyq2q0kgR8NdOM7JKuo/Y5qggqIdPvMlnkrQCKCquJFsOrxeHAJxA48eFU6Xv4EqOpv41YqnQirqliv4MEmQtN7RBSs7wL+/gvb038DfgJnyUabbHzUbQAAAABJRU5ErkJggg==",
  onClick: function() {
    var xulwindows = getWindows("navigator:browser");
    var xulactivewindow = getMostRecentBrowserWindow();
    var xulactivetab = xulactivewindow.gBrowser.selectedTab;

    xulwindows.forEach(function(win){
      if(win === xulactivewindow)
        return;
      var duplicatedtab = win.gBrowser.duplicateTab(xulactivetab);
      win.gBrowser.moveTabTo(duplicatedtab, 0); // the second argument is the index
    });
  }
});



回答2:


@paa's solution is nice but it doesn't move a tab. His is duplicating the tab. So flash movies will not retain their position etc. And its not a move its a duplicatio, like he explained.

I did a lot of research was real fun. The way they move tabs in Firefox is via docShell swapping. This will accomplish what you want. It's written for bootstrap though so needs touch up for addon sdk.

Pass second argument as string of tabbed or non-tabbed if you want to move it to a new window. Else pass second argument an existing window and it will be moved there. can copy paste and run this code from sratchpad.

this uses the gBrowser.swapBrowsersAndCloseOther function

function moveTabToWin(aTab, tDOMWin) {
  //tDOMWin means target DOMWindow means the window you want the tab in
  //if tDOMWin == 'tabbed' or == 'non-tabbed' it opens in a new window
  //if aTopContWin is the last in its window, then its window is closed
  if (tDOMWin == 'tabbed' || tDOMWin == 'non-tabbed') {
    var sa = Cc["@mozilla.org/supports-array;1"].createInstance(Ci.nsISupportsArray);
    var wuri = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
    wuri.data = 'about:blank';
    sa.AppendElement(wuri);
    let features = "chrome,dialog=no";
    if (tDOMWin == 'tabbed') {
      features += ',all';
    }
    var sDOMWin = aTab.ownerGlobal; //source DOMWindow
    if (PrivateBrowsingUtils.permanentPrivateBrowsing || PrivateBrowsingUtils.isWindowPrivate(sDOMWin)) {
       features += ",private";
    } else {
       features += ",non-private";
    }
    var XULWindow = Services.ww.openWindow(null, 'chrome://browser/content/browser.xul', null, features, sa);
    XULWindow.addEventListener('load', function() {
      var DOMWindow = XULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
      DOMWindow.gBrowser.selectedTab.linkedBrowser.webNavigation.stop(Ci.nsIWebNavigation.STOP_ALL);
      DOMWindow.gBrowser.swapBrowsersAndCloseOther(DOMWindow.gBrowser.selectedTab, aTab);
      //DOMWindow.gBrowser.selectedTab = newTab;
    }, false);
  } else if (tDOMWin) {
    //existing dom window
    var newTab = tDOMWin.gBrowser.addTab('about:blank');
    newTab.linkedBrowser.webNavigation.stop(Ci.nsIWebNavigation.STOP_ALL);
    tDOMWin.gBrowser.swapBrowsersAndCloseOther(newTab, aTab);
    tDOMWin.gBrowser.selectedTab = newTab;
  }
}

moveTabToWin(gBrowser.selectedTab, 'tabbed');



回答3:


I'v got inspired by @Noitidart's answer and came up with my solution.

I'm adding setWindow(window, index) method to Tab's prototype, so that any SDK tab can be moved to another window from anywhere in the addon with a simple call like this:

browserWindows[0].activeTab.setWindow(browserWindows.activeWindow, 0);

This will move active tab of window 0 to the beginning of active window.

And here is the method:

Update:

I've put together a module to do exactly this: jetpack-tab-setwindow


Old solution (breaks in FF43)

var Tab = require("sdk/tabs/tab").Tab;

Tab.prototype.setWindow = function (window, index) {
    var tab = this;
    var oldWindow = tab.window;
    if ( oldWindow !== window ) {
        // We have to use lower-level API here
        var Ci      = require('chrome').Ci;
        var viewFor = require("sdk/view/core").viewFor;

        var aTab = viewFor(tab);
        var aWin = viewFor(window);
        var gBrowser = aWin.gBrowser;

        // Get tab properties
        var isSelected = oldWindow.activeTab == tab;
        var isPinned   = aTab.pinned;

        // Log for debugging:
        var tabId = tab.id;
        console.log('setWindow', {index, isSelected, isPinned, tab, tabId});

        // Create a placeholder-tab on destination windows
        var newTab = gBrowser.addTab('about:newtab');
        newTab.linkedBrowser.webNavigation.stop(Ci.nsIWebNavigation.STOP_ALL); // we don't need this tab anyways

        // If index specified, move placeholder-tab to desired index
        if ( index != undefined ) {
            var length = gBrowser.tabContainer.childElementCount;
            if ( index < 0 ) index = length - index;
            if( 0 <= index && index < length ) {
                gBrowser.moveTabTo(newTab, index);
            }
        }
        // Copy tab properties to placeholder-tab
        if ( isPinned ) {
            gBrowser.pinTab(newTab);
        }

        // For some reason this doesn't seem to work :-(
        if ( isSelected ) {
            gBrowser.selectedTab = newTab;
        }

        // Swap tabs and remove placeholder-tab
        gBrowser.swapBrowsersAndCloseOther(newTab, aTab);
    }
};


来源:https://stackoverflow.com/questions/26268297/how-to-programmatically-move-a-tab-to-another-window-in-a-firefox-addon-sdk-exte

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!