Bug 1597437 - Handle 'window.content' legacy getter better with Fission, r=farre,Jamie

Differential Revision: https://phabricator.services.mozilla.com/D100167
This commit is contained in:
Nika Layzell 2020-12-21 12:08:08 +00:00
Родитель 27b04de0f6
Коммит e3097163dd
3 изменённых файлов: 46 добавлений и 61 удалений

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

@ -467,18 +467,18 @@ void RootAccessible::Shutdown() {
}
Relation RootAccessible::RelationByType(RelationType aType) const {
if (!mDocumentNode || aType != RelationType::EMBEDS)
if (!mDocumentNode || aType != RelationType::EMBEDS) {
return DocAccessibleWrap::RelationByType(aType);
}
if (nsPIDOMWindowOuter* rootWindow = mDocumentNode->GetWindow()) {
nsCOMPtr<nsPIDOMWindowOuter> contentWindow =
nsGlobalWindowOuter::Cast(rootWindow)->GetContent();
if (contentWindow) {
RefPtr<Document> contentDocumentNode = contentWindow->GetDoc();
if (contentDocumentNode) {
DocAccessible* contentDocument =
GetAccService()->GetDocAccessible(contentDocumentNode);
if (contentDocument) return Relation(contentDocument);
if (nsIDocShell* docShell = mDocumentNode->GetDocShell()) {
nsCOMPtr<nsIDocShellTreeOwner> owner;
docShell->GetTreeOwner(getter_AddRefs(owner));
if (owner) {
nsCOMPtr<nsIDocShellTreeItem> contentShell;
owner->GetPrimaryContentShell(getter_AddRefs(contentShell));
if (contentShell) {
return Relation(nsAccUtils::GetDocAccessibleFor(contentShell));
}
}
}

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

@ -3312,73 +3312,63 @@ void nsGlobalWindowOuter::GetContentOuter(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
CallerType aCallerType,
ErrorResult& aError) {
nsCOMPtr<nsPIDOMWindowOuter> content =
GetContentInternal(aError, aCallerType);
RefPtr<BrowsingContext> content = GetContentInternal(aCallerType, aError);
if (aError.Failed()) {
return;
}
if (content) {
JS::Rooted<JS::Value> val(aCx);
aError = nsContentUtils::WrapNative(aCx, content, &val);
if (aError.Failed()) {
return;
}
aRetval.set(&val.toObject());
if (!content) {
aRetval.set(nullptr);
return;
}
aRetval.set(nullptr);
JS::Rooted<JS::Value> val(aCx);
if (!ToJSValue(aCx, WindowProxyHolder{content}, &val)) {
aError.Throw(NS_ERROR_UNEXPECTED);
return;
}
MOZ_ASSERT(val.isObjectOrNull());
aRetval.set(val.toObjectOrNull());
}
already_AddRefed<nsPIDOMWindowOuter> nsGlobalWindowOuter::GetContentInternal(
ErrorResult& aError, CallerType aCallerType) {
already_AddRefed<BrowsingContext> nsGlobalWindowOuter::GetContentInternal(
CallerType aCallerType, ErrorResult& aError) {
// First check for a named frame named "content"
RefPtr<BrowsingContext> bc = GetChildWindow(u"content"_ns);
if (bc) {
nsCOMPtr<nsPIDOMWindowOuter> content(bc->GetDOMWindow());
return content.forget();
if (RefPtr<BrowsingContext> named = GetChildWindow(u"content"_ns)) {
return named.forget();
}
nsCOMPtr<nsIDocShellTreeItem> primaryContent;
if (aCallerType != CallerType::System) {
if (mDoc) {
mDoc->WarnOnceAbout(DeprecatedOperations::eWindowContentUntrusted);
}
// If we're called by non-chrome code, make sure we don't return
// the primary content window if the calling tab is hidden. In
// such a case we return the same-type root in the hidden tab,
// which is "good enough", for now.
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(mDocShell));
if (baseWin) {
bool visible = false;
baseWin->GetVisibility(&visible);
if (!visible) {
mDocShell->GetInProcessSameTypeRootTreeItem(
getter_AddRefs(primaryContent));
}
}
}
if (!primaryContent) {
// If we're in the parent process, and being called by system code, `content`
// should return the current primary content frame (if it's in-process).
//
// We return `nullptr` if the current primary content frame is out-of-process,
// rather than a remote window proxy, as that is the existing behaviour as of
// bug 1597437.
if (XRE_IsParentProcess() && aCallerType == CallerType::System) {
nsCOMPtr<nsIDocShellTreeOwner> treeOwner = GetTreeOwner();
if (!treeOwner) {
aError.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsCOMPtr<nsIDocShellTreeItem> primaryContent;
treeOwner->GetPrimaryContentShell(getter_AddRefs(primaryContent));
if (!primaryContent) {
return nullptr;
}
return do_AddRef(primaryContent->GetBrowsingContext());
}
if (!primaryContent) {
return nullptr;
// For legacy untrusted callers we always return the same value as
// `window.top`
if (mDoc && aCallerType != CallerType::System) {
mDoc->WarnOnceAbout(DeprecatedOperations::eWindowContentUntrusted);
}
nsCOMPtr<nsPIDOMWindowOuter> domWindow = primaryContent->GetWindow();
return domWindow.forget();
MOZ_ASSERT(mBrowsingContext->IsContent());
return do_AddRef(mBrowsingContext->Top());
}
nsresult nsGlobalWindowOuter::GetPrompter(nsIPrompt** aPrompt) {

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

@ -640,16 +640,11 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
void UpdateCommands(const nsAString& anAction, mozilla::dom::Selection* aSel,
int16_t aReason) override;
already_AddRefed<nsPIDOMWindowOuter> GetContentInternal(
mozilla::ErrorResult& aError, mozilla::dom::CallerType aCallerType);
already_AddRefed<mozilla::dom::BrowsingContext> GetContentInternal(
mozilla::dom::CallerType aCallerType, mozilla::ErrorResult& aError);
void GetContentOuter(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval,
mozilla::dom::CallerType aCallerType,
mozilla::ErrorResult& aError);
already_AddRefed<nsPIDOMWindowOuter> GetContent() {
nsCOMPtr<nsPIDOMWindowOuter> win = GetContentInternal(
mozilla::IgnoreErrors(), mozilla::dom::CallerType::System);
return win.forget();
}
// ChromeWindow bits. Do NOT call these unless your window is in
// fact chrome.