1429656 - Implement ShadowRoot.activeElement.
parent
a3008768e1
commit
08796d3b0f
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "DocumentOrShadowRoot.h"
|
||||
#include "mozilla/dom/StyleSheetList.h"
|
||||
#include "nsDocument.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "ShadowRoot.h"
|
||||
#include "XULDocument.h"
|
||||
|
||||
|
@ -100,5 +102,48 @@ DocumentOrShadowRoot::GetElementsByClassName(const nsAString& aClasses)
|
|||
return nsContentUtils::GetElementsByClassName(&AsNode(), aClasses);
|
||||
}
|
||||
|
||||
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,
|
||||
false,
|
||||
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) {
|
||||
if (!nsDocument::IsWebComponentsEnabled(focusedContent)) {
|
||||
return focusedContent->AsElement();
|
||||
}
|
||||
|
||||
if (nsIContent* retarget = Retarget(focusedContent)) {
|
||||
return retarget->AsElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,6 +116,15 @@ public:
|
|||
~DocumentOrShadowRoot() = default;
|
||||
|
||||
protected:
|
||||
nsIContent* Retarget(nsIContent* aContent) const;
|
||||
|
||||
/**
|
||||
* If focused element's subtree root is this document or shadow root, return
|
||||
* focused element, otherwise, get the shadow host recursively until the
|
||||
* shadow host's subtree root is this document or shadow root.
|
||||
*/
|
||||
Element* GetRetargetedFocusedElement();
|
||||
|
||||
nsTArray<RefPtr<mozilla::StyleSheet>> mStyleSheets;
|
||||
RefPtr<mozilla::dom::StyleSheetList> mDOMStyleSheets;
|
||||
|
||||
|
|
|
@ -1138,6 +1138,15 @@ FragmentOrElement::GetAssignedSlot() const
|
|||
return slots ? slots->mAssignedSlot.get() : nullptr;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsIContent::GetContainingShadowHost() const
|
||||
{
|
||||
if (mozilla::dom::ShadowRoot* shadow = GetContainingShadow()) {
|
||||
return shadow->GetHost();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
FragmentOrElement::SetAssignedSlot(HTMLSlotElement* aSlot)
|
||||
{
|
||||
|
|
|
@ -461,6 +461,12 @@ ShadowRoot::DistributeAllNodes()
|
|||
DistributionChanged();
|
||||
}
|
||||
|
||||
Element*
|
||||
ShadowRoot::GetActiveElement()
|
||||
{
|
||||
return GetRetargetedFocusedElement();
|
||||
}
|
||||
|
||||
void
|
||||
ShadowRoot::GetInnerHTML(nsAString& aInnerHTML)
|
||||
{
|
||||
|
|
|
@ -120,6 +120,8 @@ public:
|
|||
|
||||
// WebIDL methods.
|
||||
using mozilla::dom::DocumentOrShadowRoot::GetElementById;
|
||||
|
||||
Element* GetActiveElement();
|
||||
void GetInnerHTML(nsAString& aInnerHTML);
|
||||
void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError);
|
||||
void StyleSheetChanged();
|
||||
|
|
|
@ -3031,20 +3031,9 @@ Element*
|
|||
nsIDocument::GetActiveElement()
|
||||
{
|
||||
// Get the focused element.
|
||||
if (nsCOMPtr<nsPIDOMWindowOuter> window = GetWindow()) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
|
||||
nsIContent* focusedContent =
|
||||
nsFocusManager::GetFocusedDescendant(window, false,
|
||||
getter_AddRefs(focusedWindow));
|
||||
// be safe and make sure the element is from this document
|
||||
if (focusedContent && focusedContent->OwnerDoc() == this) {
|
||||
if (focusedContent->ChromeOnlyAccess()) {
|
||||
focusedContent = focusedContent->FindFirstNonChromeOnlyAccessContent();
|
||||
}
|
||||
if (focusedContent) {
|
||||
return focusedContent->AsElement();
|
||||
}
|
||||
}
|
||||
Element* focusedElement = GetRetargetedFocusedElement();
|
||||
if (focusedElement) {
|
||||
return focusedElement;
|
||||
}
|
||||
|
||||
// No focused element anywhere in this document. Try to get the BODY.
|
||||
|
|
|
@ -813,10 +813,11 @@ nsFocusManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent)
|
|||
if (!window)
|
||||
return NS_OK;
|
||||
|
||||
// if the content is currently focused in the window, or is an ancestor
|
||||
// of the currently focused element, reset the focus within that window.
|
||||
// if the content is currently focused in the window, or is an
|
||||
// shadow-including inclusive ancestor of the currently focused element,
|
||||
// reset the focus within that window.
|
||||
nsIContent* content = window->GetFocusedNode();
|
||||
if (content && nsContentUtils::ContentIsDescendantOf(content, aContent)) {
|
||||
if (content && nsContentUtils::ContentIsHostIncludingDescendantOf(content, aContent)) {
|
||||
bool shouldShowFocusRing = window->ShouldShowFocusRing();
|
||||
window->SetFocusedNode(nullptr);
|
||||
|
||||
|
|
|
@ -696,6 +696,14 @@ public:
|
|||
*/
|
||||
virtual mozilla::dom::ShadowRoot *GetContainingShadow() const = 0;
|
||||
|
||||
/**
|
||||
* Gets the shadow host if this content is in a shadow tree. That is, the host
|
||||
* of |GetContainingShadow|, if its not null.
|
||||
*
|
||||
* @return The shadow host, if this is in shadow tree, or null.
|
||||
*/
|
||||
nsIContent* GetContainingShadowHost() const;
|
||||
|
||||
/**
|
||||
* Gets the assigned slot associated with this content.
|
||||
*
|
||||
|
|
|
@ -20,6 +20,8 @@ enum ShadowRootMode {
|
|||
[Func="nsDocument::IsWebComponentsEnabled"]
|
||||
interface ShadowRoot : DocumentFragment
|
||||
{
|
||||
readonly attribute Element? activeElement;
|
||||
|
||||
// Shadow DOM v1
|
||||
readonly attribute ShadowRootMode mode;
|
||||
readonly attribute Element host;
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
[ShadowRoot-interface.html]
|
||||
type: testharness
|
||||
[ShadowRoot.activeElement must return the focused element of the context object when shadow root is open.]
|
||||
expected: FAIL
|
||||
|
||||
[ShadowRoot.activeElement must return the focused element of the context object when shadow root is closed.]
|
||||
expected: FAIL
|
||||
|
||||
[ShadowRoot.host must return the shadow host of the context object.]
|
||||
expected: FAIL
|
||||
|
||||
[ShadowRoot.innerHTML must return the result of the HTML fragment serialization algorithm when shadow root is open.]
|
||||
expected: FAIL
|
||||
|
||||
[ShadowRoot.innerHTML must return the result of the HTML fragment serialization algorithm when shadow root is closed.]
|
||||
expected: FAIL
|
||||
|
||||
[ShadowRoot.innerHTML must replace all with the result of invoking the fragment parsing algorithm when shadow root is open.]
|
||||
expected: FAIL
|
||||
|
||||
[ShadowRoot.innerHTML must replace all with the result of invoking the fragment parsing algorithm when shadow root is closed.]
|
||||
expected: FAIL
|
||||
|
||||
[ShadowRoot.styleSheets must return a StyleSheetList sequence containing the shadow root style sheets when shadow root is open.]
|
||||
expected: FAIL
|
||||
|
||||
[ShadowRoot.styleSheets must return a StyleSheetList sequence containing the shadow root style sheets when shadow root is closed.]
|
||||
expected: FAIL
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
[activeElement-confirm-return-null.html]
|
||||
type: testharness
|
||||
[confirm activeElement return null]
|
||||
expected: FAIL
|
||||
|
||||
[confirm activeElement return null when there is other element in body]
|
||||
expected: FAIL
|
||||
|
||||
[confirm activeElement return null when focus on the element in the outer shadow tree]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[test-007.html]
|
||||
type: testharness
|
||||
[A_10_01_01_03_01_T01]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[test-001.html]
|
||||
type: testharness
|
||||
[A_07_03_01_T01]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[test-002.html]
|
||||
type: testharness
|
||||
[A_07_03_02_T01]
|
||||
expected: FAIL
|
||||
|
Loading…
Reference in New Issue