2014-10-27 79 views
2

我正在尋找一種方法來阻止使用Firefox插件sdk關閉選項卡。防止用Firefox插件sdk關閉選項卡API

有沒有辦法做到這一點?

+0

請提供更多信息,您嘗試過的東西等。 – canuckistani 2014-10-27 17:56:23

+0

我查看了javascript onebeforeunload事件,這給我沒有足夠的自由度,例如定製消息。我也查找了關於在SO和Google上執行此操作的示例。當然,我查看了mdn上的標籤api,但找不到相應的事件,因爲關閉事件無法攔截關閉。 – 2014-10-27 21:07:00

+1

如果您說明了用例,可能會有幫助:您爲什麼要阻止用戶關閉該選項卡。提示:用戶是使用瀏覽器的用戶,通常應該能夠做他們想做的事。你應該有一個很好的理由。此外,SDK API傾向於關注用戶對其體驗的控制 - 您正在尋找的功能可能會對用戶控制起作用。 – canuckistani 2014-10-28 04:37:35

回答

3

好的男人在這裏是你想要的。以前的版本是看我是否可以在禁用前觸發,以便只在選項卡關閉時觸發,但我無法弄清楚。

以下是如何操作: 我們重寫removeTab函數。這裏繼guidlines:在你的插件的卸載MDN :: Overriding/Extending/Amending existing functions - Alternative: Replace + Function.apply()

// Keep a reference to the original function. 
    var _original = gBrowser.removeTab; 

    // Override a function. 
    gBrowser.removeTab = function() { 
    // Execute some action before the original function call. 
    if (window.myAddonIsInstalled = true) { 
     var closeit = confirm('are you sure you want to close the tab?') 

     // Execute original function. 
     if (closeit) { 
      var rv = _original.apply(gBrowser, arguments); 
     } 

     // return the original result 
     return rv; 
    } else { 
     var rv = _original.apply(gBrowser, arguments); 
     // return the original result 
     return rv; 
    } 
    }; 

確保window.myAddonIsInstalled的全球屬性設置爲false。因爲這是推薦的方法來禁用您的功能,每篇文章。

+0

看起來不錯,非常感謝!當我找到時間時,我會研究它。 – 2014-10-29 10:26:43

+1

這隻適用於基於XUL的插件。任何想法如何使這項工作的SDK插件? – 2015-07-09 14:20:24

+0

@MichaelGroße同樣的方式,你可以利用XUL的一些功能在那裏我不知道哪些人,但firefox-addon-sdk標籤中的人會知道 – Noitidart 2015-07-09 14:28:31

2

這是訣竅。可以複製粘貼代碼到暫存器並運行(與環境>當然,瀏覽器)

改編自點擊這裏:https://gist.github.com/Noitidart/9406437這是從:https://gist.github.com/Noitidart/51b62b356b3a21010a4d

它使用onbeforeunload的事情,它連接到所有頂層窗口的標籤的負載,還打開了與事件監聽器TabOpen

當你想撤消這個改變,運行windowListener.unregister()我給出了在窗口底部註釋掉的例子。但是如果您從暫存區運行取消註冊,請確保先排除頂部的內容,否則它不會註銷上次運行時註冊的內容,只會取消註冊當前運行中註冊的內容。

不是專爲插件-SDK,但你可以拖放到你的插件SDK這一點,但在頂部,你必須添加像var {Cu, Ci} = require('chrome'); Cu.import('resource://gre/modules/Services.jsm');

此代碼並修改警告模式的文本。

它不檢查是否有其他onbeforeunload已經註冊,它的一個ez檢查你應該添加,如果需要幫助讓我知道。

try { 
    windowListener.unregister(); 
} catch (ignore) {} 

var ignoreFrames = true; 

function beforeUnloader(e) { 
    //console.log('beforeUnload e:', e); //http://i.imgur.com/AbUn20J.png 
    var DOMWindow = e.target.defaultView.QueryInterface(Ci.nsIInterfaceRequestor) 
                .getInterface(Ci.nsIWebNavigation) 
                .QueryInterface(Ci.nsIDocShellTreeItem) 
                .rootTreeItem 
                .QueryInterface(Ci.nsIInterfaceRequestor) 
                .getInterface(Ci.nsIDOMWindow); 
    DOMWindow.setTimeout(function() { 
     try { 
      if (DOMWindow.gBrowser) { 
       var linkedBrowser = DOMWindow.gBrowser.getBrowserForDocument(e.target); 
      } else { 
       var linkedBrowser = DOMWindow.document; 
      } 
      var modal = linkedBrowser.parentNode.querySelector('tabmodalprompt'); 
      var warnTxtNode = modal.ownerDocument.getAnonymousElementByAttribute(modal, 'anonid', 'info.body').firstChild; 
      warnTxtNode.textContent = 'rawr'; 
     } catch (ex) { 
      console.warn('excpetion occured when trying to modify warn text, ex:', ex); 
     } 
    }, 10); 
    return 'dummy text so it shows unloader'; //see third bullet here: https://developer.mozilla.org/en-US/docs/WindowEventHandlers.onbeforeunload it says "Note that in Firefox 4 and later the returned string is not displayed to the user. Instead, Firefox displays the string "This page is asking you to confirm that you want to leave - data you have entered may not be saved." See bug 588292." 
}; 

function addInjections(theDoc) { 
    theDoc.defaultView.onbeforeunload = beforeUnloader; 
} 

function removeInjections(theDoc, skipChecks) { 
    theDoc.defaultView.onbeforeunload = null; 
} 

function tabopened(e) { 
    //console.info('tabopened: e:', e); //http://i.imgur.com/Re0Wmfn.png 
    addInjections(e.target.linkedBrowser.contentDocument); 
} 

function listenPageLoad(event) { 
    var win = event.originalTarget.defaultView; 
    var doc = win.document; 
    Cu.reportError('page loaded loc = ' + doc.location); 
    if (win.frameElement) { 
     //its a frame 
     Cu.reportError('its a frame'); 
     if (ignoreFrames) { 
      return;//dont want to watch frames 
     } 
    } 
    addInjections(doc); 
} 

/*start - windowlistener*/ 
var windowListener = { 
    //DO NOT EDIT HERE 
    onOpenWindow: function (aXULWindow) { 
     // Wait for the window to finish loading 
     let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow); 
     aDOMWindow.addEventListener("load", function() { 
      aDOMWindow.removeEventListener("load", arguments.callee, false); 
      windowListener.loadIntoWindow(aDOMWindow, aXULWindow); 
     }, false); 
    }, 
    onCloseWindow: function (aXULWindow) {}, 
    onWindowTitleChange: function (aXULWindow, aNewTitle) {}, 
    register: function() { 
     // Load into any existing windows 
     let XULWindows = Services.wm.getXULWindowEnumerator(null); 
     while (XULWindows.hasMoreElements()) { 
      let aXULWindow = XULWindows.getNext(); 
      let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow); 
      windowListener.loadIntoWindow(aDOMWindow, aXULWindow); 
     } 
     // Listen to new windows 
     Services.wm.addListener(windowListener); 
    }, 
    unregister: function() { 
     // Unload from any existing windows 
     let XULWindows = Services.wm.getXULWindowEnumerator(null); 
     while (XULWindows.hasMoreElements()) { 
      let aXULWindow = XULWindows.getNext(); 
      let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow); 
      windowListener.unloadFromWindow(aDOMWindow, aXULWindow); 
     } 
     //Stop listening so future added windows dont get this attached 
     Services.wm.removeListener(windowListener); 
    }, 
    //END - DO NOT EDIT HERE 
    loadIntoWindow: function (aDOMWindow, aXULWindow) { 
     if (!aDOMWindow) { 
      return; 
     } 
     if (aDOMWindow.gBrowser) { 
      aDOMWindow.gBrowser.addEventListener('DOMContentLoaded', listenPageLoad, false); 
      if (aDOMWindow.gBrowser.tabContainer) { 
       //has tabContainer 
       aDOMWindow.gBrowser.tabContainer.addEventListener("TabOpen", tabopened, false); 
       //start - go through all tabs in this window we just added to 
       var tabs = aDOMWindow.gBrowser.tabContainer.childNodes; 
       for (var i = 0; i < tabs.length; i++) { 
        Cu.reportError('DOING tab: ' + i); 
        var tabBrowser = tabs[i].linkedBrowser; 
        var win = tabBrowser.contentWindow; 
        loadIntoContentWindowAndItsFrames(win); 
       } 
       //end - go through all tabs in this window we just added to 
      } else { 
       //does not have tabContainer 
       var win = aDOMWindow.gBrowser.contentWindow; 
       loadIntoContentWindowAndItsFrames(win); 
      } 
     } else { 
      //window does not have gBrowser 
     } 
    }, 
    unloadFromWindow: function (aDOMWindow, aXULWindow) { 
     if (!aDOMWindow) { 
      return; 
     } 
     if (aDOMWindow.gBrowser) { 
      aDOMWindow.gBrowser.removeEventListener('DOMContentLoaded', listenPageLoad, false); 
      if (aDOMWindow.gBrowser.tabContainer) { 
       //has tabContainer 
       aDOMWindow.gBrowser.tabContainer.removeEventListener("TabOpen", tabopened, false); 
       //start - go through all tabs in this window we just added to 
       var tabs = aDOMWindow.gBrowser.tabContainer.childNodes; 
       for (var i = 0; i < tabs.length; i++) { 
        Cu.reportError('DOING tab: ' + i); 
        var tabBrowser = tabs[i].linkedBrowser; 
        var win = tabBrowser.contentWindow; 
        unloadFromContentWindowAndItsFrames(win); 
       } 
       //end - go through all tabs in this window we just added to 
      } else { 
       //does not have tabContainer 
       var win = aDOMWindow.gBrowser.contentWindow; 
       unloadFromContentWindowAndItsFrames(win); 
      } 
     } else { 
      //window does not have gBrowser 
     } 
    } 
}; 
/*end - windowlistener*/ 

function loadIntoContentWindowAndItsFrames(theWin) { 
    var frames = theWin.frames; 
    var winArr = [theWin]; 
    for (var j = 0; j < frames.length; j++) { 
     winArr.push(frames[j].window); 
    } 
    Cu.reportError('# of frames in tab: ' + frames.length); 
    for (var j = 0; j < winArr.length; j++) { 
     if (j == 0) { 
      Cu.reportError('**checking win: ' + j + ' location = ' + winArr[j].document.location); 
     } else { 
      Cu.reportError('**checking frame win: ' + j + ' location = ' + winArr[j].document.location); 
     } 
     var doc = winArr[j].document; 
     //START - edit below here 
     addInjections(doc); 
     if (ignoreFrames) { 
      break; 
     } 
     //END - edit above here 
    } 
} 

function unloadFromContentWindowAndItsFrames(theWin) { 
    var frames = theWin.frames; 
    var winArr = [theWin]; 
    for (var j = 0; j < frames.length; j++) { 
     winArr.push(frames[j].window); 
    } 
    Cu.reportError('# of frames in tab: ' + frames.length); 
    for (var j = 0; j < winArr.length; j++) { 
     if (j == 0) { 
      Cu.reportError('**checking win: ' + j + ' location = ' + winArr[j].document.location); 
     } else { 
      Cu.reportError('**checking frame win: ' + j + ' location = ' + winArr[j].document.location); 
     } 
     var doc = winArr[j].document; 
     //START - edit below here 
     removeInjections(doc); 
     if (ignoreFrames) { 
      break; 
     } 
     //END - edit above here 
    } 
} 

windowListener.register(); 
+0

哦,廢話我剛剛意識到,這在每次卸載時都會提示,而不僅僅是在關閉時。我們必須對其進行優化才能確定在關閉之前才能卸載 – Noitidart 2014-10-28 06:58:08