mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Stop blocking the parser on CSS stylesheet loads. We still block scriptexecution on them, however. Bug 84582, r+sr=sicking
This commit is contained in:
parent
9375a2fa83
commit
75d0ec2b2f
@ -40,14 +40,13 @@
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsIParser;
|
||||
class nsIDocument;
|
||||
class nsICSSLoaderObserver;
|
||||
class nsIURI;
|
||||
|
||||
#define NS_ISTYLESHEETLINKINGELEMENT_IID \
|
||||
{0x259f8226, 0x8dd7, 0x11db, \
|
||||
{0x98, 0x5e, 0x92, 0xb7, 0x56, 0xd8, 0x95, 0x93}}
|
||||
{ 0xd753c84a, 0x17fd, 0x4d5f, \
|
||||
{ 0xb2, 0xe9, 0x63, 0x52, 0x8c, 0x87, 0x99, 0x7a } }
|
||||
|
||||
class nsIStyleSheet;
|
||||
|
||||
@ -73,29 +72,30 @@ public:
|
||||
NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aStyleSheet) = 0;
|
||||
|
||||
/**
|
||||
* Initialize the stylesheet linking element. This method passes
|
||||
* in a parser that the element blocks if the stylesheet is
|
||||
* a stylesheet that should be loaded with the parser blocked.
|
||||
* If aDontLoadStyle is true the element will ignore the first
|
||||
* modification to the element that would cause a stylesheet to
|
||||
* be loaded. Subsequent modifications to the element will not
|
||||
* be ignored.
|
||||
* Initialize the stylesheet linking element. If aDontLoadStyle is
|
||||
* true the element will ignore the first modification to the
|
||||
* element that would cause a stylesheet to be loaded. Subsequent
|
||||
* modifications to the element will not be ignored.
|
||||
*/
|
||||
NS_IMETHOD InitStyleLinkElement(nsIParser *aParser, PRBool aDontLoadStyle) = 0;
|
||||
NS_IMETHOD InitStyleLinkElement(PRBool aDontLoadStyle) = 0;
|
||||
|
||||
/**
|
||||
* Tells this element to update the stylesheet.
|
||||
*
|
||||
* @param aOldDocument the document that this element was part
|
||||
* of (nsnull if we're not moving the element
|
||||
* from one document to another).
|
||||
* @param aObserver observer to notify once the stylesheet is loaded.
|
||||
* It might be notified before the function returns.
|
||||
* @param aForceUpdate If true, force the update even if the URI did not change
|
||||
* This will be passed to the CSSLoader
|
||||
* @param [out] aWillNotify whether aObserver will be notified when the sheet
|
||||
* loads. If this is false, then either we didn't
|
||||
* start the sheet load at all, the load failed, or
|
||||
* this was an inline sheet that completely finished
|
||||
* loading. In the case when the load failed the
|
||||
* failure code will be returned.
|
||||
* @param [out] whether the sheet is an alternate sheet. This value is only
|
||||
* meaningful if aWillNotify is true.
|
||||
*/
|
||||
NS_IMETHOD UpdateStyleSheet(nsIDocument *aOldDocument,
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
PRBool aForceUpdate = PR_FALSE) = 0;
|
||||
NS_IMETHOD UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
|
||||
PRBool *aWillNotify,
|
||||
PRBool *aIsAlternate) = 0;
|
||||
|
||||
/**
|
||||
* Tells this element whether to update the stylesheet when the
|
||||
|
@ -89,12 +89,6 @@
|
||||
|
||||
PRLogModuleInfo* gContentSinkLogModuleInfo;
|
||||
|
||||
#ifdef ALLOW_ASYNCH_STYLE_SHEETS
|
||||
const PRBool kBlockByDefault = PR_FALSE;
|
||||
#else
|
||||
const PRBool kBlockByDefault = PR_TRUE;
|
||||
#endif
|
||||
|
||||
class nsScriptLoaderObserverProxy : public nsIScriptLoaderObserver
|
||||
{
|
||||
public:
|
||||
@ -162,6 +156,7 @@ nsContentSink::nsContentSink()
|
||||
NS_ASSERTION(mDroppedTimer == PR_FALSE, "What?");
|
||||
NS_ASSERTION(mInMonolithicContainer == 0, "What?");
|
||||
NS_ASSERTION(mInNotification == 0, "What?");
|
||||
NS_ASSERTION(mDeferredLayoutStart == PR_FALSE, "What?");
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
if (!gContentSinkLogModuleInfo) {
|
||||
@ -204,9 +199,9 @@ nsContentSink::Init(nsIDocument* aDoc,
|
||||
new nsScriptLoaderObserverProxy(this);
|
||||
NS_ENSURE_TRUE(proxy, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsScriptLoader *loader = mDocument->GetScriptLoader();
|
||||
NS_ENSURE_TRUE(loader, NS_ERROR_FAILURE);
|
||||
loader->AddObserver(proxy);
|
||||
mScriptLoader = mDocument->GetScriptLoader();
|
||||
NS_ENSURE_TRUE(mScriptLoader, NS_ERROR_FAILURE);
|
||||
mScriptLoader->AddObserver(proxy);
|
||||
|
||||
mCSSLoader = aDoc->CSSLoader();
|
||||
|
||||
@ -265,6 +260,26 @@ nsContentSink::StyleSheetLoaded(nsICSSStyleSheet* aSheet,
|
||||
PRBool aWasAlternate,
|
||||
nsresult aStatus)
|
||||
{
|
||||
if (!aWasAlternate) {
|
||||
NS_ASSERTION(mPendingSheetCount > 0, "How'd that happen?");
|
||||
--mPendingSheetCount;
|
||||
|
||||
if (mPendingSheetCount == 0 && mDeferredLayoutStart) {
|
||||
// We might not have really started layout, since this sheet was still
|
||||
// loading. Do it now. Probably doesn't matter whether we do this
|
||||
// before or after we unblock scripts, but before feels saner. Note that
|
||||
// if mDeferredLayoutStart is true, that means any subclass StartLayout()
|
||||
// stuff that needs to happen has already happened, so we don't need to
|
||||
// worry about it.
|
||||
StartLayout(PR_FALSE);
|
||||
|
||||
// Go ahead and try to scroll to our ref if we have one
|
||||
TryToScrollToRef();
|
||||
}
|
||||
|
||||
mScriptLoader->RemoveExecuteBlocker();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -482,7 +497,6 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
||||
nsAutoString title;
|
||||
nsAutoString type;
|
||||
nsAutoString media;
|
||||
PRBool didBlock = PR_FALSE;
|
||||
|
||||
// copy to work buffer
|
||||
nsAutoString stringList(aLinkData);
|
||||
@ -621,9 +635,6 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
||||
|
||||
if (!href.IsEmpty() && !rel.IsEmpty()) {
|
||||
rv = ProcessLink(aElement, href, rel, title, type, media);
|
||||
if (rv == NS_ERROR_HTMLPARSER_BLOCK) {
|
||||
didBlock = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
href.Truncate();
|
||||
@ -638,10 +649,6 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
||||
|
||||
if (!href.IsEmpty() && !rel.IsEmpty()) {
|
||||
rv = ProcessLink(aElement, href, rel, title, type, media);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && didBlock) {
|
||||
rv = NS_ERROR_HTMLPARSER_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -710,19 +717,17 @@ nsContentSink::ProcessStyleLink(nsIContent* aElement,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIParser* parser = nsnull;
|
||||
if (kBlockByDefault) {
|
||||
parser = mParser;
|
||||
}
|
||||
|
||||
PRBool isAlternate;
|
||||
rv = mCSSLoader->LoadStyleLink(aElement, url, aTitle, aMedia, aAlternate,
|
||||
parser, this, &isAlternate);
|
||||
if (NS_SUCCEEDED(rv) && parser && !isAlternate) {
|
||||
rv = NS_ERROR_HTMLPARSER_BLOCK;
|
||||
this, &isAlternate);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!isAlternate) {
|
||||
++mPendingSheetCount;
|
||||
mScriptLoader->AddExecuteBlocker();
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -881,10 +886,25 @@ nsContentSink::RefreshIfEnabled(nsIViewManager* vm)
|
||||
}
|
||||
|
||||
void
|
||||
nsContentSink::StartLayout(PRBool aIsFrameset)
|
||||
nsContentSink::StartLayout(PRBool aIgnorePendingSheets)
|
||||
{
|
||||
if (mLayoutStarted) {
|
||||
// Nothing to do here
|
||||
return;
|
||||
}
|
||||
|
||||
mDeferredLayoutStart = PR_TRUE;
|
||||
|
||||
if (!aIgnorePendingSheets && mPendingSheetCount > 0) {
|
||||
// Bail out; we'll start layout when the sheets load
|
||||
return;
|
||||
}
|
||||
|
||||
mDeferredLayoutStart = PR_FALSE;
|
||||
|
||||
mLayoutStarted = PR_TRUE;
|
||||
mLastNotificationTime = PR_Now();
|
||||
|
||||
PRUint32 i, ns = mDocument->GetNumberOfShells();
|
||||
for (i = 0; i < ns; i++) {
|
||||
nsIPresShell *shell = mDocument->GetShellAt(i);
|
||||
|
@ -74,6 +74,7 @@ class nsIChannel;
|
||||
class nsIContent;
|
||||
class nsIViewManager;
|
||||
class nsNodeInfoManager;
|
||||
class nsScriptLoader;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
||||
@ -169,7 +170,11 @@ protected:
|
||||
|
||||
void ScrollToRef();
|
||||
nsresult RefreshIfEnabled(nsIViewManager* vm);
|
||||
void StartLayout(PRBool aIsFrameset);
|
||||
|
||||
// Start layout. If aIgnorePendingSheets is true, this will happen even if
|
||||
// we still have stylesheet loads pending. Otherwise, we'll wait until the
|
||||
// stylesheets are all done loading.
|
||||
void StartLayout(PRBool aIgnorePendingSheets);
|
||||
|
||||
PRBool IsTimeToNotify();
|
||||
|
||||
@ -219,6 +224,7 @@ protected:
|
||||
nsCOMPtr<nsIDocShell> mDocShell;
|
||||
nsCOMPtr<nsICSSLoader> mCSSLoader;
|
||||
nsRefPtr<nsNodeInfoManager> mNodeInfoManager;
|
||||
nsRefPtr<nsScriptLoader> mScriptLoader;
|
||||
|
||||
nsCOMArray<nsIScriptElement> mScriptElements;
|
||||
|
||||
@ -231,6 +237,7 @@ protected:
|
||||
PRInt32 mNotificationInterval;
|
||||
|
||||
// Time of last notification
|
||||
// Note: mLastNotificationTime is only valid once mLayoutStarted is true.
|
||||
PRTime mLastNotificationTime;
|
||||
|
||||
// Timer used for notification
|
||||
@ -255,6 +262,8 @@ protected:
|
||||
PRUint8 mDroppedTimer : 1;
|
||||
PRUint8 mInTitle : 1;
|
||||
PRUint8 mChangeScrollPosWhenScrollingToRef : 1;
|
||||
// If true, we deferred starting layout until sheets load
|
||||
PRUint8 mDeferredLayoutStart : 1;
|
||||
|
||||
// -- Can interrupt parsing members --
|
||||
PRUint32 mDelayTimerStart;
|
||||
@ -275,6 +284,8 @@ protected:
|
||||
|
||||
PRInt32 mInNotification;
|
||||
|
||||
PRUint32 mPendingSheetCount;
|
||||
|
||||
// Measures content model creation time for current document
|
||||
MOZ_TIMER_DECLARE(mWatch)
|
||||
};
|
||||
|
@ -110,10 +110,8 @@ nsStyleLinkElement::GetStyleSheet(nsIStyleSheet*& aStyleSheet)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStyleLinkElement::InitStyleLinkElement(nsIParser* aParser,
|
||||
PRBool aDontLoadStyle)
|
||||
nsStyleLinkElement::InitStyleLinkElement(PRBool aDontLoadStyle)
|
||||
{
|
||||
mParser = aParser;
|
||||
mDontLoadStyle = aDontLoadStyle;
|
||||
|
||||
return NS_OK;
|
||||
@ -197,17 +195,33 @@ void nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ALLOW_ASYNCH_STYLE_SHEETS
|
||||
const PRBool kBlockByDefault=PR_FALSE;
|
||||
#else
|
||||
const PRBool kBlockByDefault=PR_TRUE;
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStyleLinkElement::UpdateStyleSheet(nsIDocument *aOldDocument,
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
PRBool aForceUpdate)
|
||||
nsStyleLinkElement::UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
|
||||
PRBool* aWillNotify,
|
||||
PRBool* aIsAlternate)
|
||||
{
|
||||
return DoUpdateStyleSheet(nsnull, aObserver, aWillNotify, aIsAlternate,
|
||||
PR_FALSE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsStyleLinkElement::UpdateStyleSheetInternal(nsIDocument *aOldDocument,
|
||||
PRBool aForceUpdate)
|
||||
{
|
||||
PRBool notify, alternate;
|
||||
return DoUpdateStyleSheet(aOldDocument, nsnull, ¬ify, &alternate,
|
||||
aForceUpdate);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument *aOldDocument,
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
PRBool* aWillNotify,
|
||||
PRBool* aIsAlternate,
|
||||
PRBool aForceUpdate)
|
||||
{
|
||||
*aWillNotify = PR_FALSE;
|
||||
|
||||
if (mStyleSheet && aOldDocument) {
|
||||
// We're removing the link element from the document, unload the
|
||||
// stylesheet. We want to do this even if updates are disabled, since
|
||||
@ -223,13 +237,6 @@ nsStyleLinkElement::UpdateStyleSheet(nsIDocument *aOldDocument,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Keep a strong ref to the parser so it's still around when we pass it
|
||||
// to the CSS loader. Release strong ref in mParser so we don't hang on
|
||||
// to the parser once we start the load or if we fail to load the
|
||||
// stylesheet.
|
||||
nsCOMPtr<nsIParser> parser = mParser;
|
||||
mParser = nsnull;
|
||||
|
||||
nsCOMPtr<nsIContent> thisContent;
|
||||
QueryInterface(NS_GET_IID(nsIContent), getter_AddRefs(thisContent));
|
||||
|
||||
@ -278,11 +285,7 @@ nsStyleLinkElement::UpdateStyleSheet(nsIDocument *aOldDocument,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!kBlockByDefault) {
|
||||
parser = nsnull;
|
||||
}
|
||||
|
||||
PRBool doneLoading;
|
||||
PRBool doneLoading = PR_FALSE;
|
||||
nsresult rv = NS_OK;
|
||||
if (isInline) {
|
||||
nsAutoString content;
|
||||
@ -299,20 +302,19 @@ nsStyleLinkElement::UpdateStyleSheet(nsIDocument *aOldDocument,
|
||||
// style sheet.
|
||||
rv = doc->CSSLoader()->
|
||||
LoadInlineStyle(thisContent, uin, mLineNumber, title, media,
|
||||
parser, aObserver, &doneLoading, &isAlternate);
|
||||
aObserver, &doneLoading, &isAlternate);
|
||||
}
|
||||
else {
|
||||
doneLoading = PR_FALSE; // If rv is success, we won't be done loading; if
|
||||
// it's not, this value doesn't matter.
|
||||
rv = doc->CSSLoader()->
|
||||
LoadStyleLink(thisContent, uri, title, media, isAlternate,
|
||||
parser, aObserver, &isAlternate);
|
||||
LoadStyleLink(thisContent, uri, title, media, isAlternate, aObserver,
|
||||
&isAlternate);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && !doneLoading && !isAlternate) {
|
||||
rv = NS_ERROR_HTMLPARSER_BLOCK;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return rv;
|
||||
*aWillNotify = !doneLoading;
|
||||
*aIsAlternate = isAlternate;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,6 @@
|
||||
#include "nsIDOMLinkStyle.h"
|
||||
#include "nsIStyleSheetLinkingElement.h"
|
||||
#include "nsIStyleSheet.h"
|
||||
#include "nsIParser.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
class nsIDocument;
|
||||
@ -71,26 +70,10 @@ public:
|
||||
// nsIStyleSheetLinkingElement
|
||||
NS_IMETHOD SetStyleSheet(nsIStyleSheet* aStyleSheet);
|
||||
NS_IMETHOD GetStyleSheet(nsIStyleSheet*& aStyleSheet);
|
||||
NS_IMETHOD InitStyleLinkElement(nsIParser *aParser, PRBool aDontLoadStyle);
|
||||
/**
|
||||
* @param aForceUpdate when PR_TRUE, will force the update even if
|
||||
* the URI has not changed. This should be used in cases when
|
||||
* something about the content that affects the resulting sheet
|
||||
* changed but the URI may not have changed.
|
||||
* @returns NS_ERROR_HTMLPARSER_BLOCK if a non-alternate style sheet
|
||||
* is being loaded asynchronously. In this case aObserver
|
||||
* will be notified at a later stage when the sheet is
|
||||
* loaded (if it is not null).
|
||||
* @returns NS_OK in case when the update was successful, but the
|
||||
* caller doesn't have to wait for a notification to
|
||||
* aObserver. This can happen if there was no style sheet
|
||||
* to load, when it's inline, or when it's alternate. Note
|
||||
* that in the latter case aObserver is still notified about
|
||||
* the load when it's done.
|
||||
*/
|
||||
NS_IMETHOD UpdateStyleSheet(nsIDocument *aOldDocument = nsnull,
|
||||
nsICSSLoaderObserver* aObserver = nsnull,
|
||||
PRBool aForceUpdate = PR_FALSE);
|
||||
NS_IMETHOD InitStyleLinkElement(PRBool aDontLoadStyle);
|
||||
NS_IMETHOD UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
|
||||
PRBool* aWillNotify,
|
||||
PRBool* aIsAlternate);
|
||||
NS_IMETHOD SetEnableUpdates(PRBool aEnableUpdates);
|
||||
NS_IMETHOD GetCharset(nsAString& aCharset);
|
||||
|
||||
@ -100,6 +83,17 @@ public:
|
||||
static void ParseLinkTypes(const nsAString& aTypes, nsStringArray& aResult);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @param aOldDocument should be non-null only if we're updating because we
|
||||
* removed the node from the document.
|
||||
* @param aForceUpdate PR_TRUE will force the update even if the URI has not
|
||||
* changed. This should be used in cases when something
|
||||
* about the content that affects the resulting sheet
|
||||
* changed but the URI may not have changed.
|
||||
*/
|
||||
nsresult UpdateStyleSheetInternal(nsIDocument *aOldDocument,
|
||||
PRBool aForceUpdate = PR_FALSE);
|
||||
|
||||
virtual void GetStyleSheetURL(PRBool* aIsInline,
|
||||
nsIURI** aURI) = 0;
|
||||
virtual void GetStyleSheetInfo(nsAString& aTitle,
|
||||
@ -107,9 +101,23 @@ protected:
|
||||
nsAString& aMedia,
|
||||
PRBool* aIsAlternate) = 0;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @param aOldDocument should be non-null only if we're updating because we
|
||||
* removed the node from the document.
|
||||
* @param aForceUpdate PR_TRUE will force the update even if the URI has not
|
||||
* changed. This should be used in cases when something
|
||||
* about the content that affects the resulting sheet
|
||||
* changed but the URI may not have changed.
|
||||
*/
|
||||
nsresult DoUpdateStyleSheet(nsIDocument *aOldDocument,
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
PRBool* aWillNotify,
|
||||
PRBool* aIsAlternate,
|
||||
PRBool aForceUpdate);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIStyleSheet> mStyleSheet;
|
||||
nsCOMPtr<nsIParser> mParser;
|
||||
PRPackedBool mDontLoadStyle;
|
||||
PRPackedBool mUpdatesEnabled;
|
||||
PRUint32 mLineNumber;
|
||||
|
@ -205,7 +205,7 @@ nsHTMLLinkElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
UpdateStyleSheet(nsnull);
|
||||
UpdateStyleSheetInternal(nsnull);
|
||||
|
||||
// XXXbz we really shouldn't fire the event until after we've finished with
|
||||
// the outermost BindToTree... In particular, this can effectively cause us
|
||||
@ -247,7 +247,7 @@ nsHTMLLinkElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
// event!
|
||||
CreateAndDispatchEvent(oldDoc, NS_LITERAL_STRING("DOMLinkRemoved"));
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
UpdateStyleSheet(oldDoc);
|
||||
UpdateStyleSheetInternal(oldDoc);
|
||||
}
|
||||
|
||||
void
|
||||
@ -296,12 +296,12 @@ nsHTMLLinkElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
||||
aValue, aNotify);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
UpdateStyleSheet(nsnull, nsnull,
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
(aName == nsGkAtoms::rel ||
|
||||
aName == nsGkAtoms::title ||
|
||||
aName == nsGkAtoms::media ||
|
||||
aName == nsGkAtoms::type));
|
||||
UpdateStyleSheetInternal(nsnull,
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
(aName == nsGkAtoms::rel ||
|
||||
aName == nsGkAtoms::title ||
|
||||
aName == nsGkAtoms::media ||
|
||||
aName == nsGkAtoms::type));
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -314,12 +314,12 @@ nsHTMLLinkElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute,
|
||||
aNotify);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
UpdateStyleSheet(nsnull, nsnull,
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
(aAttribute == nsGkAtoms::rel ||
|
||||
aAttribute == nsGkAtoms::title ||
|
||||
aAttribute == nsGkAtoms::media ||
|
||||
aAttribute == nsGkAtoms::type));
|
||||
UpdateStyleSheetInternal(nsnull,
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
(aAttribute == nsGkAtoms::rel ||
|
||||
aAttribute == nsGkAtoms::title ||
|
||||
aAttribute == nsGkAtoms::media ||
|
||||
aAttribute == nsGkAtoms::type));
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -196,7 +196,7 @@ nsHTMLStyleElement::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
CharacterDataChangeInfo* aInfo)
|
||||
{
|
||||
UpdateStyleSheet();
|
||||
UpdateStyleSheetInternal(nsnull);
|
||||
}
|
||||
|
||||
void
|
||||
@ -204,7 +204,7 @@ nsHTMLStyleElement::ContentAppended(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
PRInt32 aNewIndexInContainer)
|
||||
{
|
||||
UpdateStyleSheet();
|
||||
UpdateStyleSheetInternal(nsnull);
|
||||
}
|
||||
|
||||
void
|
||||
@ -213,7 +213,7 @@ nsHTMLStyleElement::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
UpdateStyleSheet();
|
||||
UpdateStyleSheetInternal(nsnull);
|
||||
}
|
||||
|
||||
void
|
||||
@ -222,7 +222,7 @@ nsHTMLStyleElement::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
UpdateStyleSheet();
|
||||
UpdateStyleSheetInternal(nsnull);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -235,7 +235,7 @@ nsHTMLStyleElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
UpdateStyleSheet(nsnull);
|
||||
UpdateStyleSheetInternal(nsnull);
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -246,7 +246,7 @@ nsHTMLStyleElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
nsCOMPtr<nsIDocument> oldDoc = GetCurrentDoc();
|
||||
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
UpdateStyleSheet(oldDoc);
|
||||
UpdateStyleSheetInternal(oldDoc);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -257,11 +257,11 @@ nsHTMLStyleElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
|
||||
aValue, aNotify);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
UpdateStyleSheet(nsnull, nsnull,
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
(aName == nsGkAtoms::title ||
|
||||
aName == nsGkAtoms::media ||
|
||||
aName == nsGkAtoms::type));
|
||||
UpdateStyleSheetInternal(nsnull,
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
(aName == nsGkAtoms::title ||
|
||||
aName == nsGkAtoms::media ||
|
||||
aName == nsGkAtoms::type));
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -274,11 +274,11 @@ nsHTMLStyleElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute,
|
||||
aNotify);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
UpdateStyleSheet(nsnull, nsnull,
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
(aAttribute == nsGkAtoms::title ||
|
||||
aAttribute == nsGkAtoms::media ||
|
||||
aAttribute == nsGkAtoms::type));
|
||||
UpdateStyleSheetInternal(nsnull,
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
(aAttribute == nsGkAtoms::title ||
|
||||
aAttribute == nsGkAtoms::media ||
|
||||
aAttribute == nsGkAtoms::type));
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -300,7 +300,7 @@ nsHTMLStyleElement::SetInnerHTML(const nsAString& aInnerHTML)
|
||||
|
||||
SetEnableUpdates(PR_TRUE);
|
||||
|
||||
UpdateStyleSheet();
|
||||
UpdateStyleSheetInternal(nsnull);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -280,7 +280,7 @@ protected:
|
||||
|
||||
nsresult FlushTags();
|
||||
|
||||
void StartLayout();
|
||||
void StartLayout(PRBool aIgnorePendingSheets);
|
||||
|
||||
/**
|
||||
* AddBaseTagInfo adds the "current" base URI and target to the content node
|
||||
@ -786,11 +786,11 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
|
||||
// Now disable updates so that every time we add an attribute or child
|
||||
// text token, we don't try to update the style sheet.
|
||||
if (!mSink->mInsideNoXXXTag) {
|
||||
ssle->InitStyleLinkElement(mSink->mParser, PR_FALSE);
|
||||
ssle->InitStyleLinkElement(PR_FALSE);
|
||||
}
|
||||
else {
|
||||
// We're not going to be evaluating this style anyway.
|
||||
ssle->InitStyleLinkElement(nsnull, PR_TRUE);
|
||||
ssle->InitStyleLinkElement(PR_TRUE);
|
||||
}
|
||||
|
||||
ssle->SetEnableUpdates(PR_FALSE);
|
||||
@ -1811,7 +1811,6 @@ HTMLContentSink::WillBuildModel(void)
|
||||
NS_IMETHODIMP
|
||||
HTMLContentSink::DidBuildModel(void)
|
||||
{
|
||||
|
||||
// NRA Dump stopwatch stop info here
|
||||
#ifdef MOZ_PERF_METRICS
|
||||
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::DidBuildModel(), this=%p\n",
|
||||
@ -1845,7 +1844,7 @@ HTMLContentSink::DidBuildModel(void)
|
||||
}
|
||||
|
||||
if (!bDestroying) {
|
||||
StartLayout();
|
||||
StartLayout(PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2095,7 +2094,7 @@ HTMLContentSink::OpenBody(const nsIParserNode& aNode)
|
||||
mCurrentContext->mStack[parentIndex].mNumFlushed = childCount;
|
||||
}
|
||||
|
||||
StartLayout();
|
||||
StartLayout(PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2293,7 +2292,7 @@ HTMLContentSink::CloseFrameset()
|
||||
MOZ_TIMER_STOP(mWatch);
|
||||
|
||||
if (done && mFramesEnabled) {
|
||||
StartLayout();
|
||||
StartLayout(PR_FALSE);
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -2810,7 +2809,7 @@ HTMLContentSink::NotifyTagObservers(nsIParserNode* aNode)
|
||||
}
|
||||
|
||||
void
|
||||
HTMLContentSink::StartLayout()
|
||||
HTMLContentSink::StartLayout(PRBool aIgnorePendingSheets)
|
||||
{
|
||||
if (mLayoutStarted) {
|
||||
return;
|
||||
@ -2818,7 +2817,7 @@ HTMLContentSink::StartLayout()
|
||||
|
||||
mHTMLDocument->SetIsFrameset(mFrameset != nsnull);
|
||||
|
||||
nsContentSink::StartLayout(mFrameset != nsnull);
|
||||
nsContentSink::StartLayout(aIgnorePendingSheets);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2967,10 +2966,10 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
|
||||
if (ssle) {
|
||||
// XXX need prefs. check here.
|
||||
if (!mInsideNoXXXTag) {
|
||||
ssle->InitStyleLinkElement(mParser, PR_FALSE);
|
||||
ssle->InitStyleLinkElement(PR_FALSE);
|
||||
ssle->SetEnableUpdates(PR_FALSE);
|
||||
} else {
|
||||
ssle->InitStyleLinkElement(nsnull, PR_TRUE);
|
||||
ssle->InitStyleLinkElement(PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2985,7 +2984,13 @@ HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
|
||||
|
||||
if (ssle) {
|
||||
ssle->SetEnableUpdates(PR_TRUE);
|
||||
result = ssle->UpdateStyleSheet(nsnull, nsnull);
|
||||
PRBool willNotify;
|
||||
PRBool isAlternate;
|
||||
result = ssle->UpdateStyleSheet(this, &willNotify, &isAlternate);
|
||||
if (NS_SUCCEEDED(result) && willNotify && !isAlternate) {
|
||||
++mPendingSheetCount;
|
||||
mScriptLoader->AddExecuteBlocker();
|
||||
}
|
||||
|
||||
// look for <link rel="next" href="url">
|
||||
nsAutoString relVal;
|
||||
@ -3175,7 +3180,13 @@ HTMLContentSink::ProcessSTYLEEndTag(nsGenericHTMLElement* content)
|
||||
// Note: if we are inside a noXXX tag, then we init'ed this style element
|
||||
// with mDontLoadStyle = PR_TRUE, so these two calls will have no effect.
|
||||
ssle->SetEnableUpdates(PR_TRUE);
|
||||
rv = ssle->UpdateStyleSheet(nsnull, nsnull);
|
||||
PRBool willNotify;
|
||||
PRBool isAlternate;
|
||||
rv = ssle->UpdateStyleSheet(this, &willNotify, &isAlternate);
|
||||
if (NS_SUCCEEDED(rv) && willNotify && !isAlternate) {
|
||||
++mPendingSheetCount;
|
||||
mScriptLoader->AddExecuteBlocker();
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -3196,7 +3207,7 @@ HTMLContentSink::FlushPendingNotifications(mozFlushType aType)
|
||||
if (aType & Flush_OnlyReflow) {
|
||||
// Make sure that layout has started so that the reflow flush
|
||||
// will actually happen.
|
||||
StartLayout();
|
||||
StartLayout(PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ nsSVGStyleElement::InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
{
|
||||
nsresult rv = nsSVGStyleElementBase::InsertChildAt(aKid, aIndex, aNotify);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
UpdateStyleSheet();
|
||||
UpdateStyleSheetInternal(nsnull);
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -160,7 +160,7 @@ nsSVGStyleElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
||||
{
|
||||
nsresult rv = nsSVGStyleElementBase::RemoveChildAt(aIndex, aNotify);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
UpdateStyleSheet();
|
||||
UpdateStyleSheetInternal(nsnull);
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -176,7 +176,7 @@ nsSVGStyleElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
UpdateStyleSheet(nsnull);
|
||||
UpdateStyleSheetInternal(nsnull);
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -187,7 +187,7 @@ nsSVGStyleElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
nsCOMPtr<nsIDocument> oldDoc = GetCurrentDoc();
|
||||
|
||||
nsSVGStyleElementBase::UnbindFromTree(aDeep, aNullParent);
|
||||
UpdateStyleSheet(oldDoc);
|
||||
UpdateStyleSheetInternal(oldDoc);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -198,11 +198,11 @@ nsSVGStyleElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsresult rv = nsSVGStyleElementBase::SetAttr(aNameSpaceID, aName, aPrefix,
|
||||
aValue, aNotify);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
UpdateStyleSheet(nsnull, nsnull,
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
(aName == nsGkAtoms::title ||
|
||||
aName == nsGkAtoms::media ||
|
||||
aName == nsGkAtoms::type));
|
||||
UpdateStyleSheetInternal(nsnull,
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
(aName == nsGkAtoms::title ||
|
||||
aName == nsGkAtoms::media ||
|
||||
aName == nsGkAtoms::type));
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -215,11 +215,11 @@ nsSVGStyleElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
nsresult rv = nsSVGStyleElementBase::UnsetAttr(aNameSpaceID, aAttribute,
|
||||
aNotify);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
UpdateStyleSheet(nsnull, nsnull,
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
(aAttribute == nsGkAtoms::title ||
|
||||
aAttribute == nsGkAtoms::media ||
|
||||
aAttribute == nsGkAtoms::type));
|
||||
UpdateStyleSheetInternal(nsnull,
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
(aAttribute == nsGkAtoms::title ||
|
||||
aAttribute == nsGkAtoms::media ||
|
||||
aAttribute == nsGkAtoms::type));
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -111,7 +111,7 @@ nsXBLContentSink::Init(nsIDocument* aDoc,
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLContentSink::MaybeStartLayout()
|
||||
nsXBLContentSink::MaybeStartLayout(PRBool aIgnorePendingSheets)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ public:
|
||||
|
||||
protected:
|
||||
// nsXMLContentSink overrides
|
||||
void MaybeStartLayout();
|
||||
virtual void MaybeStartLayout(PRBool aIgnorePendingSheets);
|
||||
|
||||
PRBool OnOpenContainer(const PRUnichar **aAtts,
|
||||
PRUint32 aAttsCount,
|
||||
|
@ -122,7 +122,7 @@ nsXMLStylesheetPI::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
UpdateStyleSheet(nsnull);
|
||||
UpdateStyleSheetInternal(nsnull);
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -133,7 +133,7 @@ nsXMLStylesheetPI::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
nsCOMPtr<nsIDocument> oldDoc = GetCurrentDoc();
|
||||
|
||||
nsXMLProcessingInstruction::UnbindFromTree(aDeep, aNullParent);
|
||||
UpdateStyleSheet(oldDoc);
|
||||
UpdateStyleSheetInternal(oldDoc);
|
||||
}
|
||||
|
||||
// nsIDOMNode
|
||||
@ -143,7 +143,7 @@ nsXMLStylesheetPI::SetNodeValue(const nsAString& aNodeValue)
|
||||
{
|
||||
nsresult rv = nsGenericDOMDataNode::SetNodeValue(aNodeValue);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
UpdateStyleSheet(nsnull, nsnull, PR_TRUE);
|
||||
UpdateStyleSheetInternal(nsnull, PR_TRUE);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -343,7 +343,7 @@ nsXMLContentSink::DidBuildModel()
|
||||
// Check if we want to prettyprint
|
||||
MaybePrettyPrint();
|
||||
|
||||
StartLayout();
|
||||
StartLayout(PR_FALSE);
|
||||
|
||||
ScrollToRef();
|
||||
|
||||
@ -424,7 +424,7 @@ nsXMLContentSink::OnTransformDone(nsresult aResult,
|
||||
}
|
||||
|
||||
// Start the layout process
|
||||
StartLayout();
|
||||
StartLayout(PR_FALSE);
|
||||
|
||||
ScrollToRef();
|
||||
|
||||
@ -520,7 +520,7 @@ nsXMLContentSink::CreateElement(const PRUnichar** aAtts, PRUint32 aAttsCount,
|
||||
aNodeInfo->Equals(nsGkAtoms::style, kNameSpaceID_SVG)) {
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(content));
|
||||
if (ssle) {
|
||||
ssle->InitStyleLinkElement(mParser, PR_FALSE);
|
||||
ssle->InitStyleLinkElement(PR_FALSE);
|
||||
ssle->SetEnableUpdates(PR_FALSE);
|
||||
if (!aNodeInfo->Equals(nsGkAtoms::link, kNameSpaceID_XHTML)) {
|
||||
ssle->SetLineNumber(aLineNumber);
|
||||
@ -626,9 +626,12 @@ nsXMLContentSink::CloseElement(nsIContent* aContent)
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(aContent));
|
||||
if (ssle) {
|
||||
ssle->SetEnableUpdates(PR_TRUE);
|
||||
rv = ssle->UpdateStyleSheet(nsnull, nsnull);
|
||||
if (rv == NS_ERROR_HTMLPARSER_BLOCK && mParser) {
|
||||
mParser->BlockParser();
|
||||
PRBool willNotify;
|
||||
PRBool isAlternate;
|
||||
rv = ssle->UpdateStyleSheet(this, &willNotify, &isAlternate);
|
||||
if (NS_SUCCEEDED(rv) && willNotify && !isAlternate) {
|
||||
++mPendingSheetCount;
|
||||
mScriptLoader->AddExecuteBlocker();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -747,13 +750,9 @@ nsXMLContentSink::ProcessStyleLink(nsIContent* aElement,
|
||||
rv = nsContentSink::ProcessStyleLink(aElement, aHref, aAlternate,
|
||||
aTitle, aType, aMedia);
|
||||
|
||||
if (rv == NS_ERROR_HTMLPARSER_BLOCK) {
|
||||
if (mParser) {
|
||||
mParser->BlockParser();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsContentSink::ProcessStyleLink handles the bookkeeping here wrt
|
||||
// pending sheets.
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -874,32 +873,14 @@ nsXMLContentSink::PopContent()
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLContentSink::MaybeStartLayout()
|
||||
nsXMLContentSink::MaybeStartLayout(PRBool aIgnorePendingSheets)
|
||||
{
|
||||
// XXXbz if aIgnorePendingSheets is true, what should we do when
|
||||
// mXSLTProcessor or CanStillPrettyPrint()?
|
||||
if (mLayoutStarted || mXSLTProcessor || CanStillPrettyPrint()) {
|
||||
return;
|
||||
}
|
||||
StartLayout();
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLContentSink::StartLayout()
|
||||
{
|
||||
if (mLayoutStarted) {
|
||||
return;
|
||||
}
|
||||
PRBool topLevelFrameset = PR_FALSE;
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
|
||||
if (docShellAsItem) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> root;
|
||||
docShellAsItem->GetSameTypeRootTreeItem(getter_AddRefs(root));
|
||||
if(docShellAsItem == root) {
|
||||
topLevelFrameset = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
nsContentSink::StartLayout(topLevelFrameset);
|
||||
|
||||
StartLayout(aIgnorePendingSheets);
|
||||
}
|
||||
|
||||
#ifdef MOZ_MATHML
|
||||
@ -1055,7 +1036,7 @@ nsXMLContentSink::HandleStartElement(const PRUnichar *aName,
|
||||
mInMonolithicContainer++;
|
||||
}
|
||||
|
||||
MaybeStartLayout();
|
||||
MaybeStartLayout(PR_FALSE);
|
||||
|
||||
return NS_SUCCEEDED(result) ? DidProcessATokenImpl() : result;
|
||||
}
|
||||
@ -1251,7 +1232,7 @@ nsXMLContentSink::HandleProcessingInstruction(const PRUnichar *aTarget,
|
||||
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(node));
|
||||
if (ssle) {
|
||||
ssle->InitStyleLinkElement(mParser, PR_FALSE);
|
||||
ssle->InitStyleLinkElement(PR_FALSE);
|
||||
ssle->SetEnableUpdates(PR_FALSE);
|
||||
mPrettyPrintXML = PR_FALSE;
|
||||
}
|
||||
@ -1261,14 +1242,22 @@ nsXMLContentSink::HandleProcessingInstruction(const PRUnichar *aTarget,
|
||||
DidAddContent();
|
||||
|
||||
if (ssle) {
|
||||
// This is an xml-stylesheet processing instruction... but it might not be
|
||||
// a CSS one if the type is set to something else.
|
||||
ssle->SetEnableUpdates(PR_TRUE);
|
||||
rv = ssle->UpdateStyleSheet(nsnull, nsnull);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv == NS_ERROR_HTMLPARSER_BLOCK && mParser) {
|
||||
mParser->BlockParser();
|
||||
PRBool willNotify;
|
||||
PRBool isAlternate;
|
||||
rv = ssle->UpdateStyleSheet(this, &willNotify, &isAlternate);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (willNotify) {
|
||||
// Successfully started a stylesheet load
|
||||
if (!isAlternate) {
|
||||
++mPendingSheetCount;
|
||||
mScriptLoader->AddExecuteBlocker();
|
||||
}
|
||||
return rv;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1278,6 +1267,7 @@ nsXMLContentSink::HandleProcessingInstruction(const PRUnichar *aTarget,
|
||||
|
||||
if (mState != eXMLContentSinkState_InProlog ||
|
||||
!target.EqualsLiteral("xml-stylesheet") ||
|
||||
type.IsEmpty() ||
|
||||
type.LowerCaseEqualsLiteral("text/css")) {
|
||||
return DidProcessATokenImpl();
|
||||
}
|
||||
@ -1520,7 +1510,7 @@ nsXMLContentSink::FlushPendingNotifications(mozFlushType aType)
|
||||
if (aType & Flush_OnlyReflow) {
|
||||
// Make sure that layout has started so that the reflow flush
|
||||
// will actually happen.
|
||||
MaybeStartLayout();
|
||||
MaybeStartLayout(PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,8 +106,10 @@ public:
|
||||
PRBool &aIsAlternate);
|
||||
|
||||
protected:
|
||||
virtual void MaybeStartLayout();
|
||||
void StartLayout();
|
||||
// Start layout. If aIgnorePendingSheets is true, this will happen even if
|
||||
// we still have stylesheet loads pending. Otherwise, we'll wait until the
|
||||
// stylesheets are all done loading.
|
||||
virtual void MaybeStartLayout(PRBool aIgnorePendingSheets);
|
||||
|
||||
virtual nsresult AddAttributes(const PRUnichar** aNode, nsIContent* aContent);
|
||||
nsresult AddText(const PRUnichar* aString, PRInt32 aLength);
|
||||
|
@ -114,7 +114,7 @@ protected:
|
||||
nsIContent** aResult, PRBool* aAppendContent);
|
||||
virtual nsresult CloseElement(nsIContent* aContent);
|
||||
|
||||
void MaybeStartLayout();
|
||||
virtual void MaybeStartLayout(PRBool aIgnorePendingSheets);
|
||||
|
||||
// nsContentSink overrides
|
||||
virtual nsresult ProcessStyleLink(nsIContent* aElement,
|
||||
@ -265,7 +265,7 @@ nsXMLFragmentContentSink::CloseElement(nsIContent* aContent)
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLFragmentContentSink::MaybeStartLayout()
|
||||
nsXMLFragmentContentSink::MaybeStartLayout(PRBool aIgnorePendingSheets)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -349,14 +349,12 @@ txMozillaXMLOutput::endElement()
|
||||
do_QueryInterface(mCurrentNode);
|
||||
if (ssle) {
|
||||
ssle->SetEnableUpdates(PR_TRUE);
|
||||
if (ssle->UpdateStyleSheet(nsnull, mNotifier) ==
|
||||
NS_ERROR_HTMLPARSER_BLOCK) {
|
||||
nsCOMPtr<nsIStyleSheet> stylesheet;
|
||||
ssle->GetStyleSheet(*getter_AddRefs(stylesheet));
|
||||
if (mNotifier) {
|
||||
rv = mNotifier->AddStyleSheet(stylesheet);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
PRBool willNotify;
|
||||
PRBool isAlternate;
|
||||
nsresult rv = ssle->UpdateStyleSheet(mNotifier, &willNotify,
|
||||
&isAlternate);
|
||||
if (mNotifier && NS_SUCCEEDED(rv) && willNotify && !isAlternate) {
|
||||
mNotifier->AddPendingStylesheet();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -421,7 +419,7 @@ txMozillaXMLOutput::processingInstruction(const nsString& aTarget, const nsStrin
|
||||
if (mCreatingNewDocument) {
|
||||
ssle = do_QueryInterface(pi);
|
||||
if (ssle) {
|
||||
ssle->InitStyleLinkElement(nsnull, PR_FALSE);
|
||||
ssle->InitStyleLinkElement(PR_FALSE);
|
||||
ssle->SetEnableUpdates(PR_FALSE);
|
||||
}
|
||||
}
|
||||
@ -431,14 +429,11 @@ txMozillaXMLOutput::processingInstruction(const nsString& aTarget, const nsStrin
|
||||
|
||||
if (ssle) {
|
||||
ssle->SetEnableUpdates(PR_TRUE);
|
||||
rv = ssle->UpdateStyleSheet(nsnull, mNotifier);
|
||||
if (rv == NS_ERROR_HTMLPARSER_BLOCK) {
|
||||
nsCOMPtr<nsIStyleSheet> stylesheet;
|
||||
ssle->GetStyleSheet(*getter_AddRefs(stylesheet));
|
||||
if (mNotifier) {
|
||||
rv = mNotifier->AddStyleSheet(stylesheet);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
PRBool willNotify;
|
||||
PRBool isAlternate;
|
||||
rv = ssle->UpdateStyleSheet(mNotifier, &willNotify, &isAlternate);
|
||||
if (mNotifier && NS_SUCCEEDED(rv) && willNotify && !isAlternate) {
|
||||
mNotifier->AddPendingStylesheet();
|
||||
}
|
||||
}
|
||||
|
||||
@ -580,7 +575,7 @@ txMozillaXMLOutput::startElementInternal(nsIAtom* aPrefix,
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
|
||||
do_QueryInterface(mOpenedElement);
|
||||
if (ssle) {
|
||||
ssle->InitStyleLinkElement(nsnull, PR_FALSE);
|
||||
ssle->InitStyleLinkElement(PR_FALSE);
|
||||
ssle->SetEnableUpdates(PR_FALSE);
|
||||
}
|
||||
}
|
||||
@ -1003,8 +998,8 @@ txMozillaXMLOutput::createHTMLElement(nsIAtom* aName,
|
||||
}
|
||||
|
||||
txTransformNotifier::txTransformNotifier()
|
||||
: mInTransform(PR_FALSE)
|
||||
|
||||
: mPendingStylesheetCount(0),
|
||||
mInTransform(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1048,15 +1043,19 @@ txTransformNotifier::StyleSheetLoaded(nsICSSStyleSheet* aSheet,
|
||||
PRBool aWasAlternate,
|
||||
nsresult aStatus)
|
||||
{
|
||||
// Check that the stylesheet was in the mStylesheets array, if not it is an
|
||||
// alternate and we don't want to call SignalTransformEnd since we don't
|
||||
// wait on alternates before calling OnTransformDone and so the load of the
|
||||
// alternate could finish after we called OnTransformDone already.
|
||||
// See http://bugzilla.mozilla.org/show_bug.cgi?id=215465.
|
||||
if (mStylesheets.RemoveObject(aSheet)) {
|
||||
SignalTransformEnd();
|
||||
if (mPendingStylesheetCount == 0) {
|
||||
// We weren't waiting on this stylesheet anyway. This can happen if
|
||||
// SignalTransformEnd got called with an error aResult. See
|
||||
// http://bugzilla.mozilla.org/show_bug.cgi?id=215465.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We're never waiting for alternate stylesheets
|
||||
if (!aWasAlternate) {
|
||||
--mPendingStylesheetCount;
|
||||
SignalTransformEnd();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1073,11 +1072,10 @@ txTransformNotifier::AddScriptElement(nsIScriptElement* aElement)
|
||||
NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsresult
|
||||
txTransformNotifier::AddStyleSheet(nsIStyleSheet* aStyleSheet)
|
||||
void
|
||||
txTransformNotifier::AddPendingStylesheet()
|
||||
{
|
||||
return mStylesheets.AppendObject(aStyleSheet) ? NS_OK :
|
||||
NS_ERROR_OUT_OF_MEMORY;
|
||||
++mPendingStylesheetCount;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1106,11 +1104,14 @@ void
|
||||
txTransformNotifier::SignalTransformEnd(nsresult aResult)
|
||||
{
|
||||
if (mInTransform || (NS_SUCCEEDED(aResult) &&
|
||||
mScriptElements.Count() > 0 || mStylesheets.Count() > 0)) {
|
||||
mScriptElements.Count() > 0 || mPendingStylesheetCount > 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mStylesheets.Clear();
|
||||
// mPendingStylesheetCount is nonzero at this point only if aResult is an
|
||||
// error. Set it to 0 so we won't reenter this code when we stop the
|
||||
// CSSLoader.
|
||||
mPendingStylesheetCount = 0;
|
||||
mScriptElements.Clear();
|
||||
|
||||
// Make sure that we don't get deleted while this function is executed and
|
||||
|
@ -76,7 +76,7 @@ public:
|
||||
|
||||
void Init(nsITransformObserver* aObserver);
|
||||
nsresult AddScriptElement(nsIScriptElement* aElement);
|
||||
nsresult AddStyleSheet(nsIStyleSheet* aStyleSheet);
|
||||
void AddPendingStylesheet();
|
||||
void OnTransformEnd(nsresult aResult = NS_OK);
|
||||
void OnTransformStart();
|
||||
nsresult SetOutputDocument(nsIDocument* aDocument);
|
||||
@ -87,7 +87,7 @@ private:
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
nsCOMPtr<nsITransformObserver> mObserver;
|
||||
nsCOMArray<nsIScriptElement> mScriptElements;
|
||||
nsCOMArray<nsIStyleSheet> mStylesheets;
|
||||
PRUint32 mPendingStylesheetCount;
|
||||
PRPackedBool mInTransform;
|
||||
};
|
||||
|
||||
|
@ -50,9 +50,6 @@
|
||||
#include "nsXULContentSink.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsForwardReference.h"
|
||||
#include "nsICSSLoader.h"
|
||||
#include "nsICSSParser.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
#include "nsIContentSink.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
@ -369,10 +366,8 @@ XULContentSinkImpl::Init(nsIDocument* aDocument,
|
||||
preferredStyle);
|
||||
}
|
||||
|
||||
// Get the CSS loader from the document so we can load
|
||||
// stylesheets
|
||||
mCSSLoader = aDocument->CSSLoader();
|
||||
mCSSLoader->SetPreferredSheet(preferredStyle);
|
||||
// Set the right preferred style on the document's CSSLoader.
|
||||
aDocument->CSSLoader()->SetPreferredSheet(preferredStyle);
|
||||
|
||||
mNodeInfoManager = aPrototype->GetNodeInfoManager();
|
||||
if (! mNodeInfoManager)
|
||||
|
@ -49,8 +49,6 @@
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsWeakPtr.h"
|
||||
|
||||
class nsICSSLoader;
|
||||
class nsICSSParser;
|
||||
class nsIDocument;
|
||||
class nsIScriptSecurityManager;
|
||||
class nsAttrName;
|
||||
@ -173,8 +171,6 @@ protected:
|
||||
|
||||
// We use regular pointer b/c of funky exports on nsIParser:
|
||||
nsIParser* mParser; // [OWNER]
|
||||
nsCOMPtr<nsICSSLoader> mCSSLoader; // [OWNER]
|
||||
nsCOMPtr<nsICSSParser> mCSSParser; // [OWNER]
|
||||
nsCOMPtr<nsIScriptSecurityManager> mSecMan;
|
||||
};
|
||||
|
||||
|
@ -2514,7 +2514,7 @@ nsXULDocument::InsertXMLStylesheetPI(const nsXULPrototypePI* aProtoPI,
|
||||
|
||||
nsresult rv;
|
||||
|
||||
ssle->InitStyleLinkElement(nsnull, PR_FALSE);
|
||||
ssle->InitStyleLinkElement(PR_FALSE);
|
||||
// We want to be notified when the style sheet finishes loading, so
|
||||
// disable style sheet loading for now.
|
||||
ssle->SetEnableUpdates(PR_FALSE);
|
||||
@ -2527,12 +2527,11 @@ nsXULDocument::InsertXMLStylesheetPI(const nsXULPrototypePI* aProtoPI,
|
||||
|
||||
// load the stylesheet if necessary, passing ourselves as
|
||||
// nsICSSObserver
|
||||
rv = ssle->UpdateStyleSheet(nsnull, this);
|
||||
if (rv == NS_ERROR_HTMLPARSER_BLOCK) {
|
||||
PRBool willNotify;
|
||||
PRBool isAlternate;
|
||||
rv = ssle->UpdateStyleSheet(this, &willNotify, &isAlternate);
|
||||
if (NS_SUCCEEDED(rv) && willNotify && !isAlternate) {
|
||||
++mPendingSheets;
|
||||
rv = NS_OK;
|
||||
} else if (NS_FAILED(rv)) {
|
||||
rv = NS_OK;
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -2878,7 +2877,10 @@ nsXULDocument::ResumeWalk()
|
||||
do_QueryInterface(element);
|
||||
NS_ASSERTION(ssle, "<html:style> doesn't implement "
|
||||
"nsIStyleSheetLinkingElement?");
|
||||
ssle->UpdateStyleSheet(nsnull, nsnull);
|
||||
PRBool willNotify;
|
||||
PRBool isAlternate;
|
||||
ssle->UpdateStyleSheet(nsnull, &willNotify,
|
||||
&isAlternate);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,6 @@
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIParser.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -144,7 +143,6 @@ NS_IMPL_ISUPPORTS2(SheetLoadData, nsIUnicharStreamLoaderObserver, nsIRunnable)
|
||||
|
||||
SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader,
|
||||
const nsSubstring& aTitle,
|
||||
nsIParser* aParserToUnblock,
|
||||
nsIURI* aURI,
|
||||
nsICSSStyleSheet* aSheet,
|
||||
nsIStyleSheetLinkingElement* aOwningElement,
|
||||
@ -152,7 +150,6 @@ SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader,
|
||||
nsICSSLoaderObserver* aObserver)
|
||||
: mLoader(aLoader),
|
||||
mTitle(aTitle),
|
||||
mParserToUnblock(aParserToUnblock),
|
||||
mURI(aURI),
|
||||
mLineNumber(1),
|
||||
mSheet(aSheet),
|
||||
@ -180,7 +177,6 @@ SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader,
|
||||
SheetLoadData* aParentData,
|
||||
nsICSSLoaderObserver* aObserver)
|
||||
: mLoader(aLoader),
|
||||
mParserToUnblock(nsnull),
|
||||
mURI(aURI),
|
||||
mLineNumber(1),
|
||||
mSheet(aSheet),
|
||||
@ -216,7 +212,6 @@ SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader,
|
||||
PRBool aAllowUnsafeRules,
|
||||
nsICSSLoaderObserver* aObserver)
|
||||
: mLoader(aLoader),
|
||||
mParserToUnblock(nsnull),
|
||||
mURI(aURI),
|
||||
mLineNumber(1),
|
||||
mSheet(aSheet),
|
||||
@ -1117,8 +1112,6 @@ CSSLoaderImpl::InsertSheetInDoc(nsICSSStyleSheet* aSheet,
|
||||
NS_PRECONDITION(aSheet, "Nothing to insert");
|
||||
NS_PRECONDITION(aDocument, "Must have a document to insert into");
|
||||
|
||||
// all nodes that link in sheets should be implementing nsIDOM3Node
|
||||
|
||||
// XXX Need to cancel pending sheet loads for this element, if any
|
||||
|
||||
PRInt32 sheetCount = aDocument->GetNumberOfStyleSheets();
|
||||
@ -1466,6 +1459,36 @@ void
|
||||
CSSLoaderImpl::SheetComplete(SheetLoadData* aLoadData, nsresult aStatus)
|
||||
{
|
||||
LOG(("CSSLoaderImpl::SheetComplete"));
|
||||
|
||||
// 8 is probably big enough for all our common cases. It's not likely that
|
||||
// imports will nest more than 8 deep, and multiple sheets with the same URI
|
||||
// are rare.
|
||||
nsAutoTArray<nsRefPtr<SheetLoadData>, 8> datasToNotify;
|
||||
DoSheetComplete(aLoadData, aStatus, datasToNotify);
|
||||
|
||||
// Now it's safe to go ahead and notify observers
|
||||
PRUint32 count = datasToNotify.Length();
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
SheetLoadData* data = datasToNotify[i];
|
||||
NS_ASSERTION(data && data->mMustNotify && data->mObserver,
|
||||
"How did this data get here?");
|
||||
LOG((" Notifying observer 0x%x for data 0x%s. wasAlternate: %d",
|
||||
data->mObserver.get(), data, data->mWasAlternate));
|
||||
data->mObserver->StyleSheetLoaded(data->mSheet, data->mWasAlternate,
|
||||
aStatus);
|
||||
}
|
||||
|
||||
if (mLoadingDatas.Count() == 0 && mPendingDatas.Count() > 0) {
|
||||
LOG((" No more loading sheets; starting alternates"));
|
||||
mPendingDatas.Enumerate(StartAlternateLoads, this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CSSLoaderImpl::DoSheetComplete(SheetLoadData* aLoadData, nsresult aStatus,
|
||||
LoadDataArray& aDatasToNotify)
|
||||
{
|
||||
LOG(("CSSLoaderImpl::DoSheetComplete"));
|
||||
NS_PRECONDITION(aLoadData, "Must have a load data!");
|
||||
NS_PRECONDITION(aLoadData->mSheet, "Must have a sheet");
|
||||
NS_ASSERTION(mLoadingDatas.IsInitialized(),"mLoadingDatas should be initialized by now.");
|
||||
@ -1489,16 +1512,6 @@ CSSLoaderImpl::SheetComplete(SheetLoadData* aLoadData, nsresult aStatus)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This is a mess. If we have a document.write() that writes out
|
||||
// two <link> elements pointing to the same url, we will actually
|
||||
// end up blocking the same parser twice. This seems very wrong --
|
||||
// if we blocked it the first time, why is more stuff getting
|
||||
// written?? In any case, we only want to unblock it once.
|
||||
// Otherwise we get icky things like crashes in layout... We need
|
||||
// to stop blocking the parser. We really do.
|
||||
PRBool seenParser = PR_FALSE;
|
||||
|
||||
// Go through and deal with the whole linked list.
|
||||
SheetLoadData* data = aLoadData;
|
||||
while (data) {
|
||||
@ -1506,20 +1519,12 @@ CSSLoaderImpl::SheetComplete(SheetLoadData* aLoadData, nsresult aStatus)
|
||||
data->mSheet->SetModified(PR_FALSE); // it's clean
|
||||
data->mSheet->SetComplete();
|
||||
if (data->mMustNotify && data->mObserver) {
|
||||
data->mObserver->StyleSheetLoaded(data->mSheet, data->mWasAlternate,
|
||||
aStatus);
|
||||
}
|
||||
// Don't notify here so we don't trigger script. Remember the
|
||||
// info we need to notify, then do it later when it's safe.
|
||||
aDatasToNotify.AppendElement(data);
|
||||
|
||||
// Only unblock the parser if mMustNotify is true (so we're not being
|
||||
// called synchronously from LoadSheet) and mWasAlternate is false.
|
||||
if (data->mParserToUnblock) {
|
||||
LOG(("Parser to unblock: %p", data->mParserToUnblock.get()));
|
||||
if (!seenParser && data->mMustNotify && !data->mWasAlternate) {
|
||||
LOG(("Unblocking parser: %p", data->mParserToUnblock.get()));
|
||||
seenParser = PR_TRUE;
|
||||
data->mParserToUnblock->ContinueParsing();
|
||||
}
|
||||
data->mParserToUnblock = nsnull; // drop the ref, just in case
|
||||
// On append failure, just press on. We'll fail to notify the observer,
|
||||
// but not much we can do about that....
|
||||
}
|
||||
|
||||
NS_ASSERTION(!data->mParentData ||
|
||||
@ -1534,7 +1539,7 @@ CSSLoaderImpl::SheetComplete(SheetLoadData* aLoadData, nsresult aStatus)
|
||||
if (data->mParentData &&
|
||||
--(data->mParentData->mPendingChildren) == 0 &&
|
||||
mParsingDatas.IndexOf(data->mParentData) == -1) {
|
||||
SheetComplete(data->mParentData, aStatus);
|
||||
DoSheetComplete(data->mParentData, aStatus, aDatasToNotify);
|
||||
}
|
||||
|
||||
data = data->mNext;
|
||||
@ -1561,10 +1566,6 @@ CSSLoaderImpl::SheetComplete(SheetLoadData* aLoadData, nsresult aStatus)
|
||||
}
|
||||
|
||||
NS_RELEASE(aLoadData); // this will release parents and siblings and all that
|
||||
if (mLoadingDatas.Count() == 0 && mPendingDatas.Count() > 0) {
|
||||
LOG((" No more loading sheets; starting alternates"));
|
||||
mPendingDatas.Enumerate(StartAlternateLoads, this);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1573,11 +1574,9 @@ CSSLoaderImpl::LoadInlineStyle(nsIContent* aElement,
|
||||
PRUint32 aLineNumber,
|
||||
const nsSubstring& aTitle,
|
||||
const nsSubstring& aMedia,
|
||||
nsIParser* aParserToUnblock,
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
PRBool* aCompleted,
|
||||
PRBool* aIsAlternate)
|
||||
|
||||
{
|
||||
LOG(("CSSLoaderImpl::LoadInlineStyle"));
|
||||
NS_PRECONDITION(aStream, "Must have a stream to parse!");
|
||||
@ -1612,9 +1611,9 @@ CSSLoaderImpl::LoadInlineStyle(nsIContent* aElement,
|
||||
rv = InsertSheetInDoc(sheet, aElement, mDocument);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
SheetLoadData* data = new SheetLoadData(this, aTitle, aParserToUnblock,
|
||||
nsnull, sheet, owningElement,
|
||||
*aIsAlternate, aObserver);
|
||||
SheetLoadData* data = new SheetLoadData(this, aTitle, nsnull, sheet,
|
||||
owningElement, *aIsAlternate,
|
||||
aObserver);
|
||||
|
||||
if (!data) {
|
||||
sheet->SetComplete();
|
||||
@ -1640,7 +1639,6 @@ CSSLoaderImpl::LoadStyleLink(nsIContent* aElement,
|
||||
const nsSubstring& aTitle,
|
||||
const nsSubstring& aMedia,
|
||||
PRBool aHasAlternateRel,
|
||||
nsIParser* aParserToUnblock,
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
PRBool* aIsAlternate)
|
||||
{
|
||||
@ -1691,15 +1689,19 @@ CSSLoaderImpl::LoadStyleLink(nsIContent* aElement,
|
||||
if (state == eSheetComplete) {
|
||||
LOG((" Sheet already complete: 0x%p",
|
||||
NS_STATIC_CAST(void*, sheet.get())));
|
||||
return PostLoadEvent(aURL, sheet, aObserver, aParserToUnblock,
|
||||
*aIsAlternate);
|
||||
if (aObserver) {
|
||||
rv = PostLoadEvent(aURL, sheet, aObserver, *aIsAlternate);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> owningElement(do_QueryInterface(aElement));
|
||||
|
||||
// Now we need to actually load it
|
||||
SheetLoadData* data = new SheetLoadData(this, aTitle, aParserToUnblock, aURL,
|
||||
sheet, owningElement, *aIsAlternate,
|
||||
SheetLoadData* data = new SheetLoadData(this, aTitle, aURL, sheet,
|
||||
owningElement, *aIsAlternate,
|
||||
aObserver);
|
||||
if (!data) {
|
||||
sheet->SetComplete();
|
||||
@ -1916,7 +1918,7 @@ CSSLoaderImpl::InternalLoadNonDocumentSheet(nsIURI* aURL,
|
||||
if (state == eSheetComplete) {
|
||||
LOG((" Sheet already complete"));
|
||||
if (aObserver) {
|
||||
rv = PostLoadEvent(aURL, sheet, aObserver, nsnull, PR_FALSE);
|
||||
rv = PostLoadEvent(aURL, sheet, aObserver, PR_FALSE);
|
||||
}
|
||||
if (aSheet) {
|
||||
sheet.swap(*aSheet);
|
||||
@ -1950,18 +1952,14 @@ nsresult
|
||||
CSSLoaderImpl::PostLoadEvent(nsIURI* aURI,
|
||||
nsICSSStyleSheet* aSheet,
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
nsIParser* aParserToUnblock,
|
||||
PRBool aWasAlternate)
|
||||
{
|
||||
LOG(("nsCSSLoader::PostLoadEvent"));
|
||||
NS_PRECONDITION(aSheet, "Must have sheet");
|
||||
// XXXbz can't assert this yet; have to post even with a null
|
||||
// observer, since we may need to unblock the parser
|
||||
// NS_PRECONDITION(aObserver, "Must have observer");
|
||||
NS_PRECONDITION(aObserver, "Must have observer");
|
||||
|
||||
nsRefPtr<SheetLoadData> evt =
|
||||
new SheetLoadData(this, EmptyString(), // title doesn't matter here
|
||||
aParserToUnblock,
|
||||
aURI,
|
||||
aSheet,
|
||||
nsnull, // owning element doesn't matter here
|
||||
|
@ -53,7 +53,6 @@
|
||||
|
||||
class CSSLoaderImpl;
|
||||
class nsIURI;
|
||||
class nsIParser;
|
||||
class nsICSSStyleSheet;
|
||||
class nsIStyleSheetLinkingElement;
|
||||
class nsICSSLoaderObserver;
|
||||
@ -113,7 +112,6 @@ public:
|
||||
// Data for loading a sheet linked from a document
|
||||
SheetLoadData(CSSLoaderImpl* aLoader,
|
||||
const nsSubstring& aTitle,
|
||||
nsIParser* aParserToUnblock,
|
||||
nsIURI* aURI,
|
||||
nsICSSStyleSheet* aSheet,
|
||||
nsIStyleSheetLinkingElement* aOwningElement,
|
||||
@ -152,9 +150,6 @@ public:
|
||||
// Charset we decided to use for the sheet
|
||||
nsCString mCharset;
|
||||
|
||||
// Parser to be told to continue parsing once the load completes
|
||||
nsCOMPtr<nsIParser> mParserToUnblock;
|
||||
|
||||
// URI we're loading. Null for inline sheets
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
|
||||
@ -261,17 +256,15 @@ public:
|
||||
PRUint32 aLineNumber,
|
||||
const nsSubstring& aTitle,
|
||||
const nsSubstring& aMedia,
|
||||
nsIParser* aParserToUnblock,
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
PRBool* aCompleted,
|
||||
PRBool* aIsAlternate);
|
||||
|
||||
NS_IMETHOD LoadStyleLink(nsIContent* aElement,
|
||||
nsIURI* aURL,
|
||||
const nsSubstring& aTitle,
|
||||
const nsSubstring& aTitle,
|
||||
const nsSubstring& aMedia,
|
||||
PRBool aHasAlternateRel,
|
||||
nsIParser* aParserToUnblock,
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
PRBool* aIsAlternate);
|
||||
|
||||
@ -357,7 +350,6 @@ private:
|
||||
nsresult PostLoadEvent(nsIURI* aURI,
|
||||
nsICSSStyleSheet* aSheet,
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
nsIParser* aParserToUnblock,
|
||||
PRBool aWasAlternate);
|
||||
public:
|
||||
// Handle an event posted by PostLoadEvent
|
||||
@ -371,17 +363,32 @@ protected:
|
||||
friend class SheetLoadData;
|
||||
|
||||
// Protected functions and members are ones that SheetLoadData needs
|
||||
// access to
|
||||
// access to.
|
||||
|
||||
// Parse the stylesheet in aLoadData. The sheet data comes from aStream.
|
||||
// Set aCompleted to true if the parse finished, false otherwise (e.g. if the
|
||||
// sheet had an @import). If aCompleted is true when this returns, then
|
||||
// ParseSheet also called SheetComplete on aLoadData
|
||||
nsresult ParseSheet(nsIUnicharInputStream* aStream,
|
||||
SheetLoadData* aLoadData,
|
||||
PRBool& aCompleted);
|
||||
|
||||
public:
|
||||
// The load of the sheet in aLoadData is done, one way or another. Do final
|
||||
// cleanup, including releasing aLoadData.
|
||||
void SheetComplete(SheetLoadData* aLoadData, nsresult aStatus);
|
||||
|
||||
private:
|
||||
typedef nsTArray<nsRefPtr<SheetLoadData> > LoadDataArray;
|
||||
|
||||
// The guts of SheetComplete. This may be called recursively on parent datas
|
||||
// or datas that had glommed on to a single load. The array is there so load
|
||||
// datas whose observers need to be notified can be added to it.
|
||||
void DoSheetComplete(SheetLoadData* aLoadData, nsresult aStatus,
|
||||
LoadDataArray& aDatasToNotify);
|
||||
|
||||
static nsCOMArray<nsICSSParser>* gParsers; // array of idle CSS parsers
|
||||
|
||||
protected:
|
||||
// the load data needs access to the document...
|
||||
nsIDocument* mDocument; // the document we live for
|
||||
|
||||
@ -389,7 +396,6 @@ protected:
|
||||
PRPackedBool mSyncCallback;
|
||||
#endif
|
||||
|
||||
private:
|
||||
PRPackedBool mCaseSensitive; // is document CSS case sensitive
|
||||
PRPackedBool mEnabled; // is enabled to load new styles
|
||||
nsCompatibility mCompatMode;
|
||||
@ -405,7 +411,7 @@ private:
|
||||
|
||||
// The array of posted stylesheet loaded events (SheetLoadDatas) we have.
|
||||
// Note that these are rare.
|
||||
nsTArray<nsRefPtr<SheetLoadData> > mPostedEvents;
|
||||
LoadDataArray mPostedEvents;
|
||||
};
|
||||
|
||||
#endif // nsCSSLoader_h__
|
||||
|
@ -50,7 +50,6 @@ class nsICSSParser;
|
||||
class nsICSSStyleSheet;
|
||||
class nsPresContext;
|
||||
class nsIContent;
|
||||
class nsIParser;
|
||||
class nsIDocument;
|
||||
class nsIUnicharInputStream;
|
||||
class nsICSSLoaderObserver;
|
||||
@ -58,10 +57,10 @@ class nsMediaList;
|
||||
class nsICSSImportRule;
|
||||
|
||||
// IID for the nsICSSLoader interface
|
||||
// 446711e6-ad01-4702-8a9b-ce3f5e5d30f0
|
||||
// 5da3a869-270c-4f10-97d1-99eaa150eb4e
|
||||
#define NS_ICSS_LOADER_IID \
|
||||
{ 0x446711e6, 0xad01, 0x4702, \
|
||||
{ 0x8a, 0x9b, 0xce, 0x3f, 0x5e, 0x5d, 0x30, 0xf0 } }
|
||||
{ 0x5da3a869, 0x270c, 0x4f10, \
|
||||
{ 0x97, 0xd1, 0x99, 0xea, 0xa1, 0x50, 0xeb, 0x4e } }
|
||||
|
||||
typedef void (*nsCSSLoaderCallbackFunc)(nsICSSStyleSheet* aSheet, void *aData, PRBool aDidNotify);
|
||||
|
||||
@ -98,9 +97,6 @@ public:
|
||||
* @param aLineNumber the line number at which the stylesheet data started.
|
||||
* @param aTitle the title of the sheet.
|
||||
* @param aMedia the media string for the sheet.
|
||||
* @param aParserToUnblock the parser to unblock when the load completes.
|
||||
* Only loads that returned false for both aIsAlternate and
|
||||
* aCompleted will unblock the parser.
|
||||
* @param aObserver the observer to notify when the load completes.
|
||||
* May be null.
|
||||
* @param [out] aCompleted whether parsing of the sheet completed.
|
||||
@ -112,7 +108,6 @@ public:
|
||||
PRUint32 aLineNumber,
|
||||
const nsSubstring& aTitle,
|
||||
const nsSubstring& aMedia,
|
||||
nsIParser* aParserToUnblock,
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
PRBool* aCompleted,
|
||||
PRBool* aIsAlternate) = 0;
|
||||
@ -130,9 +125,6 @@ public:
|
||||
* @param aMedia the media string for the sheet.
|
||||
* @param aHasAlternateRel whether the rel for this link included
|
||||
* "alternate".
|
||||
* @param aParserToUnblock the parser to unblock when the load completes.
|
||||
* Only loads that returned false for aIsAlternate will unblock
|
||||
* the parser.
|
||||
* @param aObserver the observer to notify when the load completes.
|
||||
* May be null.
|
||||
* @param [out] aIsAlternate whether the stylesheet actually ended up beinga
|
||||
@ -144,7 +136,6 @@ public:
|
||||
const nsSubstring& aTitle,
|
||||
const nsSubstring& aMedia,
|
||||
PRBool aHasAlternateRel,
|
||||
nsIParser* aParserToUnblock,
|
||||
nsICSSLoaderObserver* aObserver,
|
||||
PRBool* aIsAlternate) = 0;
|
||||
|
||||
|
@ -392,8 +392,6 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
|
||||
if(!mHasOpenRoot) {
|
||||
// For the stack-allocated tokens below, it's safe to pass a null
|
||||
// token allocator, because there are no attributes on the tokens.
|
||||
PRBool didBlock = PR_FALSE;
|
||||
|
||||
CStartToken htmlToken(NS_LITERAL_STRING("HTML"), eHTMLTag_html);
|
||||
nsCParserNode htmlNode(&htmlToken, 0/*stack token*/);
|
||||
mSink->OpenContainer(htmlNode);
|
||||
@ -443,17 +441,13 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
|
||||
NS_LITERAL_STRING("href"),
|
||||
NS_LITERAL_STRING("resource://gre/res/viewsource.css"));
|
||||
|
||||
result = mSink->AddLeaf(theNode);
|
||||
didBlock = result == NS_ERROR_HTMLPARSER_BLOCK;
|
||||
mSink->AddLeaf(theNode);
|
||||
}
|
||||
}
|
||||
|
||||
result = mSink->CloseContainer(eHTMLTag_head);
|
||||
if(NS_SUCCEEDED(result)) {
|
||||
mHasOpenRoot = PR_TRUE;
|
||||
if (didBlock) {
|
||||
result = NS_ERROR_HTMLPARSER_BLOCK;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NS_SUCCEEDED(result) && !mHasOpenBody) {
|
||||
@ -511,8 +505,7 @@ NS_IMETHODIMP CViewSourceHTML::BuildModel(nsIParser* aParser,nsITokenizer* aToke
|
||||
result = NS_ERROR_HTMLPARSER_INTERRUPTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(NS_ERROR_HTMLPARSER_BLOCK!=result){
|
||||
} else {
|
||||
mTokenizer->PushTokenFront(theToken);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user