📄 khtml_part.cpp
字号:
}
if ( len == 0 )
return;
if ( len == -1 )
len = strlen( str );
QString decoded = d->m_decoder->decode( str, len );
if(decoded.isEmpty()) return;
if(d->m_bFirstData) {
// determine the parse mode
d->m_doc->determineParseMode( decoded );
d->m_bFirstData = false;
//kdDebug(6050) << "KHTMLPart::write haveEnc = " << d->m_haveEncoding << endl;
// ### this is still quite hacky, but should work a lot better than the old solution
if(d->m_decoder->visuallyOrdered()) d->m_doc->setVisuallyOrdered();
d->m_doc->recalcStyle( NodeImpl::Force );
}
if (jScript())
jScript()->appendSourceFile(m_url.url(),decoded);
#if NOKIA_CHANGES
// switch out from fast display mode when scripts and stylesheets have been loaded
if( d->m_fastDisplayState<ShowingFinalDocument )
{
d->m_pendingSrc.append(decoded);
if (d->m_doc->fastDisplayMode()) {
if (d->m_pendingSrc.length() > 4096 &&
khtml::Cache::loader()->numRequests(d->m_doc->docLoader(),khtml::CachedObject::Script)==0 &&
khtml::Cache::loader()->numRequests(d->m_doc->docLoader(),khtml::CachedObject::CSSStyleSheet)==0 ){
switchToFinalDoc();
return;
}
// don't bother doing fast display for the entire long document, it is too CPU-costly
if (d->m_pendingSrc.length() > cPreviewUntil) {
int l = decoded.length() - (d->m_pendingSrc.length() - cPreviewUntil);
if (l<=0)
return;
decoded = decoded.left(l);
}
}
}
#endif
Tokenizer* t = d->m_doc->tokenizer();
if(t)
t->write( decoded, true );
#if NOKIA_CHANGES
if (d->m_fastDisplayState < ShowingFinalDocument) {
if (d->m_pendingSrc.length()-decoded.length() <= cPreviewUntil) {
d->m_view->layout();
d->m_view->unscheduleRelayout();
} else {
if (d->m_doc->isHTMLDocument()) {
// tokenizer might be deleted in write() if OOM during html parsing.
khtml::HTMLTokenizer* tokenizer = static_cast<khtml::HTMLTokenizer*>(d->m_doc->tokenizer());
if( tokenizer )
tokenizer->setForceSynchronous(false);
}
}
}
#endif
}
void KHTMLPart::write( const QString &str )
{
if ( str.isNull() )
return;
if(d->m_bFirstData) {
// determine the parse mode
d->m_doc->setParseMode( DocumentImpl::Strict );
d->m_bFirstData = false;
}
if (jScript())
jScript()->appendSourceFile(m_url.url(),str);
Tokenizer* t = d->m_doc->tokenizer();
if(t)
t->write( str, true );
}
void KHTMLPart::end()
{
d->m_bLoadingMainResource = false;
endIfNotLoading();
}
void KHTMLPart::endIfNotLoading()
{
if (d->m_bLoadingMainResource)
return;
// make sure nothing's left in there...
QString decoded;
if (d->m_decoder) {
decoded = d->m_decoder->flush();
write(decoded);
}
if (d->m_doc) {
#if NOKIA_CHANGES
// switch out from fast display mode when scripts and stylesheets have been loaded
if (d->m_doc->fastDisplayMode()) {
d->m_pendingSrc.append(decoded);
if (d->m_pendingSrc.length()>0 &&
khtml::Cache::loader()->numRequests(d->m_doc->docLoader(),khtml::CachedObject::Script)==0 &&
khtml::Cache::loader()->numRequests(d->m_doc->docLoader(),khtml::CachedObject::CSSStyleSheet)==0)
{
switchToFinalDoc();
}
}
#endif
d->m_doc->finishParsing();
} else
// WebKit partially uses WebCore when loading non-HTML docs. In these cases doc==nil, but
// WebCore is enough involved that we need to checkCompleted() in order for m_bComplete to
// become true. An example is when a subframe is a pure text doc, and that subframe is the
// last one to complete.
checkCompleted();
}
void KHTMLPart::stop()
{
// make sure nothing's left in there...
Tokenizer* t = d->m_doc ? d->m_doc->tokenizer() : 0;
if (t)
t->stopped();
if (d->m_doc)
d->m_doc->finishParsing();
else
// WebKit partially uses WebCore when loading non-HTML docs. In these cases doc==nil, but
// WebCore is enough involved that we need to checkCompleted() in order for m_bComplete to
// become true. An example is when a subframe is a pure text doc, and that subframe is the
// last one to complete.
checkCompleted();
}
#if !APPLE_CHANGES
void KHTMLPart::paint(QPainter *p, const QRect &rc, int yOff, bool *more)
{
if (!d->m_view) return;
d->m_view->paint(p, rc, yOff, more);
}
#endif
void KHTMLPart::stopAnimations()
{
if ( d->m_doc )
d->m_doc->docLoader()->setShowAnimations( KHTMLSettings::KAnimationDisabled );
ConstFrameIt it = d->m_frames.begin();
ConstFrameIt end = d->m_frames.end();
for (; it != end; ++it )
if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
KParts::ReadOnlyPart* p = ( *it ).m_part;
static_cast<KHTMLPart*>( p )->stopAnimations();
}
}
void KHTMLPart::gotoAnchor()
{
if (m_url.hasRef()) {
QString ref = m_url.encodedHtmlRef();
if (!gotoAnchor(ref)) {
// Can't use htmlRef() here because it doesn't know which encoding to use to decode.
// Decoding here has to match encoding in completeURL, which means it has to use the
// page's encoding rather than UTF-8.
if (d->m_decoder)
#if !APPLE_CHANGES
gotoAnchor(KURL::decode_string(ref, d->m_decoder->codec()->mibEnum()));
#else
gotoAnchor(KURL::decode_string(ref, d->m_decoder->codec()));
#endif
}
}
}
void KHTMLPart::slotFinishedParsing()
{
#if NOKIA_CHANGES
if ( d->m_doc->fastDisplayMode())
return;
#endif
d->m_doc->setParsing(false);
if (!d->m_view)
return; // We are probably being destructed.
checkCompleted();
if (!d->m_view)
return; // We are being destroyed by something checkCompleted called.
// check if the scrollbars are really needed for the content
// if not, remove them, relayout, and repaint
d->m_view->restoreScrollBar();
gotoAnchor();
#if NOKIA_CHANGES
if (!d->m_doc->fastDisplayMode())
KWQ(this)->bridge()->Client().DocumentComplete();
#endif
}
void KHTMLPart::slotLoaderRequestStarted( khtml::DocLoader* dl, khtml::CachedObject *obj )
{
#if !APPLE_CHANGES
if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
KHTMLPart* p = this;
while ( p ) {
KHTMLPart* op = p;
p->d->m_totalObjectCount++;
p = p->parentPart();
if ( !p && d->m_loadedObjects <= d->m_totalObjectCount )
QTimer::singleShot( 200, op, SLOT( slotProgressUpdate() ) );
}
}
#endif
}
void KHTMLPart::slotLoaderRequestDone( khtml::DocLoader* dl, khtml::CachedObject *obj )
{
#if !APPLE_CHANGES
if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
KHTMLPart* p = this;
while ( p ) {
KHTMLPart* op = p;
p->d->m_loadedObjects++;
p = p->parentPart();
if ( !p && d->m_loadedObjects <= d->m_totalObjectCount && d->m_jobPercent >= 100 )
QTimer::singleShot( 200, op, SLOT( slotProgressUpdate() ) );
}
}
#endif
#if NOKIA_CHANGES
// switch out from fast display mode when scripts and stylesheets have been loaded
if ( d->m_doc && d->m_doc->fastDisplayMode() &&
khtml::Cache::loader()->numRequests(d->m_doc->docLoader(),khtml::CachedObject::Script)==0 &&
khtml::Cache::loader()->numRequests(d->m_doc->docLoader(),khtml::CachedObject::CSSStyleSheet)==0 )
{
switchToFinalDoc();
if (!d->m_bLoadingMainResource)
d->m_doc->finishParsing();
}
#endif
// We really only need to call checkCompleted when our own resources are done loading.
// So we should check that d->m_doc->docLoader() == dl here.
// That might help with performance by skipping some unnecessary work, but it's too
// risky to make that change right now (2005-02-07), because we might be accidentally
// depending on the extra checkCompleted calls.
if (d->m_doc) {
checkCompleted();
}
}
#if !APPLE_CHANGES
void KHTMLPart::slotProgressUpdate()
{
int percent;
if ( d->m_loadedObjects < d->m_totalObjectCount )
percent = d->m_jobPercent / 4 + ( d->m_loadedObjects*300 ) / ( 4*d->m_totalObjectCount );
else
percent = d->m_jobPercent;
if ( d->m_loadedObjects < d->m_totalObjectCount && percent >= 75 )
emit d->m_extension->infoMessage( i18n( "%1 of 1 Image loaded", "%1 of %n Images loaded", d->m_totalObjectCount ).arg( d->m_loadedObjects ) );
emit d->m_extension->loadingProgress( percent );
}
void KHTMLPart::slotJobSpeed( KIO::Job* /*job*/, unsigned long speed )
{
emit d->m_extension->speedProgress( speed );
}
void KHTMLPart::slotJobPercent( KIO::Job* /*job*/, unsigned long percent )
{
d->m_jobPercent = percent;
if ( !parentPart() )
QTimer::singleShot( 0, this, SLOT( slotProgressUpdate() ) );
}
#endif
void KHTMLPart::checkCompleted()
{
// kdDebug( 6050 ) << "KHTMLPart::checkCompleted() parsing: " << d->m_doc->parsing() << endl;
// kdDebug( 6050 ) << " complete: " << d->m_bComplete << endl;
#if !APPLE_CHANGES
// restore the cursor position
if (d->m_doc && !d->m_doc->parsing() && !d->m_focusNodeRestored)
{
if (d->m_focusNodeNumber >= 0)
d->m_doc->setFocusNode(d->m_doc->nodeWithAbsIndex(d->m_focusNodeNumber));
else
d->m_doc->setFocusNode(0);
d->m_focusNodeRestored = true;
}
#endif
// Any frame that hasn't completed yet ?
ConstFrameIt it = d->m_frames.begin();
ConstFrameIt end = d->m_frames.end();
for (; it != end; ++it )
if ( !(*it).m_bCompleted )
return;
// Have we completed before?
if ( d->m_bComplete )
return;
// Are we still parsing?
if ( d->m_doc && d->m_doc->parsing() )
return;
// Still waiting for images/scripts from the loader ?
int requests = 0;
if ( d->m_doc && d->m_doc->docLoader() )
requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );
if ( requests > 0 )
return;
// OK, completed.
// Now do what should be done when we are really completed.
d->m_bComplete = true;
checkEmitLoadEvent(); // if we didn't do it before
#if !APPLE_CHANGES
// check that the view has not been moved by the user
if ( !m_url.hasRef() && d->m_view->contentsY() == 0 )
d->m_view->setContentsPos( d->m_extension->urlArgs().xOffset,
d->m_extension->urlArgs().yOffset );
#endif
if ( d->m_scheduledRedirection != noRedirectionScheduled )
{
// Do not start redirection for frames here! That action is
// deferred until the parent emits a completed signal.
if ( parentPart() == 0 )
d->m_redirectionTimer.start( (int)(1000 * d->m_delayRedirect), true );
emit completed( true );
}
else
{
if ( d->m_bPendingChildRedirection )
emit completed ( true );
else
emit completed();
}
#if !APPLE_CHANGES
// find the alternate stylesheets
QStringList sheets;
if (d->m_doc)
sheets = d->m_doc->availableStyleSheets();
d->m_paUseStylesheet->setItems( sheets );
d->m_paUseStylesheet->setEnabled( !sheets.isEmpty() );
if (!sheets.isEmpty())
{
d->m_paUseStylesheet->setCurrentItem(kMax(sheets.findIndex(d->m_sheetUsed), 0));
slotUseStylesheet();
}
if (!parentPart())
emit setStatusBarText(i18n("Done."));
#endif
#ifdef SPEED_DEBUG
kdDebug(6050) << "DONE: " <<d->m_parsetime.elapsed() << endl;
#endif
}
void KHTMLPart::checkEmitLoadEvent()
{
if ( d->m_bLoadEventEmitted || !d->m_doc || d->m_doc->parsing() ) return;
ConstFrameIt it = d->m_frames.begin();
ConstFrameIt end = d->m_frames.end();
for (; it != end; ++it )
if ( !(*it).m_bCompleted ) // still got a frame running -> too early
return;
// All frames completed -> set their domain to the frameset's domain
// This must only be done when loading the frameset initially (#22039),
// not when following a link in a frame (#44162).
if ( d->m_doc )
{
DOMString domain = d->m_doc->domain();
ConstFrameIt it = d->m_frames.begin();
ConstFrameIt end = d->m_frames.end();
for (; it != end; ++it )
{
KParts::ReadOnlyPart *p = (*it).m_part;
if ( p && p->inherits( "KHTMLPart" ))
{
KHTMLPart* htmlFrame = static_cast<KHTMLPart *>(p);
if (htmlFrame->d->m_doc)
{
kdDebug() << "KHTMLPart::checkCompleted
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -