📄 khtml_part.cpp
字号:
// -*- c-basic-offset: 2 -*-/* This file is part of the KDE project * * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> * 1999 Lars Knoll <knoll@kde.org> * 1999 Antti Koivisto <koivisto@kde.org> * 2000 Simon Hausmann <hausmann@kde.org> * 2000 Stefan Schimanski <1Stein@gmx.de> * 2001 George Staikos <staikos@kde.org> * Copyright (C) 2004 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#define SPEED_DEBUG#include "khtml_part.h"#if APPLE_CHANGES#define DIRECT_LINKAGE_TO_ECMA#define QT_NO_CLIPBOARD#define QT_NO_DRAGANDDROP#endif#include "khtml_pagecache.h"#include "dom/dom_string.h"#include "dom/dom_element.h"#include "editing/htmlediting.h"#include "html/html_documentimpl.h"#include "html/html_baseimpl.h"#include "html/html_miscimpl.h"#include "html/html_imageimpl.h"#include "rendering/render_block.h"#include "rendering/render_text.h"#include "rendering/render_frames.h"#include "misc/htmlhashes.h"#include "misc/loader.h"#include "xml/dom_selection.h"#include "xml/dom2_eventsimpl.h"#include "xml/xml_tokenizer.h"#include "css/cssstyleselector.h"#include "css/csshelper.h"#include "misc/khtml_text_operations.h"#include "css/css_computedstyle.h"using namespace DOM;#include "khtmlview.h"#include <kparts/partmanager.h>#include "ecma/kjs_proxy.h"#include "khtml_settings.h"#include <sys/types.h>#include <assert.h>#include <unistd.h>#include <kstandarddirs.h>#include <kio/job.h>#include <kio/global.h>#include <kdebug.h>#include <kiconloader.h>#include <klocale.h>#include <kcharsets.h>#include <kmessagebox.h>#include <kstdaction.h>#include <kfiledialog.h>#include <ktrader.h>#include <kdatastream.h>#include <ktempfile.h>#include <kglobalsettings.h>#include <kurldrag.h>#include <kapplication.h>#if !defined(QT_NO_DRAGANDDROP)#include <kmultipledrag.h>#endif#include <ksslcertchain.h>#include <ksslinfodlg.h>#include <qclipboard.h>#include <qfile.h>#include <qmetaobject.h>#include <private/qucomextra_p.h>#include "khtmlpart_p.h"#if APPLE_CHANGES && !KWIQ#include <CoreServices/CoreServices.h>#endifusing khtml::ApplyStyleCommand;using khtml::Decoder;using khtml::DeleteSelectionCommand;using khtml::EditCommand;using khtml::InlineTextBox;using khtml::plainText;using khtml::RenderObject;using khtml::RenderText;using khtml::Tokenizer;using khtml::TypingCommand;using KParts::BrowserInterface;enum { CARET_BLINK_FREQUENCY = 500 };namespace khtml { class PartStyleSheetLoader : public CachedObjectClient { public: PartStyleSheetLoader(KHTMLPart *part, DOM::DOMString url, DocLoader* dl) { m_part = part; m_cachedSheet = Cache::requestStyleSheet(dl, url ); if (m_cachedSheet) m_cachedSheet->ref( this ); } virtual ~PartStyleSheetLoader() { if ( m_cachedSheet ) m_cachedSheet->deref(this); } virtual void setStyleSheet(const DOM::DOMString&, const DOM::DOMString &sheet) { if ( m_part ) m_part->setUserStyleSheet( sheet.string() ); delete this; } QGuardedPtr<KHTMLPart> m_part; khtml::CachedCSSStyleSheet *m_cachedSheet; };};FrameList::Iterator FrameList::find( const QString &name ){ Iterator it = begin(); Iterator e = end(); for (; it!=e; ++it ) if ( (*it).m_name==name ) break; return it;}KHTMLPart::KHTMLPart( QWidget *parentWidget, const char *widgetname, QObject *parent, const char *name, GUIProfile prof ): KParts::ReadOnlyPart( parent, name ){#if KWIQ QOBJECT_TYPE(KHTMLPart);#endif d = 0; KHTMLFactory::registerPart( this ); setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );#if !APPLE_CHANGES init( new KHTMLView( this, parentWidget, widgetname ), prof );#endif}#if !APPLE_CHANGESKHTMLPart::KHTMLPart( KHTMLView *view, QObject *parent, const char *name, GUIProfile prof ): KParts::ReadOnlyPart( parent, name ){ d = 0; KHTMLFactory::registerPart( this ); setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() ); assert( view ); init( view, prof );}#endif // APPLE_CHANGESvoid KHTMLPart::init( KHTMLView *view, GUIProfile prof ){ AtomicString::init(); if ( prof == DefaultGUI ) setXMLFile( "khtml.rc" ); else if ( prof == BrowserViewGUI ) setXMLFile( "khtml_browser.rc" ); frameCount = 0; d = new KHTMLPartPrivate(parent()); d->m_view = view; setWidget( d->m_view ); #if !APPLE_CHANGES d->m_guiProfile = prof;#endif d->m_extension = new KHTMLPartBrowserExtension( this ); d->m_hostExtension = new KHTMLPartBrowserHostExtension( this ); d->m_bSecurityInQuestion = false; d->m_bMousePressed = false;#if !APPLE_CHANGES d->m_paLoadImages = 0; d->m_paViewDocument = new KAction( i18n( "View Document Source" ), 0, this, SLOT( slotViewDocumentSource() ), actionCollection(), "viewDocumentSource" ); d->m_paViewFrame = new KAction( i18n( "View Frame Source" ), 0, this, SLOT( slotViewFrameSource() ), actionCollection(), "viewFrameSource" ); d->m_paSaveBackground = new KAction( i18n( "Save &Background Image As..." ), 0, this, SLOT( slotSaveBackground() ), actionCollection(), "saveBackground" ); d->m_paSaveDocument = new KAction( i18n( "&Save As..." ), CTRL+Key_S, this, SLOT( slotSaveDocument() ), actionCollection(), "saveDocument" ); if ( parentPart() ) d->m_paSaveDocument->setShortcut( KShortcut() ); // avoid clashes d->m_paSaveFrame = new KAction( i18n( "Save &Frame As..." ), 0, this, SLOT( slotSaveFrame() ), actionCollection(), "saveFrame" ); d->m_paSecurity = new KAction( i18n( "Security..." ), "decrypted", 0, this, SLOT( slotSecurity() ), actionCollection(), "security" ); d->m_paDebugRenderTree = new KAction( "print rendering tree to stdout", 0, this, SLOT( slotDebugRenderTree() ), actionCollection(), "debugRenderTree" ); d->m_paDebugDOMTree = new KAction( "print DOM tree to stdout", 0, this, SLOT( slotDebugDOMTree() ), actionCollection(), "debugDOMTree" ); QString foo1 = i18n("Show Images"); QString foo2 = i18n("Show Animated Images"); QString foo3 = i18n("Stop Animated Images"); d->m_paSetEncoding = new KSelectAction( i18n( "Set &Encoding" ), 0, this, SLOT( slotSetEncoding() ), actionCollection(), "setEncoding" ); QStringList encodings = KGlobal::charsets()->descriptiveEncodingNames(); encodings.prepend( i18n( "Auto" ) ); d->m_paSetEncoding->setItems( encodings ); d->m_paSetEncoding->setCurrentItem(0); d->m_paUseStylesheet = new KSelectAction( i18n( "&Use Stylesheet"), 0, this, SLOT( slotUseStylesheet() ), actionCollection(), "useStylesheet" ); d->m_paIncZoomFactor = new KHTMLZoomFactorAction( this, true, i18n( "Increase Font Sizes" ), "viewmag+", this, SLOT( slotIncZoom() ), actionCollection(), "incFontSizes" ); d->m_paDecZoomFactor = new KHTMLZoomFactorAction( this, false, i18n( "Decrease Font Sizes" ), "viewmag-", this, SLOT( slotDecZoom() ), actionCollection(), "decFontSizes" ); d->m_paFind = KStdAction::find( this, SLOT( slotFind() ), actionCollection(), "find" ); if ( parentPart() ) d->m_paFind->setShortcut( KShortcut() ); // avoid clashes d->m_paPrintFrame = new KAction( i18n( "Print Frame" ), "frameprint", 0, this, SLOT( slotPrintFrame() ), actionCollection(), "printFrame" ); d->m_paSelectAll = KStdAction::selectAll( this, SLOT( slotSelectAll() ), actionCollection(), "selectAll" ); if ( parentPart() ) d->m_paSelectAll->setShortcut( KShortcut() ); // avoid clashes#endif#if !APPLE_CHANGES // set the default java(script) flags according to the current host. d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(); d->m_bJScriptDebugEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled(); d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(); d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled();#else // The java, javascript, and plugin settings will be set after the settings // have been initialized. d->m_bJScriptEnabled = true; d->m_bJScriptDebugEnabled = true; d->m_bJavaEnabled = true; d->m_bPluginsEnabled = true;#endif#if !APPLE_CHANGES connect( this, SIGNAL( completed() ), this, SLOT( updateActions() ) ); connect( this, SIGNAL( completed( bool ) ), this, SLOT( updateActions() ) ); connect( this, SIGNAL( started( KIO::Job * ) ), this, SLOT( updateActions() ) ); d->m_popupMenuXML = KXMLGUIFactory::readConfigFile( locate( "data", "khtml/khtml_popupmenu.rc", KHTMLFactory::instance() ) );#endif connect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ), this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) ); connect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ), this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) ); connect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ), this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );#if !APPLE_CHANGES findTextBegin(); //reset find variables#endif connect( &d->m_redirectionTimer, SIGNAL( timeout() ), this, SLOT( slotRedirect() ) );#if !APPLE_CHANGES d->m_dcopobject = new KHTMLPartIface(this);#endif}KHTMLPart::~KHTMLPart(){ //kdDebug(6050) << "KHTMLPart::~KHTMLPart " << this << endl;#if !APPLE_CHANGES if ( d->m_findDialog ) disconnect( d->m_findDialog, SIGNAL( destroyed() ), this, SLOT( slotFindDialogDestroyed() ) ); if ( d->m_manager ) { d->m_manager->setActivePart( 0 ); // Shouldn't we delete d->m_manager here ? (David) // No need to, I would say. We specify "this" as parent qobject // in ::partManager() (Simon) }#endif stopAutoScroll(); cancelRedirection(); if (!d->m_bComplete) closeURL(); disconnect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ), this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) ); disconnect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ), this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) ); disconnect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ), this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) ); clear(); if ( d->m_view ) { d->m_view->hide(); d->m_view->viewport()->hide(); d->m_view->m_part = 0; } #if APPLE_CHANGES delete d->m_hostExtension;#endif delete d; d = 0; KHTMLFactory::deregisterPart( this );}bool KHTMLPart::restoreURL( const KURL &url ){ kdDebug( 6050 ) << "KHTMLPart::restoreURL " << url.url() << endl; cancelRedirection(); /* * That's not a good idea as it will call closeURL() on all * child frames, preventing them from further loading. This * method gets called from restoreState() in case of a full frameset * restoral, and restoreState() calls closeURL() before restoring * anyway. kdDebug( 6050 ) << "closing old URL" << endl; closeURL(); */ d->m_bComplete = false; d->m_bLoadEventEmitted = false; d->m_workingURL = url; // set the java(script) flags according to the current host.#if !APPLE_CHANGES d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host()); d->m_bJScriptDebugEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled(); d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host()); d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());#else d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled(url.host()); d->m_bJScriptDebugEnabled = d->m_settings->isJavaScriptDebugEnabled(); d->m_bJavaEnabled = d->m_settings->isJavaEnabled(url.host()); d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled(url.host());#endif m_url = url; KHTMLPageCache::self()->fetchData( d->m_cacheId, this, SLOT(slotRestoreData(const QByteArray &))); emit started( 0L ); return true;}#if APPLE_CHANGESbool KHTMLPart::didOpenURL(const KURL &url)#elsebool KHTMLPart::openURL( const KURL &url )#endif{ kdDebug( 6050 ) << "KHTMLPart(" << this << ")::openURL " << url.url() << endl; if (d->m_scheduledRedirection == redirectionDuringLoad){ // We're about to get a redirect that happened before the document was // created. This can happen when one frame may change the location of a // sibling. return false; } cancelRedirection(); // clear last edit command d->m_lastEditCommand = EditCommand();#if APPLE_CHANGES KWQ(this)->clearUndoRedoOperations();#endif #if !APPLE_CHANGES // check to see if this is an "error://" URL. This is caused when an error // occurs before this part was loaded (e.g. KonqRun), and is passed to // khtmlpart so that it can display the error. if ( url.protocol() == "error" && url.hasSubURL() ) { closeURL(); /** * The format of the error url is that two variables are passed in the query: * error = int kio error code, errText = QString error text from kio * and the URL where the error happened is passed as a sub URL. */ KURL::List urls = KURL::split( url ); //kdDebug() << "Handling error URL. URL count:" << urls.count() << endl; if ( urls.count() > 1 ) { KURL mainURL = urls.first(); int error = mainURL.queryItem( "error" ).toInt(); // error=0 isn't a valid error code, so 0 means it's missing from the URL if ( error == 0 ) error = KIO::ERR_UNKNOWN; QString errorText = mainURL.queryItem( "errText" ); urls.pop_front(); d->m_workingURL = KURL::join( urls ); //kdDebug() << "Emitting fixed URL " << d->m_workingURL.prettyURL() << endl; emit d->m_extension->setLocationBarURL( d->m_workingURL.prettyURL() ); htmlError( error, errorText, d->m_workingURL ); return true; } }#endif // APPLE_CHANGES KParts::URLArgs args( d->m_extension->urlArgs() );#if !APPLE_CHANGES
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -