diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index bc6748031181..70d638d1c1c2 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -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 or 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 , , or
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 referrerInfo = - isElementAnchorOrArea ? new ReferrerInfo(*aContent->AsElement()) - : new ReferrerInfo(*referrerDoc); + elementCanHaveNoopener ? new ReferrerInfo(*aContent->AsElement()) + : new ReferrerInfo(*referrerDoc); RefPtr context = mBrowsingContext->GetCurrentWindowContext(); aLoadState->SetTriggeringSandboxFlags(triggeringSandboxFlags); diff --git a/dom/base/AnchorAreaFormRelValues.cpp b/dom/base/AnchorAreaFormRelValues.cpp new file mode 100644 index 000000000000..66914341ef35 --- /dev/null +++ b/dom/base/AnchorAreaFormRelValues.cpp @@ -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 diff --git a/dom/base/AnchorAreaFormRelValues.h b/dom/base/AnchorAreaFormRelValues.h new file mode 100644 index 000000000000..b55890359fab --- /dev/null +++ b/dom/base/AnchorAreaFormRelValues.h @@ -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__ diff --git a/dom/base/moz.build b/dom/base/moz.build index f1d931ca7e3c..3c48d87d284b 100644 --- a/dom/base/moz.build +++ b/dom/base/moz.build @@ -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", diff --git a/dom/html/HTMLAnchorElement.cpp b/dom/html/HTMLAnchorElement.cpp index cdd22cfc742a..ed0ab867529f 100644 --- a/dom/html/HTMLAnchorElement.cpp +++ b/dom/html/HTMLAnchorElement.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); } diff --git a/dom/html/HTMLAnchorElement.h b/dom/html/HTMLAnchorElement.h index c6b9a5091683..cb65f893eae0 100644 --- a/dom/html/HTMLAnchorElement.h +++ b/dom/html/HTMLAnchorElement.h @@ -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(); diff --git a/dom/html/HTMLAreaElement.cpp b/dom/html/HTMLAreaElement.cpp index f63e5b3fa4dd..219662a9ce8d 100644 --- a/dom/html/HTMLAreaElement.cpp +++ b/dom/html/HTMLAreaElement.cpp @@ -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; } diff --git a/dom/html/HTMLAreaElement.h b/dom/html/HTMLAreaElement.h index 14a2d29d6d96..fe53374baad9 100644 --- a/dom/html/HTMLAreaElement.h +++ b/dom/html/HTMLAreaElement.h @@ -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&& aNodeInfo); diff --git a/dom/html/HTMLFormElement.cpp b/dom/html/HTMLFormElement.cpp index f0bb458958fe..7345144b63b7 100644 --- a/dom/html/HTMLFormElement.cpp +++ b/dom/html/HTMLFormElement.cpp @@ -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; } diff --git a/dom/html/HTMLFormElement.h b/dom/html/HTMLFormElement.h index 59cd049c31bb..e6aba2150d3c 100644 --- a/dom/html/HTMLFormElement.h +++ b/dom/html/HTMLFormElement.h @@ -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 mRelList; + /** * Number of invalid and candidate for constraint validation elements in the * form the last time UpdateValidity has been called. diff --git a/dom/html/test/file_bug1108547-2.html b/dom/html/test/file_bug1108547-2.html index af06c8c42e7e..f5d8c5f96483 100644 --- a/dom/html/test/file_bug1108547-2.html +++ b/dom/html/test/file_bug1108547-2.html @@ -1,6 +1,6 @@ - +
not tested yet
diff --git a/dom/security/ReferrerInfo.cpp b/dom/security/ReferrerInfo.cpp index 0091fe3b951c..2045a884a5ed 100644 --- a/dom/security/ReferrerInfo.cpp +++ b/dom/security/ReferrerInfo.cpp @@ -1151,8 +1151,10 @@ static ReferrerPolicy ReferrerPolicyFromAttribute(const Element& aElement) { } static bool HasRelNoReferrer(const Element& aElement) { - // rel=noreferrer is only support in
and - if (!aElement.IsAnyOfHTMLElements(nsGkAtoms::a, nsGkAtoms::area)) { + // rel=noreferrer is only supported in , , and
+ if (!aElement.IsAnyOfHTMLElements(nsGkAtoms::a, nsGkAtoms::area, + nsGkAtoms::form) && + !aElement.IsSVGElement(nsGkAtoms::a)) { return false; } diff --git a/dom/svg/SVGAElement.cpp b/dom/svg/SVGAElement.cpp index a63c036de065..9e99e125b8a3 100644 --- a/dom/svg/SVGAElement.cpp +++ b/dom/svg/SVGAElement.cpp @@ -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 diff --git a/dom/svg/SVGAElement.h b/dom/svg/SVGAElement.h index 21811ddd40bf..08f02ae07f4e 100644 --- a/dom/svg/SVGAElement.h +++ b/dom/svg/SVGAElement.h @@ -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 mRelList; - static DOMTokenListSupportedToken sSupportedRelValues[]; }; } // namespace dom diff --git a/dom/webidl/HTMLFormElement.webidl b/dom/webidl/HTMLFormElement.webidl index 746eb61b7c0c..f45401f3b96a 100644 --- a/dom/webidl/HTMLFormElement.webidl +++ b/dom/webidl/HTMLFormElement.webidl @@ -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; diff --git a/testing/web-platform/meta/html/dom/idlharness.https.html.ini b/testing/web-platform/meta/html/dom/idlharness.https.html.ini index a85489016146..417f4dbf75e4 100644 --- a/testing/web-platform/meta/html/dom/idlharness.https.html.ini +++ b/testing/web-platform/meta/html/dom/idlharness.https.html.ini @@ -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 diff --git a/testing/web-platform/meta/html/semantics/forms/form-submission-target/rel-base-target.html.ini b/testing/web-platform/meta/html/semantics/forms/form-submission-target/rel-base-target.html.ini index c72714d015a8..bfbe728fa47f 100644 --- a/testing/web-platform/meta/html/semantics/forms/form-submission-target/rel-base-target.html.ini +++ b/testing/web-platform/meta/html/semantics/forms/form-submission-target/rel-base-target.html.ini @@ -1,20 +1,3 @@ [rel-base-target.html] expected: if (os == "android") and fission: [TIMEOUT, OK] - [ with ] - expected: FAIL - - [ with ] - expected: FAIL - - [ with ] - expected: FAIL - - [ with ] - expected: FAIL - - [ with ] - expected: FAIL - - [ with ] - expected: FAIL diff --git a/testing/web-platform/meta/html/semantics/forms/form-submission-target/rel-button-target.html.ini b/testing/web-platform/meta/html/semantics/forms/form-submission-target/rel-button-target.html.ini index 25dbbdeae363..69e2b6734d31 100644 --- a/testing/web-platform/meta/html/semantics/forms/form-submission-target/rel-button-target.html.ini +++ b/testing/web-platform/meta/html/semantics/forms/form-submission-target/rel-button-target.html.ini @@ -1,20 +1,3 @@ [rel-button-target.html] expected: if (os == "android") and fission: [OK, TIMEOUT] - [ with