зеркало из https://github.com/mozilla/gecko-dev.git
Implemented a timer for loading CSS style sheets to allow content to be displayed if the sheet is taking too long to load. b=17309 r=nisheeth
This commit is contained in:
Родитель
b1d5e9188b
Коммит
0735cef009
|
@ -102,6 +102,7 @@
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
#include "nsIScrollable.h"
|
#include "nsIScrollable.h"
|
||||||
|
|
||||||
|
// #define ALLOW_ASYNCH_STYLE_SHEETS
|
||||||
#ifdef ALLOW_ASYNCH_STYLE_SHEETS
|
#ifdef ALLOW_ASYNCH_STYLE_SHEETS
|
||||||
const PRBool kBlock=PR_FALSE;
|
const PRBool kBlock=PR_FALSE;
|
||||||
#else
|
#else
|
||||||
|
@ -345,6 +346,11 @@ public:
|
||||||
PRInt32 mInsideNoXXXTag;
|
PRInt32 mInsideNoXXXTag;
|
||||||
PRInt32 mInMonolithicContainer;
|
PRInt32 mInMonolithicContainer;
|
||||||
|
|
||||||
|
nsCOMPtr<nsITimer> mStyleSheetTimer; // timer used to prevent infinite wait for style sheet
|
||||||
|
PRBool mStyleSheetTimerSet; // TRUE if a timer has been set since Init
|
||||||
|
PRInt32 mStyleSheetTimerInterval; // interval in milliseconds
|
||||||
|
PRUint32 mNumStyleSheetsLoading; // number of style sheets still loading
|
||||||
|
|
||||||
void StartLayout();
|
void StartLayout();
|
||||||
|
|
||||||
void ScrollToRef();
|
void ScrollToRef();
|
||||||
|
@ -2084,6 +2090,8 @@ HTMLContentSink::HTMLContentSink() {
|
||||||
mInNotification = 0;
|
mInNotification = 0;
|
||||||
mInMonolithicContainer = 0;
|
mInMonolithicContainer = 0;
|
||||||
mInsideNoXXXTag = 0;
|
mInsideNoXXXTag = 0;
|
||||||
|
|
||||||
|
mStyleSheetTimerSet = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HTMLContentSink::~HTMLContentSink()
|
HTMLContentSink::~HTMLContentSink()
|
||||||
|
@ -2112,6 +2120,10 @@ HTMLContentSink::~HTMLContentSink()
|
||||||
mNotificationTimer->Cancel();
|
mNotificationTimer->Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mStyleSheetTimer) {
|
||||||
|
mStyleSheetTimer->Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
PRInt32 numContexts = mContextStack.Count();
|
PRInt32 numContexts = mContextStack.Count();
|
||||||
|
|
||||||
if(mCurrentContext==mHeadContext) {
|
if(mCurrentContext==mHeadContext) {
|
||||||
|
@ -2205,6 +2217,11 @@ HTMLContentSink::Init(nsIDocument* aDoc,
|
||||||
mMaxTextRun = 8192;
|
mMaxTextRun = 8192;
|
||||||
prefs->GetIntPref("content.maxtextrun", &mMaxTextRun);
|
prefs->GetIntPref("content.maxtextrun", &mMaxTextRun);
|
||||||
|
|
||||||
|
mStyleSheetTimerSet = PR_FALSE;
|
||||||
|
mNumStyleSheetsLoading = 0;
|
||||||
|
mStyleSheetTimerInterval = (5*1000);
|
||||||
|
prefs->GetIntPref("content.notify.stylesheettimeout", &mStyleSheetTimerInterval);
|
||||||
|
|
||||||
nsIHTMLContentContainer* htmlContainer = nsnull;
|
nsIHTMLContentContainer* htmlContainer = nsnull;
|
||||||
if (NS_SUCCEEDED(aDoc->QueryInterface(kIHTMLContentContainerIID, (void**)&htmlContainer))) {
|
if (NS_SUCCEEDED(aDoc->QueryInterface(kIHTMLContentContainerIID, (void**)&htmlContainer))) {
|
||||||
htmlContainer->GetCSSLoader(mCSSLoader);
|
htmlContainer->GetCSSLoader(mCSSLoader);
|
||||||
|
@ -2284,6 +2301,11 @@ HTMLContentSink::DidBuildModel(PRInt32 aQualityLevel)
|
||||||
mNotificationTimer = 0;
|
mNotificationTimer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mStyleSheetTimer) {
|
||||||
|
mStyleSheetTimer->Cancel();
|
||||||
|
mStyleSheetTimer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (nsnull == mTitle) {
|
if (nsnull == mTitle) {
|
||||||
mHTMLDocument->SetTitle("");
|
mHTMLDocument->SetTitle("");
|
||||||
}
|
}
|
||||||
|
@ -2320,8 +2342,15 @@ HTMLContentSink::DidBuildModel(PRInt32 aQualityLevel)
|
||||||
NS_IMETHODIMP_(void)
|
NS_IMETHODIMP_(void)
|
||||||
HTMLContentSink::Notify(nsITimer *timer)
|
HTMLContentSink::Notify(nsITimer *timer)
|
||||||
{
|
{
|
||||||
|
if (timer == mStyleSheetTimer.get()) {
|
||||||
|
// our first sheet timer has expired: resume the parser now
|
||||||
|
mStyleSheetTimer = 0;
|
||||||
|
ResumeParsing();
|
||||||
|
} else {
|
||||||
|
|
||||||
MOZ_TIMER_DEBUGLOG(("Start: nsHTMLContentSink::Notify()\n"));
|
MOZ_TIMER_DEBUGLOG(("Start: nsHTMLContentSink::Notify()\n"));
|
||||||
MOZ_TIMER_START(mWatch);
|
MOZ_TIMER_START(mWatch);
|
||||||
|
|
||||||
#ifdef MOZ_DEBUG
|
#ifdef MOZ_DEBUG
|
||||||
PRTime now = PR_Now();
|
PRTime now = PR_Now();
|
||||||
PRInt64 diff, interval;
|
PRInt64 diff, interval;
|
||||||
|
@ -2338,13 +2367,16 @@ HTMLContentSink::Notify(nsITimer *timer)
|
||||||
SINK_TRACE(SINK_TRACE_REFLOW,
|
SINK_TRACE(SINK_TRACE_REFLOW,
|
||||||
("HTMLContentSink::Notify: reflow on a timer: %d milliseconds late, backoff count: %d", delay, mBackoffCount));
|
("HTMLContentSink::Notify: reflow on a timer: %d milliseconds late, backoff count: %d", delay, mBackoffCount));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mCurrentContext) {
|
if (mCurrentContext) {
|
||||||
mCurrentContext->FlushTags(PR_TRUE);
|
mCurrentContext->FlushTags(PR_TRUE);
|
||||||
}
|
}
|
||||||
mNotificationTimer = 0;
|
mNotificationTimer = 0;
|
||||||
|
|
||||||
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::Notify()\n"));
|
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::Notify()\n"));
|
||||||
MOZ_TIMER_STOP(mWatch);
|
MOZ_TIMER_STOP(mWatch);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HTMLContentSink::WillInterrupt()
|
HTMLContentSink::WillInterrupt()
|
||||||
|
@ -2420,6 +2452,7 @@ HTMLContentSink::WillResume()
|
||||||
{
|
{
|
||||||
SINK_TRACE(SINK_TRACE_CALLS,
|
SINK_TRACE(SINK_TRACE_CALLS,
|
||||||
("HTMLContentSink::WillResume: this=%p", this));
|
("HTMLContentSink::WillResume: this=%p", this));
|
||||||
|
|
||||||
// Cancel a timer if we had one out there
|
// Cancel a timer if we had one out there
|
||||||
if (mNotificationTimer) {
|
if (mNotificationTimer) {
|
||||||
SINK_TRACE(SINK_TRACE_REFLOW,
|
SINK_TRACE(SINK_TRACE_REFLOW,
|
||||||
|
@ -2427,7 +2460,6 @@ HTMLContentSink::WillResume()
|
||||||
mNotificationTimer->Cancel();
|
mNotificationTimer->Cancel();
|
||||||
mNotificationTimer = 0;
|
mNotificationTimer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3659,6 +3691,14 @@ NS_IMETHODIMP
|
||||||
HTMLContentSink::StyleSheetLoaded(nsICSSStyleSheet* aSheet,
|
HTMLContentSink::StyleSheetLoaded(nsICSSStyleSheet* aSheet,
|
||||||
PRBool aDidNotify)
|
PRBool aDidNotify)
|
||||||
{
|
{
|
||||||
|
mNumStyleSheetsLoading--;
|
||||||
|
|
||||||
|
// if out timer is still pending, cancel it.
|
||||||
|
if (mNumStyleSheetsLoading==0 && mStyleSheetTimer) {
|
||||||
|
mStyleSheetTimer->Cancel();
|
||||||
|
mStyleSheetTimer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// If there was a notification done for this style sheet, we know
|
// If there was a notification done for this style sheet, we know
|
||||||
// that frames have been created for all content seen so far
|
// that frames have been created for all content seen so far
|
||||||
// (processing of a new style sheet causes recreation of the frame
|
// (processing of a new style sheet causes recreation of the frame
|
||||||
|
@ -3719,6 +3759,9 @@ HTMLContentSink::ProcessStyleLink(nsIHTMLContent* aElement,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isStyleSheet) {
|
if (isStyleSheet) {
|
||||||
|
PRBool blockParser = kBlock;
|
||||||
|
PRBool important = PR_FALSE;
|
||||||
|
PRBool alternate = PR_FALSE; // alternate (non-preferred) style sheet
|
||||||
nsIURI* url = nsnull;
|
nsIURI* url = nsnull;
|
||||||
{
|
{
|
||||||
result = NS_NewURI(&url, aHref, mDocumentBaseURL);
|
result = NS_NewURI(&url, aHref, mDocumentBaseURL);
|
||||||
|
@ -3733,14 +3776,19 @@ HTMLContentSink::ProcessStyleLink(nsIHTMLContent* aElement,
|
||||||
mPreferredStyle = aTitle;
|
mPreferredStyle = aTitle;
|
||||||
mCSSLoader->SetPreferredSheet(aTitle);
|
mCSSLoader->SetPreferredSheet(aTitle);
|
||||||
mDocument->SetHeaderData(nsHTMLAtoms::headerDefaultStyle, aTitle);
|
mDocument->SetHeaderData(nsHTMLAtoms::headerDefaultStyle, aTitle);
|
||||||
|
} else {
|
||||||
|
alternate = PR_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool blockParser = kBlock;
|
|
||||||
|
|
||||||
if (-1 != linkTypes.IndexOf("important")) {
|
if (-1 != linkTypes.IndexOf("important")) {
|
||||||
blockParser = PR_TRUE;
|
blockParser = PR_TRUE;
|
||||||
|
important = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alternate && !important) {
|
||||||
|
blockParser = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool doneLoading;
|
PRBool doneLoading;
|
||||||
|
@ -3750,10 +3798,36 @@ HTMLContentSink::ProcessStyleLink(nsIHTMLContent* aElement,
|
||||||
doneLoading,
|
doneLoading,
|
||||||
this);
|
this);
|
||||||
NS_RELEASE(url);
|
NS_RELEASE(url);
|
||||||
if (NS_SUCCEEDED(result) && blockParser && (! doneLoading)) {
|
if (NS_SUCCEEDED(result) && (!doneLoading)) {
|
||||||
|
// we are loading another one, so increment the counter
|
||||||
|
mNumStyleSheetsLoading++;
|
||||||
|
// if important, then just block
|
||||||
|
if (important) {
|
||||||
|
NS_ASSERTION(blockParser, "Must block for important styleSheets");
|
||||||
|
result = NS_ERROR_HTMLPARSER_BLOCK;
|
||||||
|
} else {
|
||||||
|
// if not blocking the parser absolutely (!important)
|
||||||
|
// then setup a notification timer so we can locally
|
||||||
|
// unblock the parser if it takes too long
|
||||||
|
// bug=17309
|
||||||
|
if (blockParser) {
|
||||||
|
NS_ASSERTION(!alternate, "Alternates should not block parser");
|
||||||
|
// if no stylesheet timer, and none was previously set (ie. first one), then start one
|
||||||
|
if (!mStyleSheetTimer && !mStyleSheetTimerSet) {
|
||||||
|
result = NS_NewTimer(getter_AddRefs(mStyleSheetTimer));
|
||||||
|
if (NS_SUCCEEDED(result)) {
|
||||||
|
result = mStyleSheetTimer->Init(this, mStyleSheetTimerInterval);
|
||||||
|
if( NS_SUCCEEDED(result)) {
|
||||||
|
mStyleSheetTimerSet = PR_TRUE;
|
||||||
|
// block the parser: we will unblock it when the timer expires
|
||||||
result = NS_ERROR_HTMLPARSER_BLOCK;
|
result = NS_ERROR_HTMLPARSER_BLOCK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}// if no stylesheet timer
|
||||||
|
}// if !important and blockParser
|
||||||
|
} // if important
|
||||||
|
} // if succeeded && !doneLoading
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,7 @@
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
#include "nsIScrollable.h"
|
#include "nsIScrollable.h"
|
||||||
|
|
||||||
|
// #define ALLOW_ASYNCH_STYLE_SHEETS
|
||||||
#ifdef ALLOW_ASYNCH_STYLE_SHEETS
|
#ifdef ALLOW_ASYNCH_STYLE_SHEETS
|
||||||
const PRBool kBlock=PR_FALSE;
|
const PRBool kBlock=PR_FALSE;
|
||||||
#else
|
#else
|
||||||
|
@ -345,6 +346,11 @@ public:
|
||||||
PRInt32 mInsideNoXXXTag;
|
PRInt32 mInsideNoXXXTag;
|
||||||
PRInt32 mInMonolithicContainer;
|
PRInt32 mInMonolithicContainer;
|
||||||
|
|
||||||
|
nsCOMPtr<nsITimer> mStyleSheetTimer; // timer used to prevent infinite wait for style sheet
|
||||||
|
PRBool mStyleSheetTimerSet; // TRUE if a timer has been set since Init
|
||||||
|
PRInt32 mStyleSheetTimerInterval; // interval in milliseconds
|
||||||
|
PRUint32 mNumStyleSheetsLoading; // number of style sheets still loading
|
||||||
|
|
||||||
void StartLayout();
|
void StartLayout();
|
||||||
|
|
||||||
void ScrollToRef();
|
void ScrollToRef();
|
||||||
|
@ -2084,6 +2090,8 @@ HTMLContentSink::HTMLContentSink() {
|
||||||
mInNotification = 0;
|
mInNotification = 0;
|
||||||
mInMonolithicContainer = 0;
|
mInMonolithicContainer = 0;
|
||||||
mInsideNoXXXTag = 0;
|
mInsideNoXXXTag = 0;
|
||||||
|
|
||||||
|
mStyleSheetTimerSet = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HTMLContentSink::~HTMLContentSink()
|
HTMLContentSink::~HTMLContentSink()
|
||||||
|
@ -2112,6 +2120,10 @@ HTMLContentSink::~HTMLContentSink()
|
||||||
mNotificationTimer->Cancel();
|
mNotificationTimer->Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mStyleSheetTimer) {
|
||||||
|
mStyleSheetTimer->Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
PRInt32 numContexts = mContextStack.Count();
|
PRInt32 numContexts = mContextStack.Count();
|
||||||
|
|
||||||
if(mCurrentContext==mHeadContext) {
|
if(mCurrentContext==mHeadContext) {
|
||||||
|
@ -2205,6 +2217,11 @@ HTMLContentSink::Init(nsIDocument* aDoc,
|
||||||
mMaxTextRun = 8192;
|
mMaxTextRun = 8192;
|
||||||
prefs->GetIntPref("content.maxtextrun", &mMaxTextRun);
|
prefs->GetIntPref("content.maxtextrun", &mMaxTextRun);
|
||||||
|
|
||||||
|
mStyleSheetTimerSet = PR_FALSE;
|
||||||
|
mNumStyleSheetsLoading = 0;
|
||||||
|
mStyleSheetTimerInterval = (5*1000);
|
||||||
|
prefs->GetIntPref("content.notify.stylesheettimeout", &mStyleSheetTimerInterval);
|
||||||
|
|
||||||
nsIHTMLContentContainer* htmlContainer = nsnull;
|
nsIHTMLContentContainer* htmlContainer = nsnull;
|
||||||
if (NS_SUCCEEDED(aDoc->QueryInterface(kIHTMLContentContainerIID, (void**)&htmlContainer))) {
|
if (NS_SUCCEEDED(aDoc->QueryInterface(kIHTMLContentContainerIID, (void**)&htmlContainer))) {
|
||||||
htmlContainer->GetCSSLoader(mCSSLoader);
|
htmlContainer->GetCSSLoader(mCSSLoader);
|
||||||
|
@ -2284,6 +2301,11 @@ HTMLContentSink::DidBuildModel(PRInt32 aQualityLevel)
|
||||||
mNotificationTimer = 0;
|
mNotificationTimer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mStyleSheetTimer) {
|
||||||
|
mStyleSheetTimer->Cancel();
|
||||||
|
mStyleSheetTimer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (nsnull == mTitle) {
|
if (nsnull == mTitle) {
|
||||||
mHTMLDocument->SetTitle("");
|
mHTMLDocument->SetTitle("");
|
||||||
}
|
}
|
||||||
|
@ -2320,8 +2342,15 @@ HTMLContentSink::DidBuildModel(PRInt32 aQualityLevel)
|
||||||
NS_IMETHODIMP_(void)
|
NS_IMETHODIMP_(void)
|
||||||
HTMLContentSink::Notify(nsITimer *timer)
|
HTMLContentSink::Notify(nsITimer *timer)
|
||||||
{
|
{
|
||||||
|
if (timer == mStyleSheetTimer.get()) {
|
||||||
|
// our first sheet timer has expired: resume the parser now
|
||||||
|
mStyleSheetTimer = 0;
|
||||||
|
ResumeParsing();
|
||||||
|
} else {
|
||||||
|
|
||||||
MOZ_TIMER_DEBUGLOG(("Start: nsHTMLContentSink::Notify()\n"));
|
MOZ_TIMER_DEBUGLOG(("Start: nsHTMLContentSink::Notify()\n"));
|
||||||
MOZ_TIMER_START(mWatch);
|
MOZ_TIMER_START(mWatch);
|
||||||
|
|
||||||
#ifdef MOZ_DEBUG
|
#ifdef MOZ_DEBUG
|
||||||
PRTime now = PR_Now();
|
PRTime now = PR_Now();
|
||||||
PRInt64 diff, interval;
|
PRInt64 diff, interval;
|
||||||
|
@ -2338,13 +2367,16 @@ HTMLContentSink::Notify(nsITimer *timer)
|
||||||
SINK_TRACE(SINK_TRACE_REFLOW,
|
SINK_TRACE(SINK_TRACE_REFLOW,
|
||||||
("HTMLContentSink::Notify: reflow on a timer: %d milliseconds late, backoff count: %d", delay, mBackoffCount));
|
("HTMLContentSink::Notify: reflow on a timer: %d milliseconds late, backoff count: %d", delay, mBackoffCount));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mCurrentContext) {
|
if (mCurrentContext) {
|
||||||
mCurrentContext->FlushTags(PR_TRUE);
|
mCurrentContext->FlushTags(PR_TRUE);
|
||||||
}
|
}
|
||||||
mNotificationTimer = 0;
|
mNotificationTimer = 0;
|
||||||
|
|
||||||
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::Notify()\n"));
|
MOZ_TIMER_DEBUGLOG(("Stop: nsHTMLContentSink::Notify()\n"));
|
||||||
MOZ_TIMER_STOP(mWatch);
|
MOZ_TIMER_STOP(mWatch);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HTMLContentSink::WillInterrupt()
|
HTMLContentSink::WillInterrupt()
|
||||||
|
@ -2420,6 +2452,7 @@ HTMLContentSink::WillResume()
|
||||||
{
|
{
|
||||||
SINK_TRACE(SINK_TRACE_CALLS,
|
SINK_TRACE(SINK_TRACE_CALLS,
|
||||||
("HTMLContentSink::WillResume: this=%p", this));
|
("HTMLContentSink::WillResume: this=%p", this));
|
||||||
|
|
||||||
// Cancel a timer if we had one out there
|
// Cancel a timer if we had one out there
|
||||||
if (mNotificationTimer) {
|
if (mNotificationTimer) {
|
||||||
SINK_TRACE(SINK_TRACE_REFLOW,
|
SINK_TRACE(SINK_TRACE_REFLOW,
|
||||||
|
@ -2427,7 +2460,6 @@ HTMLContentSink::WillResume()
|
||||||
mNotificationTimer->Cancel();
|
mNotificationTimer->Cancel();
|
||||||
mNotificationTimer = 0;
|
mNotificationTimer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3659,6 +3691,14 @@ NS_IMETHODIMP
|
||||||
HTMLContentSink::StyleSheetLoaded(nsICSSStyleSheet* aSheet,
|
HTMLContentSink::StyleSheetLoaded(nsICSSStyleSheet* aSheet,
|
||||||
PRBool aDidNotify)
|
PRBool aDidNotify)
|
||||||
{
|
{
|
||||||
|
mNumStyleSheetsLoading--;
|
||||||
|
|
||||||
|
// if out timer is still pending, cancel it.
|
||||||
|
if (mNumStyleSheetsLoading==0 && mStyleSheetTimer) {
|
||||||
|
mStyleSheetTimer->Cancel();
|
||||||
|
mStyleSheetTimer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// If there was a notification done for this style sheet, we know
|
// If there was a notification done for this style sheet, we know
|
||||||
// that frames have been created for all content seen so far
|
// that frames have been created for all content seen so far
|
||||||
// (processing of a new style sheet causes recreation of the frame
|
// (processing of a new style sheet causes recreation of the frame
|
||||||
|
@ -3719,6 +3759,9 @@ HTMLContentSink::ProcessStyleLink(nsIHTMLContent* aElement,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isStyleSheet) {
|
if (isStyleSheet) {
|
||||||
|
PRBool blockParser = kBlock;
|
||||||
|
PRBool important = PR_FALSE;
|
||||||
|
PRBool alternate = PR_FALSE; // alternate (non-preferred) style sheet
|
||||||
nsIURI* url = nsnull;
|
nsIURI* url = nsnull;
|
||||||
{
|
{
|
||||||
result = NS_NewURI(&url, aHref, mDocumentBaseURL);
|
result = NS_NewURI(&url, aHref, mDocumentBaseURL);
|
||||||
|
@ -3733,14 +3776,19 @@ HTMLContentSink::ProcessStyleLink(nsIHTMLContent* aElement,
|
||||||
mPreferredStyle = aTitle;
|
mPreferredStyle = aTitle;
|
||||||
mCSSLoader->SetPreferredSheet(aTitle);
|
mCSSLoader->SetPreferredSheet(aTitle);
|
||||||
mDocument->SetHeaderData(nsHTMLAtoms::headerDefaultStyle, aTitle);
|
mDocument->SetHeaderData(nsHTMLAtoms::headerDefaultStyle, aTitle);
|
||||||
|
} else {
|
||||||
|
alternate = PR_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool blockParser = kBlock;
|
|
||||||
|
|
||||||
if (-1 != linkTypes.IndexOf("important")) {
|
if (-1 != linkTypes.IndexOf("important")) {
|
||||||
blockParser = PR_TRUE;
|
blockParser = PR_TRUE;
|
||||||
|
important = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alternate && !important) {
|
||||||
|
blockParser = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool doneLoading;
|
PRBool doneLoading;
|
||||||
|
@ -3750,10 +3798,36 @@ HTMLContentSink::ProcessStyleLink(nsIHTMLContent* aElement,
|
||||||
doneLoading,
|
doneLoading,
|
||||||
this);
|
this);
|
||||||
NS_RELEASE(url);
|
NS_RELEASE(url);
|
||||||
if (NS_SUCCEEDED(result) && blockParser && (! doneLoading)) {
|
if (NS_SUCCEEDED(result) && (!doneLoading)) {
|
||||||
|
// we are loading another one, so increment the counter
|
||||||
|
mNumStyleSheetsLoading++;
|
||||||
|
// if important, then just block
|
||||||
|
if (important) {
|
||||||
|
NS_ASSERTION(blockParser, "Must block for important styleSheets");
|
||||||
|
result = NS_ERROR_HTMLPARSER_BLOCK;
|
||||||
|
} else {
|
||||||
|
// if not blocking the parser absolutely (!important)
|
||||||
|
// then setup a notification timer so we can locally
|
||||||
|
// unblock the parser if it takes too long
|
||||||
|
// bug=17309
|
||||||
|
if (blockParser) {
|
||||||
|
NS_ASSERTION(!alternate, "Alternates should not block parser");
|
||||||
|
// if no stylesheet timer, and none was previously set (ie. first one), then start one
|
||||||
|
if (!mStyleSheetTimer && !mStyleSheetTimerSet) {
|
||||||
|
result = NS_NewTimer(getter_AddRefs(mStyleSheetTimer));
|
||||||
|
if (NS_SUCCEEDED(result)) {
|
||||||
|
result = mStyleSheetTimer->Init(this, mStyleSheetTimerInterval);
|
||||||
|
if( NS_SUCCEEDED(result)) {
|
||||||
|
mStyleSheetTimerSet = PR_TRUE;
|
||||||
|
// block the parser: we will unblock it when the timer expires
|
||||||
result = NS_ERROR_HTMLPARSER_BLOCK;
|
result = NS_ERROR_HTMLPARSER_BLOCK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}// if no stylesheet timer
|
||||||
|
}// if !important and blockParser
|
||||||
|
} // if important
|
||||||
|
} // if succeeded && !doneLoading
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче