Merge mozilla-inbound to mozilla-central. a=merge

This commit is contained in:
Dorel Luca 2019-08-31 12:47:56 +03:00
Родитель bb7e54e846 65d0542697
Коммит e8f334670d
29 изменённых файлов: 358 добавлений и 216 удалений

Просмотреть файл

@ -149,7 +149,10 @@ pageInfoTreeView.prototype = {
return 0;
},
getImageSrc(row, column) {},
getCellValue(row, column) {},
getCellValue(row, column) {
let col = column != null ? column : this.copycol;
return row < 0 || col < 0 ? "" : this.data[row][col] || "";
},
toggleOpenState(index) {},
cycleHeader(col) {},
selectionChanged() {},
@ -269,6 +272,19 @@ const nsIPermissionManager = Ci.nsIPermissionManager;
const nsICertificateDialogs = Ci.nsICertificateDialogs;
const CERTIFICATEDIALOGS_CONTRACTID = "@mozilla.org/nsCertificateDialogs;1";
// clipboard helper
function getClipboardHelper() {
try {
return Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
Ci.nsIClipboardHelper
);
} catch (e) {
// do nothing, later code will handle the error
return null;
}
}
const gClipboardHelper = getClipboardHelper();
// namespaces, don't need all of these yet...
const XLinkNS = "http://www.w3.org/1999/xlink";
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
@ -1175,6 +1191,37 @@ function formatDate(datestr, unknown) {
return dateTimeFormatter.format(date);
}
function doCopy() {
if (!gClipboardHelper) {
return;
}
var elem = document.commandDispatcher.focusedElement;
if (elem && elem.localName == "tree") {
var view = elem.view;
var selection = view.selection;
var text = [],
tmp = "";
var min = {},
max = {};
var count = selection.getRangeCount();
for (var i = 0; i < count; i++) {
selection.getRangeAt(i, min, max);
for (var row = min.value; row <= max.value; row++) {
tmp = view.getCellValue(row, null);
if (tmp) {
text.push(tmp);
}
}
}
gClipboardHelper.copyString(text.join("\n"));
}
}
function doSelectAllMedia() {
var tree = document.getElementById("imagetree");

Просмотреть файл

@ -47,6 +47,7 @@
<commandset id="pageInfoCommandSet">
<command id="cmd_close" oncommand="window.close();"/>
<command id="cmd_help" oncommand="doHelpButton();"/>
<command id="cmd_copy" oncommand="doCopy();"/>
<command id="cmd_selectall" oncommand="doSelectAll();"/>
</commandset>
@ -58,12 +59,14 @@
#else
<key keycode="VK_F1" command="cmd_help"/>
#endif
<key data-l10n-id="copy" data-l10n-attrs="key" modifiers="accel" command="cmd_copy"/>
<key data-l10n-id="select-all" data-l10n-attrs="key" modifiers="accel" command="cmd_selectall"/>
<key data-l10n-id="select-all" data-l10n-attrs="key" modifiers="alt" command="cmd_selectall"/>
</keyset>
<menupopup id="picontext">
<menuitem id="menu_selectall" data-l10n-id="menu-select-all" command="cmd_selectall"/>
<menuitem id="menu_copy" data-l10n-id="menu-copy" command="cmd_copy"/>
</menupopup>
<vbox id="topBar">

Просмотреть файл

@ -72,7 +72,7 @@ add_task(async function testTempPermissionSubframes() {
// FIXME(Fission): The load event fires before cross-origin iframes have
// loaded (bug 1559841).
if (content.SpecialPowers.useRemoteSubframes) {
for (let i = 0; i < 200; i++) {
for (let i = 0; i < 800; i++) {
await new Promise(resolve => content.setTimeout(resolve, 0));
}
}

Просмотреть файл

@ -5,6 +5,12 @@
page-info-window =
.style = width: 600px; min-height: 550px;
copy =
.key = C
menu-copy =
.label = Copy
.accesskey = C
select-all =
.key = A
menu-select-all =

Просмотреть файл

@ -132,7 +132,10 @@ already_AddRefed<BrowsingContext> BrowsingContext::Create(
// The name and opener fields need to be explicitly initialized. Don't bother
// using transactions to set them, as we haven't been attached yet.
context->mName = aName;
context->mOpenerId = aOpener ? aOpener->Id() : 0;
if (aOpener) {
context->mOpenerId = aOpener->Id();
context->mHadOriginalOpener = true;
}
context->mEmbedderPolicy = nsILoadInfo::EMBEDDER_POLICY_NULL;
BrowsingContext* inherit = aParent ? aParent : aOpener;

Просмотреть файл

@ -209,13 +209,22 @@ class BrowsingContext : public nsWrapperCache, public BrowsingContextBase {
BrowsingContext* Top();
already_AddRefed<BrowsingContext> GetOpener() const { return Get(mOpenerId); }
already_AddRefed<BrowsingContext> GetOpener() const {
RefPtr<BrowsingContext> opener(Get(mOpenerId));
if (!mIsDiscarded && opener && !opener->mIsDiscarded) {
return opener.forget();
}
return nullptr;
}
void SetOpener(BrowsingContext* aOpener) {
MOZ_DIAGNOSTIC_ASSERT(!aOpener || aOpener->Group() == Group());
SetOpenerId(aOpener ? aOpener->Id() : 0);
}
bool HasOpener() const;
bool HadOriginalOpener() const { return mHadOriginalOpener; }
/**
* When a new browsing context is opened by a sandboxed document, it needs to
* keep track of the browsing context that opened it, so that it can be
@ -481,9 +490,7 @@ class BrowsingContext : public nsWrapperCache, public BrowsingContextBase {
uintptr_t(this) - offsetof(BrowsingContext, mLocation));
}
already_AddRefed<nsIDocShell> GetDocShell() override {
return nullptr;
}
already_AddRefed<nsIDocShell> GetDocShell() override { return nullptr; }
};
// Ensure that opener is in the same BrowsingContextGroup.

Просмотреть файл

@ -21,6 +21,8 @@ MOZ_BC_FIELD(OpenerId, uint64_t)
MOZ_BC_FIELD(OnePermittedSandboxedNavigatorId, uint64_t)
MOZ_BC_FIELD(HadOriginalOpener, bool)
// Toplevel browsing contexts only. This field controls whether the browsing
// context is currently considered to be activated by a gesture.
MOZ_BC_FIELD(IsActivatedByUserGesture, bool)

Просмотреть файл

@ -16,6 +16,7 @@
#include "nsError.h"
#include "nsContentSecurityManager.h"
#include "nsDocShellLoadTypes.h"
#include "nsGlobalWindowOuter.h"
#include "nsIInterfaceRequestor.h"
#include "nsIMultiPartChannel.h"
@ -48,10 +49,11 @@ nsIInterfaceRequestor* MaybeCloseWindowHelper::MaybeCloseWindow() {
if (mShouldCloseWindow) {
// Reset the window context to the opener window so that the dependent
// dialogs have a parent
nsCOMPtr<nsPIDOMWindowOuter> opener = window->GetOpener();
nsCOMPtr<nsPIDOMWindowOuter> opener =
nsGlobalWindowOuter::Cast(window)->GetSameProcessOpener();
if (opener && !opener->Closed()) {
mContentContext = do_GetInterface(opener);
mContentContext = do_QueryInterface(opener);
// Now close the old window. Do it on a timer so that we don't run
// into issues trying to close the window before it has fully opened.

Просмотреть файл

@ -14863,12 +14863,12 @@ void Document::MaybeAllowStorageForOpenerAfterUserInteraction() {
return;
}
nsCOMPtr<nsPIDOMWindowOuter> outer = inner->GetOuterWindow();
auto* outer = nsGlobalWindowOuter::Cast(inner->GetOuterWindow());
if (NS_WARN_IF(!outer)) {
return;
}
nsCOMPtr<nsPIDOMWindowOuter> outerOpener = outer->GetOpener();
nsCOMPtr<nsPIDOMWindowOuter> outerOpener = outer->GetSameProcessOpener();
if (!outerOpener) {
return;
}

Просмотреть файл

@ -2084,12 +2084,6 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
newWindow->SetFrameElementInternal(mOwnerContent);
// TODO(farre): Remove this when nsGlobalWindowOuter::GetOpenerWindowOuter
// starts using BrowsingContext::GetOpener.
if (RefPtr<BrowsingContext> opener = mBrowsingContext->GetOpener()) {
newWindow->SetOpenerWindow(opener->GetDOMWindow(), true);
}
// Allow scripts to close the docshell if specified.
if (mOwnerContent->IsXULElement(nsGkAtoms::browser) &&
mOwnerContent->AttrValueIs(kNameSpaceID_None,

Просмотреть файл

@ -3034,27 +3034,33 @@ nsresult nsGlobalWindowInner::GetControllers(nsIControllers** aResult) {
return rv.StealNSResult();
}
nsPIDOMWindowOuter* nsGlobalWindowInner::GetOpenerWindow(ErrorResult& aError) {
Nullable<WindowProxyHolder> nsGlobalWindowInner::GetOpenerWindow(
ErrorResult& aError) {
FORWARD_TO_OUTER_OR_THROW(GetOpenerWindowOuter, (), aError, nullptr);
}
void nsGlobalWindowInner::GetOpener(JSContext* aCx,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aError) {
nsCOMPtr<nsPIDOMWindowOuter> opener = GetOpenerWindow(aError);
if (aError.Failed() || !opener) {
Nullable<WindowProxyHolder> opener = GetOpenerWindow(aError);
if (aError.Failed() || opener.IsNull()) {
aRetval.setNull();
return;
}
aError = nsContentUtils::WrapNative(aCx, opener, aRetval);
if (!ToJSValue(aCx, opener.Value(), aRetval)) {
aError.NoteJSContextException(aCx);
}
}
void nsGlobalWindowInner::SetOpener(JSContext* aCx,
JS::Handle<JS::Value> aOpener,
ErrorResult& aError) {
if (aOpener.isNull()) {
FORWARD_TO_OUTER_VOID(SetOpenerWindow, (nullptr, false));
RefPtr<BrowsingContext> bc(GetBrowsingContext());
if (!bc->IsDiscarded()) {
bc->SetOpener(nullptr);
}
return;
}

Просмотреть файл

@ -622,7 +622,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
void InitWasOffline();
public:
nsPIDOMWindowOuter* GetOpenerWindow(mozilla::ErrorResult& aError);
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetOpenerWindow(
mozilla::ErrorResult& aError);
void GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError);
void SetOpener(JSContext* aCx, JS::Handle<JS::Value> aOpener,

Просмотреть файл

@ -1095,7 +1095,6 @@ nsGlobalWindowOuter::nsGlobalWindowOuter(uint64_t aWindowID)
mIsClosed(false),
mInClose(false),
mHavePendingClose(false),
mHadOriginalOpener(false),
mIsPopupSpam(false),
mBlockScriptedClosingFlag(false),
mWasOffline(false),
@ -1298,10 +1297,7 @@ void nsGlobalWindowOuter::CleanUp() {
ClearControllers();
mOpener = nullptr; // Forces Release
if (mContext) {
mContext = nullptr; // Forces Release
}
mContext = nullptr; // Forces Release
mChromeEventHandler = nullptr; // Forces Release
mParentTarget = nullptr;
mMessageManager = nullptr;
@ -2518,70 +2514,6 @@ void nsGlobalWindowOuter::DetachFromDocShell() {
CleanUp();
}
void nsGlobalWindowOuter::SetOpenerWindow(nsPIDOMWindowOuter* aOpener,
bool aOriginalOpener) {
nsWeakPtr opener = do_GetWeakReference(aOpener);
if (opener == mOpener) {
MOZ_DIAGNOSTIC_ASSERT(!aOpener || !aOpener->GetDocShell() ||
(GetBrowsingContext() &&
aOpener->GetBrowsingContext() &&
aOpener->GetBrowsingContext()->Id() ==
GetBrowsingContext()->GetOpenerId()));
return;
}
NS_ASSERTION(!aOriginalOpener || !mSetOpenerWindowCalled,
"aOriginalOpener is true, but not first call to "
"SetOpenerWindow!");
NS_ASSERTION(aOpener || !aOriginalOpener,
"Shouldn't set mHadOriginalOpener if aOpener is null");
mOpener = opener.forget();
NS_ASSERTION(mOpener || !aOpener, "Opener must support weak references!");
if (mDocShell) {
MOZ_DIAGNOSTIC_ASSERT(
!aOriginalOpener || !aOpener ||
// TODO(farre): Allowing to set a closed or closing window as
// opener is not ideal, since it won't have a docshell and
// therefore no browsing context. This means that we're
// effectively setting the browsing context opener to null and
// the window opener to a closed window. This needs to be
// cleaned up, see Bug 1511353.
nsGlobalWindowOuter::Cast(aOpener)->IsClosedOrClosing() ||
// TODO(farre): Allowing to set an opener on a closed window is
// not ideal either, but we need to allow it for now. Bug 1543056.
IsClosedOrClosing() ||
aOpener->GetBrowsingContext()->Id() ==
GetBrowsingContext()->GetOpenerId());
// TODO(farre): Here we really wish to only consider the case
// where 'aOriginalOpener'. See bug 1509016.
GetBrowsingContext()->SetOpener(aOpener ? aOpener->GetBrowsingContext()
: nullptr);
}
// Check that the js visible opener matches! We currently don't depend on this
// being true outside of nightly, so we disable the assertion in optimized
// release / beta builds.
nsPIDOMWindowOuter* contentOpener = GetSanitizedOpener(aOpener);
// contentOpener is not used when the DIAGNOSTIC_ASSERT is compiled out.
mozilla::Unused << contentOpener;
MOZ_DIAGNOSTIC_ASSERT(
!contentOpener || !mTabGroup ||
mTabGroup == nsGlobalWindowOuter::Cast(contentOpener)->mTabGroup);
if (aOriginalOpener) {
MOZ_ASSERT(!mHadOriginalOpener,
"Probably too late to call ComputeIsSecureContext again");
mHadOriginalOpener = true;
}
#ifdef DEBUG
mSetOpenerWindowCalled = true;
#endif
}
void nsGlobalWindowOuter::UpdateParentTarget() {
// NOTE: This method is nearly identical to
// nsGlobalWindowInner::UpdateParentTarget(). IF YOU UPDATE THIS METHOD,
@ -3290,63 +3222,44 @@ nsresult nsGlobalWindowOuter::GetControllers(nsIControllers** aResult) {
FORWARD_TO_INNER(GetControllers, (aResult), NS_ERROR_UNEXPECTED);
}
nsPIDOMWindowOuter* nsGlobalWindowOuter::GetSanitizedOpener(
nsPIDOMWindowOuter* aOpener) {
if (!aOpener) {
already_AddRefed<BrowsingContext>
nsGlobalWindowOuter::GetOpenerBrowsingContext() {
RefPtr<BrowsingContext> opener = GetBrowsingContext()->GetOpener();
MOZ_DIAGNOSTIC_ASSERT(!opener ||
opener->Group() == GetBrowsingContext()->Group());
if (!opener || opener->Group() != GetBrowsingContext()->Group()) {
return nullptr;
}
nsGlobalWindowOuter* win = nsGlobalWindowOuter::Cast(aOpener);
// First, ensure that we're not handing back a chrome window to content:
if (win->IsChromeWindow()) {
return nullptr;
}
// We don't want to reveal the opener if the opener is a mail window,
// because opener can be used to spoof the contents of a message (bug 105050).
// So, we look in the opener's root docshell to see if it's a mail window.
nsCOMPtr<nsIDocShell> openerDocShell = aOpener->GetDocShell();
if (openerDocShell) {
nsCOMPtr<nsIDocShellTreeItem> openerRootItem;
openerDocShell->GetInProcessRootTreeItem(getter_AddRefs(openerRootItem));
nsCOMPtr<nsIDocShell> openerRootDocShell(do_QueryInterface(openerRootItem));
if (openerRootDocShell) {
nsIDocShell::AppType appType = openerRootDocShell->GetAppType();
if (appType != nsIDocShell::APP_TYPE_MAIL) {
return aOpener;
}
// Catch the case where we're chrome but the opener is not...
if (nsContentUtils::LegacyIsCallerChromeOrNativeCode() &&
GetPrincipal() == nsContentUtils::GetSystemPrincipal()) {
auto* openerWin = nsGlobalWindowOuter::Cast(opener->GetDOMWindow());
if (!openerWin ||
openerWin->GetPrincipal() != nsContentUtils::GetSystemPrincipal()) {
return nullptr;
}
}
return opener.forget();
}
nsPIDOMWindowOuter* nsGlobalWindowOuter::GetSameProcessOpener() {
if (RefPtr<BrowsingContext> opener = GetOpenerBrowsingContext()) {
return opener->GetDOMWindow();
}
return nullptr;
}
nsPIDOMWindowOuter* nsGlobalWindowOuter::GetOpenerWindowOuter() {
nsCOMPtr<nsPIDOMWindowOuter> opener = do_QueryReferent(mOpener);
if (!opener) {
return nullptr;
Nullable<WindowProxyHolder> nsGlobalWindowOuter::GetOpenerWindowOuter() {
if (RefPtr<BrowsingContext> opener = GetOpenerBrowsingContext()) {
return WindowProxyHolder(opener.forget());
}
// First, check if we were called from a privileged chrome script
if (nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
// Catch the case where we're chrome but the opener is not...
if (GetPrincipal() == nsContentUtils::GetSystemPrincipal() &&
nsGlobalWindowOuter::Cast(opener)->GetPrincipal() !=
nsContentUtils::GetSystemPrincipal()) {
return nullptr;
}
return opener;
}
return GetSanitizedOpener(opener);
return nullptr;
}
already_AddRefed<nsPIDOMWindowOuter> nsGlobalWindowOuter::GetOpener() {
nsCOMPtr<nsPIDOMWindowOuter> opener = GetOpenerWindowOuter();
return opener.forget();
Nullable<WindowProxyHolder> nsGlobalWindowOuter::GetOpener() {
return GetOpenerWindowOuter();
}
void nsGlobalWindowOuter::GetStatusOuter(nsAString& aStatus) {
@ -4740,7 +4653,7 @@ bool nsGlobalWindowOuter::CanMoveResizeWindows(CallerType aCallerType) {
if (aCallerType != CallerType::System) {
// Don't allow scripts to move or resize windows that were not opened by a
// script.
if (!mHadOriginalOpener) {
if (!HadOriginalOpener()) {
return false;
}
@ -4972,13 +4885,15 @@ void nsGlobalWindowOuter::FocusOuter() {
nsCOMPtr<nsPIDOMWindowInner> caller = do_QueryInterface(GetEntryGlobal());
nsPIDOMWindowOuter* callerOuter = caller ? caller->GetOuterWindow() : nullptr;
nsCOMPtr<nsPIDOMWindowOuter> opener = GetOpener();
BrowsingContext* callerBC =
callerOuter ? callerOuter->GetBrowsingContext() : nullptr;
RefPtr<BrowsingContext> openerBC = GetOpenerBrowsingContext();
// Enforce dom.disable_window_flip (for non-chrome), but still allow the
// window which opened us to raise us at times when popups are allowed
// (bugs 355482 and 369306).
bool canFocus = CanSetProperty("dom.disable_window_flip") ||
(opener == callerOuter &&
(openerBC == callerBC &&
RevisePopupAbuseLevel(PopupBlocker::GetPopupControlState()) <
PopupBlocker::openBlocked);
@ -6283,7 +6198,7 @@ void nsGlobalWindowOuter::CloseOuter(bool aTrustedCaller) {
NS_ENSURE_SUCCESS_VOID(rv);
if (!StringBeginsWith(url, NS_LITERAL_STRING("about:neterror")) &&
!mHadOriginalOpener && !aTrustedCaller) {
!HadOriginalOpener() && !aTrustedCaller) {
bool allowClose =
mAllowScriptsToClose ||
Preferences::GetBool("dom.allow_scripts_to_close_windows", true);
@ -7781,11 +7696,11 @@ mozilla::dom::TabGroup* nsGlobalWindowOuter::TabGroupOuter() {
// because a document is getting its NodePrincipal, and asking for the
// TabGroup to determine its DocGroup.
if (!mTabGroup) {
// Get mOpener ourselves, instead of relying on GetOpenerWindowOuter,
// Get the opener ourselves, instead of relying on GetOpenerWindowOuter,
// because that way we dodge the LegacyIsCallerChromeOrNativeCode() call
// which we want to return false.
nsCOMPtr<nsPIDOMWindowOuter> piOpener = do_QueryReferent(mOpener);
nsPIDOMWindowOuter* opener = GetSanitizedOpener(piOpener);
RefPtr<BrowsingContext> openerBC = GetBrowsingContext()->GetOpener();
nsPIDOMWindowOuter* opener = openerBC ? openerBC->GetDOMWindow() : nullptr;
nsPIDOMWindowOuter* parent = GetInProcessScriptableParentOrNull();
MOZ_ASSERT(!parent || !opener,
"Only one of parent and opener may be provided");
@ -7823,9 +7738,11 @@ mozilla::dom::TabGroup* nsGlobalWindowOuter::TabGroupOuter() {
// Sanity check that our tabgroup matches our opener or parent.
RefPtr<nsPIDOMWindowOuter> parent = GetInProcessScriptableParentOrNull();
MOZ_ASSERT_IF(parent, parent->TabGroup() == mTabGroup);
nsCOMPtr<nsPIDOMWindowOuter> piOpener = do_QueryReferent(mOpener);
nsPIDOMWindowOuter* opener = GetSanitizedOpener(piOpener);
MOZ_ASSERT_IF(opener && nsGlobalWindowOuter::Cast(opener) != this,
RefPtr<BrowsingContext> openerBC = GetBrowsingContext()->GetOpener();
nsPIDOMWindowOuter* opener =
openerBC ? openerBC->GetDOMWindow() : nullptr;
MOZ_ASSERT_IF(opener && Cast(opener) != this,
opener->TabGroup() == mTabGroup);
}
mIsValidatingTabGroup = false;

Просмотреть файл

@ -323,9 +323,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
// Outer windows only.
void DispatchDOMWindowCreated();
virtual void SetOpenerWindow(nsPIDOMWindowOuter* aOpener,
bool aOriginalOpener) override;
// Outer windows only.
virtual void EnsureSizeAndPositionUpToDate() override;
@ -456,7 +453,9 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
bool IsCleanedUp() const { return mCleanedUp; }
bool HadOriginalOpener() const { return mHadOriginalOpener; }
bool HadOriginalOpener() const {
return GetBrowsingContext()->HadOriginalOpener();
}
bool IsTopLevelWindow();
@ -548,14 +547,15 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
RefPtr<mozilla::ThrottledEventQueue> mPostMessageEventQueue;
protected:
nsPIDOMWindowOuter* GetOpenerWindowOuter();
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder>
GetOpenerWindowOuter();
// Initializes the mWasOffline member variable
void InitWasOffline();
public:
nsPIDOMWindowOuter* GetSanitizedOpener(nsPIDOMWindowOuter* aOpener);
already_AddRefed<nsPIDOMWindowOuter> GetOpener() override;
nsPIDOMWindowOuter* GetSameProcessOpener();
already_AddRefed<mozilla::dom::BrowsingContext> GetOpenerBrowsingContext();
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetOpener() override;
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetParentOuter();
already_AddRefed<nsPIDOMWindowOuter> GetInProcessParent() override;
nsPIDOMWindowOuter* GetInProcessScriptableParent() override;
@ -1074,7 +1074,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
// close us when the JS stops executing or that we have a close
// event posted. If this is set, just ignore window.close() calls.
bool mHavePendingClose : 1;
bool mHadOriginalOpener : 1;
bool mIsPopupSpam : 1;
// Indicates whether scripts are allowed to close this window.
@ -1100,7 +1099,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
bool mHasStorageAccess : 1;
nsCOMPtr<nsIScriptContext> mContext;
nsWeakPtr mOpener;
nsCOMPtr<nsIControllers> mControllers;
// For |window.arguments|, via |openDialog|.

Просмотреть файл

@ -885,16 +885,6 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
Document* aDocument, nsISupports* aState, bool aForceReuseInnerWindow,
mozilla::dom::WindowGlobalChild* aActor = nullptr) = 0;
/**
* Set the opener window. aOriginalOpener is true if and only if this is the
* original opener for the window. That is, it can only be true at most once
* during the life cycle of a window, and then only the first time
* SetOpenerWindow is called. It might never be true, of course, if the
* window does not have an opener when it's created.
*/
virtual void SetOpenerWindow(nsPIDOMWindowOuter* aOpener,
bool aOriginalOpener) = 0;
/**
* Ensure the size and position of this window are up-to-date by doing
* a layout flush in the parent (which will in turn, do a layout flush
@ -1047,7 +1037,8 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
virtual nsresult GetPrompter(nsIPrompt** aPrompt) = 0;
virtual nsresult GetControllers(nsIControllers** aControllers) = 0;
virtual already_AddRefed<mozilla::dom::Selection> GetSelection() = 0;
virtual already_AddRefed<nsPIDOMWindowOuter> GetOpener() = 0;
virtual mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder>
GetOpener() = 0;
// aLoadState will be passed on through to the windowwatcher.
// aForceNoOpener will act just like a "noopener" feature in aOptions except

Просмотреть файл

@ -962,16 +962,17 @@ nsresult ContentChild::ProvideWindowCommon(
// parent. Otherwise, the parent could send messages to us before we have a
// proper TabGroup for that actor.
RefPtr<TabGroup> tabGroup;
RefPtr<BrowsingContext> openerBC;
if (aTabOpener && !aForceNoOpener) {
// The new actor will use the same tab group as the opener.
tabGroup = aTabOpener->TabGroup();
if (aParent) {
openerBC = nsPIDOMWindowOuter::From(aParent)->GetBrowsingContext();
}
} else {
tabGroup = new TabGroup();
}
RefPtr<BrowsingContext> openerBC =
aParent ? nsPIDOMWindowOuter::From(aParent)->GetBrowsingContext()
: nullptr;
RefPtr<BrowsingContext> browsingContext = BrowsingContext::Create(
nullptr, openerBC, aName, BrowsingContext::Type::Content);
@ -1099,17 +1100,25 @@ nsresult ContentChild::ProvideWindowCommon(
newChild->SetMaxTouchPoints(maxTouchPoints);
newChild->SetHasSiblings(hasSiblings);
// Set the opener window for this window before we start loading the
// document inside of it. We have to do this before loading the remote
// scripts, because they can poke at the document and cause the Document
// to be created before the openerwindow
nsCOMPtr<mozIDOMWindowProxy> windowProxy =
do_GetInterface(newChild->WebNavigation());
if (!aForceNoOpener && windowProxy && aParent) {
nsPIDOMWindowOuter* outer = nsPIDOMWindowOuter::From(windowProxy);
nsPIDOMWindowOuter* parent = nsPIDOMWindowOuter::From(aParent);
outer->SetOpenerWindow(parent, *aWindowIsNew);
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
if (nsCOMPtr<nsPIDOMWindowOuter> outer =
do_GetInterface(newChild->WebNavigation())) {
BrowsingContext* bc = outer->GetBrowsingContext();
auto parentBC =
aParent
? nsPIDOMWindowOuter::From(aParent)->GetBrowsingContext()->Id()
: 0;
if (aForceNoOpener) {
MOZ_DIAGNOSTIC_ASSERT(!*aWindowIsNew || !bc->HadOriginalOpener());
MOZ_DIAGNOSTIC_ASSERT(bc->GetOpenerId() == 0);
} else {
MOZ_DIAGNOSTIC_ASSERT(!*aWindowIsNew ||
bc->HadOriginalOpener() == !!parentBC);
MOZ_DIAGNOSTIC_ASSERT(bc->GetOpenerId() == parentBC);
}
}
#endif
// Unfortunately we don't get a window unless we've shown the frame. That's
// pretty bogus; see bug 763602.

Просмотреть файл

@ -38,6 +38,8 @@ support-files =
test2_bug622361.html
file1_bug414291.html
file2_bug414291.html
prefs =
fission.rebuild_frameloaders_on_remoteness_change=true
[test_DOMWindowCreated_chromeonly.html]
[test_bug132255.html]

Просмотреть файл

@ -18,6 +18,8 @@ support-files =
frameLocalStorageSessionOnly.html
file_tryAccessSessionStorage.html
windowProxy.html
prefs =
fission.rebuild_frameloaders_on_remoteness_change=true
[test_brokenUTF-16.html]
[test_bug600307-DBOps.html]
@ -53,6 +55,5 @@ skip-if = toolkit == 'android' || (verify && (os == 'linux' || os == 'mac' || os
[test_localStorageQuotaSessionOnly2.html]
skip-if = true # bug 1347690
[test_localStorageReplace.html]
fail-if = fission
skip-if = toolkit == 'android'
[test_storageConstructor.html]

Просмотреть файл

@ -7,11 +7,12 @@ support-files =
frameReplace.html
interOriginSlave.js
interOriginTest.js
prefs =
fission.rebuild_frameloaders_on_remoteness_change=true
[test_sessionStorageBase.html]
[test_sessionStorageBaseSessionOnly.html]
[test_sessionStorageClone.html]
fail-if = fission
skip-if = toolkit == 'android'
[test_sessionStorageHttpHttps.html]
skip-if = toolkit == 'android' #TIMED_OUT

Просмотреть файл

@ -15,6 +15,8 @@ support-files =
postMessage_throw_helper.html
postMessage_transfer_helper.html
postMessage_userpass_helper.html
prefs =
fission.rebuild_frameloaders_on_remoteness_change=true
[test_bug477323.html]
[test_document_scripts.html]
@ -31,17 +33,14 @@ skip-if = fission # Timeouts
[test_postMessage_joined.html]
skip-if = fission # Timeouts
[test_postMessage_onOther.html]
skip-if = fission #Bug 1571273
[test_postMessage_origin.xhtml]
skip-if = fission # Timeouts
[test_postMessage_override.html]
skip-if = fission
[test_postMessage_special.xhtml]
[test_postMessage_structured_clone.html]
skip-if = fission #Bug 1570918
[test_postMessage_throw.html]
[test_postMessage_transfer.html]
skip-if = fission #Bug 1571208
[test_postMessage_userpass.html]
skip-if = fission # Timeouts
[test_bug500328.html]

Просмотреть файл

@ -2701,14 +2701,8 @@ nsresult WebSocketImpl::GetLoadingPrincipal(nsIPrincipal** aPrincipal) {
// We are at the top. Let's see if we have an opener window.
if (innerWindow == currentInnerWindow) {
ErrorResult error;
parentWindow =
nsGlobalWindowInner::Cast(innerWindow)->GetOpenerWindow(error);
if (NS_WARN_IF(error.Failed())) {
error.SuppressException();
return NS_ERROR_DOM_SECURITY_ERR;
}
parentWindow = nsGlobalWindowOuter::Cast(innerWindow->GetOuterWindow())
->GetSameProcessOpener();
if (!parentWindow) {
break;
}

Просмотреть файл

@ -0,0 +1,98 @@
// Type conversion to number should use ECMA-style semantics.
load(libdir + 'asserts.js');
function test() {
function checkValue(type, provided, expected) {
assertEq(ctypes[type](provided).value, expected,
`ctypes.${type}(${provided}) contains unexpected value`);
}
function checkCantConvert(type, value) {
var ctor = ctypes[type];
assertTypeErrorMessage(() => ctor(value),
/can't convert the number/);
}
let testInt8 = checkValue.bind(undefined, "int8_t");
let testInt8Throws = checkCantConvert.bind(undefined, "int8_t");
testInt8(1e100, 0);
testInt8Throws(-129);
testInt8(-128, -128);
testInt8(-1, -1);
testInt8(0, 0);
testInt8(1, 1);
testInt8(127, 127);
testInt8Throws(128);
let testUint8 = checkValue.bind(undefined, "uint8_t");
let testUint8Throws = checkCantConvert.bind(undefined, "uint8_t");
testUint8(1e100, 0);
testUint8Throws(-1);
testUint8(0, 0);
testUint8(1, 1);
testUint8(127, 127);
testUint8(128, 128);
testUint8(255, 255);
testUint8Throws(256);
let testInt16 = checkValue.bind(undefined, "int16_t");
let testInt16Throws = checkCantConvert.bind(undefined, "int16_t");
testInt16(1e100, 0);
testInt16Throws(-32769);
testInt16(-32768, -32768);
testInt16(-1, -1);
testInt16(0, 0);
testInt16(1, 1);
testInt16(32767, 32767);
testInt16Throws(32768);
let testUint16 = checkValue.bind(undefined, "uint16_t");
let testUint16Throws = checkCantConvert.bind(undefined, "uint16_t");
testUint16(1e100, 0);
testUint16Throws(-1);
testUint16(0, 0);
testUint16(1, 1);
testUint16(32767, 32767);
testUint16(32768, 32768);
testUint16(65535, 65535);
testUint16Throws(65536);
let testInt32 = checkValue.bind(undefined, "int32_t");
let testInt32Throws = checkCantConvert.bind(undefined, "int32_t");
testInt32(1e100, 0);
// This probably should pass, but right now doubles fall into a different
// code path where no error occurs. ctypes is probably/hopefully declining in
// use now, so just don't bother with this test.
//testInt32Throws(-2147483649);
testInt32(-2147483648, -2147483648);
testInt32(-1, -1);
testInt32(0, 0);
testInt32(1, 1);
testInt32(2147483647, 2147483647);
// This probably should pass, but right now doubles fall into a different
// code path where no error occurs. ctypes is probably/hopefully declining in
// use now, so just don't bother with this test.
//testInt32Throws(2147483648);
let testUint32 = checkValue.bind(undefined, "uint32_t");
let testUint32Throws = checkCantConvert.bind(undefined, "uint32_t");
testUint32(1e100, 0);
testUint32Throws(-1);
// This probably should pass, but right now doubles fall into a different
// code path where no error occurs. ctypes is probably/hopefully declining in
// use now, so just don't bother with this test.
//testUint32Throws(-1 * Math.cos(Math.PI)); // -1.0 encoded as a double
testUint32(0, 0);
testUint32(1, 1);
testUint32(2147483647, 2147483647);
testUint32(2147483648, 2147483648);
testUint32(4294967295, 4294967295);
// This probably should pass, but right now doubles fall into a different
// code path where no error occurs. ctypes is probably/hopefully declining in
// use now, so just don't bother with this test.
//testUint32Throws(4294967296);
}
if (typeof ctypes === "object")
test();

Просмотреть файл

@ -85,7 +85,6 @@ skip-if = (!debug && android_version == '18') #Bug 1523193
skip-if = os == 'android' # Android does not support multiple windows.
[test_ext_contentscript_permission.html]
[test_ext_cookies.html]
fail-if = fission
[test_ext_cookies_containers.html]
[test_ext_cookies_expiry.html]
[test_ext_cookies_first_party.html]

Просмотреть файл

@ -951,10 +951,19 @@ nsresult nsWindowWatcher::OpenWindowInternal(
newDocShell->SetSandboxFlags(activeDocsSandboxFlags);
}
nsCOMPtr<nsPIDOMWindowOuter> win(newBC->GetDOMWindow());
RefPtr<nsGlobalWindowOuter> win(
nsGlobalWindowOuter::Cast(newBC->GetDOMWindow()));
if (win) {
if (!aForceNoOpener) {
win->SetOpenerWindow(parentWindow, windowIsNew);
if (windowIsNew) {
// If this is a new window, its opener should have been set when its
// BrowsingContext was created. If not, we need to set it ourselves.
MOZ_DIAGNOSTIC_ASSERT(newBC->GetOpenerId() ==
(parentBC ? parentBC->Id() : 0));
MOZ_DIAGNOSTIC_ASSERT(!!parentBC == newBC->HadOriginalOpener());
} else {
newBC->SetOpener(parentBC);
}
} else if (parentWindow && parentWindow != win) {
MOZ_ASSERT(
win->TabGroup() != parentWindow->TabGroup(),
@ -1069,7 +1078,7 @@ nsresult nsWindowWatcher::OpenWindowInternal(
// SetInitialPrincipalToSubject is safe to call multiple times.
if (win) {
nsCOMPtr<nsIContentSecurityPolicy> cspToInheritForAboutBlank;
nsCOMPtr<mozIDOMWindowProxy> targetOpener = win->GetOpener();
nsCOMPtr<mozIDOMWindowProxy> targetOpener = win->GetSameProcessOpener();
nsCOMPtr<nsIDocShell> openerDocShell(do_GetInterface(targetOpener));
if (openerDocShell) {
RefPtr<Document> openerDoc =
@ -1079,13 +1088,12 @@ nsresult nsWindowWatcher::OpenWindowInternal(
win->SetInitialPrincipalToSubject(cspToInheritForAboutBlank);
if (aIsPopupSpam) {
auto* globalWin = nsGlobalWindowOuter::Cast(win);
MOZ_ASSERT(!globalWin->IsPopupSpamWindow(),
MOZ_ASSERT(!win->IsPopupSpamWindow(),
"Who marked it as popup spam already???");
if (!globalWin->IsPopupSpamWindow()) { // Make sure we don't mess up
// our counter even if the above
// assert fails.
globalWin->SetIsPopupSpamWindow(true);
if (!win->IsPopupSpamWindow()) { // Make sure we don't mess up
// our counter even if the above
// assert fails.
win->SetIsPopupSpamWindow(true);
}
}
}
@ -1162,7 +1170,8 @@ nsresult nsWindowWatcher::OpenWindowInternal(
nsCOMPtr<nsIObserverService> obsSvc =
mozilla::services::GetObserverService();
if (obsSvc) {
obsSvc->NotifyObservers(win, "toplevel-window-ready", nullptr);
obsSvc->NotifyObservers(ToSupports(win), "toplevel-window-ready",
nullptr);
}
}

Просмотреть файл

@ -189,7 +189,7 @@ It owns wl_buffer object, owns WaylandDMABufSurface
(which provides the DMA Buffer) and ties them together.
WindowBackBufferDMABuf backend is used only when WaylandDMABufSurface is
available and gfx.wayland_dmabuf_backend.enabled preference is set.
available and widget.wayland_dmabuf_backend.enabled preference is set.
*/
@ -504,6 +504,8 @@ WindowSurfaceWayland::WindowSurfaceWayland(nsWindow* aWindow)
mIsMainThread(NS_IsMainThread()),
mNeedScaleFactorUpdate(true) {
for (int i = 0; i < BACK_BUFFER_NUM; i++) mBackupBuffer[i] = nullptr;
mRenderingCacheMode = static_cast<RenderingCacheMode>(
mWaylandDisplay->GetRenderingCacheModePref());
}
WindowSurfaceWayland::~WindowSurfaceWayland() {
@ -810,10 +812,12 @@ already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::Lock(
mBufferScreenRect = lockedScreenRect;
}
if (mWholeWindowBufferDamage) {
if (mWholeWindowBufferDamage || mRenderingCacheMode != CACHE_ALL) {
// We can lock/commit entire buffer direcly.
mDrawToWaylandBufferDirectly = true;
}
if (mDrawToWaylandBufferDirectly) {
// If there's any pending image commit scratch them as we're going
// to redraw the whole sceen anyway.
mDelayedImageCommits.Clear();
@ -821,10 +825,29 @@ already_AddRefed<gfx::DrawTarget> WindowSurfaceWayland::Lock(
RefPtr<gfx::DrawTarget> dt = LockWaylandBuffer(
/* aCanSwitchBuffer */ mWholeWindowBufferDamage);
if (dt) {
// TODO: Try to set clip regions according to given area provided by
// compositor, not sure it has any effect. Also disable when drawing
// without any cache to speed up rendering.
if (!mWholeWindowBufferDamage && mRenderingCacheMode != CACHE_NONE) {
uint32_t numRects = aRegion.GetNumRects();
if (numRects != 1) {
AutoTArray<IntRect, 32> rects;
rects.SetCapacity(numRects);
for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
rects.AppendElement(iter.Get().ToUnknownRect());
}
dt->PushDeviceSpaceClipRects(rects.Elements(), rects.Length());
}
}
return dt.forget();
}
}
// Any caching is disabled and we don't have any back buffer available.
if (mRenderingCacheMode == CACHE_NONE) {
return nullptr;
}
// We do indirect drawing due to:
//
// 1) We don't have any front buffer available. Try indirect drawing

Просмотреть файл

@ -175,6 +175,21 @@ class WindowSurfaceWayland : public WindowSurface {
void FrameCallbackHandler();
void DelayedCommitHandler();
// Image cache mode can be set by widget.wayland_cache_mode
typedef enum {
// Cache and clip all drawings, default. It's slowest
// but also without any rendered artifacts.
CACHE_ALL = 0,
// Cache drawing only when back buffer is missing. May produce
// some rendering artifacts and flickering when partial screen update
// is rendered.
CACHE_MISSING = 1,
// Don't cache anything, draw only when back buffer is available.
// Suitable for fullscreen content only like fullscreen video playback and
// may work well with dmabuf backend.
CACHE_NONE = 2
} RenderingCacheMode;
private:
WindowBackBuffer* CreateWaylandBuffer(int aWidth, int aHeight);
WindowBackBuffer* GetWaylandBufferToDraw(bool aCanSwitchBuffer);
@ -215,6 +230,7 @@ class WindowSurfaceWayland : public WindowSurface {
bool mBufferNeedsClear;
bool mIsMainThread;
bool mNeedScaleFactorUpdate;
RenderingCacheMode mRenderingCacheMode;
static bool UseDMABufBackend();
static bool mUseDMABufInitialized;

Просмотреть файл

@ -13,10 +13,15 @@ namespace widget {
#define GBMLIB_NAME "libgbm.so.1"
#define DRMLIB_NAME "libdrm.so.2"
#define DMABUF_PREF "widget.wayland_dmabuf_backend.enabled"
// See WindowSurfaceWayland::RenderingCacheMode for details.
#define CACHE_MODE_PREF "widget.wayland_cache_mode"
bool nsWaylandDisplay::mIsDMABufEnabled = false;
// -1 mean the pref was not loaded yet
int nsWaylandDisplay::mIsDMABufPrefState = -1;
bool nsWaylandDisplay::mIsDMABufConfigured = false;
int nsWaylandDisplay::mRenderingCacheModePref = -1;
wl_display* WaylandDisplayGetWLDisplay(GdkDisplay* aGdkDisplay) {
if (!aGdkDisplay) {
@ -317,14 +322,15 @@ nsWaylandDisplay::nsWaylandDisplay(wl_display* aDisplay)
wl_registry_add_listener(mRegistry, &registry_listener, this);
if (NS_IsMainThread()) {
// We can't load the preference from compositor/render thread,
// only from main one. So we can't call it directly from
// nsWaylandDisplay::IsDMABufEnabled() as it can be called from various
// threads.
// We can't load the preference from compositor/render thread
// so load all Wayland prefs here.
if (mIsDMABufPrefState == -1) {
mIsDMABufPrefState =
Preferences::GetBool("widget.wayland_dmabuf_backend.enabled", false);
mIsDMABufPrefState = Preferences::GetBool(DMABUF_PREF, false);
}
if (mRenderingCacheModePref == -1) {
mRenderingCacheModePref = Preferences::GetInt(CACHE_MODE_PREF, 0);
}
// Use default event queue in main thread operated by Gtk+.
mEventQueue = nullptr;
wl_display_roundtrip(mDisplay);

Просмотреть файл

@ -77,6 +77,9 @@ class nsWaylandDisplay {
uint32_t mModifierLo);
static bool IsDMABufEnabled();
// See WindowSurfaceWayland::CacheMode for details.
int GetRenderingCacheModePref() { return mRenderingCacheModePref; };
private:
bool ConfigureGbm();
@ -100,6 +103,7 @@ class nsWaylandDisplay {
static bool mIsDMABufEnabled;
static int mIsDMABufPrefState;
static bool mIsDMABufConfigured;
static int mRenderingCacheModePref;
};
void WaylandDispatchDisplays();

Просмотреть файл

@ -210,11 +210,15 @@ nsresult nsWebShellWindow::Initialize(
nsIWebProgress::NOTIFY_STATE_NETWORK);
}
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
if (aOpenerWindow) {
nsPIDOMWindowOuter* window = mDocShell->GetWindow();
MOZ_ASSERT(window);
window->SetOpenerWindow(nsPIDOMWindowOuter::From(aOpenerWindow), true);
BrowsingContext* bc = mDocShell->GetBrowsingContext();
BrowsingContext* openerBC =
nsPIDOMWindowOuter::From(aOpenerWindow)->GetBrowsingContext();
MOZ_DIAGNOSTIC_ASSERT(bc->GetOpenerId() == openerBC->Id());
MOZ_DIAGNOSTIC_ASSERT(bc->HadOriginalOpener());
}
#endif
// Eagerly create an about:blank content viewer with the right principal here,
// rather than letting it happening in the upcoming call to