michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsHtml5AttributeName.h" michael@0: #include "nsHtml5ElementName.h" michael@0: #include "nsHtml5HtmlAttributes.h" michael@0: #include "nsHtml5NamedCharacters.h" michael@0: #include "nsHtml5Portability.h" michael@0: #include "nsHtml5StackNode.h" michael@0: #include "nsHtml5Tokenizer.h" michael@0: #include "nsHtml5TreeBuilder.h" michael@0: #include "nsHtml5UTF16Buffer.h" michael@0: #include "nsHtml5Module.h" michael@0: #include "nsIObserverService.h" michael@0: #include "nsIServiceManager.h" michael@0: #include "mozilla/Services.h" michael@0: #include "mozilla/Preferences.h" michael@0: #include "mozilla/Attributes.h" michael@0: michael@0: using namespace mozilla; michael@0: michael@0: // static michael@0: bool nsHtml5Module::sOffMainThread = true; michael@0: nsIThread* nsHtml5Module::sStreamParserThread = nullptr; michael@0: nsIThread* nsHtml5Module::sMainThread = nullptr; michael@0: michael@0: // static michael@0: void michael@0: nsHtml5Module::InitializeStatics() michael@0: { michael@0: Preferences::AddBoolVarCache(&sOffMainThread, "html5.offmainthread"); michael@0: nsHtml5Atoms::AddRefAtoms(); michael@0: nsHtml5AttributeName::initializeStatics(); michael@0: nsHtml5ElementName::initializeStatics(); michael@0: nsHtml5HtmlAttributes::initializeStatics(); michael@0: nsHtml5NamedCharacters::initializeStatics(); michael@0: nsHtml5Portability::initializeStatics(); michael@0: nsHtml5StackNode::initializeStatics(); michael@0: nsHtml5Tokenizer::initializeStatics(); michael@0: nsHtml5TreeBuilder::initializeStatics(); michael@0: nsHtml5UTF16Buffer::initializeStatics(); michael@0: nsHtml5StreamParser::InitializeStatics(); michael@0: nsHtml5TreeOpExecutor::InitializeStatics(); michael@0: #ifdef DEBUG michael@0: sNsHtml5ModuleInitialized = true; michael@0: #endif michael@0: } michael@0: michael@0: // static michael@0: void michael@0: nsHtml5Module::ReleaseStatics() michael@0: { michael@0: #ifdef DEBUG michael@0: sNsHtml5ModuleInitialized = false; michael@0: #endif michael@0: nsHtml5AttributeName::releaseStatics(); michael@0: nsHtml5ElementName::releaseStatics(); michael@0: nsHtml5HtmlAttributes::releaseStatics(); michael@0: nsHtml5NamedCharacters::releaseStatics(); michael@0: nsHtml5Portability::releaseStatics(); michael@0: nsHtml5StackNode::releaseStatics(); michael@0: nsHtml5Tokenizer::releaseStatics(); michael@0: nsHtml5TreeBuilder::releaseStatics(); michael@0: nsHtml5UTF16Buffer::releaseStatics(); michael@0: NS_IF_RELEASE(sStreamParserThread); michael@0: NS_IF_RELEASE(sMainThread); michael@0: } michael@0: michael@0: // static michael@0: already_AddRefed michael@0: nsHtml5Module::NewHtml5Parser() michael@0: { michael@0: NS_ABORT_IF_FALSE(sNsHtml5ModuleInitialized, "nsHtml5Module not initialized."); michael@0: nsCOMPtr rv = new nsHtml5Parser(); michael@0: return rv.forget(); michael@0: } michael@0: michael@0: // static michael@0: nsresult michael@0: nsHtml5Module::Initialize(nsIParser* aParser, nsIDocument* aDoc, nsIURI* aURI, nsISupports* aContainer, nsIChannel* aChannel) michael@0: { michael@0: NS_ABORT_IF_FALSE(sNsHtml5ModuleInitialized, "nsHtml5Module not initialized."); michael@0: nsHtml5Parser* parser = static_cast (aParser); michael@0: return parser->Initialize(aDoc, aURI, aContainer, aChannel); michael@0: } michael@0: michael@0: class nsHtml5ParserThreadTerminator MOZ_FINAL : public nsIObserver michael@0: { michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: nsHtml5ParserThreadTerminator(nsIThread* aThread) michael@0: : mThread(aThread) michael@0: {} michael@0: NS_IMETHODIMP Observe(nsISupports *, const char *topic, const char16_t *) michael@0: { michael@0: NS_ASSERTION(!strcmp(topic, "xpcom-shutdown-threads"), michael@0: "Unexpected topic"); michael@0: if (mThread) { michael@0: mThread->Shutdown(); michael@0: mThread = nullptr; michael@0: } michael@0: return NS_OK; michael@0: } michael@0: private: michael@0: nsCOMPtr mThread; michael@0: }; michael@0: michael@0: NS_IMPL_ISUPPORTS(nsHtml5ParserThreadTerminator, nsIObserver) michael@0: michael@0: // static michael@0: nsIThread* michael@0: nsHtml5Module::GetStreamParserThread() michael@0: { michael@0: if (sOffMainThread) { michael@0: if (!sStreamParserThread) { michael@0: NS_NewNamedThread("HTML5 Parser", &sStreamParserThread); michael@0: NS_ASSERTION(sStreamParserThread, "Thread creation failed!"); michael@0: nsCOMPtr os = mozilla::services::GetObserverService(); michael@0: NS_ASSERTION(os, "do_GetService failed"); michael@0: os->AddObserver(new nsHtml5ParserThreadTerminator(sStreamParserThread), michael@0: "xpcom-shutdown-threads", michael@0: false); michael@0: } michael@0: return sStreamParserThread; michael@0: } michael@0: if (!sMainThread) { michael@0: NS_GetMainThread(&sMainThread); michael@0: NS_ASSERTION(sMainThread, "Main thread getter failed"); michael@0: } michael@0: return sMainThread; michael@0: } michael@0: michael@0: #ifdef DEBUG michael@0: bool nsHtml5Module::sNsHtml5ModuleInitialized = false; michael@0: #endif