fune/dom/base/nsWindowRoot.cpp
Narcis Beleuzu 0186cbe565 Backed out 8 changesets (bug 1620322) for bustages on nsContentSink.cpp . CLOSED TREE
Backed out changeset f41739c64dff (bug 1620322)
Backed out changeset be942a7f329e (bug 1620322)
Backed out changeset a916987c7c71 (bug 1620322)
Backed out changeset ead3484ffb5f (bug 1620322)
Backed out changeset 4e1e8b9afa1a (bug 1620322)
Backed out changeset 473bba698e5a (bug 1620322)
Backed out changeset 0e5e5d41597d (bug 1620322)
Backed out changeset 31b24d79db3d (bug 1620322)

--HG--
rename : toolkit/components/antitracking/ContentBlockingLog.cpp => dom/base/ContentBlockingLog.cpp
rename : toolkit/components/antitracking/ContentBlockingLog.h => dom/base/ContentBlockingLog.h
rename : toolkit/components/antitracking/ContentBlocking.cpp => toolkit/components/antitracking/AntiTrackingCommon.cpp
rename : toolkit/components/antitracking/ContentBlocking.h => toolkit/components/antitracking/AntiTrackingCommon.h
2020-03-09 22:18:36 +02:00

331 lines
11 KiB
C++

/* -*- 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/. */
#include "mozilla/BasicEvents.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventListenerManager.h"
#include "mozilla/dom/WindowRootBinding.h"
#include "nsCOMPtr.h"
#include "nsWindowRoot.h"
#include "nsPIDOMWindow.h"
#include "nsPresContext.h"
#include "nsLayoutCID.h"
#include "nsContentCID.h"
#include "nsString.h"
#include "nsGlobalWindow.h"
#include "nsFocusManager.h"
#include "nsIContent.h"
#include "nsIControllers.h"
#include "nsIController.h"
#include "xpcpublic.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/dom/BrowserParent.h"
#include "mozilla/dom/HTMLTextAreaElement.h"
#include "mozilla/dom/HTMLInputElement.h"
#include "mozilla/dom/JSWindowActorService.h"
#ifdef MOZ_XUL
# include "nsXULElement.h"
#endif
using namespace mozilla;
using namespace mozilla::dom;
nsWindowRoot::nsWindowRoot(nsPIDOMWindowOuter* aWindow) {
mWindow = aWindow;
mShowFocusRings = StaticPrefs::browser_display_show_focus_rings();
}
nsWindowRoot::~nsWindowRoot() {
if (mListenerManager) {
mListenerManager->Disconnect();
}
if (XRE_IsContentProcess()) {
JSWindowActorService::UnregisterChromeEventTarget(this);
}
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsWindowRoot, mWindow, mListenerManager,
mParent)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWindowRoot)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsPIWindowRoot)
NS_INTERFACE_MAP_ENTRY(mozilla::dom::EventTarget)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsWindowRoot)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWindowRoot)
bool nsWindowRoot::DispatchEvent(Event& aEvent, CallerType aCallerType,
ErrorResult& aRv) {
nsEventStatus status = nsEventStatus_eIgnore;
nsresult rv = EventDispatcher::DispatchDOMEvent(
static_cast<EventTarget*>(this), nullptr, &aEvent, nullptr, &status);
bool retval = !aEvent.DefaultPrevented(aCallerType);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
return retval;
}
bool nsWindowRoot::ComputeDefaultWantsUntrusted(ErrorResult& aRv) {
return false;
}
EventListenerManager* nsWindowRoot::GetOrCreateListenerManager() {
if (!mListenerManager) {
mListenerManager =
new EventListenerManager(static_cast<EventTarget*>(this));
}
return mListenerManager;
}
EventListenerManager* nsWindowRoot::GetExistingListenerManager() const {
return mListenerManager;
}
void nsWindowRoot::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
aVisitor.mCanHandle = true;
aVisitor.mForceContentDispatch = true; // FIXME! Bug 329119
// To keep mWindow alive
aVisitor.mItemData = static_cast<nsISupports*>(mWindow);
aVisitor.SetParentTarget(mParent, false);
}
nsresult nsWindowRoot::PostHandleEvent(EventChainPostVisitor& aVisitor) {
return NS_OK;
}
nsPIDOMWindowOuter* nsWindowRoot::GetOwnerGlobalForBindingsInternal() {
return mWindow;
}
nsIGlobalObject* nsWindowRoot::GetOwnerGlobal() const {
nsCOMPtr<nsIGlobalObject> global =
do_QueryInterface(mWindow->GetCurrentInnerWindow());
// We're still holding a ref to it, so returning the raw pointer is ok...
return global;
}
nsPIDOMWindowOuter* nsWindowRoot::GetWindow() { return mWindow; }
nsresult nsWindowRoot::GetControllers(bool aForVisibleWindow,
nsIControllers** aResult) {
*aResult = nullptr;
// XXX: we should fix this so there's a generic interface that
// describes controllers, so this code would have no special
// knowledge of what object might have controllers.
nsFocusManager::SearchRange searchRange =
aForVisibleWindow ? nsFocusManager::eIncludeVisibleDescendants
: nsFocusManager::eIncludeAllDescendants;
nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
nsIContent* focusedContent = nsFocusManager::GetFocusedDescendant(
mWindow, searchRange, getter_AddRefs(focusedWindow));
if (focusedContent) {
#ifdef MOZ_XUL
RefPtr<nsXULElement> xulElement = nsXULElement::FromNode(focusedContent);
if (xulElement) {
ErrorResult rv;
*aResult = xulElement->GetControllers(rv);
NS_IF_ADDREF(*aResult);
return rv.StealNSResult();
}
#endif
HTMLTextAreaElement* htmlTextArea =
HTMLTextAreaElement::FromNode(focusedContent);
if (htmlTextArea) return htmlTextArea->GetControllers(aResult);
HTMLInputElement* htmlInputElement =
HTMLInputElement::FromNode(focusedContent);
if (htmlInputElement) return htmlInputElement->GetControllers(aResult);
if (focusedContent->IsEditable() && focusedWindow)
return focusedWindow->GetControllers(aResult);
} else {
return focusedWindow->GetControllers(aResult);
}
return NS_OK;
}
nsresult nsWindowRoot::GetControllerForCommand(const char* aCommand,
bool aForVisibleWindow,
nsIController** _retval) {
NS_ENSURE_ARG_POINTER(_retval);
*_retval = nullptr;
{
nsCOMPtr<nsIControllers> controllers;
GetControllers(aForVisibleWindow, getter_AddRefs(controllers));
if (controllers) {
nsCOMPtr<nsIController> controller;
controllers->GetControllerForCommand(aCommand,
getter_AddRefs(controller));
if (controller) {
controller.forget(_retval);
return NS_OK;
}
}
}
nsFocusManager::SearchRange searchRange =
aForVisibleWindow ? nsFocusManager::eIncludeVisibleDescendants
: nsFocusManager::eIncludeAllDescendants;
nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
nsFocusManager::GetFocusedDescendant(mWindow, searchRange,
getter_AddRefs(focusedWindow));
while (focusedWindow) {
nsCOMPtr<nsIControllers> controllers;
focusedWindow->GetControllers(getter_AddRefs(controllers));
if (controllers) {
nsCOMPtr<nsIController> controller;
controllers->GetControllerForCommand(aCommand,
getter_AddRefs(controller));
if (controller) {
controller.forget(_retval);
return NS_OK;
}
}
// XXXndeakin P3 is this casting safe?
nsGlobalWindowOuter* win = nsGlobalWindowOuter::Cast(focusedWindow);
focusedWindow = win->GetPrivateParent();
}
return NS_OK;
}
void nsWindowRoot::GetEnabledDisabledCommandsForControllers(
nsIControllers* aControllers,
nsTHashtable<nsCStringHashKey>& aCommandsHandled,
nsTArray<nsCString>& aEnabledCommands,
nsTArray<nsCString>& aDisabledCommands) {
uint32_t controllerCount;
aControllers->GetControllerCount(&controllerCount);
for (uint32_t c = 0; c < controllerCount; c++) {
nsCOMPtr<nsIController> controller;
aControllers->GetControllerAt(c, getter_AddRefs(controller));
nsCOMPtr<nsICommandController> commandController(
do_QueryInterface(controller));
if (commandController) {
// All of our default command controllers have 20-60 commands. Let's just
// leave enough space here for all of them so we probably don't need to
// heap-allocate.
AutoTArray<nsCString, 64> commands;
if (NS_SUCCEEDED(commandController->GetSupportedCommands(commands))) {
for (auto& commandStr : commands) {
// Use a hash to determine which commands have already been handled by
// earlier controllers, as the earlier controller's result should get
// priority.
if (aCommandsHandled.EnsureInserted(commandStr)) {
// We inserted a new entry into aCommandsHandled.
bool enabled = false;
controller->IsCommandEnabled(commandStr.get(), &enabled);
if (enabled) {
aEnabledCommands.AppendElement(commandStr);
} else {
aDisabledCommands.AppendElement(commandStr);
}
}
}
}
}
}
}
void nsWindowRoot::GetEnabledDisabledCommands(
nsTArray<nsCString>& aEnabledCommands,
nsTArray<nsCString>& aDisabledCommands) {
nsTHashtable<nsCStringHashKey> commandsHandled;
nsCOMPtr<nsIControllers> controllers;
GetControllers(false, getter_AddRefs(controllers));
if (controllers) {
GetEnabledDisabledCommandsForControllers(
controllers, commandsHandled, aEnabledCommands, aDisabledCommands);
}
nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
nsFocusManager::GetFocusedDescendant(mWindow,
nsFocusManager::eIncludeAllDescendants,
getter_AddRefs(focusedWindow));
while (focusedWindow) {
focusedWindow->GetControllers(getter_AddRefs(controllers));
if (controllers) {
GetEnabledDisabledCommandsForControllers(
controllers, commandsHandled, aEnabledCommands, aDisabledCommands);
}
nsGlobalWindowOuter* win = nsGlobalWindowOuter::Cast(focusedWindow);
focusedWindow = win->GetPrivateParent();
}
}
already_AddRefed<nsINode> nsWindowRoot::GetPopupNode() {
nsCOMPtr<nsINode> popupNode = do_QueryReferent(mPopupNode);
return popupNode.forget();
}
void nsWindowRoot::SetPopupNode(nsINode* aNode) {
mPopupNode = do_GetWeakReference(aNode);
}
nsIGlobalObject* nsWindowRoot::GetParentObject() {
return xpc::NativeGlobal(xpc::PrivilegedJunkScope());
}
JSObject* nsWindowRoot::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
return mozilla::dom::WindowRoot_Binding::Wrap(aCx, this, aGivenProto);
}
void nsWindowRoot::AddBrowser(nsIRemoteTab* aBrowser) {
nsWeakPtr weakBrowser = do_GetWeakReference(aBrowser);
mWeakBrowsers.PutEntry(weakBrowser);
}
void nsWindowRoot::RemoveBrowser(nsIRemoteTab* aBrowser) {
nsWeakPtr weakBrowser = do_GetWeakReference(aBrowser);
mWeakBrowsers.RemoveEntry(weakBrowser);
}
void nsWindowRoot::EnumerateBrowsers(BrowserEnumerator aEnumFunc, void* aArg) {
// Collect strong references to all browsers in a separate array in
// case aEnumFunc alters mWeakBrowsers.
nsTArray<nsCOMPtr<nsIRemoteTab>> remoteTabs;
for (auto iter = mWeakBrowsers.ConstIter(); !iter.Done(); iter.Next()) {
nsCOMPtr<nsIRemoteTab> remoteTab(do_QueryReferent(iter.Get()->GetKey()));
if (remoteTab) {
remoteTabs.AppendElement(remoteTab);
}
}
for (uint32_t i = 0; i < remoteTabs.Length(); ++i) {
aEnumFunc(remoteTabs[i], aArg);
}
}
///////////////////////////////////////////////////////////////////////////////////
already_AddRefed<EventTarget> NS_NewWindowRoot(nsPIDOMWindowOuter* aWindow) {
nsCOMPtr<EventTarget> result = new nsWindowRoot(aWindow);
if (XRE_IsContentProcess()) {
RefPtr<JSWindowActorService> wasvc = JSWindowActorService::GetSingleton();
wasvc->RegisterChromeEventTarget(result);
}
return result.forget();
}