Bug 1612724 - Part 1: Add a NotifyWhenScriptSafe helper method to nsIObserverService, r=froydnj

Differential Revision: https://phabricator.services.mozilla.com/D61600

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nika Layzell 2020-02-04 22:09:34 +00:00
parent 1395be1f23
commit 185c260183
2 changed files with 62 additions and 0 deletions

View File

@ -63,6 +63,24 @@ interface nsIObserverService : nsISupports
in string aTopic,
[optional] in wstring someData );
%{C++
/**
* notifyWhenScriptSafe
*
* Notifies all registered listeners of the given topic once it is safe to
* run script.
*
* Implemented in "nsObserverService.cpp".
*
* @param aSubject : Notification specific interface pointer.
* @param aTopic : The notification topic or subject.
* @param someData : Notification specific wide string.
*/
nsresult NotifyWhenScriptSafe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData = nullptr);
%}
/**
* enumerateObservers
*

View File

@ -6,6 +6,7 @@
#include "mozilla/Logging.h"
#include "nsComponentManagerUtils.h"
#include "nsContentUtils.h"
#include "nsIConsoleService.h"
#include "nsIObserverService.h"
#include "nsIObserver.h"
@ -318,3 +319,46 @@ nsObserverService::UnmarkGrayStrongObservers() {
return NS_OK;
}
namespace {
class NotifyWhenScriptSafeRunnable : public mozilla::Runnable {
public:
NotifyWhenScriptSafeRunnable(nsIObserverService* aObs, nsISupports* aSubject,
const char* aTopic, const char16_t* aData)
: mozilla::Runnable("NotifyWhenScriptSafeRunnable"),
mObs(aObs),
mSubject(aSubject),
mTopic(aTopic) {
if (aData) {
mData.Assign(aData);
} else {
mData.SetIsVoid(true);
}
}
NS_IMETHOD Run() {
const char16_t* data = mData.IsVoid() ? nullptr : mData.get();
return mObs->NotifyObservers(mSubject, mTopic.get(), data);
}
private:
nsCOMPtr<nsIObserverService> mObs;
nsCOMPtr<nsISupports> mSubject;
nsCString mTopic;
nsString mData;
};
} // namespace
nsresult nsIObserverService::NotifyWhenScriptSafe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData) {
if (nsContentUtils::IsSafeToRunScript()) {
return NotifyObservers(aSubject, aTopic, aData);
}
nsContentUtils::AddScriptRunner(MakeAndAddRef<NotifyWhenScriptSafeRunnable>(
this, aSubject, aTopic, aData));
return NS_OK;
}