Bug 1509346 - Add support for <form rel>. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D166489
This commit is contained in:
Adam Vandolder 2023-01-16 21:32:19 +00:00
Родитель b09e6b2e7b
Коммит b2b544c7ed
21 изменённых файлов: 91 добавлений и 116 удалений

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

@ -12958,10 +12958,12 @@ bool nsDocShell::ShouldOpenInBlankTarget(const nsAString& aOriginalTarget,
: !linkHost.Equals("www."_ns + docHost);
}
static bool IsElementAnchorOrArea(nsIContent* aContent) {
// Make sure we are dealing with either an <A> or <AREA> element in the HTML
// or XHTML namespace.
return aContent->IsAnyOfHTMLElements(nsGkAtoms::a, nsGkAtoms::area);
static bool ElementCanHaveNoopener(nsIContent* aContent) {
// Make sure we are dealing with either an <A>, <AREA>, or <FORM> element in
// the HTML, XHTML, or SVG namespace.
return aContent->IsAnyOfHTMLElements(nsGkAtoms::a, nsGkAtoms::area,
nsGkAtoms::form) ||
aContent->IsSVGElement(nsGkAtoms::a);
}
nsresult nsDocShell::OnLinkClickSync(nsIContent* aContent,
@ -13020,10 +13022,10 @@ nsresult nsDocShell::OnLinkClickSync(nsIContent* aContent,
}
uint32_t flags = INTERNAL_LOAD_FLAGS_NONE;
bool isElementAnchorOrArea = IsElementAnchorOrArea(aContent);
bool elementCanHaveNoopener = ElementCanHaveNoopener(aContent);
bool triggeringPrincipalIsSystemPrincipal =
aLoadState->TriggeringPrincipal()->IsSystemPrincipal();
if (isElementAnchorOrArea) {
if (elementCanHaveNoopener) {
MOZ_ASSERT(aContent->IsHTMLElement());
nsAutoString relString;
aContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::rel,
@ -13107,8 +13109,8 @@ nsresult nsDocShell::OnLinkClickSync(nsIContent* aContent,
uint32_t loadType = inOnLoadHandler ? LOAD_NORMAL_REPLACE : LOAD_LINK;
nsCOMPtr<nsIReferrerInfo> referrerInfo =
isElementAnchorOrArea ? new ReferrerInfo(*aContent->AsElement())
: new ReferrerInfo(*referrerDoc);
elementCanHaveNoopener ? new ReferrerInfo(*aContent->AsElement())
: new ReferrerInfo(*referrerDoc);
RefPtr<WindowContext> context = mBrowsingContext->GetCurrentWindowContext();
aLoadState->SetTriggeringSandboxFlags(triggeringSandboxFlags);

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

@ -0,0 +1,16 @@
/* -*- 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 "mozilla/dom/AnchorAreaFormRelValues.h"
namespace mozilla::dom {
// static
const DOMTokenListSupportedToken
AnchorAreaFormRelValues::sSupportedRelValues[] = {"noreferrer", "noopener",
"opener", nullptr};
} // namespace mozilla::dom

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

@ -0,0 +1,21 @@
/* -*- 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 mozilla_dom_AnchorAreaFormRelValues_h__
#define mozilla_dom_AnchorAreaFormRelValues_h__
#include "mozilla/dom/DOMTokenListSupportedTokens.h"
namespace mozilla::dom {
class AnchorAreaFormRelValues {
protected:
static const DOMTokenListSupportedToken sSupportedRelValues[];
};
} // namespace mozilla::dom
#endif // mozilla_dom_AnchorAreaFormRelValues_h__

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

@ -148,6 +148,7 @@ EXPORTS.mozilla.dom += [
"!UseCounterWorkerList.h",
"AbstractRange.h",
"AncestorIterator.h",
"AnchorAreaFormRelValues.h",
"AnimationFrameProvider.h",
"AnonymousContent.h",
"Attr.h",
@ -307,6 +308,7 @@ if CONFIG["COMPILE_ENVIRONMENT"]:
UNIFIED_SOURCES += [
"AbstractRange.cpp",
"AnchorAreaFormRelValues.cpp",
"AnimationFrameProvider.cpp",
"AnonymousContent.cpp",
"Attr.cpp",

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

@ -24,10 +24,6 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Anchor)
namespace mozilla::dom {
// static
const DOMTokenListSupportedToken HTMLAnchorElement::sSupportedRelValues[] = {
"noreferrer", "noopener", nullptr};
HTMLAnchorElement::~HTMLAnchorElement() {
SupportsDNSPrefetch::Destroyed(*this);
}

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

@ -8,6 +8,7 @@
#define mozilla_dom_HTMLAnchorElement_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/AnchorAreaFormRelValues.h"
#include "mozilla/dom/Link.h"
#include "mozilla/dom/HTMLDNSPrefetch.h"
#include "nsGenericHTMLElement.h"
@ -20,7 +21,8 @@ namespace dom {
class HTMLAnchorElement final : public nsGenericHTMLElement,
public Link,
public SupportsDNSPrefetch {
public SupportsDNSPrefetch,
public AnchorAreaFormRelValues {
public:
using Element::GetText;
@ -193,8 +195,6 @@ class HTMLAnchorElement final : public nsGenericHTMLElement,
nsGenericHTMLElement::NodeInfoChanged(aOldDoc);
}
static DOMTokenListSupportedToken sSupportedRelValues[];
protected:
virtual ~HTMLAnchorElement();

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

@ -58,8 +58,7 @@ void HTMLAreaElement::GetLinkTarget(nsAString& aTarget) {
nsDOMTokenList* HTMLAreaElement::RelList() {
if (!mRelList) {
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel,
HTMLAnchorElement::sSupportedRelValues);
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel, sSupportedRelValues);
}
return mRelList;
}

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

@ -8,6 +8,7 @@
#define mozilla_dom_HTMLAreaElement_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/AnchorAreaFormRelValues.h"
#include "mozilla/dom/Link.h"
#include "nsGenericHTMLElement.h"
#include "nsGkAtoms.h"
@ -17,7 +18,9 @@ class EventChainPostVisitor;
class EventChainPreVisitor;
namespace dom {
class HTMLAreaElement final : public nsGenericHTMLElement, public Link {
class HTMLAreaElement final : public nsGenericHTMLElement,
public Link,
public AnchorAreaFormRelValues {
public:
explicit HTMLAreaElement(
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);

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

@ -77,6 +77,8 @@
#include "nsSandboxFlags.h"
#include "mozilla/dom/HTMLAnchorElement.h"
// images
#include "mozilla/dom/HTMLImageElement.h"
#include "mozilla/dom/HTMLButtonElement.h"
@ -139,12 +141,14 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLFormElement,
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mControls)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImageNameLookupTable)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPastNameLookupTable)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRelList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTargetContext)
RadioGroupManager::Traverse(tmp, cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLFormElement,
nsGenericHTMLElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRelList)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTargetContext)
RadioGroupManager::Unlink(tmp);
tmp->Clear();
@ -164,6 +168,13 @@ void HTMLFormElement::AsyncEventRunning(AsyncEventDispatcher* aEvent) {
}
}
nsDOMTokenList* HTMLFormElement::RelList() {
if (!mRelList) {
mRelList = new nsDOMTokenList(this, nsGkAtoms::rel, sSupportedRelValues);
}
return mRelList;
}
NS_IMPL_ELEMENT_CLONE(HTMLFormElement)
nsIHTMLCollection* HTMLFormElement::Elements() { return mControls; }

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

@ -10,6 +10,7 @@
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/Attributes.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/dom/AnchorAreaFormRelValues.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/PopupBlocker.h"
#include "mozilla/dom/RadioGroupManager.h"
@ -39,6 +40,7 @@ class FormData;
class HTMLFormElement final : public nsGenericHTMLElement,
public nsIRadioGroupContainer,
public AnchorAreaFormRelValues,
RadioGroupManager {
friend class HTMLFormControlsCollection;
@ -329,6 +331,12 @@ class HTMLFormElement final : public nsGenericHTMLElement,
SetHTMLAttr(nsGkAtoms::target, aValue, aRv);
}
void GetRel(DOMString& aValue) { GetHTMLAttr(nsGkAtoms::rel, aValue); }
void SetRel(const nsAString& aRel, ErrorResult& aError) {
SetHTMLAttr(nsGkAtoms::rel, aRel, aError);
}
nsDOMTokenList* RelList();
// it's only out-of-line because the class definition is not available in the
// header
nsIHTMLCollection* Elements();
@ -582,6 +590,8 @@ class HTMLFormElement final : public nsGenericHTMLElement,
/** Keep track of what the popup state was when the submit was initiated */
PopupBlocker::PopupControlState mSubmitPopupState;
RefPtr<nsDOMTokenList> mRelList;
/**
* Number of invalid and candidate for constraint validation elements in the
* form the last time UpdateValidity has been called.

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

@ -1,6 +1,6 @@
<!DOCTYPE html>
<body onload="document.querySelector('form').submit();">
<form action="javascript:opener.document.getElementById('result').textContent = document.cookie;" target="_blank">
<form action="javascript:opener.document.getElementById('result').textContent = document.cookie;" target="_blank" rel="opener">
</form>
<div id="result">not tested yet</div>
</body>

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

@ -1151,8 +1151,10 @@ static ReferrerPolicy ReferrerPolicyFromAttribute(const Element& aElement) {
}
static bool HasRelNoReferrer(const Element& aElement) {
// rel=noreferrer is only support in <a> and <area>
if (!aElement.IsAnyOfHTMLElements(nsGkAtoms::a, nsGkAtoms::area)) {
// rel=noreferrer is only supported in <a>, <area>, and <form>
if (!aElement.IsAnyOfHTMLElements(nsGkAtoms::a, nsGkAtoms::area,
nsGkAtoms::form) &&
!aElement.IsSVGElement(nsGkAtoms::a)) {
return false;
}

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

@ -31,10 +31,6 @@ SVGElement::StringInfo SVGAElement::sStringInfo[3] = {
{nsGkAtoms::href, kNameSpaceID_XLink, true},
{nsGkAtoms::target, kNameSpaceID_None, true}};
// static
const DOMTokenListSupportedToken SVGAElement::sSupportedRelValues[] = {
"noreferrer", "noopener", nullptr};
//----------------------------------------------------------------------
// nsISupports methods

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

@ -10,6 +10,7 @@
#include "Link.h"
#include "nsDOMTokenList.h"
#include "SVGAnimatedString.h"
#include "mozilla/dom/AnchorAreaFormRelValues.h"
#include "mozilla/dom/SVGGraphicsElement.h"
nsresult NS_NewSVGAElement(
@ -24,7 +25,9 @@ namespace dom {
using SVGAElementBase = SVGGraphicsElement;
class SVGAElement final : public SVGAElementBase, public Link {
class SVGAElement final : public SVGAElementBase,
public Link,
public AnchorAreaFormRelValues {
protected:
using Element::GetText;
@ -100,7 +103,6 @@ class SVGAElement final : public SVGAElementBase, public Link {
static StringInfo sStringInfo[3];
RefPtr<nsDOMTokenList> mRelList;
static DOMTokenListSupportedToken sSupportedRelValues[];
};
} // namespace dom

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

@ -34,6 +34,10 @@ interface HTMLFormElement : HTMLElement {
attribute boolean noValidate;
[CEReactions, Pure, SetterThrows]
attribute DOMString target;
[CEReactions, Pure, SetterThrows]
attribute DOMString rel;
[PutForwards=value]
readonly attribute DOMTokenList relList;
[Constant]
readonly attribute HTMLCollection elements;

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

@ -547,9 +547,6 @@ prefs: [dom.security.featurePolicy.experimental.enabled:true, dom.security.featu
[HTMLMediaElement interface: document.createElement("audio") must inherit property "audioTracks" with the proper type]
expected: FAIL
[HTMLFormElement interface: attribute rel]
expected: FAIL
[HTMLMediaElement interface: document.createElement("audio") must inherit property "videoTracks" with the proper type]
expected: FAIL
@ -595,9 +592,6 @@ prefs: [dom.security.featurePolicy.experimental.enabled:true, dom.security.featu
[HTMLInputElement interface: createInput("checkbox") must inherit property "dirName" with the proper type]
expected: FAIL
[HTMLFormElement interface: attribute relList]
expected: FAIL
[HTMLInputElement interface: createInput("hidden") must inherit property "dirName" with the proper type]
expected: FAIL
@ -643,9 +637,6 @@ prefs: [dom.security.featurePolicy.experimental.enabled:true, dom.security.featu
[HTMLMediaElement interface: attribute audioTracks]
expected: FAIL
[HTMLFormElement interface: document.createElement("form") must inherit property "rel" with the proper type]
expected: FAIL
[HTMLInputElement interface: createInput("email") must inherit property "dirName" with the proper type]
expected: FAIL
@ -655,9 +646,6 @@ prefs: [dom.security.featurePolicy.experimental.enabled:true, dom.security.featu
[HTMLTextAreaElement interface: document.createElement("textarea") must inherit property "dirName" with the proper type]
expected: FAIL
[HTMLFormElement interface: document.createElement("form") must inherit property "relList" with the proper type]
expected: FAIL
[HTMLInputElement interface: createInput("button") must inherit property "dirName" with the proper type]
expected: FAIL

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

@ -1,20 +1,3 @@
[rel-base-target.html]
expected:
if (os == "android") and fission: [TIMEOUT, OK]
[<form rel="noreferrer opener"> with <base target>]
expected: FAIL
[<form rel="opener noopener"> with <base target>]
expected: FAIL
[<form rel="noopener noreferrer"> with <base target>]
expected: FAIL
[<form rel="noopener"> with <base target>]
expected: FAIL
[<form rel="noreferrer"> with <base target>]
expected: FAIL
[<form rel=""> with <base target>]
expected: FAIL

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

@ -1,20 +1,3 @@
[rel-button-target.html]
expected:
if (os == "android") and fission: [OK, TIMEOUT]
[<form rel="opener noopener"> with <button formtarget>]
expected: FAIL
[<form rel="noopener noreferrer"> with <button formtarget>]
expected: FAIL
[<form rel="noreferrer opener"> with <button formtarget>]
expected: FAIL
[<form rel="noopener"> with <button formtarget>]
expected: FAIL
[<form rel="noreferrer"> with <button formtarget>]
expected: FAIL
[<form rel=""> with <button formtarget>]
expected: FAIL

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

@ -1,20 +1,3 @@
[rel-form-target.html]
expected:
if (os == "android") and fission: [OK, TIMEOUT]
[<form rel="noopener noreferrer"> with <form target>]
expected: FAIL
[<form rel="noreferrer opener"> with <form target>]
expected: FAIL
[<form rel="noreferrer"> with <form target>]
expected: FAIL
[<form rel="opener noopener"> with <form target>]
expected: FAIL
[<form rel="noopener"> with <form target>]
expected: FAIL
[<form rel=""> with <form target>]
expected: FAIL

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

@ -2,20 +2,3 @@
expected:
if (os == "android") and debug and fission: [TIMEOUT, OK]
if (os == "android") and not debug: [OK, TIMEOUT]
[<form rel="opener noopener"> with <input formtarget>]
expected: FAIL
[<form rel="noreferrer opener"> with <input formtarget>]
expected: FAIL
[<form rel="noopener noreferrer"> with <input formtarget>]
expected: FAIL
[<form rel="noreferrer"> with <input formtarget>]
expected: FAIL
[<form rel="noopener"> with <input formtarget>]
expected: FAIL
[<form rel=""> with <input formtarget>]
expected: FAIL

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

@ -1,13 +1,4 @@
[rellist-feature-detection.html]
[Make sure that relList based feature detection is working for <a>]
expected: FAIL
[Make sure that relList based feature detection is working for <form>]
expected: FAIL
[Make sure that relList based feature detection is working for <area>]
expected: FAIL
[Make sure that relList based feature detection is working for <link>]
expected: FAIL