2017-12-21 04:09:22 +03:00
|
|
|
/* -*- 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/. */
|
|
|
|
|
2017-12-21 01:29:21 +03:00
|
|
|
#include "DocumentOrShadowRoot.h"
|
2018-02-03 23:08:30 +03:00
|
|
|
#include "mozilla/EventStateManager.h"
|
2017-12-21 04:09:22 +03:00
|
|
|
#include "mozilla/dom/StyleSheetList.h"
|
2018-01-15 09:42:47 +03:00
|
|
|
#include "nsDocument.h"
|
|
|
|
#include "nsFocusManager.h"
|
2017-12-21 04:09:22 +03:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
|
2017-12-21 01:29:21 +03:00
|
|
|
DocumentOrShadowRoot::DocumentOrShadowRoot(mozilla::dom::ShadowRoot& aShadowRoot)
|
2017-12-20 08:44:24 +03:00
|
|
|
: mAsNode(aShadowRoot)
|
|
|
|
, mKind(Kind::ShadowRoot)
|
|
|
|
{}
|
|
|
|
|
2017-12-21 01:29:21 +03:00
|
|
|
DocumentOrShadowRoot::DocumentOrShadowRoot(nsIDocument& aDoc)
|
2017-12-20 08:44:24 +03:00
|
|
|
: mAsNode(aDoc)
|
|
|
|
, mKind(Kind::Document)
|
|
|
|
{}
|
|
|
|
|
2017-12-21 04:09:22 +03:00
|
|
|
StyleSheetList&
|
2017-12-21 01:29:21 +03:00
|
|
|
DocumentOrShadowRoot::EnsureDOMStyleSheets()
|
2017-12-21 04:09:22 +03:00
|
|
|
{
|
|
|
|
if (!mDOMStyleSheets) {
|
|
|
|
mDOMStyleSheets = new StyleSheetList(*this);
|
|
|
|
}
|
|
|
|
return *mDOMStyleSheets;
|
|
|
|
}
|
|
|
|
|
2017-12-20 08:46:01 +03:00
|
|
|
Element*
|
2017-12-21 01:29:21 +03:00
|
|
|
DocumentOrShadowRoot::GetElementById(const nsAString& aElementId)
|
2017-12-20 08:46:01 +03:00
|
|
|
{
|
|
|
|
if (MOZ_UNLIKELY(aElementId.IsEmpty())) {
|
|
|
|
nsContentUtils::ReportEmptyGetElementByIdArg(AsNode().OwnerDoc());
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nsIdentifierMapEntry* entry = mIdentifierMap.GetEntry(aElementId)) {
|
|
|
|
if (Element* el = entry->GetIdElement()) {
|
|
|
|
return el;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<nsContentList>
|
2017-12-21 01:29:21 +03:00
|
|
|
DocumentOrShadowRoot::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
|
2017-12-20 08:46:01 +03:00
|
|
|
const nsAString& aLocalName)
|
|
|
|
{
|
|
|
|
ErrorResult rv;
|
|
|
|
RefPtr<nsContentList> list =
|
|
|
|
GetElementsByTagNameNS(aNamespaceURI, aLocalName, rv);
|
|
|
|
if (rv.Failed()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return list.forget();
|
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<nsContentList>
|
2017-12-21 01:29:21 +03:00
|
|
|
DocumentOrShadowRoot::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
|
2017-12-20 08:46:01 +03:00
|
|
|
const nsAString& aLocalName,
|
|
|
|
mozilla::ErrorResult& aResult)
|
|
|
|
{
|
|
|
|
int32_t nameSpaceId = kNameSpaceID_Wildcard;
|
|
|
|
|
|
|
|
if (!aNamespaceURI.EqualsLiteral("*")) {
|
|
|
|
aResult =
|
|
|
|
nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
|
|
|
|
nameSpaceId);
|
|
|
|
if (aResult.Failed()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_ASSERTION(nameSpaceId != kNameSpaceID_Unknown, "Unexpected namespace ID!");
|
|
|
|
return NS_GetContentList(&AsNode(), nameSpaceId, aLocalName);
|
|
|
|
}
|
|
|
|
|
|
|
|
already_AddRefed<nsContentList>
|
2017-12-21 01:29:21 +03:00
|
|
|
DocumentOrShadowRoot::GetElementsByClassName(const nsAString& aClasses)
|
2017-12-20 08:46:01 +03:00
|
|
|
{
|
|
|
|
return nsContentUtils::GetElementsByClassName(&AsNode(), aClasses);
|
|
|
|
}
|
|
|
|
|
2018-01-15 09:42:47 +03:00
|
|
|
nsIContent*
|
|
|
|
DocumentOrShadowRoot::Retarget(nsIContent* aContent) const
|
|
|
|
{
|
|
|
|
for (nsIContent* cur = aContent;
|
|
|
|
cur;
|
|
|
|
cur = cur->GetContainingShadowHost()) {
|
|
|
|
if (cur->SubtreeRoot() == &AsNode()) {
|
|
|
|
return cur;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
Element*
|
|
|
|
DocumentOrShadowRoot::GetRetargetedFocusedElement()
|
|
|
|
{
|
|
|
|
if (nsCOMPtr<nsPIDOMWindowOuter> window = AsNode().OwnerDoc()->GetWindow()) {
|
|
|
|
nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
|
|
|
|
nsIContent* focusedContent =
|
|
|
|
nsFocusManager::GetFocusedDescendant(window,
|
|
|
|
nsFocusManager::eOnlyCurrentWindow,
|
|
|
|
getter_AddRefs(focusedWindow));
|
|
|
|
// be safe and make sure the element is from this document
|
|
|
|
if (focusedContent && focusedContent->OwnerDoc() == AsNode().OwnerDoc()) {
|
|
|
|
if (focusedContent->ChromeOnlyAccess()) {
|
|
|
|
focusedContent = focusedContent->FindFirstNonChromeOnlyAccessContent();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (focusedContent) {
|
2018-01-16 12:42:00 +03:00
|
|
|
if (!nsDocument::IsShadowDOMEnabled(focusedContent)) {
|
2018-01-15 09:42:47 +03:00
|
|
|
return focusedContent->AsElement();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nsIContent* retarget = Retarget(focusedContent)) {
|
|
|
|
return retarget->AsElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2018-02-03 23:08:30 +03:00
|
|
|
Element*
|
|
|
|
DocumentOrShadowRoot::GetPointerLockElement()
|
|
|
|
{
|
|
|
|
nsCOMPtr<Element> pointerLockedElement =
|
|
|
|
do_QueryReferent(EventStateManager::sPointerLockedElement);
|
|
|
|
if (!pointerLockedElement) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIContent* retargetedPointerLockedElement = Retarget(pointerLockedElement);
|
|
|
|
return
|
|
|
|
retargetedPointerLockedElement && retargetedPointerLockedElement->IsElement() ?
|
|
|
|
retargetedPointerLockedElement->AsElement() : nullptr;
|
|
|
|
}
|
|
|
|
|
2018-02-13 19:57:32 +03:00
|
|
|
Element*
|
|
|
|
DocumentOrShadowRoot::GetFullscreenElement()
|
|
|
|
{
|
|
|
|
if (!AsNode().IsInComposedDoc()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
Element* element = AsNode().OwnerDoc()->FullScreenStackTop();
|
|
|
|
NS_ASSERTION(!element ||
|
|
|
|
element->State().HasState(NS_EVENT_STATE_FULL_SCREEN),
|
|
|
|
"Fullscreen element should have fullscreen styles applied");
|
|
|
|
|
|
|
|
nsIContent* retargeted = Retarget(element);
|
|
|
|
if (retargeted && retargeted->IsElement()) {
|
|
|
|
return retargeted->AsElement();
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2017-12-21 04:09:22 +03:00
|
|
|
}
|
|
|
|
}
|