summaryrefslogtreecommitdiffstats
path: root/dom/html
diff options
context:
space:
mode:
authorjanekptacijarabaci <janekptacijarabaci@seznam.cz>2018-03-30 09:44:21 +0200
committerjanekptacijarabaci <janekptacijarabaci@seznam.cz>2018-03-30 09:44:21 +0200
commita1a007a4856fa50d6d811c2268f881e3666f4c67 (patch)
tree24b082c1bfb5777f1770c82a534bf765160bc1b8 /dom/html
parenteddd0de2ae80e176011f41a5400e81522d53f4f3 (diff)
parent59bf4204a84f7638d3f89a29bc7c04e5dc401369 (diff)
downloadUXP-a1a007a4856fa50d6d811c2268f881e3666f4c67.tar
UXP-a1a007a4856fa50d6d811c2268f881e3666f4c67.tar.gz
UXP-a1a007a4856fa50d6d811c2268f881e3666f4c67.tar.lz
UXP-a1a007a4856fa50d6d811c2268f881e3666f4c67.tar.xz
UXP-a1a007a4856fa50d6d811c2268f881e3666f4c67.zip
Merge branch 'master' of https://github.com/MoonchildProductions/UXP into html_input_datetime_1
Diffstat (limited to 'dom/html')
-rw-r--r--dom/html/HTMLAllCollection.cpp7
-rw-r--r--dom/html/HTMLDataListElement.cpp6
-rw-r--r--dom/html/HTMLDataListElement.h4
-rw-r--r--dom/html/HTMLFieldSetElement.cpp4
-rw-r--r--dom/html/HTMLFieldSetElement.h4
-rw-r--r--dom/html/HTMLInputElement.cpp10
-rw-r--r--dom/html/HTMLInputElement.h2
-rw-r--r--dom/html/HTMLLabelElement.cpp23
-rw-r--r--dom/html/HTMLMediaElement.cpp43
-rw-r--r--dom/html/HTMLMediaElement.h10
-rw-r--r--dom/html/HTMLSelectElement.cpp4
-rw-r--r--dom/html/HTMLSelectElement.h2
-rw-r--r--dom/html/HTMLTableRowElement.cpp4
-rw-r--r--dom/html/nsGenericHTMLElement.cpp40
-rw-r--r--dom/html/nsGenericHTMLElement.h6
-rw-r--r--dom/html/nsHTMLDocument.cpp48
-rw-r--r--dom/html/nsHTMLDocument.h11
-rw-r--r--dom/html/test/forms/test_button_attributes_reflection.html9
18 files changed, 184 insertions, 53 deletions
diff --git a/dom/html/HTMLAllCollection.cpp b/dom/html/HTMLAllCollection.cpp
index afa160e0c..6305cce31 100644
--- a/dom/html/HTMLAllCollection.cpp
+++ b/dom/html/HTMLAllCollection.cpp
@@ -8,6 +8,7 @@
#include "mozilla/dom/HTMLAllCollectionBinding.h"
#include "mozilla/dom/Nullable.h"
+#include "mozilla/dom/Element.h"
#include "nsHTMLDocument.h"
namespace mozilla {
@@ -86,14 +87,14 @@ IsAllNamedElement(nsIContent* aContent)
}
static bool
-DocAllResultMatch(nsIContent* aContent, int32_t aNamespaceID, nsIAtom* aAtom,
+DocAllResultMatch(Element* aElement, int32_t aNamespaceID, nsIAtom* aAtom,
void* aData)
{
- if (aContent->GetID() == aAtom) {
+ if (aElement->GetID() == aAtom) {
return true;
}
- nsGenericHTMLElement* elm = nsGenericHTMLElement::FromContent(aContent);
+ nsGenericHTMLElement* elm = nsGenericHTMLElement::FromContent(aElement);
if (!elm) {
return false;
}
diff --git a/dom/html/HTMLDataListElement.cpp b/dom/html/HTMLDataListElement.cpp
index d9ad4da09..5aa772645 100644
--- a/dom/html/HTMLDataListElement.cpp
+++ b/dom/html/HTMLDataListElement.cpp
@@ -35,11 +35,11 @@ NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
NS_IMPL_ELEMENT_CLONE(HTMLDataListElement)
bool
-HTMLDataListElement::MatchOptions(nsIContent* aContent, int32_t aNamespaceID,
+HTMLDataListElement::MatchOptions(Element* aElement, int32_t aNamespaceID,
nsIAtom* aAtom, void* aData)
{
- return aContent->NodeInfo()->Equals(nsGkAtoms::option, kNameSpaceID_XHTML) &&
- !aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
+ return aElement->NodeInfo()->Equals(nsGkAtoms::option, kNameSpaceID_XHTML) &&
+ !aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
}
} // namespace dom
diff --git a/dom/html/HTMLDataListElement.h b/dom/html/HTMLDataListElement.h
index e0aff818b..ba2a2e0b4 100644
--- a/dom/html/HTMLDataListElement.h
+++ b/dom/html/HTMLDataListElement.h
@@ -37,8 +37,8 @@ public:
virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
// This function is used to generate the nsContentList (option elements).
- static bool MatchOptions(nsIContent* aContent, int32_t aNamespaceID,
- nsIAtom* aAtom, void* aData);
+ static bool MatchOptions(Element* aElement, int32_t aNamespaceID,
+ nsIAtom* aAtom, void* aData);
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLDataListElement,
nsGenericHTMLElement)
diff --git a/dom/html/HTMLFieldSetElement.cpp b/dom/html/HTMLFieldSetElement.cpp
index 865d3c9cf..d72fd1061 100644
--- a/dom/html/HTMLFieldSetElement.cpp
+++ b/dom/html/HTMLFieldSetElement.cpp
@@ -120,10 +120,10 @@ HTMLFieldSetElement::GetType(nsAString& aType)
/* static */
bool
-HTMLFieldSetElement::MatchListedElements(nsIContent* aContent, int32_t aNamespaceID,
+HTMLFieldSetElement::MatchListedElements(Element* aElement, int32_t aNamespaceID,
nsIAtom* aAtom, void* aData)
{
- nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aContent);
+ nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aElement);
return formControl;
}
diff --git a/dom/html/HTMLFieldSetElement.h b/dom/html/HTMLFieldSetElement.h
index d169434ae..96fff4582 100644
--- a/dom/html/HTMLFieldSetElement.h
+++ b/dom/html/HTMLFieldSetElement.h
@@ -124,8 +124,8 @@ private:
void NotifyElementsForFirstLegendChange(bool aNotify);
// This function is used to generate the nsContentList (listed form elements).
- static bool MatchListedElements(nsIContent* aContent, int32_t aNamespaceID,
- nsIAtom* aAtom, void* aData);
+ static bool MatchListedElements(Element* aElement, int32_t aNamespaceID,
+ nsIAtom* aAtom, void* aData);
// listed form controls elements.
RefPtr<nsContentList> mElements;
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
index dc755cd02..e8a4af454 100644
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -8807,6 +8807,16 @@ HTMLInputElement::GetWebkitEntries(nsTArray<RefPtr<FileSystemEntry>>& aSequence)
aSequence.AppendElements(mEntries);
}
+already_AddRefed<nsINodeList>
+HTMLInputElement::GetLabels()
+{
+ if (!IsLabelable()) {
+ return nullptr;
+ }
+
+ return nsGenericHTMLElement::Labels();
+}
+
} // namespace dom
} // namespace mozilla
diff --git a/dom/html/HTMLInputElement.h b/dom/html/HTMLInputElement.h
index e5d670e08..9ca876aee 100644
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -704,6 +704,8 @@ public:
// XPCOM GetCustomVisibility() is OK
+ already_AddRefed<nsINodeList> GetLabels();
+
// XPCOM Select() is OK
Nullable<int32_t> GetSelectionStart(ErrorResult& aRv);
diff --git a/dom/html/HTMLLabelElement.cpp b/dom/html/HTMLLabelElement.cpp
index c1d22b0a6..d1c037336 100644
--- a/dom/html/HTMLLabelElement.cpp
+++ b/dom/html/HTMLLabelElement.cpp
@@ -14,6 +14,7 @@
#include "nsFocusManager.h"
#include "nsIDOMMouseEvent.h"
#include "nsQueryObject.h"
+#include "mozilla/dom/ShadowRoot.h"
// construction, destruction
@@ -268,17 +269,23 @@ HTMLLabelElement::GetLabeledElement() const
return GetFirstLabelableDescendant();
}
- // We have a @for. The id has to be linked to an element in the same document
+ // We have a @for. The id has to be linked to an element in the same tree
// and this element should be a labelable form control.
- //XXXsmaug It is unclear how this should work in case the element is in
- // Shadow DOM.
- // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=26365.
- nsIDocument* doc = GetUncomposedDoc();
- if (!doc) {
- return nullptr;
+ nsINode* root = SubtreeRoot();
+ ShadowRoot* shadow = ShadowRoot::FromNode(root);
+ Element* element = nullptr;
+
+ if (shadow) {
+ element = shadow->GetElementById(elementId);
+ } else {
+ nsIDocument* doc = GetUncomposedDoc();
+ if (doc) {
+ element = doc->GetElementById(elementId);
+ } else {
+ element = nsContentUtils::MatchElementId(root->AsContent(), elementId);
+ }
}
- Element* element = doc->GetElementById(elementId);
if (element && element->IsLabelable()) {
return static_cast<nsGenericHTMLElement*>(element);
}
diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp
index e81cd20bc..1f1a545fa 100644
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -11,7 +11,9 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/AsyncEventDispatcher.h"
+#ifdef MOZ_EME
#include "mozilla/dom/MediaEncryptedEvent.h"
+#endif
#include "base/basictypes.h"
#include "nsIDOMHTMLMediaElement.h"
@@ -820,7 +822,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTM
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTextTrackManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioTrackList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVideoTrackList)
+#ifdef MOZ_EME
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaKeys)
+#endif
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelectedVideoStreamTrack)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@@ -845,7 +849,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLE
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTextTrackManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioTrackList)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mVideoTrackList)
+#ifdef MOZ_EME
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMediaKeys)
+#endif
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSelectedVideoStreamTrack)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@@ -1020,12 +1026,14 @@ void HTMLMediaElement::ShutdownDecoder()
void HTMLMediaElement::AbortExistingLoads()
{
+#ifdef MOZ_EME
// If there is no existing decoder then we don't have anything to
// report. This prevents reporting the initial load from an
// empty video element as a failed EME load.
if (mDecoder) {
ReportEMETelemetry();
}
+#endif
// Abort any already-running instance of the resource selection algorithm.
mLoadWaitStatus = NOT_WAITING;
@@ -1084,7 +1092,9 @@ void HTMLMediaElement::AbortExistingLoads()
mDownloadSuspendedByCache = false;
mMediaInfo = MediaInfo();
mIsEncrypted = false;
+#ifdef MOZ_EME
mPendingEncryptedInitData.mInitDatas.Clear();
+#endif
mWaitingForKey = NOT_WAITING_FOR_KEY;
mSourcePointer = nullptr;
@@ -2681,9 +2691,11 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded,
if (!window) {
return nullptr;
}
+#ifdef MOZ_EME
if (ContainsRestrictedContent()) {
return nullptr;
}
+#endif
if (!mOutputStreams.IsEmpty() &&
aGraph != mOutputStreams[0].mStream->GetInputStream()->Graph()) {
@@ -3638,6 +3650,7 @@ void HTMLMediaElement::HiddenVideoStop()
mVideoDecodeSuspendTimer = nullptr;
}
+#ifdef MOZ_EME
void
HTMLMediaElement::ReportEMETelemetry()
{
@@ -3649,6 +3662,7 @@ HTMLMediaElement::ReportEMETelemetry()
this, mLoadedDataFired ? "true" : "false"));
}
}
+#endif
void
HTMLMediaElement::ReportTelemetry()
@@ -3997,6 +4011,7 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
ms.mFinishWhenEnded);
}
+#ifdef MOZ_EME
if (mMediaKeys) {
if (mMediaKeys->GetCDMProxy()) {
mDecoder->SetCDMProxy(mMediaKeys->GetCDMProxy());
@@ -4006,6 +4021,7 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
return NS_ERROR_FAILURE;
}
}
+#endif
MediaEventSource<void>* waitingForKeyProducer = mDecoder->WaitingForKeyEvent();
// Not every decoder will produce waitingForKey events, only add ones that can
@@ -4468,7 +4484,11 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
SetMediaInfo(*aInfo);
- mIsEncrypted = aInfo->IsEncrypted() || mPendingEncryptedInitData.IsEncrypted();
+ mIsEncrypted = aInfo->IsEncrypted()
+#ifdef MOZ_EME
+ || mPendingEncryptedInitData.IsEncrypted()
+#endif
+ ;
mTags = aTags.forget();
mLoadedDataFired = false;
ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
@@ -4494,11 +4514,13 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
return;
}
+#ifdef MOZ_EME
// Dispatch a distinct 'encrypted' event for each initData we have.
for (const auto& initData : mPendingEncryptedInitData.mInitDatas) {
DispatchEncrypted(initData.mInitData, initData.mType);
}
mPendingEncryptedInitData.mInitDatas.Clear();
+#endif
}
mWatchManager.ManualNotify(&HTMLMediaElement::UpdateReadyStateInternal);
@@ -5431,9 +5453,12 @@ void HTMLMediaElement::SuspendOrResumeElement(bool aPauseElement, bool aSuspendE
UpdateAudioChannelPlayingState();
if (aPauseElement) {
ReportTelemetry();
+#ifdef MOZ_EME
ReportEMETelemetry();
+#endif
- // For EME content, force destruction of the CDM client (and CDM
+#ifdef MOZ_EME
+ // For EME content, we may force destruction of the CDM client (and CDM
// instance if this is the last client for that CDM instance) and
// the CDM's decoder. This ensures the CDM gets reliable and prompt
// shutdown notifications, as it may have book-keeping it needs
@@ -5445,6 +5470,7 @@ void HTMLMediaElement::SuspendOrResumeElement(bool aPauseElement, bool aSuspendE
ShutdownDecoder();
}
}
+#endif
if (mDecoder) {
mDecoder->Pause();
mDecoder->Suspend();
@@ -5495,6 +5521,17 @@ void HTMLMediaElement::NotifyOwnerDocumentActivityChanged()
bool pauseElement = ShouldElementBePaused();
SuspendOrResumeElement(pauseElement, !IsActive());
+#ifdef MOZ_EME
+ // If the owning document has become inactive we should shutdown the CDM.
+ if (!OwnerDoc()->IsCurrentActiveDocument() && mMediaKeys) {
+ mMediaKeys->Shutdown();
+ mMediaKeys = nullptr;
+ if (mDecoder) {
+ ShutdownDecoder();
+ }
+ }
+#endif
+
AddRemoveSelfReference();
}
@@ -6270,6 +6307,7 @@ HTMLMediaElement::OnVisibilityChange(Visibility aNewVisibility)
}
+#ifdef MOZ_EME
MediaKeys*
HTMLMediaElement::GetMediaKeys() const
{
@@ -6479,6 +6517,7 @@ HTMLMediaElement::GetTopLevelPrincipal()
principal = doc->NodePrincipal();
return principal.forget();
}
+#endif //MOZ_EME
void
HTMLMediaElement::CannotDecryptWaitingForKey()
diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h
index d40e9df46..b65049206 100644
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -20,7 +20,9 @@
#include "mozilla/dom/TextTrackManager.h"
#include "mozilla/WeakPtr.h"
#include "MediaDecoder.h"
+#ifdef MOZ_EME
#include "mozilla/dom/MediaKeys.h"
+#endif
#include "mozilla/StateWatching.h"
#include "nsGkAtoms.h"
#include "PrincipalChangeObserver.h"
@@ -630,6 +632,7 @@ public:
// XPCOM MozPreservesPitch() is OK
+#ifdef MOZ_EME
MediaKeys* GetMediaKeys() const;
already_AddRefed<Promise> SetMediaKeys(MediaKeys* mediaKeys,
@@ -651,6 +654,7 @@ public:
already_AddRefed<nsIPrincipal> GetTopLevelPrincipal();
bool ContainsRestrictedContent();
+#endif // MOZ_EME
void CannotDecryptWaitingForKey();
@@ -1198,7 +1202,9 @@ protected:
*/
void HiddenVideoStop();
+#ifdef MOZ_EME
void ReportEMETelemetry();
+#endif
void ReportTelemetry();
@@ -1471,8 +1477,10 @@ protected:
// Timer used to simulate video-suspend.
nsCOMPtr<nsITimer> mVideoDecodeSuspendTimer;
+#ifdef MOZ_EME
// Encrypted Media Extension media keys.
RefPtr<MediaKeys> mMediaKeys;
+#endif
// Stores the time at the start of the current 'played' range.
double mCurrentPlayRangeStart;
@@ -1627,8 +1635,10 @@ protected:
// Listens for waitingForKey events from the owned decoder.
MediaEventListener mWaitingForKeyListener;
+#ifdef MOZ_EME
// Init Data that needs to be sent in 'encrypted' events in MetadataLoaded().
EncryptionInfo mPendingEncryptedInitData;
+#endif
// True if the media's channel's download has been suspended.
Watchable<bool> mDownloadSuspendedByCache;
diff --git a/dom/html/HTMLSelectElement.cpp b/dom/html/HTMLSelectElement.cpp
index 24ddabb65..53f42317a 100644
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -735,12 +735,12 @@ HTMLSelectElement::SetLength(uint32_t aLength, ErrorResult& aRv)
/* static */
bool
-HTMLSelectElement::MatchSelectedOptions(nsIContent* aContent,
+HTMLSelectElement::MatchSelectedOptions(Element* aElement,
int32_t /* unused */,
nsIAtom* /* unused */,
void* /* unused*/)
{
- HTMLOptionElement* option = HTMLOptionElement::FromContent(aContent);
+ HTMLOptionElement* option = HTMLOptionElement::FromContent(aElement);
return option && option->Selected();
}
diff --git a/dom/html/HTMLSelectElement.h b/dom/html/HTMLSelectElement.h
index d7e4350b4..8a25385de 100644
--- a/dom/html/HTMLSelectElement.h
+++ b/dom/html/HTMLSelectElement.h
@@ -247,7 +247,7 @@ public:
mOptions->IndexedSetter(aIndex, aOption, aRv);
}
- static bool MatchSelectedOptions(nsIContent* aContent, int32_t, nsIAtom*,
+ static bool MatchSelectedOptions(Element* aElement, int32_t, nsIAtom*,
void*);
nsIHTMLCollection* SelectedOptions();
diff --git a/dom/html/HTMLTableRowElement.cpp b/dom/html/HTMLTableRowElement.cpp
index 2dec9c883..ac2463400 100644
--- a/dom/html/HTMLTableRowElement.cpp
+++ b/dom/html/HTMLTableRowElement.cpp
@@ -120,10 +120,10 @@ HTMLTableRowElement::SectionRowIndex() const
}
static bool
-IsCell(nsIContent *aContent, int32_t aNamespaceID,
+IsCell(Element *aElement, int32_t aNamespaceID,
nsIAtom* aAtom, void *aData)
{
- return aContent->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th);
+ return aElement->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th);
}
nsIHTMLCollection*
diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp
index d75001a83..2f890325a 100644
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -108,6 +108,7 @@
#include "mozilla/StyleSetHandle.h"
#include "mozilla/StyleSetHandleInlines.h"
#include "ReferrerPolicy.h"
+#include "mozilla/dom/HTMLLabelElement.h"
using namespace mozilla;
using namespace mozilla::dom;
@@ -493,6 +494,14 @@ nsGenericHTMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
}
}
+ // We need to consider a labels element is moved to another subtree
+ // with different root, it needs to update labels list and its root
+ // as well.
+ nsDOMSlots* slots = GetExistingDOMSlots();
+ if (slots && slots->mLabelsList) {
+ slots->mLabelsList->MaybeResetRoot(SubtreeRoot());
+ }
+
return rv;
}
@@ -513,6 +522,13 @@ nsGenericHTMLElement::UnbindFromTree(bool aDeep, bool aNullParent)
}
}
+ // We need to consider a labels element is removed from tree,
+ // it needs to update labels list and its root as well.
+ nsDOMSlots* slots = GetExistingDOMSlots();
+ if (slots && slots->mLabelsList) {
+ slots->mLabelsList->MaybeResetRoot(SubtreeRoot());
+ }
+
nsStyledElement::UnbindFromTree(aDeep, aNullParent);
}
@@ -1701,6 +1717,30 @@ nsGenericHTMLElement::IsLabelable() const
return IsAnyOfHTMLElements(nsGkAtoms::progress, nsGkAtoms::meter);
}
+/* static */ bool
+nsGenericHTMLElement::MatchLabelsElement(Element* aElement, int32_t aNamespaceID,
+ nsIAtom* aAtom, void* aData)
+{
+ HTMLLabelElement* element = HTMLLabelElement::FromContent(aElement);
+ return element && element->GetControl() == aData;
+}
+
+already_AddRefed<nsINodeList>
+nsGenericHTMLElement::Labels()
+{
+ MOZ_ASSERT(IsLabelable(),
+ "Labels() only allow labelable elements to use it.");
+ nsDOMSlots* slots = DOMSlots();
+
+ if (!slots->mLabelsList) {
+ slots->mLabelsList = new nsLabelsNodeList(SubtreeRoot(), MatchLabelsElement,
+ nullptr, this);
+ }
+
+ RefPtr<nsLabelsNodeList> labels = slots->mLabelsList;
+ return labels.forget();
+}
+
bool
nsGenericHTMLElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const
{
diff --git a/dom/html/nsGenericHTMLElement.h b/dom/html/nsGenericHTMLElement.h
index 3cca41c3d..0635c27e1 100644
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -834,6 +834,12 @@ public:
}
virtual bool IsLabelable() const override;
+
+ static bool MatchLabelsElement(Element* aElement, int32_t aNamespaceID,
+ nsIAtom* aAtom, void* aData);
+
+ already_AddRefed<nsINodeList> Labels();
+
virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
static bool TouchEventsEnabled(JSContext* /* unused */, JSObject* /* unused */);
diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp
index 7d66aab04..be5a34d41 100644
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -1100,31 +1100,31 @@ nsHTMLDocument::Applets()
}
bool
-nsHTMLDocument::MatchLinks(nsIContent *aContent, int32_t aNamespaceID,
+nsHTMLDocument::MatchLinks(Element* aElement, int32_t aNamespaceID,
nsIAtom* aAtom, void* aData)
{
- nsIDocument* doc = aContent->GetUncomposedDoc();
+ nsIDocument* doc = aElement->GetUncomposedDoc();
if (doc) {
- NS_ASSERTION(aContent->IsInUncomposedDoc(),
+ NS_ASSERTION(aElement->IsInUncomposedDoc(),
"This method should never be called on content nodes that "
"are not in a document!");
#ifdef DEBUG
{
nsCOMPtr<nsIHTMLDocument> htmldoc =
- do_QueryInterface(aContent->GetUncomposedDoc());
+ do_QueryInterface(aElement->GetUncomposedDoc());
NS_ASSERTION(htmldoc,
"Huh, how did this happen? This should only be used with "
"HTML documents!");
}
#endif
- mozilla::dom::NodeInfo *ni = aContent->NodeInfo();
+ mozilla::dom::NodeInfo *ni = aElement->NodeInfo();
nsIAtom *localName = ni->NameAtom();
if (ni->NamespaceID() == kNameSpaceID_XHTML &&
(localName == nsGkAtoms::a || localName == nsGkAtoms::area)) {
- return aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::href);
+ return aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::href);
}
}
@@ -1148,24 +1148,24 @@ nsHTMLDocument::Links()
}
bool
-nsHTMLDocument::MatchAnchors(nsIContent *aContent, int32_t aNamespaceID,
+nsHTMLDocument::MatchAnchors(Element* aElement, int32_t aNamespaceID,
nsIAtom* aAtom, void* aData)
{
- NS_ASSERTION(aContent->IsInUncomposedDoc(),
+ NS_ASSERTION(aElement->IsInUncomposedDoc(),
"This method should never be called on content nodes that "
"are not in a document!");
#ifdef DEBUG
{
nsCOMPtr<nsIHTMLDocument> htmldoc =
- do_QueryInterface(aContent->GetUncomposedDoc());
+ do_QueryInterface(aElement->GetUncomposedDoc());
NS_ASSERTION(htmldoc,
"Huh, how did this happen? This should only be used with "
"HTML documents!");
}
#endif
- if (aContent->NodeInfo()->Equals(nsGkAtoms::a, kNameSpaceID_XHTML)) {
- return aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::name);
+ if (aElement->IsHTMLElement(nsGkAtoms::a)) {
+ return aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::name);
}
return false;
@@ -1536,6 +1536,18 @@ nsHTMLDocument::Open(JSContext* cx,
nsCOMPtr<nsIDocument> ret = this;
return ret.forget();
}
+
+ // Now double-check that our invariants still hold.
+ if (!mScriptGlobalObject) {
+ nsCOMPtr<nsIDocument> ret = this;
+ return ret.forget();
+ }
+
+ nsPIDOMWindowOuter* outer = GetWindow();
+ if (!outer || (GetInnerWindow() != outer->GetCurrentInnerWindow())) {
+ nsCOMPtr<nsIDocument> ret = this;
+ return ret.forget();
+ }
}
nsCOMPtr<nsIWebNavigation> webnav(do_QueryInterface(shell));
@@ -1952,14 +1964,14 @@ nsHTMLDocument::Writeln(JSContext* cx, const Sequence<nsString>& aText,
}
bool
-nsHTMLDocument::MatchNameAttribute(nsIContent* aContent, int32_t aNamespaceID,
+nsHTMLDocument::MatchNameAttribute(Element* aElement, int32_t aNamespaceID,
nsIAtom* aAtom, void* aData)
{
- NS_PRECONDITION(aContent, "Must have content node to work with!");
+ NS_PRECONDITION(aElement, "Must have element to work with!");
nsString* elementName = static_cast<nsString*>(aData);
return
- aContent->GetNameSpaceID() == kNameSpaceID_XHTML &&
- aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
+ aElement->GetNameSpaceID() == kNameSpaceID_XHTML &&
+ aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
*elementName, eCaseMatters);
}
@@ -2279,10 +2291,10 @@ nsHTMLDocument::GetForms()
return mForms;
}
-static bool MatchFormControls(nsIContent* aContent, int32_t aNamespaceID,
- nsIAtom* aAtom, void* aData)
+static bool MatchFormControls(Element* aElement, int32_t aNamespaceID,
+ nsIAtom* aAtom, void* aData)
{
- return aContent->IsNodeOfType(nsIContent::eHTML_FORM_CONTROL);
+ return aElement->IsNodeOfType(nsIContent::eHTML_FORM_CONTROL);
}
nsContentList*
diff --git a/dom/html/nsHTMLDocument.h b/dom/html/nsHTMLDocument.h
index 2dbbf2b57..426ebddc5 100644
--- a/dom/html/nsHTMLDocument.h
+++ b/dom/html/nsHTMLDocument.h
@@ -261,12 +261,13 @@ protected:
nsIContent *MatchId(nsIContent *aContent, const nsAString& aId);
- static bool MatchLinks(nsIContent *aContent, int32_t aNamespaceID,
+ static bool MatchLinks(mozilla::dom::Element* aElement, int32_t aNamespaceID,
+ nsIAtom* aAtom, void* aData);
+ static bool MatchAnchors(mozilla::dom::Element* aElement, int32_t aNamespaceID,
nsIAtom* aAtom, void* aData);
- static bool MatchAnchors(nsIContent *aContent, int32_t aNamespaceID,
- nsIAtom* aAtom, void* aData);
- static bool MatchNameAttribute(nsIContent* aContent, int32_t aNamespaceID,
- nsIAtom* aAtom, void* aData);
+ static bool MatchNameAttribute(mozilla::dom::Element* aElement,
+ int32_t aNamespaceID,
+ nsIAtom* aAtom, void* aData);
static void* UseExistingNameString(nsINode* aRootNode, const nsString* aName);
static void DocumentWriteTerminationFunc(nsISupports *aRef);
diff --git a/dom/html/test/forms/test_button_attributes_reflection.html b/dom/html/test/forms/test_button_attributes_reflection.html
index 26858e939..4e702b3ac 100644
--- a/dom/html/test/forms/test_button_attributes_reflection.html
+++ b/dom/html/test/forms/test_button_attributes_reflection.html
@@ -128,9 +128,12 @@ is(typeof(document.createElement("button").setCustomValidity), "function",
"button.setCustomValidity should be a function");
// .labels
-todo("labels" in document.createElement("button"),
- "button.labels isn't implemented yet");
-
+ok("labels" in document.createElement("button"),
+ "button.labels should be an IDL attribute of the button element");
+is(typeof(document.createElement("button").labels), "object",
+ "button.labels should be an object");
+ok(document.createElement("button").labels instanceof NodeList,
+ "button.labels sohuld be an instance of NodeList");
</script>
</pre>
</body>