📄 khtml_part.cpp
字号:
emit setWindowCaption( i18n( "no title", "* Unknown *" ) ); // ### not sure if XHTML documents served as text/xml should use DocumentImpl or HTMLDocumentImpl if (args.serviceType == "text/xml") d->m_doc = new DocumentImpl( d->m_view ); else d->m_doc = new HTMLDocumentImpl( d->m_view ); d->m_doc->ref(); d->m_doc->attach( d->m_view ); d->m_doc->setURL( m_url.url() ); setAutoloadImages( KHTMLFactory::defaultHTMLSettings()->autoLoadImages() ); QString userStyleSheet = KHTMLFactory::defaultHTMLSettings()->userStyleSheet(); if ( !userStyleSheet.isEmpty() ) setUserStyleSheet( KURL( userStyleSheet ) ); d->m_doc->setRestoreState(args.docState); d->m_doc->open(); // clear widget d->m_view->resizeContents( 0, 0 ); connect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing())); emit d->m_extension->enableAction( "print", true ); d->m_bParsing = true;}void KHTMLPart::write( const char *str, int len ){ if ( !d->m_decoder ) { d->m_decoder = new khtml::Decoder(); if(d->m_encoding != QString::null) d->m_decoder->setEncoding(d->m_encoding.latin1(), d->m_haveEncoding); else d->m_decoder->setEncoding(settings()->encoding().latin1(), d->m_haveEncoding); } 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(); if (!d->m_haveCharset) { const QTextCodec *c = d->m_decoder->codec(); //kdDebug(6005) << "setting up charset to " << (int) KGlobal::charsets()->charsetForEncoding(c->name()) << endl; d->m_charset = KGlobal::charsets()->charsetForEncoding(c->name()); d->m_settings->setCharset( d->m_charset ); d->m_settings->setScript( KGlobal::charsets()->charsetForEncoding(c->name(), true )); //kdDebug(6005) << "charset is " << (int)d->m_settings->charset() << endl; } d->m_doc->applyChanges(true, true); } Tokenizer* t = d->m_doc->tokenizer(); if(t) t->write( decoded, true );}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; } Tokenizer* t = d->m_doc->tokenizer(); if(t) t->write( str, true );}void KHTMLPart::end(){ // make sure nothing's left in there... if(d->m_decoder) write(d->m_decoder->flush()); d->m_doc->finishParsing();}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);}void KHTMLPart::stopAnimations(){ if ( d->m_doc ) d->m_doc->docLoader()->setShowAnimations(false); 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::slotFinishedParsing(){ d->m_bParsing = false; d->m_doc->close(); checkEmitLoadEvent(); disconnect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing())); if (!d->m_view) return; // We are probably being destructed. // check if the scrollbars are really needed for the content // if not, remove them, relayout, and repaint d->m_view->restoreScrollBar(); if ( !m_url.encodedHtmlRef().isEmpty() ) gotoAnchor( m_url.encodedHtmlRef() );#if 0 HTMLCollectionImpl imgColl( d->m_doc, HTMLCollectionImpl::DOC_IMAGES ); d->m_totalImageCount = 0; KURL::List imageURLs; unsigned long i = 0; unsigned long len = imgColl.length(); for (; i < len; i++ ) { NodeImpl *node = imgColl.item( i ); if ( node->id() != ID_IMG ) continue; QString imgURL = static_cast<DOM::ElementImpl *>( node )->getAttribute( ATTR_SRC ).string(); KURL url; if ( KURL::isRelativeURL( imgURL ) ) url = completeURL( imgURL ); else url = KURL( imgURL ); if ( !imageURLs.contains( url ) ) { d->m_totalImageCount++; imageURLs.append( url ); } }#endif checkCompleted();}void KHTMLPart::slotLoaderRequestDone( const DOM::DOMString &/*baseURL*/, khtml::CachedObject *obj ){ if ( obj && obj->type() == khtml::CachedObject::Image ) { d->m_loadedImages++; // in case we have more images than we originally found, then they are most likely loaded by some // javascript code. as we can't find out the exact number anyway we skip displaying any further image // loading info message :P if ( d->m_loadedImages <= d->m_totalImageCount && autoloadImages()) emit d->m_extension->infoMessage( i18n( "%1 of 1 Image loaded", "%1 of %n Images loaded", d->m_totalImageCount ).arg( d->m_loadedImages ) ); } checkCompleted();}void KHTMLPart::checkCompleted(){ //kdDebug( 6050 ) << "KHTMLPart::checkCompleted() parsing: " << d->m_bParsing << endl; //kdDebug( 6050 ) << " complete: " << d->m_bComplete << endl; // restore the cursor position if (d->m_doc && !d->m_bParsing && !d->m_focusNodeRestored) { int focusNodeNumber; if ((focusNodeNumber = d->m_focusNodeNumber)) { DOM::ElementImpl *focusNode = 0; while(focusNodeNumber--) { if ((focusNode = d->m_doc->findNextLink(focusNode, true))==0) break; } if (focusNode) { //QRect focusRect = focusNode->getRect(); //d->m_view->ensureVisible(focusRect.x(), focusRect.y()); d->m_doc->setFocusNode(focusNode); } } d->m_focusNodeRestored = true; } int requests = 0; // 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; // Are we still parsing - or have we done the completed stuff already ? if ( d->m_bParsing || d->m_bComplete ) return; // Still waiting for images/scripts from the loader ? requests = khtml::Cache::loader()->numRequests( m_url.url() ); //kdDebug( 6060 ) << "Number of loader requests left: " << requests << endl; 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 (!parentPart()) emit setStatusBarText(i18n("Done.")); // check for a <link rel="SHORTCUT ICON" href="url to icon">, // IE extension to set an icon for this page to use in // bookmarks and the locationbar if (!parentPart() && d->m_doc && d->m_doc->isHTMLDocument()) { DOM::TagNodeListImpl links(d->m_doc, "LINK"); for (unsigned long i = 0; i < links.length(); ++i) if (links.item(i)->isElementNode()) { DOM::ElementImpl *link = static_cast<DOM::ElementImpl *>(links.item(i)); kdDebug(6005) << "Checking..." << endl; if (link->getAttribute("REL").string().upper() == "SHORTCUT ICON") { KURL iconURL(d->m_baseURL, link->getAttribute("HREF").string()); if (!iconURL.isEmpty()) { emit d->m_extension->setIconURL(iconURL); break; } } } } if ( m_url.encodedHtmlRef().isEmpty() && d->m_view->contentsY() == 0 ) // check that the view has not been moved by the user d->m_view->setContentsPos( d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset ); // when encountering if ( !d->m_redirectURL.isEmpty() ) { // Do not start redirection for frames here! That action is // deferred until the parent emits a completed signal. if ( parentPart() == 0 ) { //kdDebug(6050) << this << ": redirect to -> " << d->m_redirectURL << endl; d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true ); } emit completed( true ); } else { if ( d->m_bPendingChildRedirection ) emit completed ( true ); else emit completed(); } emit setStatusBarText( i18n("Loading complete") );#ifdef SPEED_DEBUG kdDebug(6050) << "DONE: " <<d->m_parsetime.elapsed() << endl;#endif}void KHTMLPart::checkEmitLoadEvent(){ if ( d->m_bLoadEventEmitted || d->m_bParsing ) return; ConstFrameIt it = d->m_frames.begin(); ConstFrameIt end = d->m_frames.end(); for (; it != end; ++it ) if ( (*it).m_run ) // still got a frame running -> too early return; emitLoadEvent();}void KHTMLPart::emitLoadEvent(){ d->m_bLoadEventEmitted = true; kdDebug(6050) << "KHTMLPart::emitLoadEvent " << this << endl; if ( d->m_doc && d->m_doc->isHTMLDocument() ) { HTMLDocumentImpl* hdoc = static_cast<HTMLDocumentImpl*>( d->m_doc ); if ( hdoc->body() ) { hdoc->body()->dispatchWindowEvent( EventImpl::LOAD_EVENT, false, false ); hdoc->updateRendering(); } }}void KHTMLPart::emitUnloadEvent(){ if ( d->m_doc && d->m_doc->isHTMLDocument() ) { HTMLDocumentImpl* hdoc = static_cast<HTMLDocumentImpl*>( d->m_doc ); if ( hdoc->body() && d->m_bLoadEventEmitted ) { hdoc->body()->dispatchWindowEvent( EventImpl::UNLOAD_EVENT, false, false ); d->m_bLoadEventEmitted = false; hdoc->updateRendering(); } }}const KHTMLSettings *KHTMLPart::settings() const{ return d->m_settings;}void KHTMLPart::setBaseURL( const KURL &url ){ d->m_baseURL = url; if ( d->m_baseURL.protocol().startsWith( "http" ) && !d->m_baseURL.host().isEmpty() && d->m_baseURL.path().isEmpty() ) d->m_baseURL.setPath( "/" );}KURL KHTMLPart::baseURL() const{ if ( d->m_baseURL.isEmpty() ) return m_url; return d->m_baseURL;}void KHTMLPart::setBaseTarget( const QString &target ){ d->m_baseTarget = target;}QString KHTMLPart::baseTarget() const{ return d->m_baseTarget;}KURL KHTMLPart::completeURL( const QString &url, const QString &/*target*/ ){ return KURL( d->m_baseURL.isEmpty() ? m_url : d->m_baseURL, url );}void KHTMLPart::scheduleRedirection( int delay, const QString &url ){ if( d->m_redirectURL.isEmpty() || delay < d->m_delayRedirect ) { //kdDebug( 6050 ) << this << ": scheduling redirection to " // << url << " in " << delay << endl; d->m_delayRedirect = delay; d->m_redirectURL = url; if ( d->m_bComplete ) { d->m_redirectionTimer.stop(); d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true ); } }}void KHTMLPart::slotRedirect(){ kdDebug( 6050 ) << "KHTMLPart::slotRedirect()" << endl; QString u = d->m_redirectURL; d->m_delayRedirect = 0; d->m_redirectURL = QString::null; QString target; u = splitUrlTarget( u, &target ); KParts::URLArgs args; args.reload = true; args.setLockHistory( true ); urlSelected( u, 0, 0, target, args );}void KHTMLPart::slotRedirection(KIO::Job*, const KURL& url){ // the slave told us that we got redirected // kdDebug( 6050 ) << "redirection by KIO to " << url.url() << endl; emit d->m_extension->setLocationBarURL( url.prettyURL() ); d->m_workingURL = url;}// ####bool KHTMLPart::setCharset( const QString &name, bool override ){ QFont f(settings()->stdFontName()); KGlobal::charsets()->setQFont(f, KGlobal::charsets()->charsetForEncoding(name) ); //kdDebug(6005) << "setting to charset " << (int)QFontInfo(f).charSet() <<" " << override << " should be " << name << endl; d->m_settings->setDefaultCharset( f.charSet(), override ); return true;}bool KHTMLPart::setEncoding( const QString &name, bool override ){ d->m_encoding = name; d->m_haveEncoding = override;// setCharset( name, override ); d->m_charset = KGlobal::charsets()->charsetForEncoding(name); d->m_settings->setCharset( d->m_charset ); // the script should not be unicode. We need to know the document is eg. arabic to be // able to choose a unicode font that contains arabic glyphs. d->m_settings->setScript( KGlobal::charsets()->charsetForEncoding( name, true ) ); if( !m_url.isEmpty() ) { // reload document closeURL(); KURL url = m_url; m_url = 0; openURL(url); } return true;}QString KHTMLPart::encoding(){ if(d->m_haveEncoding && !d->m_encoding.isEmpty()) return d->m_encoding; if(d->m_decoder && d->m_decoder->encoding()) return QString(d->m_decoder->encoding()); return(settings()->encoding());}void KHTMLPart::setUserStyleSheet(const KURL &url){ if ( d->m_doc && d->m_doc->docLoader() ) (void) new khtml::PartStyleSheetLoader(this, url.url(), d->m_doc->docLoader());}void KHTMLPart::setUserStyleSheet(const QString &styleSheet){ if ( d->m_doc ) d->m_doc->setUserStyleSheet( styleSheet );}bool KHTMLPart::gotoAnchor( const QString &name )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -