Bug 816406 - Disallow dragging a private tab into a non-private window and vice versa; r=dao

This commit is contained in:
Ehsan Akhgari 2012-12-02 15:57:06 -05:00
parent 7a3ea75982
commit 77bb9823b5
4 changed files with 80 additions and 9 deletions

View File

@ -1896,6 +1896,14 @@
<parameter name="aOtherTab"/>
<body>
<![CDATA[
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
// Do not allow transfering a private tab to a non-private window
// and vice versa.
if (PrivateBrowsingUtils.isWindowPrivate(window) !=
PrivateBrowsingUtils.isWindowPrivate(aOtherTab.ownerDocument.defaultView))
return;
#endif
// That's gBrowser for the other window, not the tab's browser!
var remoteBrowser = aOtherTab.ownerDocument.defaultView.gBrowser;
@ -3422,6 +3430,14 @@
sourceNode.ownerDocument.defaultView instanceof ChromeWindow &&
sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser" &&
sourceNode.ownerDocument.defaultView.gBrowser.tabContainer == sourceNode.parentNode) {
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
// Do not allow transfering a private tab to a non-private window
// and vice versa.
if (PrivateBrowsingUtils.isWindowPrivate(window) !=
PrivateBrowsingUtils.isWindowPrivate(sourceNode.ownerDocument.defaultView))
return dt.effectAllowed = "none";
#endif
#ifdef XP_MACOSX
return dt.effectAllowed = event.altKey ? "copy" : "move";
#else

View File

@ -320,6 +320,7 @@ _BROWSER_FILES += \
browser_save_link-perwindowpb.js \
browser_save_private_link_perwindowpb.js \
browser_tabMatchesInAwesomebar_perwindowpb.js \
browser_tab_drag_drop_perwindow.js \
$(NULL)
else
_BROWSER_FILES += \

View File

@ -0,0 +1,50 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
function test() {
//initialization
waitForExplicitFinish();
let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
getService(Ci.mozIJSSubScriptLoader);
let chromeUtils = {};
scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js", chromeUtils);
function testOnWindow(aIsPrivate, aCallback) {
whenNewWindowLoaded({private: aIsPrivate}, function(win) {
executeSoon(function() aCallback(win));
});
}
testOnWindow(false, function(aNormalWindow) {
testOnWindow(true, function(aPrivateWindow) {
// Open a tab in each window
let normalTab = aNormalWindow.gBrowser.addTab("about:blank", {skipAnimation: true});
let privateTab = aPrivateWindow.gBrowser.addTab("about:blank", {skipAnimation: true});
let effect = chromeUtils.synthesizeDrop(normalTab, privateTab,
[[{type: TAB_DROP_TYPE, data: normalTab}]],
null, aNormalWindow, EventUtils, aPrivateWindow);
is(effect, "none", "Should not be able to drag a normal tab to a private window");
effect = chromeUtils.synthesizeDrop(privateTab, normalTab,
[[{type: TAB_DROP_TYPE, data: privateTab}]],
null, aPrivateWindow, EventUtils, aNormalWindow);
is(effect, "none", "Should not be able to drag a private tab to a normal window");
aNormalWindow.gBrowser.swapBrowsersAndCloseOther(normalTab, privateTab);
is(aNormalWindow.gBrowser.tabs.length, 2, "Prevent moving a normal tab to a private tabbrowser");
is(aPrivateWindow.gBrowser.tabs.length, 2, "Prevent accepting a normal tab in a private tabbrowser");
aPrivateWindow.gBrowser.swapBrowsersAndCloseOther(privateTab, normalTab);
is(aPrivateWindow.gBrowser.tabs.length, 2, "Prevent moving a private tab to a normal tabbrowser");
is(aNormalWindow.gBrowser.tabs.length, 2, "Prevent accepting a private tab in a normal tabbrowser");
aNormalWindow.close();
aPrivateWindow.close();
finish();
});
});
}

View File

@ -210,13 +210,17 @@ function synthesizeDragStart(element, expectedDragData, aWindow, x, y)
* eventUtils - optional; allows you to pass in a reference to EventUtils.js.
* If the eventUtils parameter is not passed in, we assume EventUtils.js is
* in the scope. Used by browser-chrome tests.
* aDestWindow - optional; defaults to aWindow.
* Used when destElement is in a different window than srcElement.
*
* Returns the drop effect that was desired.
*/
function synthesizeDrop(srcElement, destElement, dragData, dropEffect, aWindow, eventUtils)
function synthesizeDrop(srcElement, destElement, dragData, dropEffect, aWindow, eventUtils, aDestWindow)
{
if (!aWindow)
aWindow = window;
if (!aDestWindow)
aDestWindow = aWindow;
var synthesizeMouseAtCenter = (eventUtils || window).synthesizeMouseAtCenter;
var synthesizeMouse = (eventUtils || window).synthesizeMouse;
@ -254,24 +258,24 @@ function synthesizeDrop(srcElement, destElement, dragData, dropEffect, aWindow,
synthesizeMouse(srcElement, x+10, y+10, { type: "mousemove" }, aWindow);
aWindow.removeEventListener("dragstart", trapDrag, true);
event = aWindow.document.createEvent("DragEvents");
event.initDragEvent("dragenter", true, true, aWindow, 0, 0, 0, 0, 0, false, false, false, false, 0, null, dataTransfer);
event = aDestWindow.document.createEvent("DragEvents");
event.initDragEvent("dragenter", true, true, aDestWindow, 0, 0, 0, 0, 0, false, false, false, false, 0, null, dataTransfer);
gWindowUtils.dispatchDOMEventViaPresShell(destElement, event, true);
var event = aWindow.document.createEvent("DragEvents");
event.initDragEvent("dragover", true, true, aWindow, 0, 0, 0, 0, 0, false, false, false, false, 0, null, dataTransfer);
var event = aDestWindow.document.createEvent("DragEvents");
event.initDragEvent("dragover", true, true, aDestWindow, 0, 0, 0, 0, 0, false, false, false, false, 0, null, dataTransfer);
if (gWindowUtils.dispatchDOMEventViaPresShell(destElement, event, true)) {
synthesizeMouseAtCenter(destElement, { type: "mouseup" }, aWindow);
synthesizeMouseAtCenter(destElement, { type: "mouseup" }, aDestWindow);
return "none";
}
if (dataTransfer.dropEffect != "none") {
event = aWindow.document.createEvent("DragEvents");
event.initDragEvent("drop", true, true, aWindow, 0, 0, 0, 0, 0, false, false, false, false, 0, null, dataTransfer);
event = aDestWindow.document.createEvent("DragEvents");
event.initDragEvent("drop", true, true, aDestWindow, 0, 0, 0, 0, 0, false, false, false, false, 0, null, dataTransfer);
gWindowUtils.dispatchDOMEventViaPresShell(destElement, event, true);
}
synthesizeMouseAtCenter(destElement, { type: "mouseup" }, aWindow);
synthesizeMouseAtCenter(destElement, { type: "mouseup" }, aDestWindow);
return dataTransfer.dropEffect;
} finally {