diff options
Diffstat (limited to 'dom/base/DocumentOrShadowRoot.cpp')
-rw-r--r-- | dom/base/DocumentOrShadowRoot.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/dom/base/DocumentOrShadowRoot.cpp b/dom/base/DocumentOrShadowRoot.cpp index 8376ab97e..13ee3cb15 100644 --- a/dom/base/DocumentOrShadowRoot.cpp +++ b/dom/base/DocumentOrShadowRoot.cpp @@ -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; +} + } } |