michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=2 sw=2 et tw=78: */ 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 "nsHtml5DocumentBuilder.h" michael@0: michael@0: #include "nsIStyleSheetLinkingElement.h" michael@0: #include "nsStyleLinkElement.h" michael@0: #include "nsScriptLoader.h" michael@0: #include "nsIHTMLDocument.h" michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION_INHERITED(nsHtml5DocumentBuilder, nsContentSink, michael@0: mOwnedElements) michael@0: michael@0: NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsHtml5DocumentBuilder) michael@0: NS_INTERFACE_MAP_END_INHERITING(nsContentSink) michael@0: michael@0: NS_IMPL_ADDREF_INHERITED(nsHtml5DocumentBuilder, nsContentSink) michael@0: NS_IMPL_RELEASE_INHERITED(nsHtml5DocumentBuilder, nsContentSink) michael@0: michael@0: nsHtml5DocumentBuilder::nsHtml5DocumentBuilder(bool aRunsToCompletion) michael@0: { michael@0: mRunsToCompletion = aRunsToCompletion; michael@0: } michael@0: michael@0: nsresult michael@0: nsHtml5DocumentBuilder::Init(nsIDocument* aDoc, michael@0: nsIURI* aURI, michael@0: nsISupports* aContainer, michael@0: nsIChannel* aChannel) michael@0: { michael@0: return nsContentSink::Init(aDoc, aURI, aContainer, aChannel); michael@0: } michael@0: michael@0: nsHtml5DocumentBuilder::~nsHtml5DocumentBuilder() michael@0: { michael@0: } michael@0: michael@0: nsresult michael@0: nsHtml5DocumentBuilder::MarkAsBroken(nsresult aReason) michael@0: { michael@0: mBroken = aReason; michael@0: return aReason; michael@0: } michael@0: michael@0: void michael@0: nsHtml5DocumentBuilder::SetDocumentCharsetAndSource(nsACString& aCharset, int32_t aCharsetSource) michael@0: { michael@0: if (mDocument) { michael@0: mDocument->SetDocumentCharacterSetSource(aCharsetSource); michael@0: mDocument->SetDocumentCharacterSet(aCharset); michael@0: } michael@0: } michael@0: michael@0: void michael@0: nsHtml5DocumentBuilder::UpdateStyleSheet(nsIContent* aElement) michael@0: { michael@0: // Break out of the doc update created by Flush() to zap a runnable michael@0: // waiting to call UpdateStyleSheet without the right observer michael@0: EndDocUpdate(); michael@0: michael@0: if (MOZ_UNLIKELY(!mParser)) { michael@0: // EndDocUpdate ran stuff that called nsIParser::Terminate() michael@0: return; michael@0: } michael@0: michael@0: nsCOMPtr ssle(do_QueryInterface(aElement)); michael@0: NS_ASSERTION(ssle, "Node didn't QI to style."); michael@0: michael@0: ssle->SetEnableUpdates(true); michael@0: michael@0: bool willNotify; michael@0: bool isAlternate; michael@0: nsresult rv = ssle->UpdateStyleSheet(mRunsToCompletion ? nullptr : this, michael@0: &willNotify, michael@0: &isAlternate); michael@0: if (NS_SUCCEEDED(rv) && willNotify && !isAlternate && !mRunsToCompletion) { michael@0: ++mPendingSheetCount; michael@0: mScriptLoader->AddExecuteBlocker(); michael@0: } michael@0: michael@0: if (aElement->IsHTML(nsGkAtoms::link)) { michael@0: // look for michael@0: nsAutoString relVal; michael@0: aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, relVal); michael@0: if (!relVal.IsEmpty()) { michael@0: uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(relVal); michael@0: bool hasPrefetch = linkTypes & nsStyleLinkElement::ePREFETCH; michael@0: if (hasPrefetch || (linkTypes & nsStyleLinkElement::eNEXT)) { michael@0: nsAutoString hrefVal; michael@0: aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal); michael@0: if (!hrefVal.IsEmpty()) { michael@0: PrefetchHref(hrefVal, aElement, hasPrefetch); michael@0: } michael@0: } michael@0: if (linkTypes & nsStyleLinkElement::eDNS_PREFETCH) { michael@0: nsAutoString hrefVal; michael@0: aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal); michael@0: if (!hrefVal.IsEmpty()) { michael@0: PrefetchDNS(hrefVal); michael@0: } michael@0: } michael@0: } michael@0: } michael@0: michael@0: // Re-open update michael@0: BeginDocUpdate(); michael@0: } michael@0: michael@0: void michael@0: nsHtml5DocumentBuilder::SetDocumentMode(nsHtml5DocumentMode m) michael@0: { michael@0: nsCompatibility mode = eCompatibility_NavQuirks; michael@0: switch (m) { michael@0: case STANDARDS_MODE: michael@0: mode = eCompatibility_FullStandards; michael@0: break; michael@0: case ALMOST_STANDARDS_MODE: michael@0: mode = eCompatibility_AlmostStandards; michael@0: break; michael@0: case QUIRKS_MODE: michael@0: mode = eCompatibility_NavQuirks; michael@0: break; michael@0: } michael@0: nsCOMPtr htmlDocument = do_QueryInterface(mDocument); michael@0: NS_ASSERTION(htmlDocument, "Document didn't QI into HTML document."); michael@0: htmlDocument->SetCompatibilityMode(mode); michael@0: } michael@0: michael@0: // nsContentSink overrides michael@0: michael@0: void michael@0: nsHtml5DocumentBuilder::UpdateChildCounts() michael@0: { michael@0: // No-op michael@0: } michael@0: michael@0: nsresult michael@0: nsHtml5DocumentBuilder::FlushTags() michael@0: { michael@0: return NS_OK; michael@0: }