📄 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.
* Copyright (c) 2005 Nokia Corporation, 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.
*/
#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 "css/csshelper.h"
#include "css/cssproperties.h"
#include "css/cssstyleselector.h"
#include "css/css_computedstyle.h"
#include "css/css_valueimpl.h"
#include "dom/dom_string.h"
#include "dom/dom_element.h"
#include "dom/html_document.h"
#include "editing/markup.h"
#include "editing/selection.h"
#include "editing/visible_position.h"
#include "editing/visible_text.h"
#include "editing/visible_units.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/dom2_eventsimpl.h"
#include "xml/dom2_rangeimpl.h"
#include "xml/xml_tokenizer.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 <qptrlist.h>
#include <private/qucomextra_p.h>
#include "khtmlpart_p.h"
#if NOKIA_CHANGES
#include "html/htmltokenizer.h"
const int cPreviewUntil = 32768;
#else
#if APPLE_CHANGES
#include <CoreServices/CoreServices.h>
#endif
#endif
using khtml::ApplyStyleCommand;
using khtml::CHARACTER;
using khtml::ChildFrame;
using khtml::Decoder;
using khtml::EAffinity;
using khtml::EditAction;
using khtml::EditCommandPtr;
using khtml::ETextGranularity;
using khtml::FormData;
using khtml::InlineTextBox;
using khtml::isEndOfDocument;
using khtml::isStartOfDocument;
using khtml::PARAGRAPH;
using khtml::plainText;
using khtml::RenderObject;
using khtml::RenderText;
using khtml::RenderWidget;
using khtml::Selection;
using khtml::Tokenizer;
using khtml::TypingCommand;
using khtml::VisiblePosition;
using khtml::WORD;
using KParts::BrowserInterface;
const int CARET_BLINK_FREQUENCY = 500;
#if NOKIA_CHANGES && __OOM__
#include <oom.h>
class KHTMLPartOOMStopper : public MOOMStopper
{
public:
KHTMLPartOOMStopper( KHTMLPart* part_ ) : iPart( part_ ) { MemoryManager::AddStopper( this ); }
~KHTMLPartOOMStopper() { MemoryManager::RemoveStopper( this ); }
void Stop() { iPart->switchToEmptyDoc(); }
TOOMPriority Priority() { return EOOM_PriorityHigh; }
private:
KHTMLPart* iPart;
};
#endif
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 )
{
d = 0;
KHTMLFactory::registerPart( this );
setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
#if !APPLE_CHANGES
init( new KHTMLView( this, parentWidget, widgetname ), prof );
#endif
}
#if !APPLE_CHANGES
KHTMLPart::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_CHANGES
void 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() ) );
connect(&d->m_lifeSupportTimer, SIGNAL(timeout()), this, SLOT(slotEndLifeSupport()));
#if !APPLE_CHANGES
d->m_dcopobject = new KHTMLPartIface(this);
#endif
#if NOKIA_CHANGES && __OOM__
iOOMStopper = new KHTMLPartOOMStopper( 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 );
#if NOKIA_CHANGES && __OOM__
delete iOOMStopper;
#endif
}
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());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -