summaryrefslogtreecommitdiff
path: root/dom/base/DocumentOrShadowRoot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/DocumentOrShadowRoot.cpp')
-rw-r--r--dom/base/DocumentOrShadowRoot.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/dom/base/DocumentOrShadowRoot.cpp b/dom/base/DocumentOrShadowRoot.cpp
index 8376ab97e4..13ee3cb150 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;
+}
+
}
}