зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1560400: Part 1 - Support remote frames in Window indexed getters. r=nika
Differential Revision: https://phabricator.services.mozilla.com/D35471 --HG-- extra : rebase_source : b326799f8ced75068f7e7fec6edbd39455cdb9b1 extra : source : 84633034590f2d1a4c336f9653e6c542f3a09039
This commit is contained in:
Родитель
c98e734fe6
Коммит
f180f12646
|
@ -16,7 +16,6 @@
|
|||
#include "nsQueryObject.h"
|
||||
|
||||
#include "mozilla/dom/URL.h"
|
||||
#include "nsDOMWindowList.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "mozilla/dom/WindowBinding.h"
|
||||
#include "mozilla/dom/WindowProxyHolder.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDOMWindowList.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsHTMLDocument.h"
|
||||
#include "nsJSUtils.h"
|
||||
|
@ -18,7 +17,7 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static bool ShouldExposeChildWindow(nsString& aNameBeingResolved,
|
||||
static bool ShouldExposeChildWindow(const nsString& aNameBeingResolved,
|
||||
BrowsingContext* aChild) {
|
||||
nsPIDOMWindowOuter* child = aChild->GetDOMWindow();
|
||||
Element* e = child->GetFrameElementInternal();
|
||||
|
@ -169,23 +168,12 @@ bool WindowNamedPropertiesHandler::ownPropNames(
|
|||
// The names live on the outer window, which might be null
|
||||
nsGlobalWindowOuter* outer = win->GetOuterWindowInternal();
|
||||
if (outer) {
|
||||
nsDOMWindowList* childWindows = outer->GetFrames();
|
||||
if (childWindows) {
|
||||
uint32_t length = childWindows->GetLength();
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> item =
|
||||
childWindows->GetDocShellTreeItemAt(i);
|
||||
// This is a bit silly, since we could presumably just do
|
||||
// item->GetWindow(). But it's not obvious whether this does the same
|
||||
// thing as GetChildWindow() with the item's name (due to the complexity
|
||||
// of FindChildWithName). Since GetChildWindow is what we use in
|
||||
// getOwnPropDescriptor, let's try to be consistent.
|
||||
nsString name;
|
||||
item->GetName(name);
|
||||
if (!names.Contains(name)) {
|
||||
if (BrowsingContext* bc = outer->GetBrowsingContext()) {
|
||||
for (const auto& child : bc->GetChildren()) {
|
||||
const nsString& name = child->Name();
|
||||
if (!name.IsEmpty() && !names.Contains(name)) {
|
||||
// Make sure we really would expose it from getOwnPropDescriptor.
|
||||
RefPtr<BrowsingContext> child = win->GetChildWindow(name);
|
||||
if (child && ShouldExposeChildWindow(name, child)) {
|
||||
if (ShouldExposeChildWindow(name, child)) {
|
||||
names.AppendElement(name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -336,7 +336,6 @@ UNIFIED_SOURCES += [
|
|||
'nsDOMNavigationTiming.cpp',
|
||||
'nsDOMSerializer.cpp',
|
||||
'nsDOMTokenList.cpp',
|
||||
'nsDOMWindowList.cpp',
|
||||
'nsFocusManager.cpp',
|
||||
'nsFrameLoader.cpp',
|
||||
'nsFrameLoaderOwner.cpp',
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsDOMWindowList.h"
|
||||
|
||||
#include "FlushType.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
nsDOMWindowList::nsDOMWindowList(nsIDocShell* aDocShell) {
|
||||
SetDocShell(aDocShell);
|
||||
}
|
||||
|
||||
nsDOMWindowList::~nsDOMWindowList() {}
|
||||
|
||||
void nsDOMWindowList::SetDocShell(nsIDocShell* aDocShell) {
|
||||
mDocShellNode = aDocShell; // Weak Reference
|
||||
}
|
||||
|
||||
void nsDOMWindowList::EnsureFresh() {
|
||||
nsCOMPtr<nsIWebNavigation> shellAsNav = do_QueryInterface(mDocShellNode);
|
||||
|
||||
if (shellAsNav) {
|
||||
nsCOMPtr<dom::Document> doc;
|
||||
shellAsNav->GetDocument(getter_AddRefs(doc));
|
||||
|
||||
if (doc) {
|
||||
doc->FlushPendingNotifications(FlushType::ContentAndNotify);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t nsDOMWindowList::GetLength() {
|
||||
EnsureFresh();
|
||||
|
||||
NS_ENSURE_TRUE(mDocShellNode, 0);
|
||||
|
||||
int32_t length;
|
||||
nsresult rv = mDocShellNode->GetChildCount(&length);
|
||||
NS_ENSURE_SUCCESS(rv, 0);
|
||||
|
||||
return uint32_t(length);
|
||||
}
|
||||
|
||||
already_AddRefed<nsPIDOMWindowOuter> nsDOMWindowList::IndexedGetter(
|
||||
uint32_t aIndex) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> item = GetDocShellTreeItemAt(aIndex);
|
||||
if (!item) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = item->GetWindow();
|
||||
MOZ_ASSERT(window);
|
||||
|
||||
return window.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsPIDOMWindowOuter> nsDOMWindowList::NamedItem(
|
||||
const nsAString& aName) {
|
||||
EnsureFresh();
|
||||
|
||||
if (!mDocShellNode) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> item;
|
||||
mDocShellNode->FindChildWithName(aName, false, false, nullptr, nullptr,
|
||||
getter_AddRefs(item));
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> childWindow(do_GetInterface(item));
|
||||
return childWindow.forget();
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
#ifndef nsDOMWindowList_h___
|
||||
#define nsDOMWindowList_h___
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include <stdint.h>
|
||||
#include "nsIDocShell.h"
|
||||
|
||||
class nsIDocShell;
|
||||
class nsIDOMWindow;
|
||||
|
||||
class nsDOMWindowList final {
|
||||
public:
|
||||
explicit nsDOMWindowList(nsIDocShell* aDocShell);
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(nsDOMWindowList)
|
||||
|
||||
uint32_t GetLength();
|
||||
already_AddRefed<nsPIDOMWindowOuter> IndexedGetter(uint32_t aIndex);
|
||||
already_AddRefed<nsPIDOMWindowOuter> NamedItem(const nsAString& aName);
|
||||
|
||||
// local methods
|
||||
void SetDocShell(nsIDocShell* aDocShell);
|
||||
already_AddRefed<nsIDocShellTreeItem> GetDocShellTreeItemAt(uint32_t aIndex) {
|
||||
EnsureFresh();
|
||||
nsCOMPtr<nsIDocShellTreeItem> item;
|
||||
if (mDocShellNode) {
|
||||
mDocShellNode->GetChildAt(aIndex, getter_AddRefs(item));
|
||||
}
|
||||
return item.forget();
|
||||
}
|
||||
|
||||
protected:
|
||||
~nsDOMWindowList();
|
||||
|
||||
// Note: this function may flush and cause mDocShellNode to become null.
|
||||
void EnsureFresh();
|
||||
|
||||
nsIDocShell* mDocShellNode; // Weak Reference
|
||||
};
|
||||
|
||||
#endif // nsDOMWindowList_h___
|
|
@ -50,7 +50,6 @@
|
|||
#include "nsISizeOfEventTarget.h"
|
||||
#include "nsDOMJSUtils.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsDOMWindowList.h"
|
||||
#include "mozilla/dom/WakeLock.h"
|
||||
#include "mozilla/dom/power/PowerManagerService.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
|
@ -2708,11 +2707,7 @@ bool nsGlobalWindowInner::GetClosed(ErrorResult& aError) {
|
|||
FORWARD_TO_OUTER(GetClosedOuter, (), true);
|
||||
}
|
||||
|
||||
nsDOMWindowList* nsGlobalWindowInner::GetFrames() {
|
||||
FORWARD_TO_OUTER(GetFrames, (), nullptr);
|
||||
}
|
||||
|
||||
already_AddRefed<nsPIDOMWindowOuter> nsGlobalWindowInner::IndexedGetter(
|
||||
Nullable<WindowProxyHolder> nsGlobalWindowInner::IndexedGetter(
|
||||
uint32_t aIndex) {
|
||||
FORWARD_TO_OUTER(IndexedGetterOuter, (aIndex), nullptr);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,6 @@ class nsITimeoutHandler;
|
|||
class nsIWebBrowserChrome;
|
||||
class mozIDOMWindowProxy;
|
||||
|
||||
class nsDOMWindowList;
|
||||
class nsScreen;
|
||||
class nsHistory;
|
||||
class nsGlobalWindowObserver;
|
||||
|
@ -381,7 +380,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
// WebIDL interface.
|
||||
already_AddRefed<nsPIDOMWindowOuter> IndexedGetter(uint32_t aIndex);
|
||||
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> IndexedGetter(
|
||||
uint32_t aIndex);
|
||||
|
||||
static bool IsPrivilegedChromeWindow(JSContext* /* unused */, JSObject* aObj);
|
||||
|
||||
|
@ -612,7 +612,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||
void Focus(mozilla::ErrorResult& aError);
|
||||
nsresult Focus() override;
|
||||
void Blur(mozilla::ErrorResult& aError);
|
||||
nsDOMWindowList* GetFrames() final;
|
||||
mozilla::dom::BrowsingContext* GetFrames(mozilla::ErrorResult& aError);
|
||||
uint32_t Length();
|
||||
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetTop(
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#include "nsISizeOfEventTarget.h"
|
||||
#include "nsDOMJSUtils.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsDOMWindowList.h"
|
||||
#include "mozilla/dom/WakeLock.h"
|
||||
#include "mozilla/dom/power/PowerManagerService.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
|
@ -510,8 +509,9 @@ class nsOuterWindowProxy : public MaybeCrossOriginObject<js::Wrapper> {
|
|||
|
||||
// Returns a non-null window only if id is an index and we have a
|
||||
// window at that index.
|
||||
already_AddRefed<nsPIDOMWindowOuter> GetSubframeWindow(
|
||||
JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id) const;
|
||||
Nullable<WindowProxyHolder> GetSubframeWindow(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id) const;
|
||||
|
||||
bool AppendIndexedPropertyNames(JSObject* proxy,
|
||||
JS::MutableHandleVector<jsid> props) const;
|
||||
|
@ -784,7 +784,7 @@ bool nsOuterWindowProxy::delete_(JSContext* cx, JS::Handle<JSObject*> proxy,
|
|||
return ReportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("delete"));
|
||||
}
|
||||
|
||||
if (nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id)) {
|
||||
if (!GetSubframeWindow(cx, proxy, id).IsNull()) {
|
||||
// Fail (which means throw if strict, else return false).
|
||||
return result.failCantDeleteWindowElement();
|
||||
}
|
||||
|
@ -818,7 +818,7 @@ bool nsOuterWindowProxy::has(JSContext* cx, JS::Handle<JSObject*> proxy,
|
|||
return hasOwn(cx, proxy, id, bp);
|
||||
}
|
||||
|
||||
if (nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id)) {
|
||||
if (!GetSubframeWindow(cx, proxy, id).IsNull()) {
|
||||
*bp = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -851,7 +851,7 @@ bool nsOuterWindowProxy::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy,
|
|||
return js::BaseProxyHandler::hasOwn(cx, proxy, id, bp);
|
||||
}
|
||||
|
||||
if (nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id)) {
|
||||
if (!GetSubframeWindow(cx, proxy, id).IsNull()) {
|
||||
*bp = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -982,28 +982,17 @@ bool nsOuterWindowProxy::GetSubframeWindow(JSContext* cx,
|
|||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JS::Value> vp,
|
||||
bool& found) const {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> frame = GetSubframeWindow(cx, proxy, id);
|
||||
if (!frame) {
|
||||
Nullable<WindowProxyHolder> frame = GetSubframeWindow(cx, proxy, id);
|
||||
if (frame.IsNull()) {
|
||||
found = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
found = true;
|
||||
// Just return the window's global
|
||||
nsGlobalWindowOuter* global = nsGlobalWindowOuter::Cast(frame);
|
||||
frame->EnsureInnerWindow();
|
||||
JSObject* obj = global->GetGlobalJSObject();
|
||||
// This null check fixes a hard-to-reproduce crash that occurs when we
|
||||
// get here when we're mid-call to nsDocShell::Destroy. See bug 640904
|
||||
// comment 105.
|
||||
if (MOZ_UNLIKELY(!obj)) {
|
||||
return xpc::Throw(cx, NS_ERROR_FAILURE);
|
||||
}
|
||||
vp.setObject(*obj);
|
||||
return JS_WrapValue(cx, vp);
|
||||
return WrapObject(cx, frame.Value(), vp);
|
||||
}
|
||||
|
||||
already_AddRefed<nsPIDOMWindowOuter> nsOuterWindowProxy::GetSubframeWindow(
|
||||
Nullable<WindowProxyHolder> nsOuterWindowProxy::GetSubframeWindow(
|
||||
JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id) const {
|
||||
uint32_t index = GetArrayIndexFromId(id);
|
||||
if (!IsArrayIndex(index)) {
|
||||
|
@ -1300,7 +1289,6 @@ void nsGlobalWindowOuter::CleanUp() {
|
|||
|
||||
StartDying();
|
||||
|
||||
mFrames = nullptr;
|
||||
mWindowUtils = nullptr;
|
||||
|
||||
ClearControllers();
|
||||
|
@ -2380,10 +2368,6 @@ void nsGlobalWindowOuter::SetDocShell(nsDocShell* aDocShell) {
|
|||
mTopLevelOuterContentWindow =
|
||||
!mIsChrome && GetScriptableTopInternal() == this;
|
||||
|
||||
if (mFrames) {
|
||||
mFrames->SetDocShell(aDocShell);
|
||||
}
|
||||
|
||||
// Get our enclosing chrome shell and retrieve its global window impl, so
|
||||
// that we can do some forwarding to the chrome document.
|
||||
RefPtr<EventTarget> chromeEventHandler;
|
||||
|
@ -2475,10 +2459,6 @@ void nsGlobalWindowOuter::DetachFromDocShell() {
|
|||
mDocShell = nullptr;
|
||||
mBrowsingContext->ClearDocShell();
|
||||
|
||||
if (mFrames) {
|
||||
mFrames->SetDocShell(nullptr);
|
||||
}
|
||||
|
||||
MaybeForgiveSpamCount();
|
||||
CleanUp();
|
||||
}
|
||||
|
@ -3196,20 +3176,16 @@ bool nsGlobalWindowOuter::GetClosedOuter() {
|
|||
|
||||
bool nsGlobalWindowOuter::Closed() { return GetClosedOuter(); }
|
||||
|
||||
nsDOMWindowList* nsGlobalWindowOuter::GetFrames() {
|
||||
if (!mFrames && mDocShell) {
|
||||
mFrames = new nsDOMWindowList(mDocShell);
|
||||
}
|
||||
|
||||
return mFrames;
|
||||
}
|
||||
|
||||
already_AddRefed<nsPIDOMWindowOuter> nsGlobalWindowOuter::IndexedGetterOuter(
|
||||
Nullable<WindowProxyHolder> nsGlobalWindowOuter::IndexedGetterOuter(
|
||||
uint32_t aIndex) {
|
||||
nsDOMWindowList* windows = GetFrames();
|
||||
NS_ENSURE_TRUE(windows, nullptr);
|
||||
BrowsingContext* bc = GetBrowsingContext();
|
||||
NS_ENSURE_TRUE(bc, nullptr);
|
||||
|
||||
return windows->IndexedGetter(aIndex);
|
||||
const BrowsingContext::Children& children = bc->GetChildren();
|
||||
if (aIndex < children.Length()) {
|
||||
return WindowProxyHolder(children[aIndex]);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIControllers* nsGlobalWindowOuter::GetControllersOuter(ErrorResult& aError) {
|
||||
|
@ -3962,9 +3938,8 @@ double nsGlobalWindowOuter::GetScrollXOuter() { return GetScrollXY(false).x; }
|
|||
double nsGlobalWindowOuter::GetScrollYOuter() { return GetScrollXY(false).y; }
|
||||
|
||||
uint32_t nsGlobalWindowOuter::Length() {
|
||||
nsDOMWindowList* windows = GetFrames();
|
||||
|
||||
return windows ? windows->GetLength() : 0;
|
||||
BrowsingContext* bc = GetBrowsingContext();
|
||||
return bc ? bc->GetChildren().Length() : 0;
|
||||
}
|
||||
|
||||
Nullable<WindowProxyHolder> nsGlobalWindowOuter::GetTopOuter() {
|
||||
|
|
|
@ -74,7 +74,6 @@ class nsIWebBrowserChrome;
|
|||
class mozIDOMWindowProxy;
|
||||
|
||||
class nsDocShellLoadState;
|
||||
class nsDOMWindowList;
|
||||
class nsScreen;
|
||||
class nsHistory;
|
||||
class nsGlobalWindowObserver;
|
||||
|
@ -354,7 +353,8 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
|||
// nsIObserver
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
already_AddRefed<nsPIDOMWindowOuter> IndexedGetterOuter(uint32_t aIndex);
|
||||
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> IndexedGetterOuter(
|
||||
uint32_t aIndex);
|
||||
|
||||
already_AddRefed<nsPIDOMWindowOuter> GetTop() override;
|
||||
// Similar to GetTop() except that it stops at content frames that an
|
||||
|
@ -535,7 +535,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
|||
nsresult Focus() override;
|
||||
void BlurOuter();
|
||||
mozilla::dom::BrowsingContext* GetFramesOuter();
|
||||
nsDOMWindowList* GetFrames() final;
|
||||
uint32_t Length();
|
||||
mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> GetTopOuter();
|
||||
|
||||
|
@ -918,8 +917,8 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
|||
|
||||
virtual bool ShouldShowFocusRing() override;
|
||||
|
||||
virtual void SetKeyboardIndicators(UIStateChangeType aShowFocusRings)
|
||||
override;
|
||||
virtual void SetKeyboardIndicators(
|
||||
UIStateChangeType aShowFocusRings) override;
|
||||
|
||||
public:
|
||||
virtual already_AddRefed<nsPIWindowRoot> GetTopWindowRoot() override;
|
||||
|
@ -1099,7 +1098,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
|||
// For |window.arguments|, via |openDialog|.
|
||||
nsCOMPtr<nsIArray> mArguments;
|
||||
|
||||
RefPtr<nsDOMWindowList> mFrames;
|
||||
RefPtr<nsDOMWindowUtils> mWindowUtils;
|
||||
nsString mStatus;
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#define DOM_WINDOW_THAWED_TOPIC "dom-window-thawed"
|
||||
|
||||
class nsDOMOfflineResourceList;
|
||||
class nsDOMWindowList;
|
||||
class nsGlobalWindowInner;
|
||||
class nsGlobalWindowOuter;
|
||||
class nsIArray;
|
||||
|
@ -546,8 +545,6 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
|||
|
||||
virtual nsresult GetControllers(nsIControllers** aControllers) = 0;
|
||||
|
||||
virtual nsDOMWindowList* GetFrames() = 0;
|
||||
|
||||
virtual nsresult GetInnerWidth(int32_t* aWidth) = 0;
|
||||
virtual nsresult GetInnerHeight(int32_t* aHeight) = 0;
|
||||
|
||||
|
@ -1045,8 +1042,6 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
|
|||
virtual already_AddRefed<mozilla::dom::Selection> GetSelection() = 0;
|
||||
virtual already_AddRefed<nsPIDOMWindowOuter> GetOpener() = 0;
|
||||
|
||||
virtual nsDOMWindowList* GetFrames() = 0;
|
||||
|
||||
// aLoadState will be passed on through to the windowwatcher.
|
||||
// aForceNoOpener will act just like a "noopener" feature in aOptions except
|
||||
// will not affect any other window features.
|
||||
|
|
|
@ -7,13 +7,14 @@
|
|||
#include "nsWindowMemoryReporter.h"
|
||||
#include "nsWindowSizes.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "nsDOMWindowList.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "XPCJSMemoryReporter.h"
|
||||
|
@ -61,19 +62,16 @@ static nsresult AddNonJSSizeOfWindowAndItsDescendents(
|
|||
|
||||
windowSizes.addToTabSizes(aSizes);
|
||||
|
||||
nsDOMWindowList* frames = aWindow->GetFrames();
|
||||
|
||||
uint32_t length = frames->GetLength();
|
||||
BrowsingContext* bc = aWindow->GetBrowsingContext();
|
||||
if (!bc) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Measure this window's descendents.
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> child = frames->IndexedGetter(i);
|
||||
NS_ENSURE_STATE(child);
|
||||
|
||||
nsGlobalWindowOuter* childWin = nsGlobalWindowOuter::Cast(child);
|
||||
|
||||
nsresult rv = AddNonJSSizeOfWindowAndItsDescendents(childWin, aSizes);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
for (const auto& frame : bc->GetChildren()) {
|
||||
if (auto* childWin = nsGlobalWindowOuter::Cast(frame->GetDOMWindow())) {
|
||||
MOZ_TRY(AddNonJSSizeOfWindowAndItsDescendents(childWin, aSizes));
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
var SimpleTest = opener.wrappedJSObject.SimpleTest;
|
||||
var ok = opener.wrappedJSObject.ok;
|
||||
|
||||
var doc = frames[0].document;
|
||||
// Note: We can't use frames[0] here because the type="content" attribute
|
||||
// isolates it into a separate browsing context hierarchy.
|
||||
var doc = document.querySelector("iframe").contentDocument;
|
||||
ok(doc.createElement("body") instanceof HTMLBodyElement,
|
||||
"Should be instance of HTMLBodyElement");
|
||||
ok(doc.createElement("div") instanceof HTMLDivElement,
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "AccessCheck.h"
|
||||
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "nsDOMWindowList.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
|
||||
#include "XPCWrapper.h"
|
||||
|
|
|
@ -1648,16 +1648,12 @@ bool DOMXrayTraits::resolveOwnProperty(JSContext* cx, HandleObject wrapper,
|
|||
nsGlobalWindowInner* win = AsWindow(cx, wrapper);
|
||||
// Note: As() unwraps outer windows to get to the inner window.
|
||||
if (win) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> subframe = win->IndexedGetter(index);
|
||||
if (subframe) {
|
||||
subframe->EnsureInnerWindow();
|
||||
nsGlobalWindowOuter* global = nsGlobalWindowOuter::Cast(subframe);
|
||||
JSObject* obj = global->GetGlobalJSObject();
|
||||
if (MOZ_UNLIKELY(!obj)) {
|
||||
Nullable<WindowProxyHolder> subframe = win->IndexedGetter(index);
|
||||
if (!subframe.IsNull()) {
|
||||
if (MOZ_UNLIKELY(!WrapObject(cx, subframe.Value(), desc.value()))) {
|
||||
// It's gone?
|
||||
return xpc::Throw(cx, NS_ERROR_FAILURE);
|
||||
}
|
||||
desc.value().setObject(*obj);
|
||||
FillPropertyDescriptor(desc, wrapper, true);
|
||||
return JS_WrapPropertyDescriptor(cx, desc);
|
||||
}
|
||||
|
|
|
@ -11,13 +11,17 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=396024
|
|||
<iframe src="about:blank" type="content"></iframe>
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
// Note: We can't use window.frames directly here because the type="content"
|
||||
// attributes isolate the frames into their own BrowsingContext hierarchies.
|
||||
let frameElts = document.getElementsByTagName("iframe");
|
||||
|
||||
var is = window.opener.wrappedJSObject.is;
|
||||
var ok = window.opener.wrappedJSObject.ok;
|
||||
var todo = window.opener.wrappedJSObject.todo;
|
||||
var SimpleTest = window.opener.wrappedJSObject.SimpleTest;
|
||||
var gWbp;
|
||||
function printpreview() {
|
||||
gWbp = window.frames[1].docShell.initOrReusePrintPreviewViewer();
|
||||
gWbp = frameElts[1].contentWindow.docShell.initOrReusePrintPreviewViewer();
|
||||
var listener = {
|
||||
onLocationChange: function(webProgress, request, location, flags) { },
|
||||
onProgressChange: function(webProgress, request, curSelfProgress,
|
||||
|
@ -39,12 +43,12 @@ function printpreview() {
|
|||
prefs.setBoolPref('print.show_print_progress', false);
|
||||
//XXX I would have thought this would work, instead I'm forced to use prefs service
|
||||
gWbp.globalPrintSettings.showPrintProgress = false;
|
||||
gWbp.printPreview(gWbp.globalPrintSettings, window.frames[0], listener);
|
||||
gWbp.printPreview(gWbp.globalPrintSettings, frameElts[0].contentWindow, listener);
|
||||
prefs.clearUserPref('print.show_print_progress');
|
||||
}
|
||||
|
||||
function exitprintpreview() {
|
||||
window.frames[1].docShell.exitPrintPreview();
|
||||
frameElts[1].contentWindow.docShell.exitPrintPreview();
|
||||
}
|
||||
|
||||
function finish() {
|
||||
|
@ -86,11 +90,11 @@ function run2() {
|
|||
setTimeout(run3, 0);
|
||||
};
|
||||
document.getElementById("i").addEventListener("load", loadhandler, true);
|
||||
window.frames[0].location.reload();
|
||||
frameElts[0].contentWindow.location.reload();
|
||||
}
|
||||
|
||||
function run3() {
|
||||
gWbp = window.frames[1].docShell.initOrReusePrintPreviewViewer();
|
||||
gWbp = frameElts[1].contentWindow.docShell.initOrReusePrintPreviewViewer();
|
||||
ok(gWbp.doingPrintPreview, "Should be doing print preview");
|
||||
exitprintpreview();
|
||||
setTimeout(run4, 0);
|
||||
|
@ -109,7 +113,7 @@ function run4() {
|
|||
}
|
||||
|
||||
function run5() {
|
||||
gWbp = window.frames[1].docShell.initOrReusePrintPreviewViewer();
|
||||
gWbp = frameElts[1].contentWindow.docShell.initOrReusePrintPreviewViewer();
|
||||
ok(!gWbp.doingPrintPreview, "Should not be doing print preview anymore2");
|
||||
|
||||
//XXX this shouldn't be necessary, see bug 405555
|
||||
|
|
|
@ -11,13 +11,17 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=482976
|
|||
<iframe src="about:blank" type="content"></iframe>
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
// Note: We can't use window.frames directly here because the type="content"
|
||||
// attributes isolate the frames into their own BrowsingContext hierarchies.
|
||||
let frameElts = document.getElementsByTagName("iframe");
|
||||
|
||||
var is = window.opener.wrappedJSObject.is;
|
||||
var ok = window.opener.wrappedJSObject.ok;
|
||||
var todo = window.opener.wrappedJSObject.todo;
|
||||
var SimpleTest = window.opener.wrappedJSObject.SimpleTest;
|
||||
var gWbp;
|
||||
function printpreview() {
|
||||
gWbp = window.frames[1].docShell.initOrReusePrintPreviewViewer();
|
||||
gWbp = frameElts[1].contentWindow.docShell.initOrReusePrintPreviewViewer();
|
||||
var listener = {
|
||||
onLocationChange: function(webProgress, request, location, flags) { },
|
||||
onProgressChange: function(webProgress, request, curSelfProgress,
|
||||
|
@ -39,12 +43,12 @@ function printpreview() {
|
|||
prefs.setBoolPref('print.show_print_progress', false);
|
||||
//XXX I would have thought this would work, instead I'm forced to use prefs service
|
||||
gWbp.globalPrintSettings.showPrintProgress = false;
|
||||
gWbp.printPreview(gWbp.globalPrintSettings, window.frames[0], listener);
|
||||
gWbp.printPreview(gWbp.globalPrintSettings, frameElts[0].contentWindow, listener);
|
||||
prefs.clearUserPref('print.show_print_progress');
|
||||
}
|
||||
|
||||
function exitprintpreview() {
|
||||
window.frames[1].docShell.exitPrintPreview();
|
||||
frameElts[1].contentWindow.docShell.exitPrintPreview();
|
||||
}
|
||||
|
||||
function finish() {
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
<iframe height="200" width="600" type="content"></iframe>
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
// Note: We can't use window.frames directly here because the type="content"
|
||||
// attributes isolate the frames into their own BrowsingContext hierarchies.
|
||||
let frameElts = document.getElementsByTagName("iframe");
|
||||
|
||||
var is = window.opener.wrappedJSObject.is;
|
||||
var isnot = window.opener.wrappedJSObject.isnot;
|
||||
var ok = window.opener.wrappedJSObject.ok;
|
||||
|
@ -24,7 +28,7 @@ var file = Cc["@mozilla.org/file/directory_service;1"]
|
|||
filePath = file.path;
|
||||
|
||||
function printpreview(hasMozPrintCallback) {
|
||||
gWbp = window.frames[1].docShell.initOrReusePrintPreviewViewer();
|
||||
gWbp = frameElts[1].docShell.initOrReusePrintPreviewViewer();
|
||||
var listener = {
|
||||
onLocationChange: function(webProgress, request, location, flags) { },
|
||||
onProgressChange: function(webProgress, request, curSelfProgress,
|
||||
|
@ -50,22 +54,22 @@ function printpreview(hasMozPrintCallback) {
|
|||
var after = 0;
|
||||
function beforeprint() { ++before; }
|
||||
function afterprint() { ++after; }
|
||||
window.frames[0].addEventListener("beforeprint", beforeprint, true);
|
||||
window.frames[0].addEventListener("afterprint", afterprint, true);
|
||||
gWbp.printPreview(gWbp.globalPrintSettings, window.frames[0], listener);
|
||||
frameElts[0].contentWindow.addEventListener("beforeprint", beforeprint, true);
|
||||
frameElts[0].contentWindow.addEventListener("afterprint", afterprint, true);
|
||||
gWbp.printPreview(gWbp.globalPrintSettings, frameElts[0].contentWindow, listener);
|
||||
is(before, 1, "Should have called beforeprint listener!");
|
||||
if (!hasMozPrintCallback) {
|
||||
// If there's a mozPrintCallback the after print event won't fire until
|
||||
// later.
|
||||
is(after, 1, "Should have called afterprint listener!");
|
||||
}
|
||||
window.frames[0].removeEventListener("beforeprint", beforeprint, true);
|
||||
window.frames[0].removeEventListener("afterprint", afterprint, true);
|
||||
frameElts[0].contentWindow.removeEventListener("beforeprint", beforeprint, true);
|
||||
frameElts[0].contentWindow.removeEventListener("afterprint", afterprint, true);
|
||||
prefs.clearUserPref('print.show_print_progress');
|
||||
}
|
||||
|
||||
function exitprintpreview() {
|
||||
window.frames[1].docShell.exitPrintPreview();
|
||||
frameElts[1].contentWindow.docShell.exitPrintPreview();
|
||||
}
|
||||
|
||||
function finish() {
|
||||
|
@ -117,45 +121,45 @@ function addHTMLContent(parent) {
|
|||
function startTest1() {
|
||||
ctx1 = document.getElementsByTagName("canvas")[0].getContext("2d");
|
||||
ctx2 = document.getElementsByTagName("canvas")[1].getContext("2d");
|
||||
window.frames[0].document.body.innerHTML = "<div> </div><div>" + counter + " timers</div><div> </div>";
|
||||
frameElts[0].contentDocument.body.innerHTML = "<div> </div><div>" + counter + " timers</div><div> </div>";
|
||||
|
||||
// Note this timeout is needed so that we can check that timers run
|
||||
// after print preview, but not during it.
|
||||
window.frames[0].wrappedJSObject.counter = counter;
|
||||
window.frames[0].counterTimeout = "document.body.firstChild.nextSibling.innerHTML = ++counter + ' timers';" +
|
||||
frameElts[0].contentWindow.wrappedJSObject.counter = counter;
|
||||
frameElts[0].contentWindow.counterTimeout = "document.body.firstChild.nextSibling.innerHTML = ++counter + ' timers';" +
|
||||
"window.setTimeout(counterTimeout, 0);";
|
||||
window.frames[0].setTimeout(window.frames[0].counterTimeout, 0);
|
||||
window.frames[0].document.body.firstChild.innerHTML = "Print preview";
|
||||
frameElts[0].contentWindow.setTimeout(frameElts[0].contentWindow.counterTimeout, 0);
|
||||
frameElts[0].contentDocument.body.firstChild.innerHTML = "Print preview";
|
||||
|
||||
printpreview();
|
||||
ctx1.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(256,256,256)");
|
||||
window.frames[0].document.body.firstChild.innerHTML = "Galley presentation";
|
||||
ctx1.drawWindow(frameElts[1].contentWindow, 0, 0, 400, 400, "rgb(256,256,256)");
|
||||
frameElts[0].contentDocument.body.firstChild.innerHTML = "Galley presentation";
|
||||
|
||||
// Add some elements.
|
||||
addHTMLContent(window.frames[0].document.body.lastChild);
|
||||
addHTMLContent(frameElts[0].contentDocument.body.lastChild);
|
||||
// Delete them.
|
||||
window.frames[0].document.body.lastChild.innerHTML = "";
|
||||
frameElts[0].contentDocument.body.lastChild.innerHTML = "";
|
||||
// And readd.
|
||||
addHTMLContent(window.frames[0].document.body.lastChild);
|
||||
addHTMLContent(frameElts[0].contentDocument.body.lastChild);
|
||||
|
||||
setTimeout(finalizeTest1, 1000);
|
||||
}
|
||||
|
||||
function finalizeTest1() {
|
||||
ctx2.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(256,256,256)");
|
||||
ctx2.drawWindow(frameElts[1].contentWindow, 0, 0, 400, 400, "rgb(256,256,256)");
|
||||
exitprintpreview();
|
||||
ok(compareCanvases(), "Canvas should be the same!");
|
||||
counter = window.frames[0].counter;
|
||||
counter = frameElts[0].contentWindow.counter;
|
||||
// This timeout is needed so that we can check that timers do run after
|
||||
// print preview.
|
||||
setTimeout(runTest2, 1000);
|
||||
}
|
||||
|
||||
function runTest2() {
|
||||
isnot(window.frames[0].document.body.firstChild.nextSibling.textContent, "0 timers", "Timers should have run!");
|
||||
isnot(window.frames[0].counter, 0, "Timers should have run!");
|
||||
counter = window.frames[0].counter;
|
||||
window.frames[0].counterTimeout = "";
|
||||
isnot(frameElts[0].contentDocument.body.firstChild.nextSibling.textContent, "0 timers", "Timers should have run!");
|
||||
isnot(frameElts[0].contentWindow.counter, 0, "Timers should have run!");
|
||||
counter = frameElts[0].contentWindow.counter;
|
||||
frameElts[0].contentWindow.counterTimeout = "";
|
||||
setTimeout(runTest3, 0);
|
||||
}
|
||||
|
||||
|
@ -208,17 +212,17 @@ function runTest3() {
|
|||
}
|
||||
|
||||
function compareFormElementPrint(el1, el2, equals) {
|
||||
window.frames[0].document.body.innerHTML = el1;
|
||||
window.frames[0].document.body.firstChild.value =
|
||||
window.frames[0].document.body.firstChild.getAttribute('value');
|
||||
frameElts[0].contentDocument.body.innerHTML = el1;
|
||||
frameElts[0].contentDocument.body.firstChild.value =
|
||||
frameElts[0].contentDocument.body.firstChild.getAttribute('value');
|
||||
printpreview();
|
||||
ctx1.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(256,256,256)");
|
||||
ctx1.drawWindow(frameElts[1].contentWindow, 0, 0, 400, 400, "rgb(256,256,256)");
|
||||
exitprintpreview();
|
||||
window.frames[0].document.body.innerHTML = el2;
|
||||
window.frames[0].document.body.firstChild.value =
|
||||
window.frames[0].document.body.firstChild.getAttribute('value');
|
||||
frameElts[0].contentDocument.body.innerHTML = el2;
|
||||
frameElts[0].contentDocument.body.firstChild.value =
|
||||
frameElts[0].contentDocument.body.firstChild.getAttribute('value');
|
||||
printpreview();
|
||||
ctx2.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(256,256,256)");
|
||||
ctx2.drawWindow(frameElts[1].contentWindow, 0, 0, 400, 400, "rgb(256,256,256)");
|
||||
exitprintpreview();
|
||||
is(compareCanvases(), equals,
|
||||
"Comparing print preview didn't succeed [" + el1 + " : " + el2 + "]");
|
||||
|
@ -227,7 +231,7 @@ function compareFormElementPrint(el1, el2, equals) {
|
|||
|
||||
// This is a crash test for bug 539060.
|
||||
function runTest4() {
|
||||
window.frames[0].document.body.innerHTML =
|
||||
frameElts[0].contentDocument.body.innerHTML =
|
||||
"<iframe style='display: none;' src='data:text/html,<iframe>'></iframe>";
|
||||
setTimeout(runTest4end, 500);
|
||||
}
|
||||
|
@ -241,7 +245,7 @@ function runTest4end() {
|
|||
|
||||
// This is a crash test for bug 595337
|
||||
function runTest5() {
|
||||
window.frames[0].document.body.innerHTML =
|
||||
frameElts[0].contentDocument.body.innerHTML =
|
||||
'<iframe style="position: fixed; visibility: hidden; bottom: 10em;"></iframe>' +
|
||||
'<input contenteditable="true" style="display: table; page-break-before: left; width: 10000px;">';
|
||||
printpreview();
|
||||
|
@ -252,7 +256,7 @@ function runTest5() {
|
|||
|
||||
// Crash test for bug 878037
|
||||
function runTest6() {
|
||||
window.frames[0].document.body.innerHTML =
|
||||
frameElts[0].contentDocument.body.innerHTML =
|
||||
'<style> li { list-style-image: url("animated.gif"); } </style>' +
|
||||
'<li>Firefox will crash if you try and print this page</li>';
|
||||
|
||||
|
@ -269,19 +273,19 @@ function runTest6end() {
|
|||
function runTest7() {
|
||||
var contentText = "<a href='#'>mozilla</a><input>test<select><option>option1</option></select>";
|
||||
// Create normal content
|
||||
window.frames[0].document.body.innerHTML =
|
||||
frameElts[0].contentDocument.body.innerHTML =
|
||||
"<div>" + contentText + "</div>";
|
||||
window.frames[0].document.body.firstChild.value =
|
||||
window.frames[0].document.body.firstChild.getAttribute('value');
|
||||
frameElts[0].contentDocument.body.firstChild.value =
|
||||
frameElts[0].contentDocument.body.firstChild.getAttribute('value');
|
||||
printpreview();
|
||||
ctx1.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
ctx1.drawWindow(frameElts[1].contentWindow, 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
exitprintpreview();
|
||||
|
||||
window.frames[0].document.body.innerHTML = "<div></div>";
|
||||
var sr = window.frames[0].document.body.firstChild.attachShadow({mode: "open"});
|
||||
frameElts[0].contentDocument.body.innerHTML = "<div></div>";
|
||||
var sr = frameElts[0].contentDocument.body.firstChild.attachShadow({mode: "open"});
|
||||
sr.innerHTML = contentText;
|
||||
printpreview();
|
||||
ctx2.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
ctx2.drawWindow(frameElts[1].contentWindow, 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
exitprintpreview();
|
||||
ok(compareCanvases(), "Printing light DOM and shadow DOM should create same output");
|
||||
|
||||
|
@ -298,7 +302,7 @@ async function runTest8() {
|
|||
iframeElement.setAttribute("src", "printpreview_font_api_ref.html");
|
||||
});
|
||||
printpreview();
|
||||
ctx1.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
ctx1.drawWindow(frameElts[1].contentWindow, 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
exitprintpreview();
|
||||
|
||||
// Second, snapshot the page with font loaded in JS.
|
||||
|
@ -307,7 +311,7 @@ async function runTest8() {
|
|||
iframeElement.setAttribute("src", "printpreview_font_api.html");
|
||||
});
|
||||
printpreview();
|
||||
ctx2.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
ctx2.drawWindow(frameElts[1].contentWindow, 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
exitprintpreview();
|
||||
ok(compareCanvases(), "Printing pages with fonts loaded from CSS and JS should be the same.");
|
||||
|
||||
|
@ -316,17 +320,17 @@ async function runTest8() {
|
|||
|
||||
// Test for bug 1487649
|
||||
async function runTest9() {
|
||||
window.frames[0].document.body.innerHTML = `
|
||||
frameElts[0].contentDocument.body.innerHTML = `
|
||||
<svg width="100" height="100">
|
||||
<rect width='100' height='100' fill='lime'/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
printpreview();
|
||||
ctx1.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
ctx1.drawWindow(frameElts[1].contentWindow, 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
exitprintpreview();
|
||||
|
||||
window.frames[0].document.body.innerHTML = `
|
||||
frameElts[0].contentDocument.body.innerHTML = `
|
||||
<svg width="100" height="100">
|
||||
<defs>
|
||||
<g id="useme">
|
||||
|
@ -339,13 +343,13 @@ async function runTest9() {
|
|||
|
||||
// Set the attribute explicitly because this is a chrome document, and the
|
||||
// href attribute would get sanitized.
|
||||
window.frames[0].document.querySelector("use").setAttribute("href", "#useme");
|
||||
frameElts[0].contentDocument.querySelector("use").setAttribute("href", "#useme");
|
||||
|
||||
// Ensure the <use> shadow tree is created so we test what we want to test.
|
||||
window.frames[0].document.body.offsetTop;
|
||||
frameElts[0].contentDocument.body.offsetTop;
|
||||
|
||||
printpreview();
|
||||
ctx2.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
ctx2.drawWindow(frameElts[1].contentWindow, 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
exitprintpreview();
|
||||
ok(compareCanvases(), "Printing <use> subtrees should create same output");
|
||||
|
||||
|
@ -368,7 +372,7 @@ async function runTest10() {
|
|||
});
|
||||
printpreview(true);
|
||||
await mozPrintCallbackDone;
|
||||
ctx1.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
ctx1.drawWindow(frameElts[1].contentWindow, 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
exitprintpreview();
|
||||
|
||||
// Second, snapshot the page with font loaded in JS.
|
||||
|
@ -382,7 +386,7 @@ async function runTest10() {
|
|||
printpreview(true);
|
||||
// Wait for the mozprintcallback to finish.
|
||||
await mozPrintCallbackDone;
|
||||
ctx2.drawWindow(window.frames[1], 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
ctx2.drawWindow(frameElts[1].contentWindow, 0, 0, 400, 400, "rgb(255,255,255)");
|
||||
|
||||
exitprintpreview();
|
||||
ok(compareCanvases(), "Printing pages with fonts loaded from a mozPrintCallback should be the same.");
|
||||
|
|
|
@ -524,7 +524,11 @@ function FlushRendering(aFlushMode) {
|
|||
}
|
||||
|
||||
for (var i = 0; i < win.frames.length; ++i) {
|
||||
flushWindow(win.frames[i]);
|
||||
try {
|
||||
flushWindow(win.frames[i]);
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/PerformanceUtils.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "mozilla/dom/WorkerDebugger.h"
|
||||
|
@ -16,7 +17,6 @@
|
|||
#include "jsfriendapi.h"
|
||||
#include "js/MemoryMetrics.h"
|
||||
#include "nsWindowMemoryReporter.h"
|
||||
#include "nsDOMWindowList.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -93,15 +93,16 @@ nsresult GetTabSizes(nsGlobalWindowOuter* aWindow, nsTabSizes* aSizes) {
|
|||
// Add the window (and inner window) sizes. Might be cached.
|
||||
AddWindowTabSizes(aWindow, aSizes);
|
||||
|
||||
nsDOMWindowList* frames = aWindow->GetFrames();
|
||||
uint32_t length = frames->GetLength();
|
||||
BrowsingContext* bc = aWindow->GetBrowsingContext();
|
||||
if (!bc) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Measure this window's descendents.
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> child = frames->IndexedGetter(i);
|
||||
NS_ENSURE_STATE(child);
|
||||
nsGlobalWindowOuter* childWin = nsGlobalWindowOuter::Cast(child);
|
||||
nsresult rv = GetTabSizes(childWin, aSizes);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
for (const auto& frame : bc->GetChildren()) {
|
||||
if (auto* childWin = nsGlobalWindowOuter::Cast(frame->GetDOMWindow())) {
|
||||
MOZ_TRY(GetTabSizes(childWin, aSizes));
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче