forked from mirrors/gecko-dev
The basic idea is to make non-initial about:blank fire document-element-inserted notifications just like every other document. We then ensure that there's a notification (initial-document-element-inserted) that only gets fired once per window for documents that are in a window. This notification is what webextensions use to inject into the document. The old setup which injected into about:blank when its global is created gets removed in favor of injecting the same way as into every other document. The changes to Document.cpp are fixing a bug in the "block the parser" stuff webextensions do. For about:blank, the blocking happens at a point when the parser really has nothing else to parse (since it's parsing the empty string). So the blocking is a no-op. But we do want to prevent DOMContentLoaded firing, because otherwise the "end of document" scripts could run before we finish doing the "beginning of document" work in webextensions. So we want to make sure we block DOMContentLoaded, not just the load event. Differential Revision: https://phabricator.services.mozilla.com/D19892 --HG-- extra : moz-landing-system : lando
134 lines
4 KiB
C++
134 lines
4 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
|
|
/* 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/. */
|
|
|
|
#ifndef mozilla_ExtensionPolicyService_h
|
|
#define mozilla_ExtensionPolicyService_h
|
|
|
|
#include "mozilla/MemoryReporting.h"
|
|
#include "mozilla/extensions/WebExtensionPolicy.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsCycleCollectionParticipant.h"
|
|
#include "nsHashKeys.h"
|
|
#include "nsIAddonPolicyService.h"
|
|
#include "nsAtom.h"
|
|
#include "nsIDOMEventListener.h"
|
|
#include "nsIMemoryReporter.h"
|
|
#include "nsIObserver.h"
|
|
#include "nsIObserverService.h"
|
|
#include "nsISupports.h"
|
|
#include "nsPointerHashKeys.h"
|
|
#include "nsRefPtrHashtable.h"
|
|
#include "nsTHashtable.h"
|
|
|
|
class nsIChannel;
|
|
class nsIObserverService;
|
|
|
|
class nsIPIDOMWindowInner;
|
|
class nsIPIDOMWindowOuter;
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
class ContentFrameMessageManager;
|
|
class Promise;
|
|
} // namespace dom
|
|
namespace extensions {
|
|
class DocInfo;
|
|
class DocumentObserver;
|
|
class WebExtensionContentScript;
|
|
} // namespace extensions
|
|
|
|
using extensions::DocInfo;
|
|
using extensions::WebExtensionPolicy;
|
|
|
|
class ExtensionPolicyService final : public nsIAddonPolicyService,
|
|
public nsIObserver,
|
|
public nsIDOMEventListener,
|
|
public nsIMemoryReporter {
|
|
public:
|
|
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ExtensionPolicyService,
|
|
nsIAddonPolicyService)
|
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
|
NS_DECL_NSIADDONPOLICYSERVICE
|
|
NS_DECL_NSIOBSERVER
|
|
NS_DECL_NSIDOMEVENTLISTENER
|
|
NS_DECL_NSIMEMORYREPORTER
|
|
|
|
static ExtensionPolicyService& GetSingleton();
|
|
|
|
static already_AddRefed<ExtensionPolicyService> GetInstance() {
|
|
return do_AddRef(&GetSingleton());
|
|
}
|
|
|
|
WebExtensionPolicy* GetByID(const nsAtom* aAddonId) {
|
|
return mExtensions.GetWeak(aAddonId);
|
|
}
|
|
|
|
WebExtensionPolicy* GetByID(const nsAString& aAddonId) {
|
|
RefPtr<nsAtom> atom = NS_AtomizeMainThread(aAddonId);
|
|
return GetByID(atom);
|
|
}
|
|
|
|
WebExtensionPolicy* GetByURL(const extensions::URLInfo& aURL);
|
|
|
|
WebExtensionPolicy* GetByHost(const nsACString& aHost) const {
|
|
return mExtensionHosts.GetWeak(aHost);
|
|
}
|
|
|
|
void GetAll(nsTArray<RefPtr<WebExtensionPolicy>>& aResult);
|
|
|
|
bool RegisterExtension(WebExtensionPolicy& aPolicy);
|
|
bool UnregisterExtension(WebExtensionPolicy& aPolicy);
|
|
|
|
bool RegisterObserver(extensions::DocumentObserver& aPolicy);
|
|
bool UnregisterObserver(extensions::DocumentObserver& aPolicy);
|
|
|
|
void BaseCSP(nsAString& aDefaultCSP) const;
|
|
void DefaultCSP(nsAString& aDefaultCSP) const;
|
|
|
|
bool UseRemoteExtensions() const;
|
|
bool IsExtensionProcess() const;
|
|
|
|
nsresult InjectContentScripts(WebExtensionPolicy* aExtension);
|
|
|
|
protected:
|
|
virtual ~ExtensionPolicyService();
|
|
|
|
private:
|
|
ExtensionPolicyService();
|
|
|
|
void RegisterObservers();
|
|
void UnregisterObservers();
|
|
|
|
void CheckRequest(nsIChannel* aChannel);
|
|
void CheckDocument(dom::Document* aDocument);
|
|
|
|
void CheckContentScripts(const DocInfo& aDocInfo, bool aIsPreload);
|
|
|
|
already_AddRefed<dom::Promise> ExecuteContentScript(
|
|
nsPIDOMWindowInner* aWindow,
|
|
extensions::WebExtensionContentScript& aScript);
|
|
|
|
RefPtr<dom::Promise> ExecuteContentScripts(
|
|
JSContext* aCx, nsPIDOMWindowInner* aWindow,
|
|
const nsTArray<RefPtr<extensions::WebExtensionContentScript>>& aScripts);
|
|
|
|
nsRefPtrHashtable<nsPtrHashKey<const nsAtom>, WebExtensionPolicy> mExtensions;
|
|
nsRefPtrHashtable<nsCStringHashKey, WebExtensionPolicy> mExtensionHosts;
|
|
|
|
nsTHashtable<nsRefPtrHashKey<dom::ContentFrameMessageManager>>
|
|
mMessageManagers;
|
|
|
|
nsRefPtrHashtable<nsPtrHashKey<const extensions::DocumentObserver>,
|
|
extensions::DocumentObserver>
|
|
mObservers;
|
|
|
|
nsCOMPtr<nsIObserverService> mObs;
|
|
|
|
static bool sRemoteExtensions;
|
|
};
|
|
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_ExtensionPolicyService_h
|