зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1472491: Part 2a - Split matching logic for content scripts into MozDocumentMatcher base class. r=zombie
MozReview-Commit-ID: JAOWZcB4hZW --HG-- extra : rebase_source : 35847d616bd2f04f1d82788f76649b8acb5c1090 extra : source : 466c39fc8af5170ea39d19d6d7aa13b8fe5cd838
This commit is contained in:
Родитель
57d6fb6016
Коммит
cdd41d5705
|
@ -581,6 +581,11 @@ DOMInterfaces = {
|
|||
'notflattened': True
|
||||
},
|
||||
|
||||
'MozDocumentMatcher': {
|
||||
'nativeType': 'mozilla::extensions::MozDocumentMatcher',
|
||||
'headerFile': 'mozilla/extensions/WebExtensionContentScript.h',
|
||||
},
|
||||
|
||||
'MozSharedMap': {
|
||||
'nativeType': 'mozilla::dom::ipc::SharedMap',
|
||||
},
|
||||
|
|
|
@ -6,32 +6,8 @@ interface LoadInfo;
|
|||
interface URI;
|
||||
interface WindowProxy;
|
||||
|
||||
/**
|
||||
* Describes the earliest point in the load cycle at which a script should
|
||||
* run.
|
||||
*/
|
||||
enum ContentScriptRunAt {
|
||||
/**
|
||||
* The point in the load cycle just after the document element has been
|
||||
* inserted, before any page scripts have been allowed to run.
|
||||
*/
|
||||
"document_start",
|
||||
/**
|
||||
* The point after which the page DOM has fully loaded, but before all page
|
||||
* resources have necessarily been loaded. Corresponds approximately to the
|
||||
* DOMContentLoaded event.
|
||||
*/
|
||||
"document_end",
|
||||
/**
|
||||
* The first point after the page and all of its resources has fully loaded
|
||||
* when the event loop is idle, and can run scripts without delaying a paint
|
||||
* event.
|
||||
*/
|
||||
"document_idle",
|
||||
};
|
||||
|
||||
[Constructor(WebExtensionPolicy extension, WebExtensionContentScriptInit options), ChromeOnly, Exposed=System]
|
||||
interface WebExtensionContentScript {
|
||||
[Constructor(MozDocumentMatcherInit options), ChromeOnly, Exposed=System]
|
||||
interface MozDocumentMatcher {
|
||||
/**
|
||||
* Returns true if the script's match and exclude patterns match the given
|
||||
* URI, without reference to attributes such as `allFrames`.
|
||||
|
@ -39,52 +15,33 @@ interface WebExtensionContentScript {
|
|||
boolean matchesURI(URI uri);
|
||||
|
||||
/**
|
||||
* Returns true if the script matches the given URI and LoadInfo objects.
|
||||
* Returns true if the the given URI and LoadInfo objects match.
|
||||
* This should be used to determine whether to begin pre-loading a content
|
||||
* script based on network events.
|
||||
*/
|
||||
boolean matchesLoadInfo(URI uri, LoadInfo loadInfo);
|
||||
|
||||
/**
|
||||
* Returns true if the script matches the given window. This should be used
|
||||
* Returns true if the given window matches. This should be used
|
||||
* to determine whether to run a script in a window at load time.
|
||||
*/
|
||||
boolean matchesWindow(WindowProxy window);
|
||||
|
||||
/**
|
||||
* The policy object for the extension that this script belongs to.
|
||||
*/
|
||||
[Constant]
|
||||
readonly attribute WebExtensionPolicy extension;
|
||||
|
||||
/**
|
||||
* If true, this script runs in all frames. If false, it only runs in
|
||||
* top-level frames.
|
||||
* If true, match all frames. If false, match only top-level frames.
|
||||
*/
|
||||
[Constant]
|
||||
readonly attribute boolean allFrames;
|
||||
|
||||
/**
|
||||
* If true, this (misleadingly-named, but inherited from Chrome) attribute
|
||||
* causes the script to run in frames with URLs which inherit a principal
|
||||
* that matches one of the match patterns, such as about:blank or
|
||||
* about:srcdoc. If false, the script only runs in frames with an explicit
|
||||
* matching URL.
|
||||
* causes us to match frames with URLs which inherit a principal that
|
||||
* matches one of the match patterns, such as about:blank or about:srcdoc.
|
||||
* If false, we only match frames with an explicit matching URL.
|
||||
*/
|
||||
[Constant]
|
||||
readonly attribute boolean matchAboutBlank;
|
||||
|
||||
/**
|
||||
* The earliest point in the load cycle at which this script should run. For
|
||||
* static content scripts, in extensions which were present at browser
|
||||
* startup, the browser makes every effort to make sure that the script runs
|
||||
* no later than this point in the load cycle. For dynamic content scripts,
|
||||
* and scripts from extensions installed during this session, the scripts
|
||||
* may run at a later point.
|
||||
*/
|
||||
[Constant]
|
||||
readonly attribute ContentScriptRunAt runAt;
|
||||
|
||||
/**
|
||||
* The outer window ID of the frame in which to run the script, or 0 if it
|
||||
* should run in the top-level frame. Should only be used for
|
||||
|
@ -123,6 +80,68 @@ interface WebExtensionContentScript {
|
|||
[Cached, Constant, Frozen]
|
||||
readonly attribute sequence<MatchGlob>? excludeGlobs;
|
||||
|
||||
/**
|
||||
* The policy object for the extension that this matcher belongs to.
|
||||
*/
|
||||
[Constant]
|
||||
readonly attribute WebExtensionPolicy? extension;
|
||||
};
|
||||
|
||||
dictionary MozDocumentMatcherInit {
|
||||
boolean allFrames = false;
|
||||
|
||||
boolean matchAboutBlank = false;
|
||||
|
||||
unsigned long long? frameID = null;
|
||||
|
||||
required MatchPatternSet matches;
|
||||
|
||||
MatchPatternSet? excludeMatches = null;
|
||||
|
||||
sequence<MatchGlob>? includeGlobs = null;
|
||||
|
||||
sequence<MatchGlob>? excludeGlobs = null;
|
||||
|
||||
boolean hasActiveTabPermission = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the earliest point in the load cycle at which a script should
|
||||
* run.
|
||||
*/
|
||||
enum ContentScriptRunAt {
|
||||
/**
|
||||
* The point in the load cycle just after the document element has been
|
||||
* inserted, before any page scripts have been allowed to run.
|
||||
*/
|
||||
"document_start",
|
||||
/**
|
||||
* The point after which the page DOM has fully loaded, but before all page
|
||||
* resources have necessarily been loaded. Corresponds approximately to the
|
||||
* DOMContentLoaded event.
|
||||
*/
|
||||
"document_end",
|
||||
/**
|
||||
* The first point after the page and all of its resources has fully loaded
|
||||
* when the event loop is idle, and can run scripts without delaying a paint
|
||||
* event.
|
||||
*/
|
||||
"document_idle",
|
||||
};
|
||||
|
||||
[Constructor(WebExtensionPolicy extension, WebExtensionContentScriptInit options), ChromeOnly, Exposed=System]
|
||||
interface WebExtensionContentScript : MozDocumentMatcher {
|
||||
/**
|
||||
* The earliest point in the load cycle at which this script should run. For
|
||||
* static content scripts, in extensions which were present at browser
|
||||
* startup, the browser makes every effort to make sure that the script runs
|
||||
* no later than this point in the load cycle. For dynamic content scripts,
|
||||
* and scripts from extensions installed during this session, the scripts
|
||||
* may run at a later point.
|
||||
*/
|
||||
[Constant]
|
||||
readonly attribute ContentScriptRunAt runAt;
|
||||
|
||||
/**
|
||||
* A set of paths, relative to the extension root, of CSS sheets to inject
|
||||
* into matching pages.
|
||||
|
@ -138,25 +157,9 @@ interface WebExtensionContentScript {
|
|||
readonly attribute sequence<DOMString> jsPaths;
|
||||
};
|
||||
|
||||
dictionary WebExtensionContentScriptInit {
|
||||
boolean allFrames = false;
|
||||
|
||||
boolean matchAboutBlank = false;
|
||||
|
||||
dictionary WebExtensionContentScriptInit : MozDocumentMatcherInit {
|
||||
ContentScriptRunAt runAt = "document_idle";
|
||||
|
||||
unsigned long long? frameID = null;
|
||||
|
||||
boolean hasActiveTabPermission = false;
|
||||
|
||||
required MatchPatternSet matches;
|
||||
|
||||
MatchPatternSet? excludeMatches = null;
|
||||
|
||||
sequence<MatchGlob>? includeGlobs = null;
|
||||
|
||||
sequence<MatchGlob>? excludeGlobs = null;
|
||||
|
||||
sequence<DOMString> cssPaths = [];
|
||||
|
||||
sequence<DOMString> jsPaths = [];
|
||||
|
|
|
@ -80,23 +80,19 @@ private:
|
|||
};
|
||||
|
||||
|
||||
class WebExtensionContentScript final : public nsISupports
|
||||
, public nsWrapperCache
|
||||
class MozDocumentMatcher : public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebExtensionContentScript)
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MozDocumentMatcher)
|
||||
|
||||
using MatchGlobArray = nsTArray<RefPtr<MatchGlob>>;
|
||||
using RunAtEnum = dom::ContentScriptRunAt;
|
||||
|
||||
static already_AddRefed<WebExtensionContentScript>
|
||||
static already_AddRefed<MozDocumentMatcher>
|
||||
Constructor(dom::GlobalObject& aGlobal,
|
||||
WebExtensionPolicy& aExtension,
|
||||
const ContentScriptInit& aInit,
|
||||
const dom::MozDocumentMatcherInit& aInit,
|
||||
ErrorResult& aRv);
|
||||
|
||||
|
||||
bool Matches(const DocInfo& aDoc) const;
|
||||
bool MatchesURI(const URLInfo& aURL) const;
|
||||
|
||||
|
@ -110,14 +106,13 @@ class WebExtensionContentScript final : public nsISupports
|
|||
}
|
||||
|
||||
|
||||
WebExtensionPolicy* GetExtension() { return mExtension; }
|
||||
|
||||
WebExtensionPolicy* Extension() { return mExtension; }
|
||||
const WebExtensionPolicy* Extension() const { return mExtension; }
|
||||
|
||||
bool AllFrames() const { return mAllFrames; }
|
||||
bool MatchAboutBlank() const { return mMatchAboutBlank; }
|
||||
RunAtEnum RunAt() const { return mRunAt; }
|
||||
|
||||
Nullable<uint64_t> GetFrameID() const { return mFrameID; }
|
||||
|
||||
MatchPatternSet* Matches() { return mMatches; }
|
||||
const MatchPatternSet* GetMatches() const { return mMatches; }
|
||||
|
@ -134,6 +129,63 @@ class WebExtensionContentScript final : public nsISupports
|
|||
ToNullable(mExcludeGlobs, aGlobs);
|
||||
}
|
||||
|
||||
Nullable<uint64_t> GetFrameID() const { return mFrameID; }
|
||||
|
||||
|
||||
WebExtensionPolicy* GetParentObject() const { return mExtension; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::HandleObject aGivenProto) override;
|
||||
|
||||
protected:
|
||||
friend class WebExtensionPolicy;
|
||||
|
||||
virtual ~MozDocumentMatcher() = default;
|
||||
|
||||
MozDocumentMatcher(const dom::MozDocumentMatcherInit& aInit,
|
||||
ErrorResult& aRv);
|
||||
|
||||
RefPtr<WebExtensionPolicy> mExtension;
|
||||
|
||||
bool mHasActiveTabPermission;
|
||||
bool mRestricted;
|
||||
|
||||
RefPtr<MatchPatternSet> mMatches;
|
||||
RefPtr<MatchPatternSet> mExcludeMatches;
|
||||
|
||||
Nullable<MatchGlobSet> mIncludeGlobs;
|
||||
Nullable<MatchGlobSet> mExcludeGlobs;
|
||||
|
||||
|
||||
bool mAllFrames;
|
||||
Nullable<uint64_t> mFrameID;
|
||||
bool mMatchAboutBlank;
|
||||
|
||||
private:
|
||||
template <typename T, typename U>
|
||||
void
|
||||
ToNullable(const Nullable<T>& aInput, Nullable<U>& aOutput)
|
||||
{
|
||||
if (aInput.IsNull()) {
|
||||
aOutput.SetNull();
|
||||
} else {
|
||||
aOutput.SetValue(aInput.Value());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class WebExtensionContentScript final : public MozDocumentMatcher
|
||||
{
|
||||
public:
|
||||
|
||||
using RunAtEnum = dom::ContentScriptRunAt;
|
||||
|
||||
static already_AddRefed<WebExtensionContentScript>
|
||||
Constructor(dom::GlobalObject& aGlobal,
|
||||
WebExtensionPolicy& aExtension,
|
||||
const ContentScriptInit& aInit,
|
||||
ErrorResult& aRv);
|
||||
|
||||
RunAtEnum RunAt() const { return mRunAt; }
|
||||
|
||||
void GetCssPaths(nsTArray<nsString>& aPaths) const
|
||||
{
|
||||
aPaths.AppendElements(mCssPaths);
|
||||
|
@ -143,9 +195,6 @@ class WebExtensionContentScript final : public nsISupports
|
|||
aPaths.AppendElements(mJsPaths);
|
||||
}
|
||||
|
||||
|
||||
WebExtensionPolicy* GetParentObject() const { return mExtension; }
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::HandleObject aGivenProto) override;
|
||||
|
||||
protected:
|
||||
|
@ -158,36 +207,10 @@ protected:
|
|||
ErrorResult& aRv);
|
||||
|
||||
private:
|
||||
RefPtr<WebExtensionPolicy> mExtension;
|
||||
|
||||
bool mHasActiveTabPermission;
|
||||
bool mRestricted;
|
||||
|
||||
RefPtr<MatchPatternSet> mMatches;
|
||||
RefPtr<MatchPatternSet> mExcludeMatches;
|
||||
|
||||
Nullable<MatchGlobSet> mIncludeGlobs;
|
||||
Nullable<MatchGlobSet> mExcludeGlobs;
|
||||
|
||||
nsTArray<nsString> mCssPaths;
|
||||
nsTArray<nsString> mJsPaths;
|
||||
|
||||
RunAtEnum mRunAt;
|
||||
|
||||
bool mAllFrames;
|
||||
Nullable<uint64_t> mFrameID;
|
||||
bool mMatchAboutBlank;
|
||||
|
||||
template <typename T, typename U>
|
||||
void
|
||||
ToNullable(const Nullable<T>& aInput, Nullable<U>& aOutput)
|
||||
{
|
||||
if (aInput.IsNull()) {
|
||||
aOutput.SetNull();
|
||||
} else {
|
||||
aOutput.SetValue(aInput.Value());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace extensions
|
||||
|
|
|
@ -428,9 +428,21 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(WebExtensionPolicy)
|
|||
|
||||
|
||||
/*****************************************************************************
|
||||
* WebExtensionContentScript
|
||||
* WebExtensionContentScript / MozDocumentMatcher
|
||||
*****************************************************************************/
|
||||
|
||||
/* static */ already_AddRefed<MozDocumentMatcher>
|
||||
MozDocumentMatcher::Constructor(GlobalObject& aGlobal,
|
||||
const dom::MozDocumentMatcherInit& aInit,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<MozDocumentMatcher> matcher = new MozDocumentMatcher(aInit, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
return matcher.forget();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<WebExtensionContentScript>
|
||||
WebExtensionContentScript::Constructor(GlobalObject& aGlobal,
|
||||
WebExtensionPolicy& aExtension,
|
||||
|
@ -444,17 +456,12 @@ WebExtensionContentScript::Constructor(GlobalObject& aGlobal,
|
|||
return script.forget();
|
||||
}
|
||||
|
||||
WebExtensionContentScript::WebExtensionContentScript(WebExtensionPolicy& aExtension,
|
||||
const ContentScriptInit& aInit,
|
||||
ErrorResult& aRv)
|
||||
: mExtension(&aExtension)
|
||||
, mHasActiveTabPermission(aInit.mHasActiveTabPermission)
|
||||
, mRestricted(!aExtension.HasPermission(nsGkAtoms::mozillaAddons))
|
||||
MozDocumentMatcher::MozDocumentMatcher(const dom::MozDocumentMatcherInit& aInit,
|
||||
ErrorResult& aRv)
|
||||
: mHasActiveTabPermission(aInit.mHasActiveTabPermission)
|
||||
, mRestricted(false)
|
||||
, mMatches(aInit.mMatches)
|
||||
, mExcludeMatches(aInit.mExcludeMatches)
|
||||
, mCssPaths(aInit.mCssPaths)
|
||||
, mJsPaths(aInit.mJsPaths)
|
||||
, mRunAt(aInit.mRunAt)
|
||||
, mAllFrames(aInit.mAllFrames)
|
||||
, mFrameID(aInit.mFrameID)
|
||||
, mMatchAboutBlank(aInit.mMatchAboutBlank)
|
||||
|
@ -468,8 +475,20 @@ WebExtensionContentScript::WebExtensionContentScript(WebExtensionPolicy& aExtens
|
|||
}
|
||||
}
|
||||
|
||||
WebExtensionContentScript::WebExtensionContentScript(WebExtensionPolicy& aExtension,
|
||||
const ContentScriptInit& aInit,
|
||||
ErrorResult& aRv)
|
||||
: MozDocumentMatcher(aInit, aRv)
|
||||
, mCssPaths(aInit.mCssPaths)
|
||||
, mJsPaths(aInit.mJsPaths)
|
||||
, mRunAt(aInit.mRunAt)
|
||||
{
|
||||
mExtension = &aExtension;
|
||||
mRestricted = !aExtension.HasPermission(nsGkAtoms::mozillaAddons);
|
||||
}
|
||||
|
||||
bool
|
||||
WebExtensionContentScript::Matches(const DocInfo& aDoc) const
|
||||
MozDocumentMatcher::Matches(const DocInfo& aDoc) const
|
||||
{
|
||||
if (!mFrameID.IsNull()) {
|
||||
if (aDoc.FrameID() != mFrameID.Value()) {
|
||||
|
@ -508,7 +527,7 @@ WebExtensionContentScript::Matches(const DocInfo& aDoc) const
|
|||
}
|
||||
|
||||
bool
|
||||
WebExtensionContentScript::MatchesURI(const URLInfo& aURL) const
|
||||
MozDocumentMatcher::MatchesURI(const URLInfo& aURL) const
|
||||
{
|
||||
if (!mMatches->Matches(aURL)) {
|
||||
return false;
|
||||
|
@ -534,6 +553,12 @@ WebExtensionContentScript::MatchesURI(const URLInfo& aURL) const
|
|||
}
|
||||
|
||||
|
||||
JSObject*
|
||||
MozDocumentMatcher::WrapObject(JSContext* aCx, JS::HandleObject aGivenProto)
|
||||
{
|
||||
return MozDocumentMatcher_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
WebExtensionContentScript::WrapObject(JSContext* aCx, JS::HandleObject aGivenProto)
|
||||
{
|
||||
|
@ -541,18 +566,18 @@ WebExtensionContentScript::WrapObject(JSContext* aCx, JS::HandleObject aGivenPro
|
|||
}
|
||||
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebExtensionContentScript,
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MozDocumentMatcher,
|
||||
mMatches, mExcludeMatches,
|
||||
mIncludeGlobs, mExcludeGlobs,
|
||||
mExtension)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebExtensionContentScript)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MozDocumentMatcher)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(WebExtensionContentScript)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(WebExtensionContentScript)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(MozDocumentMatcher)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(MozDocumentMatcher)
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
Загрузка…
Ссылка в новой задаче