2014-03-05 11:38:49 -08:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=2 sw=2 et tw=78: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#include "nsHtml5DocumentBuilder.h"
|
|
|
|
|
2014-03-05 11:38:50 -08:00
|
|
|
#include "nsIStyleSheetLinkingElement.h"
|
|
|
|
#include "nsStyleLinkElement.h"
|
2014-03-05 11:38:49 -08:00
|
|
|
#include "nsScriptLoader.h"
|
2014-03-05 11:38:50 -08:00
|
|
|
#include "nsIHTMLDocument.h"
|
2014-03-05 11:38:49 -08:00
|
|
|
|
2014-04-25 09:49:00 -07:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_INHERITED(nsHtml5DocumentBuilder, nsContentSink,
|
|
|
|
mOwnedElements)
|
2014-03-05 11:38:49 -08:00
|
|
|
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsHtml5DocumentBuilder)
|
|
|
|
NS_INTERFACE_MAP_END_INHERITING(nsContentSink)
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF_INHERITED(nsHtml5DocumentBuilder, nsContentSink)
|
|
|
|
NS_IMPL_RELEASE_INHERITED(nsHtml5DocumentBuilder, nsContentSink)
|
|
|
|
|
2014-03-05 11:38:50 -08:00
|
|
|
nsHtml5DocumentBuilder::nsHtml5DocumentBuilder(bool aRunsToCompletion)
|
|
|
|
{
|
|
|
|
mRunsToCompletion = aRunsToCompletion;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsHtml5DocumentBuilder::Init(nsIDocument* aDoc,
|
|
|
|
nsIURI* aURI,
|
|
|
|
nsISupports* aContainer,
|
|
|
|
nsIChannel* aChannel)
|
|
|
|
{
|
|
|
|
return nsContentSink::Init(aDoc, aURI, aContainer, aChannel);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsHtml5DocumentBuilder::~nsHtml5DocumentBuilder()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsHtml5DocumentBuilder::MarkAsBroken(nsresult aReason)
|
|
|
|
{
|
|
|
|
mBroken = aReason;
|
|
|
|
return aReason;
|
|
|
|
}
|
|
|
|
|
2014-03-05 11:38:49 -08:00
|
|
|
void
|
2014-03-05 11:38:50 -08:00
|
|
|
nsHtml5DocumentBuilder::SetDocumentCharsetAndSource(nsACString& aCharset, int32_t aCharsetSource)
|
2014-03-05 11:38:49 -08:00
|
|
|
{
|
2014-03-05 11:38:50 -08:00
|
|
|
if (mDocument) {
|
|
|
|
mDocument->SetDocumentCharacterSetSource(aCharsetSource);
|
|
|
|
mDocument->SetDocumentCharacterSet(aCharset);
|
|
|
|
}
|
2014-03-05 11:38:49 -08:00
|
|
|
}
|
|
|
|
|
2014-03-05 11:38:50 -08:00
|
|
|
void
|
|
|
|
nsHtml5DocumentBuilder::UpdateStyleSheet(nsIContent* aElement)
|
|
|
|
{
|
|
|
|
// Break out of the doc update created by Flush() to zap a runnable
|
|
|
|
// waiting to call UpdateStyleSheet without the right observer
|
|
|
|
EndDocUpdate();
|
|
|
|
|
|
|
|
if (MOZ_UNLIKELY(!mParser)) {
|
|
|
|
// EndDocUpdate ran stuff that called nsIParser::Terminate()
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(aElement));
|
|
|
|
NS_ASSERTION(ssle, "Node didn't QI to style.");
|
|
|
|
|
|
|
|
ssle->SetEnableUpdates(true);
|
|
|
|
|
|
|
|
bool willNotify;
|
|
|
|
bool isAlternate;
|
|
|
|
nsresult rv = ssle->UpdateStyleSheet(mRunsToCompletion ? nullptr : this,
|
|
|
|
&willNotify,
|
|
|
|
&isAlternate);
|
|
|
|
if (NS_SUCCEEDED(rv) && willNotify && !isAlternate && !mRunsToCompletion) {
|
|
|
|
++mPendingSheetCount;
|
|
|
|
mScriptLoader->AddExecuteBlocker();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aElement->IsHTML(nsGkAtoms::link)) {
|
|
|
|
// look for <link rel="next" href="url">
|
|
|
|
nsAutoString relVal;
|
|
|
|
aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::rel, relVal);
|
|
|
|
if (!relVal.IsEmpty()) {
|
|
|
|
uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(relVal);
|
|
|
|
bool hasPrefetch = linkTypes & nsStyleLinkElement::ePREFETCH;
|
|
|
|
if (hasPrefetch || (linkTypes & nsStyleLinkElement::eNEXT)) {
|
|
|
|
nsAutoString hrefVal;
|
|
|
|
aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
|
|
|
|
if (!hrefVal.IsEmpty()) {
|
|
|
|
PrefetchHref(hrefVal, aElement, hasPrefetch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (linkTypes & nsStyleLinkElement::eDNS_PREFETCH) {
|
|
|
|
nsAutoString hrefVal;
|
|
|
|
aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
|
|
|
|
if (!hrefVal.IsEmpty()) {
|
|
|
|
PrefetchDNS(hrefVal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Re-open update
|
|
|
|
BeginDocUpdate();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsHtml5DocumentBuilder::SetDocumentMode(nsHtml5DocumentMode m)
|
|
|
|
{
|
|
|
|
nsCompatibility mode = eCompatibility_NavQuirks;
|
|
|
|
switch (m) {
|
|
|
|
case STANDARDS_MODE:
|
|
|
|
mode = eCompatibility_FullStandards;
|
|
|
|
break;
|
|
|
|
case ALMOST_STANDARDS_MODE:
|
|
|
|
mode = eCompatibility_AlmostStandards;
|
|
|
|
break;
|
|
|
|
case QUIRKS_MODE:
|
|
|
|
mode = eCompatibility_NavQuirks;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(mDocument);
|
|
|
|
NS_ASSERTION(htmlDocument, "Document didn't QI into HTML document.");
|
|
|
|
htmlDocument->SetCompatibilityMode(mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
// nsContentSink overrides
|
|
|
|
|
|
|
|
void
|
|
|
|
nsHtml5DocumentBuilder::UpdateChildCounts()
|
|
|
|
{
|
|
|
|
// No-op
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsHtml5DocumentBuilder::FlushTags()
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|