Bug 1538056 Part 1 - Notify devtools about HTML file contents, r=hsivonen.

Differential Revision: https://phabricator.services.mozilla.com/D33178
This commit is contained in:
Brian Hackett
2019-08-04 21:33:07 +00:00
parent c4b151f218
commit 88f29587cf
4 changed files with 117 additions and 18 deletions

View File

@@ -36,6 +36,7 @@
#include "mozilla/SchedulerGroup.h"
#include "nsJSEnvironment.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/DebuggerUtilsBinding.h"
using namespace mozilla;
using namespace mozilla::dom;
@@ -230,9 +231,6 @@ nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
nsHtml5StreamParser::~nsHtml5StreamParser() {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
mTokenizer->end();
if (recordreplay::IsRecordingOrReplaying()) {
recordreplay::EndContentParse(this);
}
#ifdef DEBUG
{
mozilla::MutexAutoLock flushTimerLock(mFlushTimerMutex);
@@ -349,10 +347,19 @@ void nsHtml5StreamParser::FeedDetector(Span<const uint8_t> aBuffer,
}
void nsHtml5StreamParser::SetViewSourceTitle(nsIURI* aURL) {
if (recordreplay::IsRecordingOrReplaying()) {
nsAutoCString spec;
aURL->GetSpec(spec);
recordreplay::BeginContentParse(this, spec.get(), "text/html");
MOZ_ASSERT(NS_IsMainThread());
nsIDocShell* docshell = mExecutor->GetDocument()->GetDocShell();
if (docshell && docshell->GetWatchedByDevtools()) {
mURIToSendToDevtools = aURL;
nsID uuid;
nsresult rv = nsContentUtils::GenerateUUIDInPlace(uuid);
if (!NS_FAILED(rv)) {
char buffer[NSID_LENGTH];
uuid.ToProvidedString(buffer);
mUUIDForDevtools = NS_ConvertASCIItoUTF16(buffer);
}
}
if (aURL) {
@@ -836,6 +843,56 @@ nsresult nsHtml5StreamParser::SniffStreamBytes(
return NS_OK;
}
class AddContentRunnable : public Runnable {
public:
AddContentRunnable(const nsAString& aParserID, nsIURI* aURI,
Span<const char16_t> aData, bool aComplete)
: Runnable("AddContent") {
nsAutoCString spec;
aURI->GetSpec(spec);
mData.mUri.Construct(NS_ConvertUTF8toUTF16(spec));
mData.mParserID.Construct(aParserID);
mData.mContents.Construct(aData.Elements(), aData.Length());
mData.mComplete.Construct(aComplete);
}
NS_IMETHOD Run() override {
nsAutoString json;
if (!mData.ToJSON(json)) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
if (obsService) {
obsService->NotifyObservers(nullptr, "devtools-html-content",
PromiseFlatString(json).get());
}
return NS_OK;
}
HTMLContent mData;
};
inline void nsHtml5StreamParser::OnNewContent(Span<const char16_t> aData) {
if (mURIToSendToDevtools) {
NS_DispatchToMainThread(new AddContentRunnable(mUUIDForDevtools,
mURIToSendToDevtools,
aData,
/* aComplete */ false));
}
}
inline void nsHtml5StreamParser::OnContentComplete() {
if (mURIToSendToDevtools) {
NS_DispatchToMainThread(new AddContentRunnable(mUUIDForDevtools,
mURIToSendToDevtools,
Span<const char16_t>(),
/* aComplete */ true));
mURIToSendToDevtools = nullptr;
}
}
nsresult nsHtml5StreamParser::WriteStreamBytes(
Span<const uint8_t> aFromSegment) {
NS_ASSERTION(IsParserThread(), "Wrong thread!");
@@ -856,8 +913,8 @@ nsresult nsHtml5StreamParser::WriteStreamBytes(
bool hadErrors;
Tie(result, read, written, hadErrors) =
mUnicodeDecoder->DecodeToUTF16(src, dst, false);
if (!mDecodingLocalFileAsUTF8 && recordreplay::IsRecordingOrReplaying()) {
recordreplay::AddContentParseData16(this, dst.data(), written);
if (!mDecodingLocalFileAsUTF8) {
OnNewContent(dst.To(written));
}
if (hadErrors && !mHasHadErrors) {
if (mDecodingLocalFileAsUTF8) {
@@ -924,13 +981,12 @@ void nsHtml5StreamParser::CommitLocalFileToUTF8() {
mCharsetSource = kCharsetFromFileURLGuess;
mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource);
if (recordreplay::IsRecordingOrReplaying()) {
nsHtml5OwningUTF16Buffer* buffer = mLastBuffer;
while (buffer) {
recordreplay::AddContentParseData16(
this, buffer->getBuffer() + buffer->getStart(), buffer->getLength());
buffer = buffer->next;
}
nsHtml5OwningUTF16Buffer* buffer = mFirstBuffer;
while (buffer) {
Span<const char16_t> data(buffer->getBuffer() + buffer->getStart(),
buffer->getLength());
OnNewContent(data);
buffer = buffer->next;
}
}
@@ -1145,6 +1201,10 @@ void nsHtml5StreamParser::DoStopRequest() {
"Stream ended without being open.");
mTokenizerMutex.AssertCurrentThreadOwns();
auto guard = MakeScopeExit([&] {
OnContentComplete();
});
if (IsTerminated()) {
return;
}
@@ -1182,8 +1242,8 @@ void nsHtml5StreamParser::DoStopRequest() {
bool hadErrors;
Tie(result, read, written, hadErrors) =
mUnicodeDecoder->DecodeToUTF16(src, dst, true);
if (!mDecodingLocalFileAsUTF8 && recordreplay::IsRecordingOrReplaying()) {
recordreplay::AddContentParseData16(this, dst.data(), written);
if (!mDecodingLocalFileAsUTF8) {
OnNewContent(dst.To(written));
}
if (hadErrors && !mHasHadErrors) {
if (mDecodingLocalFileAsUTF8) {