khtml Library API Documentation

khtml_part.cpp

00001 // -*- c-basic-offset: 2 -*-
00002 /* This file is part of the KDE project
00003  *
00004  * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
00005  *                     1999 Lars Knoll <knoll@kde.org>
00006  *                     1999 Antti Koivisto <koivisto@kde.org>
00007  *                     2000 Simon Hausmann <hausmann@kde.org>
00008  *                     2000 Stefan Schimanski <1Stein@gmx.de>
00009  *                     2001-2003 George Staikos <staikos@kde.org>
00010  *                     2001-2003 Dirk Mueller <mueller@kde.org>
00011  *                     2002 Apple Computer, Inc.
00012  *
00013  * This library is free software; you can redistribute it and/or
00014  * modify it under the terms of the GNU Library General Public
00015  * License as published by the Free Software Foundation; either
00016  * version 2 of the License, or (at your option) any later version.
00017  *
00018  * This library is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021  * Library General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU Library General Public License
00024  * along with this library; see the file COPYING.LIB.  If not, write to
00025  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00026  * Boston, MA 02111-1307, USA.
00027  */
00028 
00029 #define SPEED_DEBUG
00030 #include "khtml_part.h"
00031 
00032 #include "khtml_pagecache.h"
00033 
00034 #include "dom/dom_string.h"
00035 #include "dom/dom_element.h"
00036 #include "html/html_documentimpl.h"
00037 #include "html/html_baseimpl.h"
00038 #include "html/html_miscimpl.h"
00039 #include "html/html_imageimpl.h"
00040 #include "rendering/render_text.h"
00041 #include "rendering/render_frames.h"
00042 #include "rendering/render_layer.h"
00043 #include "misc/htmlhashes.h"
00044 #include "misc/loader.h"
00045 #include "xml/dom2_eventsimpl.h"
00046 #include "xml/dom2_rangeimpl.h"
00047 #include "xml/xml_tokenizer.h"
00048 #include "css/cssstyleselector.h"
00049 #include "css/csshelper.h"
00050 using namespace DOM;
00051 
00052 #include "khtmlview.h"
00053 #include <kparts/partmanager.h>
00054 #include "ecma/kjs_proxy.h"
00055 #include "khtml_settings.h"
00056 #include "kjserrordlg.h"
00057 
00058 #include <kjs/function.h>
00059 #include <kjs/interpreter.h>
00060 
00061 #include "htmlpageinfo.h"
00062 
00063 #include <sys/types.h>
00064 #include <assert.h>
00065 #include <unistd.h>
00066 
00067 #include <config.h>
00068 
00069 #include <dcopclient.h>
00070 #include <dcopref.h>
00071 #include <kstandarddirs.h>
00072 #include <kstringhandler.h>
00073 #include <kio/job.h>
00074 #include <kio/global.h>
00075 #include <kdebug.h>
00076 #include <kiconloader.h>
00077 #include <klocale.h>
00078 #include <kcharsets.h>
00079 #include <kmessagebox.h>
00080 #include <kstdaction.h>
00081 #include <kfiledialog.h>
00082 #include <ktrader.h>
00083 #include <kdatastream.h>
00084 #include <ktempfile.h>
00085 #include <kglobalsettings.h>
00086 #include <kurldrag.h>
00087 #include <kapplication.h>
00088 #include <kparts/browserinterface.h>
00089 #if !defined(QT_NO_DRAGANDDROP)
00090 #include <kmultipledrag.h>
00091 #endif
00092 #include "../kutils/kfinddialog.h"
00093 #include "../kutils/kfind.h"
00094 
00095 #include <ksslcertchain.h>
00096 #include <ksslinfodlg.h>
00097 
00098 #include <kfileitem.h>
00099 #include <kurifilter.h>
00100 #include <kstatusbar.h>
00101 #include <kurllabel.h>
00102 
00103 #include <qclipboard.h>
00104 #include <qfile.h>
00105 #include <qtooltip.h>
00106 #include <qmetaobject.h>
00107 #include <private/qucomextra_p.h>
00108 
00109 #include "khtmlpart_p.h"
00110 #include "kpopupmenu.h"
00111 #include "rendering/render_form.h"
00112 #include <kwin.h>
00113 
00114 #define HINT_UTF8   106
00115 
00116 namespace khtml {
00117     class PartStyleSheetLoader : public CachedObjectClient
00118     {
00119     public:
00120         PartStyleSheetLoader(KHTMLPart *part, DOM::DOMString url, DocLoader* dl)
00121         {
00122             m_part = part;
00123             m_cachedSheet = dl->requestStyleSheet(url, QString::null, "text/css",
00124                                                   true /* "user sheet" */);
00125             if (m_cachedSheet)
00126         m_cachedSheet->ref( this );
00127         }
00128         virtual ~PartStyleSheetLoader()
00129         {
00130             if ( m_cachedSheet ) m_cachedSheet->deref(this);
00131         }
00132         virtual void setStyleSheet(const DOM::DOMString&, const DOM::DOMString &sheet)
00133         {
00134           if ( m_part )
00135             m_part->setUserStyleSheet( sheet.string() );
00136 
00137             delete this;
00138         }
00139         virtual void error( int, const QString& ) {
00140           delete this;
00141         }
00142         QGuardedPtr<KHTMLPart> m_part;
00143         khtml::CachedCSSStyleSheet *m_cachedSheet;
00144     };
00145 }
00146 
00147 
00148 KHTMLFrameList::Iterator KHTMLFrameList::find( const QString &name )
00149 {
00150     Iterator it = begin();
00151     Iterator e = end();
00152 
00153     for (; it!=e; ++it )
00154         if ( (*it).m_name==name )
00155             break;
00156 
00157     return it;
00158 }
00159 
00160 KHTMLPart::KHTMLPart( QWidget *parentWidget, const char *widgetname, QObject *parent, const char *name, GUIProfile prof )
00161 : KParts::ReadOnlyPart( parent, name )
00162 {
00163     d = 0;
00164     KHTMLFactory::registerPart( this );
00165     setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
00166     init( new KHTMLView( this, parentWidget, widgetname ), prof );
00167 }
00168 
00169 KHTMLPart::KHTMLPart( KHTMLView *view, QObject *parent, const char *name, GUIProfile prof )
00170 : KParts::ReadOnlyPart( parent, name )
00171 {
00172     d = 0;
00173     KHTMLFactory::registerPart( this );
00174     setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
00175     assert( view );
00176     init( view, prof );
00177 }
00178 
00179 void KHTMLPart::init( KHTMLView *view, GUIProfile prof )
00180 {
00181   if ( prof == DefaultGUI )
00182     setXMLFile( "khtml.rc" );
00183   else if ( prof == BrowserViewGUI )
00184     setXMLFile( "khtml_browser.rc" );
00185 
00186   d = new KHTMLPartPrivate(parent());
00187 
00188   d->m_view = view;
00189   setWidget( d->m_view );
00190 
00191   d->m_guiProfile = prof;
00192   d->m_extension = new KHTMLPartBrowserExtension( this );
00193   d->m_hostExtension = new KHTMLPartBrowserHostExtension( this );
00194   d->m_statusBarExtension = new KParts::StatusBarExtension( this );
00195   d->m_statusBarIconLabel = 0L;
00196 
00197   d->m_bSecurityInQuestion = false;
00198   d->m_paLoadImages = 0;
00199   d->m_paDebugScript = 0;
00200   d->m_bMousePressed = false;
00201   d->m_bRightMousePressed = false;
00202   d->m_paViewDocument = new KAction( i18n( "View Do&cument Source" ), CTRL + Key_U, this, SLOT( slotViewDocumentSource() ), actionCollection(), "viewDocumentSource" );
00203   d->m_paViewFrame = new KAction( i18n( "View Frame Source" ), 0, this, SLOT( slotViewFrameSource() ), actionCollection(), "viewFrameSource" );
00204   d->m_paViewInfo = new KAction( i18n( "View Document Information" ), CTRL+Key_I, this, SLOT( slotViewPageInfo() ), actionCollection(), "viewPageInfo" );
00205   d->m_paSaveBackground = new KAction( i18n( "Save &Background Image As..." ), 0, this, SLOT( slotSaveBackground() ), actionCollection(), "saveBackground" );
00206   d->m_paSaveDocument = KStdAction::saveAs( this, SLOT( slotSaveDocument() ), actionCollection(), "saveDocument" );
00207   if ( parentPart() )
00208       d->m_paSaveDocument->setShortcut( KShortcut() ); // avoid clashes
00209   d->m_paSaveFrame = new KAction( i18n( "Save &Frame As..." ), 0, this, SLOT( slotSaveFrame() ), actionCollection(), "saveFrame" );
00210   d->m_paSecurity = new KAction( i18n( "Security..." ), "decrypted", 0, this, SLOT( slotSecurity() ), actionCollection(), "security" );
00211   d->m_paSecurity->setWhatsThis( i18n( "Security Settings<p>"
00212                                        "Shows the certificate of the displayed page. Only "
00213                        "pages that have been transmitted using a secure, encrypted connection have a "
00214                        "certificate.<p> "
00215                        "Hint: If the image shows a closed lock, the page has been transmitted over a "
00216                        "secure connection.") );
00217   d->m_paDebugRenderTree = new KAction( i18n( "Print Rendering Tree to STDOUT" ), 0, this, SLOT( slotDebugRenderTree() ), actionCollection(), "debugRenderTree" );
00218   d->m_paDebugDOMTree = new KAction( i18n( "Print DOM Tree to STDOUT" ), 0, this, SLOT( slotDebugDOMTree() ), actionCollection(), "debugDOMTree" );
00219   d->m_paStopAnimations = new KAction( i18n( "Stop Animated Images" ), 0, this, SLOT( slotStopAnimations() ), actionCollection(), "stopAnimations" );
00220 
00221   d->m_paSetEncoding = new KActionMenu( i18n( "Set &Encoding" ), "charset", actionCollection(), "setEncoding" );
00222   d->m_paSetEncoding->setDelayed( false );
00223 
00224   d->m_automaticDetection = new KPopupMenu( 0L );
00225 
00226   d->m_automaticDetection->insertItem( i18n( "Semi-Automatic" ), 0 );
00227   d->m_automaticDetection->insertItem( i18n( "Arabic" ), 1 );
00228   d->m_automaticDetection->insertItem( i18n( "Baltic" ), 2 );
00229   d->m_automaticDetection->insertItem( i18n( "Central European" ), 3 );
00230   //d->m_automaticDetection->insertItem( i18n( "Chinese" ), 4 );
00231   d->m_automaticDetection->insertItem( i18n( "Greek" ), 5 );
00232   d->m_automaticDetection->insertItem( i18n( "Hebrew" ), 6 );
00233   d->m_automaticDetection->insertItem( i18n( "Japanese" ), 7 );
00234   //d->m_automaticDetection->insertItem( i18n( "Korean" ), 8 );
00235   d->m_automaticDetection->insertItem( i18n( "Russian" ), 9 );
00236   //d->m_automaticDetection->insertItem( i18n( "Thai" ), 10 );
00237   d->m_automaticDetection->insertItem( i18n( "Turkish" ), 11 );
00238   d->m_automaticDetection->insertItem( i18n( "Ukrainian" ), 12 );
00239   //d->m_automaticDetection->insertItem( i18n( "Unicode" ), 13 );
00240   d->m_automaticDetection->insertItem( i18n( "Western European" ), 14 );
00241 
00242   connect( d->m_automaticDetection, SIGNAL( activated( int ) ), this, SLOT( slotAutomaticDetectionLanguage( int ) ) );
00243 
00244   d->m_paSetEncoding->popupMenu()->insertItem( i18n( "Automatic Detection" ), d->m_automaticDetection, 0 );
00245 
00246   d->m_paSetEncoding->insert( new KActionSeparator( actionCollection() ) );
00247 
00248 
00249   d->m_manualDetection = new KSelectAction( i18n( "short for Manual Detection", "Manual" ), 0, this, SLOT( slotSetEncoding() ), actionCollection(), "manualDetection" );
00250   QStringList encodings = KGlobal::charsets()->descriptiveEncodingNames();
00251   d->m_manualDetection->setItems( encodings );
00252   d->m_manualDetection->setCurrentItem( -1 );
00253   d->m_paSetEncoding->insert( d->m_manualDetection );
00254 
00255 
00256   KConfig *config = KGlobal::config();
00257   if ( config->hasGroup( "HTML Settings" ) ) {
00258     config->setGroup( "HTML Settings" );
00259     khtml::Decoder::AutoDetectLanguage language;
00260     QCString name = QTextCodec::codecForLocale()->name();
00261     name = name.lower();
00262 
00263     if ( name == "cp1256" || name == "iso-8859-6" ) {
00264       language = khtml::Decoder::Arabic;
00265     }
00266     else if ( name == "cp1257" || name == "iso-8859-13" || name == "iso-8859-4" ) {
00267       language = khtml::Decoder::Baltic;
00268     }
00269     else if ( name == "cp1250" || name == "ibm852" || name == "iso-8859-2" || name == "iso-8859-3" ) {
00270       language = khtml::Decoder::CentralEuropean;
00271     }
00272     else if ( name == "cp1251" || name == "koi8-r" || name == "iso-8859-5" ) {
00273       language = khtml::Decoder::Russian;
00274     }
00275     else if ( name == "koi8-u" ) {
00276       language = khtml::Decoder::Ukrainian;
00277     }
00278     else if ( name == "cp1253" || name == "iso-8859-7" ) {
00279       language = khtml::Decoder::Greek;
00280     }
00281     else if ( name == "cp1255" || name == "iso-8859-8" || name == "iso-8859-8-i" ) {
00282       language = khtml::Decoder::Hebrew;
00283     }
00284     else if ( name == "jis7" || name == "eucjp" || name == "sjis"  ) {
00285       language = khtml::Decoder::Japanese;
00286     }
00287     else if ( name == "cp1254" || name == "iso-8859-9" ) {
00288       language = khtml::Decoder::Turkish;
00289     }
00290     else if ( name == "cp1252" || name == "iso-8859-1" || name == "iso-8859-15" ) {
00291       language = khtml::Decoder::WesternEuropean;
00292     }
00293     else
00294       language = khtml::Decoder::SemiautomaticDetection;
00295 
00296     int _id = config->readNumEntry( "AutomaticDetectionLanguage", language );
00297     d->m_automaticDetection->setItemChecked( _id, true );
00298     d->m_paSetEncoding->popupMenu()->setItemChecked( 0, true );
00299 
00300     d->m_autoDetectLanguage = static_cast< khtml::Decoder::AutoDetectLanguage >( _id );
00301   }
00302 
00303 
00304   d->m_paUseStylesheet = new KSelectAction( i18n( "Use S&tylesheet"), 0, this, SLOT( slotUseStylesheet() ), actionCollection(), "useStylesheet" );
00305 
00306   if ( prof == BrowserViewGUI ) {
00307       d->m_paIncZoomFactor = new KHTMLZoomFactorAction( this, true, i18n(
00308                   "Increase Font Sizes" ), "viewmag+", "CTRL++;CTRL+=", this,
00309               SLOT( slotIncZoom() ), actionCollection(), "incFontSizes" );
00310       d->m_paIncZoomFactor->setWhatsThis( i18n( "Increase Font Size<p>"
00311                                                 "Make the font in this window bigger. "
00312                             "Click and hold down the mouse button for a menu with all available font sizes." ) );
00313       d->m_paDecZoomFactor = new KHTMLZoomFactorAction( this, false, i18n(
00314                   "Decrease Font Sizes" ), "viewmag-", CTRL + Key_Minus, this,
00315               SLOT( slotDecZoom() ), actionCollection(), "decFontSizes" );
00316       d->m_paDecZoomFactor->setWhatsThis( i18n( "Decrease Font Size<p>"
00317                                                 "Make the font in this window smaller. "
00318                             "Click and hold down the mouse button for a menu with all available font sizes." ) );
00319   }
00320 
00321   d->m_paFind = KStdAction::find( this, SLOT( slotFind() ), actionCollection(), "find" );
00322   d->m_paFind->setWhatsThis( i18n( "Find text<p>"
00323                    "Shows a dialog that allows you to find text on the displayed page." ) );
00324 
00325   d->m_paFindNext = KStdAction::findNext( this, SLOT( slotFindNext() ), actionCollection(), "findNext" );
00326   d->m_paFindNext->setWhatsThis( i18n( "Find next<p>"
00327                        "Find the next occurrence of the text that you "
00328                        "have found using the <b>Find Text</b> function" ) );
00329   if ( parentPart() )
00330   {
00331       d->m_paFind->setShortcut( KShortcut() ); // avoid clashes
00332       d->m_paFindNext->setShortcut( KShortcut() ); // avoid clashes
00333   }
00334 
00335   d->m_paPrintFrame = new KAction( i18n( "Print Frame..." ), "frameprint", 0, this, SLOT( slotPrintFrame() ), actionCollection(), "printFrame" );
00336   d->m_paPrintFrame->setWhatsThis( i18n( "Print Frame<p>"
00337                      "Some pages have several frames. To print only a single frame, click "
00338                      "on it and then use this function." ) );
00339 
00340   d->m_paSelectAll = KStdAction::selectAll( this, SLOT( slotSelectAll() ), actionCollection(), "selectAll" );
00341   if ( parentPart() )
00342       d->m_paSelectAll->setShortcut( KShortcut() ); // avoid clashes
00343 
00344   d->m_paToggleCaretMode = new KToggleAction(i18n("Toggle Caret Mode"),
00345                 Key_F7, this, SLOT(slotToggleCaretMode()),
00346                                 actionCollection(), "caretMode");
00347   d->m_paToggleCaretMode->setChecked(isCaretMode());
00348   if (parentPart())
00349       d->m_paToggleCaretMode->setShortcut(KShortcut()); // avoid clashes
00350 
00351   // set the default java(script) flags according to the current host.
00352   d->m_bBackRightClick = d->m_settings->isBackRightClickEnabled();
00353   d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled();
00354   setDebugScript( d->m_settings->isJavaScriptDebugEnabled() );
00355   d->m_bJavaEnabled = d->m_settings->isJavaEnabled();
00356   d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled();
00357 
00358   // Set the meta-refresh flag...
00359   d->m_metaRefreshEnabled = d->m_settings->isAutoDelayedActionsEnabled ();
00360 
00361   connect( view, SIGNAL( zoomView( int ) ), SLOT( slotZoomView( int ) ) );
00362 
00363   connect( this, SIGNAL( completed() ),
00364            this, SLOT( updateActions() ) );
00365   connect( this, SIGNAL( completed( bool ) ),
00366            this, SLOT( updateActions() ) );
00367   connect( this, SIGNAL( started( KIO::Job * ) ),
00368            this, SLOT( updateActions() ) );
00369 
00370   d->m_popupMenuXML = KXMLGUIFactory::readConfigFile( locate( "data", "khtml/khtml_popupmenu.rc", KHTMLFactory::instance() ) );
00371 
00372   connect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
00373            this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
00374   connect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
00375            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00376   connect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
00377            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00378 
00379   connect ( &d->m_progressUpdateTimer, SIGNAL( timeout() ), this, SLOT( slotProgressUpdate() ) );
00380 
00381   findTextBegin(); //reset find variables
00382 
00383   connect( &d->m_redirectionTimer, SIGNAL( timeout() ),
00384            this, SLOT( slotRedirect() ) );
00385 
00386   d->m_dcopobject = new KHTMLPartIface(this);
00387 
00388   // "khtml" catalog does not exist, our translations are in kdelibs.
00389   // removing this catalog from KGlobal::locale() prevents problems
00390   // with changing the language in applications at runtime -Thomas Reitelbach
00391   KGlobal::locale()->removeCatalogue("khtml");
00392 }
00393 
00394 KHTMLPart::~KHTMLPart()
00395 {
00396   //kdDebug(6050) << "KHTMLPart::~KHTMLPart " << this << endl;
00397 
00398   KConfig *config = KGlobal::config();
00399   config->setGroup( "HTML Settings" );
00400   config->writeEntry( "AutomaticDetectionLanguage", d->m_autoDetectLanguage );
00401 
00402   delete d->m_automaticDetection;
00403   delete d->m_manualDetection;
00404 
00405   slotWalletClosed();
00406   if (!parentPart()) { // only delete it if the top khtml_part closes
00407     removeJSErrorExtension();
00408   }
00409 
00410   d->m_find = 0; // deleted by its parent, the view.
00411 
00412   if ( d->m_manager )
00413   {
00414     d->m_manager->setActivePart( 0 );
00415     // We specify "this" as parent qobject for d->manager, so no need to delete it.
00416   }
00417 
00418   stopAutoScroll();
00419   d->m_redirectionTimer.stop();
00420 
00421   if (!d->m_bComplete)
00422     closeURL();
00423 
00424   disconnect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
00425            this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
00426   disconnect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
00427            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00428   disconnect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
00429            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00430 
00431   clear();
00432 
00433   if ( d->m_view )
00434   {
00435     d->m_view->hide();
00436     d->m_view->viewport()->hide();
00437     d->m_view->m_part = 0;
00438   }
00439 
00440   // Have to delete this here since we forward declare it in khtmlpart_p and
00441   // at least some compilers won't call the destructor in this case.
00442   delete d->m_jsedlg;
00443   d->m_jsedlg = 0;
00444 
00445   delete d; d = 0;
00446   KHTMLFactory::deregisterPart( this );
00447 }
00448 
00449 bool KHTMLPart::restoreURL( const KURL &url )
00450 {
00451   kdDebug( 6050 ) << "KHTMLPart::restoreURL " << url.url() << endl;
00452 
00453   d->m_redirectionTimer.stop();
00454 
00455   /*
00456    * That's not a good idea as it will call closeURL() on all
00457    * child frames, preventing them from further loading. This
00458    * method gets called from restoreState() in case of a full frameset
00459    * restoral, and restoreState() calls closeURL() before restoring
00460    * anyway.
00461   kdDebug( 6050 ) << "closing old URL" << endl;
00462   closeURL();
00463   */
00464 
00465   d->m_bComplete = false;
00466   d->m_bLoadEventEmitted = false;
00467   d->m_workingURL = url;
00468 
00469   // set the java(script) flags according to the current host.
00470   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
00471   setDebugScript( KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled() );
00472   d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
00473   d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
00474 
00475   m_url = url;
00476 
00477   KHTMLPageCache::self()->fetchData( d->m_cacheId, this, SLOT(slotRestoreData(const QByteArray &)));
00478 
00479   emit started( 0L );
00480 
00481   return true;
00482 }
00483 
00484 
00485 bool KHTMLPart::openURL( const KURL &url )
00486 {
00487   kdDebug( 6050 ) << "KHTMLPart(" << this << ")::openURL " << url.url() << endl;
00488 
00489   d->m_redirectionTimer.stop();
00490 
00491   // check to see if this is an "error://" URL. This is caused when an error
00492   // occurs before this part was loaded (e.g. KonqRun), and is passed to
00493   // khtmlpart so that it can display the error.
00494   if ( url.protocol() == "error" && url.hasSubURL() ) {
00495     closeURL();
00496 
00497     if(  d->m_bJScriptEnabled )
00498       d->m_statusBarText[BarOverrideText] = d->m_statusBarText[BarDefaultText] = QString::null;
00499 
00505     KURL::List urls = KURL::split( url );
00506     //kdDebug(6050) << "Handling error URL. URL count:" << urls.count() << endl;
00507 
00508     if ( urls.count() > 1 ) {
00509       KURL mainURL = urls.first();
00510       int error = mainURL.queryItem( "error" ).toInt();
00511       // error=0 isn't a valid error code, so 0 means it's missing from the URL
00512       if ( error == 0 ) error = KIO::ERR_UNKNOWN;
00513       QString errorText = mainURL.queryItem( "errText", HINT_UTF8 );
00514       urls.pop_front();
00515       d->m_workingURL = KURL::join( urls );
00516       //kdDebug(6050) << "Emitting fixed URL " << d->m_workingURL.prettyURL() << endl;
00517       emit d->m_extension->setLocationBarURL( d->m_workingURL.prettyURL() );
00518       htmlError( error, errorText, d->m_workingURL );
00519       return true;
00520     }
00521   }
00522 
00523   KParts::URLArgs args( d->m_extension->urlArgs() );
00524   // in case we have a) no frameset (don't test m_frames.count(), iframes get in there)
00525   // b) the url is identical with the currently
00526   // displayed one (except for the htmlref!) , c) the url request is not a POST
00527   // operation and d) the caller did not request to reload the page we try to
00528   // be smart and instead of reloading the whole document we just jump to the
00529   // request html anchor
00530   bool isFrameSet = false;
00531   if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
00532       HTMLDocumentImpl* htmlDoc = static_cast<HTMLDocumentImpl*>(d->m_doc);
00533       isFrameSet = htmlDoc->body() && (htmlDoc->body()->id() == ID_FRAMESET);
00534   }
00535   
00536   if ( url.hasRef() && !isFrameSet )
00537   {
00538 
00539     //if new url == old url, jump to anchor straight away
00540     //no need to reload unless explicitly asked
00541     bool noReloadForced = !args.reload && !args.redirectedRequest() && !args.doPost();
00542     if (urlcmp( url.url(), m_url.url(), true, true ) && noReloadForced)
00543     {
00544         kdDebug( 6050 ) << "KHTMLPart::openURL, jumping to anchor. m_url = " << url.url() << endl;
00545         m_url = url;
00546         emit started( 0L );
00547         
00548         if ( !gotoAnchor( url.encodedHtmlRef()) )
00549           gotoAnchor( url.htmlRef() );
00550         
00551         d->m_bComplete = true;
00552         if (d->m_doc)
00553         d->m_doc->setParsing(false);
00554         
00555         kdDebug( 6050 ) << "completed..." << endl;
00556         emit completed();
00557         return true;
00558     }
00559     //jump to the anchor AFTER layouting is done, otherwise the position of the
00560     //anchor is not known and we have no clue to which coordinates to jump
00561     else
00562     {
00563         disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(gotoAnchor()));
00564         if ( !url.encodedHtmlRef().isEmpty() )
00565           connect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(gotoAnchor()));
00566     }
00567   }
00568 
00569   // Save offset of viewport when page is reloaded to be compliant
00570   // to every other capable browser out there.
00571   if (args.reload) {
00572     args.xOffset = d->m_view->contentsX();
00573     args.yOffset = d->m_view->contentsY();
00574     d->m_extension->setURLArgs(args);
00575     connect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
00576   }
00577 
00578   if (!d->m_restored)
00579     closeURL();
00580 
00581   // initializing m_url to the new url breaks relative links when opening such a link after this call and _before_ begin() is called (when the first
00582   // data arrives) (Simon)
00583   m_url = url;
00584   if(m_url.protocol().startsWith( "http" ) && !m_url.host().isEmpty() &&
00585      m_url.path().isEmpty()) {
00586     m_url.setPath("/");
00587     emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
00588   }
00589   // copy to m_workingURL after fixing m_url above
00590   d->m_workingURL = m_url;
00591 
00592   args.metaData().insert("main_frame_request", parentPart() == 0 ? "TRUE" : "FALSE" );
00593   args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
00594   args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
00595   args.metaData().insert("PropagateHttpHeader", "true");
00596   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE" : "FALSE" );
00597   args.metaData().insert("ssl_activate_warnings", "TRUE" );
00598   args.metaData().insert("cross-domain", toplevelURL().url());
00599 
00600   if (d->m_restored)
00601   {
00602      args.metaData().insert("referrer", d->m_pageReferrer);
00603      d->m_cachePolicy = KIO::CC_Cache;
00604   }
00605   else if (args.reload)
00606      d->m_cachePolicy = KIO::CC_Refresh;
00607   else
00608      d->m_cachePolicy = KIO::CC_Verify;
00609 
00610   if ( args.doPost() && (m_url.protocol().startsWith("http")) )
00611   {
00612       d->m_job = KIO::http_post( m_url, args.postData, false );
00613       d->m_job->addMetaData("content-type", args.contentType() );
00614   }
00615   else
00616   {
00617       d->m_job = KIO::get( m_url, false, false );
00618       d->m_job->addMetaData("cache", KIO::getCacheControlString(d->m_cachePolicy));
00619   }
00620 
00621   if (widget())
00622      d->m_job->setWindow(widget()->topLevelWidget());
00623   d->m_job->addMetaData(args.metaData());
00624 
00625   connect( d->m_job, SIGNAL( result( KIO::Job* ) ),
00626            SLOT( slotFinished( KIO::Job* ) ) );
00627   connect( d->m_job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
00628            SLOT( slotData( KIO::Job*, const QByteArray& ) ) );
00629   connect ( d->m_job, SIGNAL( infoMessage( KIO::Job*, const QString& ) ),
00630            SLOT( slotInfoMessage(KIO::Job*, const QString& ) ) );
00631   connect( d->m_job, SIGNAL(redirection(KIO::Job*, const KURL& ) ),
00632            SLOT( slotRedirection(KIO::Job*, const KURL&) ) );
00633 
00634   d->m_bComplete = false;
00635   d->m_bLoadEventEmitted = false;
00636 
00637   // delete old status bar msg's from kjs (if it _was_ activated on last URL)
00638   if( d->m_bJScriptEnabled )
00639     d->m_statusBarText[BarOverrideText] = d->m_statusBarText[BarDefaultText] = QString::null;
00640 
00641   // set the javascript flags according to the current url
00642   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
00643   setDebugScript( KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled() );
00644   d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
00645   d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
00646 
00647 
00648   connect( d->m_job, SIGNAL( speed( KIO::Job*, unsigned long ) ),
00649            this, SLOT( slotJobSpeed( KIO::Job*, unsigned long ) ) );
00650 
00651   connect( d->m_job, SIGNAL( percent( KIO::Job*, unsigned long ) ),
00652            this, SLOT( slotJobPercent( KIO::Job*, unsigned long ) ) );
00653 
00654   connect( d->m_job, SIGNAL( result( KIO::Job* ) ),
00655            this, SLOT( slotJobDone( KIO::Job* ) ) );
00656 
00657   d->m_jobspeed = 0;
00658 
00659   // If this was an explicit reload and the user style sheet should be used,
00660   // do a stat to see whether the stylesheet was changed in the meanwhile.
00661   if ( args.reload && !settings()->userStyleSheet().isEmpty() ) {
00662     KURL url( settings()->userStyleSheet() );
00663     KIO::StatJob *job = KIO::stat( url, false /* don't show progress */ );
00664     connect( job, SIGNAL( result( KIO::Job * ) ),
00665              this, SLOT( slotUserSheetStatDone( KIO::Job * ) ) );
00666   }
00667   emit started( 0L );
00668 
00669   return true;
00670 }
00671 
00672 bool KHTMLPart::closeURL()
00673 {
00674   if ( d->m_job )
00675   {
00676     KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
00677     d->m_job->kill();
00678     d->m_job = 0;
00679   }
00680 
00681   if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
00682     HTMLDocumentImpl* hdoc = static_cast<HTMLDocumentImpl*>( d->m_doc );
00683 
00684     if ( hdoc->body() && d->m_bLoadEventEmitted ) {
00685       hdoc->body()->dispatchWindowEvent( EventImpl::UNLOAD_EVENT, false, false );
00686       if ( d->m_doc )
00687         d->m_doc->updateRendering();
00688       d->m_bLoadEventEmitted = false;
00689     }
00690   }
00691 
00692   d->m_bComplete = true; // to avoid emitting completed() in slotFinishedParsing() (David)
00693   d->m_bLoadEventEmitted = true; // don't want that one either
00694   d->m_cachePolicy = KIO::CC_Verify; // reset cache policy
00695 
00696   KHTMLPageCache::self()->cancelFetch(this);
00697   if ( d->m_doc && d->m_doc->parsing() )
00698   {
00699     kdDebug( 6050 ) << " was still parsing... calling end " << endl;
00700     slotFinishedParsing();
00701     d->m_doc->setParsing(false);
00702   }
00703 
00704   if ( !d->m_workingURL.isEmpty() )
00705   {
00706     // Aborted before starting to render
00707     kdDebug( 6050 ) << "Aborted before starting to render, reverting location bar to " << m_url.prettyURL() << endl;
00708     emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
00709   }
00710 
00711   d->m_workingURL = KURL();
00712 
00713   if ( d->m_doc && d->m_doc->docLoader() )
00714     khtml::Cache::loader()->cancelRequests( d->m_doc->docLoader() );
00715 
00716   // tell all subframes to stop as well
00717   ConstFrameIt it = d->m_frames.begin();
00718   ConstFrameIt end = d->m_frames.end();
00719   for (; it != end; ++it )
00720   {
00721     if ( (*it).m_run )
00722       (*it).m_run->abort();
00723     if ( !( *it ).m_part.isNull() )
00724       ( *it ).m_part->closeURL();
00725   }
00726   // tell all objects to stop as well
00727   for (it = d->m_objects.begin(); it != d->m_objects.end(); ++it )
00728   {
00729     if ( !( *it ).m_part.isNull() )
00730       ( *it ).m_part->closeURL();
00731   }
00732 
00733   // Stop any started redirections as well!! (DA)
00734   if ( d && d->m_redirectionTimer.isActive() )
00735     d->m_redirectionTimer.stop();
00736 
00737   // null node activated.
00738   emit nodeActivated(Node());
00739 
00740   // make sure before clear() runs, we pop out of a dialog's message loop
00741   if ( d->m_view )
00742     d->m_view->closeChildDialogs();
00743 
00744   return true;
00745 }
00746 
00747 DOM::HTMLDocument KHTMLPart::htmlDocument() const
00748 {
00749   if (d->m_doc && d->m_doc->isHTMLDocument())
00750     return static_cast<HTMLDocumentImpl*>(d->m_doc);
00751   else
00752     return static_cast<HTMLDocumentImpl*>(0);
00753 }
00754 
00755 DOM::Document KHTMLPart::document() const
00756 {
00757     return d->m_doc;
00758 }
00759 
00760 KParts::BrowserExtension *KHTMLPart::browserExtension() const
00761 {
00762   return d->m_extension;
00763 }
00764 
00765 KParts::BrowserHostExtension *KHTMLPart::browserHostExtension() const
00766 {
00767   return d->m_hostExtension;
00768 }
00769 
00770 KHTMLView *KHTMLPart::view() const
00771 {
00772   return d->m_view;
00773 }
00774 
00775 void KHTMLPart::setStatusMessagesEnabled( bool enable )
00776 {
00777   d->m_statusMessagesEnabled = enable;
00778 }
00779 
00780 KJS::Interpreter *KHTMLPart::jScriptInterpreter()
00781 {
00782   KJSProxy *proxy = jScript();
00783   if (!proxy || proxy->paused())
00784     return 0;
00785 
00786   return proxy->interpreter();
00787 }
00788 
00789 bool KHTMLPart::statusMessagesEnabled() const
00790 {
00791   return d->m_statusMessagesEnabled;
00792 }
00793 
00794 void KHTMLPart::setJScriptEnabled( bool enable )
00795 {
00796   if ( !enable && jScriptEnabled() && d->m_jscript ) {
00797     d->m_jscript->clear();
00798   }
00799   d->m_bJScriptForce = enable;
00800   d->m_bJScriptOverride = true;
00801 }
00802 
00803 bool KHTMLPart::jScriptEnabled() const
00804 {
00805   if(onlyLocalReferences()) return false;
00806 
00807   if ( d->m_bJScriptOverride )
00808       return d->m_bJScriptForce;
00809   return d->m_bJScriptEnabled;
00810 }
00811 
00812 void KHTMLPart::setMetaRefreshEnabled( bool enable )
00813 {
00814   d->m_metaRefreshEnabled = enable;
00815 }
00816 
00817 bool KHTMLPart::metaRefreshEnabled() const
00818 {
00819   return d->m_metaRefreshEnabled;
00820 }
00821 
00822 // Define this to disable dlopening kjs_html, when directly linking to it.
00823 // You need to edit khtml/Makefile.am to add ./ecma/libkjs_html.la to LIBADD
00824 // and to edit khtml/ecma/Makefile.am to s/kjs_html/libkjs_html/, remove libkhtml from LIBADD,
00825 //        remove LDFLAGS line, and replace kde_module with either lib (shared) or noinst (static)
00826 //        Also, change the order of "ecma" and "." in khtml's SUBDIRS line.
00827 // OK - that's the default now, use the opposite of the above instructions to go back
00828 // to "dlopening it" - but it breaks exception catching in kjs_binding.cpp
00829 #define DIRECT_LINKAGE_TO_ECMA
00830 
00831 #ifdef DIRECT_LINKAGE_TO_ECMA
00832 extern "C" { KJSProxy *kjs_html_init(KHTMLPart *khtmlpart); }
00833 #endif
00834 
00835 KJSProxy *KHTMLPart::jScript()
00836 {
00837   if (!jScriptEnabled()) return 0;
00838 
00839   if ( !d->m_jscript )
00840   {
00841 #ifndef DIRECT_LINKAGE_TO_ECMA
00842     KLibrary *lib = KLibLoader::self()->library("kjs_html");
00843     if ( !lib ) {
00844       setJScriptEnabled( false );
00845       return 0;
00846     }
00847     // look for plain C init function
00848     void *sym = lib->symbol("kjs_html_init");
00849     if ( !sym ) {
00850       lib->unload();
00851       setJScriptEnabled( false );
00852       return 0;
00853     }
00854     typedef KJSProxy* (*initFunction)(KHTMLPart *);
00855     initFunction initSym = (initFunction) sym;
00856     d->m_jscript = (*initSym)(this);
00857     d->m_kjs_lib = lib;
00858 #else
00859     d->m_jscript = kjs_html_init(this);
00860     // d->m_kjs_lib remains 0L.
00861 #endif
00862     if (d->m_bJScriptDebugEnabled)
00863         d->m_jscript->setDebugEnabled(true);
00864   }
00865 
00866   return d->m_jscript;
00867 }
00868 
00869 QVariant KHTMLPart::crossFrameExecuteScript(const QString& target,  const QString& script)
00870 {
00871   KHTMLPart* destpart = this;
00872 
00873   QString trg = target.lower();
00874 
00875   if (target == "_top") {
00876     while (destpart->parentPart())
00877       destpart = destpart->parentPart();
00878   }
00879   else if (target == "_parent") {
00880     if (parentPart())
00881       destpart = parentPart();
00882   }
00883   else if (target == "_self" || target == "_blank")  {
00884     // we always allow these
00885   }
00886   else {
00887     destpart = findFrame(target);
00888     if (!destpart)
00889        destpart = this;
00890   }
00891 
00892   // easy way out?
00893   if (destpart == this)
00894     return executeScript(DOM::Node(), script);
00895 
00896   // now compare the domains
00897   if (destpart->checkFrameAccess(this))
00898     return destpart->executeScript(DOM::Node(), script);
00899 
00900   // eww, something went wrong. better execute it in our frame
00901   return executeScript(DOM::Node(), script);
00902 }
00903 
00904 //Enable this to see all JS scripts being executed
00905 //#define KJS_VERBOSE
00906 
00907 KJSErrorDlg *KHTMLPart::jsErrorExtension() {
00908   if (!d->m_settings->jsErrorsEnabled()) {
00909     return 0L;
00910   }
00911 
00912   if (parentPart()) {
00913     return parentPart()->jsErrorExtension();
00914   }
00915 
00916   if (!d->m_statusBarJSErrorLabel) {
00917     d->m_statusBarJSErrorLabel = new KURLLabel(d->m_statusBarExtension->statusBar());
00918     d->m_statusBarJSErrorLabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
00919     d->m_statusBarJSErrorLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
00920     d->m_statusBarJSErrorLabel->setUseCursor(false);
00921     d->m_statusBarExtension->addStatusBarItem(d->m_statusBarJSErrorLabel, 0, false);
00922     QToolTip::add(d->m_statusBarJSErrorLabel, i18n("This web page contains coding errors."));
00923     d->m_statusBarJSErrorLabel->setPixmap(SmallIcon("bug", instance()));
00924     connect(d->m_statusBarJSErrorLabel, SIGNAL(leftClickedURL()), SLOT(launchJSErrorDialog()));
00925     connect(d->m_statusBarJSErrorLabel, SIGNAL(rightClickedURL()), SLOT(jsErrorDialogContextMenu()));
00926   }
00927   if (!d->m_jsedlg) {
00928     d->m_jsedlg = new KJSErrorDlg;
00929     d->m_jsedlg->setURL(m_url.prettyURL());
00930   }
00931   return d->m_jsedlg;
00932 }
00933 
00934 void KHTMLPart::removeJSErrorExtension() {
00935   if (parentPart()) {
00936     parentPart()->removeJSErrorExtension();
00937     return;
00938   }
00939   if (d->m_statusBarJSErrorLabel != 0) {
00940     d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarJSErrorLabel );
00941     delete d->m_statusBarJSErrorLabel;
00942     d->m_statusBarJSErrorLabel = 0;
00943   }
00944   delete d->m_jsedlg;
00945   d->m_jsedlg = 0;
00946 }
00947 
00948 void KHTMLPart::disableJSErrorExtension() {
00949   removeJSErrorExtension();
00950   // These two lines are really kind of hacky, and it sucks to do this inside
00951   // KHTML but I don't know of anything that's reasonably easy as an alternative
00952   // right now.  It makes me wonder if there should be a more clean way to
00953   // contact all running "KHTML" instance as opposed to Konqueror instances too.
00954   d->m_settings->setJSErrorsEnabled(false);
00955   DCOPClient::mainClient()->send("konqueror*", "KonquerorIface", "reparseConfiguration()", QByteArray());
00956 }
00957 
00958 void KHTMLPart::jsErrorDialogContextMenu() {
00959   KPopupMenu *m = new KPopupMenu(0L);
00960   m->insertItem(i18n("&Hide Errors"), this, SLOT(removeJSErrorExtension()));
00961   m->insertItem(i18n("&Disable Error Reporting"), this, SLOT(disableJSErrorExtension()));
00962   m->popup(QCursor::pos());
00963 }
00964 
00965 void KHTMLPart::launchJSErrorDialog() {
00966   KJSErrorDlg *dlg = jsErrorExtension();
00967   if (dlg) {
00968     dlg->show();
00969     dlg->raise();
00970   }
00971 }
00972 
00973 QVariant KHTMLPart::executeScript(const QString& filename, int baseLine, const DOM::Node& n, const QString& script)
00974 {
00975 #ifdef KJS_VERBOSE
00976   kdDebug(6070) << "executeScript: caller='" << name() << "' filename=" << filename << " baseLine=" << baseLine << " script=" << script << endl;
00977 #endif
00978   KJSProxy *proxy = jScript();
00979 
00980   if (!proxy || proxy->paused())
00981     return QVariant();
00982 
00983   KJS::Completion comp;
00984 
00985   QVariant ret = proxy->evaluate(filename, baseLine, script, n, &comp);
00986 
00987   /*
00988    *  Error handling
00989    */
00990   if (comp.complType() == KJS::Throw && !comp.value().isNull()) {
00991     KJSErrorDlg *dlg = jsErrorExtension();
00992     if (dlg) {
00993       KJS::UString msg = comp.value().toString(proxy->interpreter()->globalExec());
00994       dlg->addError(i18n("<b>Error</b>: %1: %2").arg(filename, msg.qstring()));
00995     }
00996   }
00997 
00998   return ret;
00999 }
01000 
01001 QVariant KHTMLPart::executeScript( const QString &script )
01002 {
01003     return executeScript( DOM::Node(), script );
01004 }
01005 
01006 QVariant KHTMLPart::executeScript( const DOM::Node &n, const QString &script )
01007 {
01008 #ifdef KJS_VERBOSE
01009   kdDebug(6070) << "KHTMLPart::executeScript caller='" << name() << "' node=" << n.nodeName().string().latin1() << "(" << (n.isNull() ? 0 : n.nodeType()) << ") " << script << endl;
01010 #endif
01011   KJSProxy *proxy = jScript();
01012 
01013   if (!proxy || proxy->paused())
01014     return QVariant();
01015   d->m_runningScripts++;
01016   KJS::Completion comp;
01017   QVariant ret = proxy->evaluate( QString::null, 1, script, n, &comp );
01018   d->m_runningScripts--;
01019 
01020   /*
01021    *  Error handling
01022    */
01023   if (comp.complType() == KJS::Throw && !comp.value().isNull()) {
01024     KJSErrorDlg *dlg = jsErrorExtension();
01025     if (dlg) {
01026       KJS::UString msg = comp.value().toString(proxy->interpreter()->globalExec());
01027       dlg->addError(i18n("<b>Error</b>: node %1: %2").arg(n.nodeName().string()).arg(msg.qstring()));
01028     }
01029   }
01030 
01031   if (!d->m_runningScripts && d->m_doc && !d->m_doc->parsing() && d->m_submitForm )
01032       submitFormAgain();
01033 
01034 #ifdef KJS_VERBOSE
01035   kdDebug(6070) << "KHTMLPart::executeScript - done" << endl;
01036 #endif
01037   return ret;
01038 }
01039 
01040 bool KHTMLPart::scheduleScript(const DOM::Node &n, const QString& script)
01041 {
01042     //kdDebug(6050) << "KHTMLPart::scheduleScript "<< script << endl;
01043 
01044     d->scheduledScript = script;
01045     d->scheduledScriptNode = n;
01046 
01047     return true;
01048 }
01049 
01050 QVariant KHTMLPart::executeScheduledScript()
01051 {
01052   if( d->scheduledScript.isEmpty() )
01053     return QVariant();
01054 
01055   //kdDebug(6050) << "executing delayed " << d->scheduledScript << endl;
01056 
01057   QVariant ret = executeScript( d->scheduledScriptNode, d->scheduledScript );
01058   d->scheduledScript = QString();
01059   d->scheduledScriptNode = DOM::Node();
01060 
01061   return ret;
01062 }
01063 
01064 void KHTMLPart::setJavaEnabled( bool enable )
01065 {
01066   d->m_bJavaForce = enable;
01067   d->m_bJavaOverride = true;
01068 }
01069 
01070 bool KHTMLPart::javaEnabled() const
01071 {
01072   if (onlyLocalReferences()) return false;
01073 
01074 #ifndef Q_WS_QWS
01075   if( d->m_bJavaOverride )
01076       return d->m_bJavaForce;
01077   return d->m_bJavaEnabled;
01078 #else
01079   return false;
01080 #endif
01081 }
01082 
01083 KJavaAppletContext *KHTMLPart::javaContext()
01084 {
01085   return 0;
01086 }
01087 
01088 KJavaAppletContext *KHTMLPart::createJavaContext()
01089 {
01090   return 0;
01091 }
01092 
01093 void KHTMLPart::setPluginsEnabled( bool enable )
01094 {
01095   d->m_bPluginsForce = enable;
01096   d->m_bPluginsOverride = true;
01097 }
01098 
01099 bool KHTMLPart::pluginsEnabled() const
01100 {
01101   if (onlyLocalReferences()) return false;
01102 
01103   if ( d->m_bPluginsOverride )
01104       return d->m_bPluginsForce;
01105   return d->m_bPluginsEnabled;
01106 }
01107 
01108 void KHTMLPart::slotDebugDOMTree()
01109 {
01110   if ( d->m_doc && d->m_doc->firstChild() )
01111     qDebug("%s", d->m_doc->firstChild()->toHTML().latin1());
01112 }
01113 
01114 void KHTMLPart::slotDebugScript()
01115 {
01116   if (jScript())
01117     jScript()->showDebugWindow();
01118 }
01119 
01120 void KHTMLPart::slotDebugRenderTree()
01121 {
01122 #ifndef NDEBUG
01123   if ( d->m_doc ) {
01124     d->m_doc->renderer()->printTree();
01125     // dump out the contents of the rendering & DOM trees
01126 //    QString dumps;
01127 //    QTextStream outputStream(dumps,IO_WriteOnly);
01128 //    d->m_doc->renderer()->layer()->dump( outputStream );
01129 //    kdDebug() << "dump output:" << "\n" + dumps;
01130   }
01131 #endif
01132 }
01133 
01134 void KHTMLPart::slotStopAnimations()
01135 {
01136   stopAnimations();
01137 }
01138 
01139 void KHTMLPart::setAutoloadImages( bool enable )
01140 {
01141   if ( d->m_doc && d->m_doc->docLoader()->autoloadImages() == enable )
01142     return;
01143 
01144   if ( d->m_doc )
01145     d->m_doc->docLoader()->setAutoloadImages( enable );
01146 
01147   unplugActionList( "loadImages" );
01148 
01149   if ( enable ) {
01150     delete d->m_paLoadImages;
01151     d->m_paLoadImages = 0;
01152   }
01153   else if ( !d->m_paLoadImages )
01154     d->m_paLoadImages = new KAction( i18n( "Display Images on Page" ), "images_display", 0, this, SLOT( slotLoadImages() ), actionCollection(), "loadImages" );
01155 
01156   if ( d->m_paLoadImages ) {
01157     QPtrList<KAction> lst;
01158     lst.append( d->m_paLoadImages );
01159     plugActionList( "loadImages", lst );
01160   }
01161 }
01162 
01163 bool KHTMLPart::autoloadImages() const
01164 {
01165   if ( d->m_doc )
01166     return d->m_doc->docLoader()->autoloadImages();
01167 
01168   return true;
01169 }
01170 
01171 void KHTMLPart::clear()
01172 {
01173   if ( d->m_bCleared )
01174     return;
01175 
01176   d->m_bCleared = true;
01177 
01178   d->m_bClearing = true;
01179 
01180   {
01181     ConstFrameIt it = d->m_frames.begin();
01182     ConstFrameIt end = d->m_frames.end();
01183     for(; it != end; ++it )
01184     {
01185       // Stop HTMLRun jobs for frames
01186       if ( (*it).m_run )
01187         (*it).m_run->abort();
01188     }
01189   }
01190 
01191   {
01192     QValueList<khtml::ChildFrame>::ConstIterator it = d->m_objects.begin();
01193     QValueList<khtml::ChildFrame>::ConstIterator end = d->m_objects.end();
01194     for(; it != end; ++it )
01195     {
01196       // Stop HTMLRun jobs for objects
01197       if ( (*it).m_run )
01198         (*it).m_run->abort();
01199     }
01200   }
01201 
01202 
01203   findTextBegin(); // resets d->m_findNode and d->m_findPos
01204   d->m_mousePressNode = DOM::Node();
01205 
01206 
01207   if ( d->m_doc )
01208     d->m_doc->detach();
01209 
01210   // Moving past doc so that onUnload works.
01211   if ( d->m_jscript )
01212     d->m_jscript->clear();
01213 
01214   if ( d->m_view )
01215     d->m_view->clear();
01216 
01217   // do not dereference the document before the jscript and view are cleared, as some destructors
01218   // might still try to access the document.
01219   if ( d->m_doc ) {
01220     d->m_doc->deref();
01221   }
01222   d->m_doc = 0;
01223 
01224   delete d->m_decoder;
01225   d->m_decoder = 0;
01226 
01227   {
01228     ConstFrameIt it = d->m_frames.begin();
01229     ConstFrameIt end = d->m_frames.end();
01230     for(; it != end; ++it )
01231     {
01232       if ( (*it).m_part )
01233       {
01234         partManager()->removePart( (*it).m_part );
01235         delete (KParts::ReadOnlyPart *)(*it).m_part;
01236       }
01237     }
01238   }
01239 
01240   d->m_frames.clear();
01241   d->m_objects.clear();
01242 
01243   d->m_delayRedirect = 0;
01244   d->m_redirectURL = QString::null;
01245   d->m_redirectionTimer.stop();
01246   d->m_redirectLockHistory = true;
01247   d->m_bClearing = false;
01248   d->m_frameNameId = 1;
01249   d->m_bFirstData = true;
01250 
01251   d->m_bMousePressed = false;
01252 
01253   d->m_selectionStart = DOM::Node();
01254   d->m_selectionEnd = DOM::Node();
01255   d->m_startOffset = 0;
01256   d->m_endOffset = 0;
01257 #ifndef QT_NO_CLIPBOARD
01258   connect( kapp->clipboard(), SIGNAL( selectionChanged()), SLOT( slotClearSelection()));
01259 #endif
01260 
01261   d->m_jobPercent = 0;
01262 
01263   if ( !d->m_haveEncoding )
01264     d->m_encoding = QString::null;
01265 #ifdef SPEED_DEBUG
01266   d->m_parsetime.restart();
01267 #endif
01268 }
01269 
01270 bool KHTMLPart::openFile()
01271 {
01272   return true;
01273 }
01274 
01275 DOM::HTMLDocumentImpl *KHTMLPart::docImpl() const
01276 {
01277     if ( d && d->m_doc && d->m_doc->isHTMLDocument() )
01278         return static_cast<HTMLDocumentImpl*>(d->m_doc);
01279     return 0;
01280 }
01281 
01282 DOM::DocumentImpl *KHTMLPart::xmlDocImpl() const
01283 {
01284     if ( d )
01285         return d->m_doc;
01286     return 0;
01287 }
01288 
01289 void KHTMLPart::slotInfoMessage(KIO::Job* kio_job, const QString& msg)
01290 {
01291   assert(d->m_job == kio_job);
01292 
01293   if (!parentPart())
01294     setStatusBarText(msg, BarDefaultText);
01295 }
01296 
01297 void KHTMLPart::setPageSecurity( PageSecurity sec )
01298 {
01299   if ( sec != NotCrypted && !d->m_statusBarIconLabel && !parentPart() ) {
01300     d->m_statusBarIconLabel = new KURLLabel( d->m_statusBarExtension->statusBar() );
01301     d->m_statusBarIconLabel->setFixedHeight( instance()->iconLoader()->currentSize(KIcon::Small) );
01302     d->m_statusBarIconLabel->setSizePolicy(QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ));
01303     d->m_statusBarIconLabel->setUseCursor( false );
01304     d->m_statusBarExtension->addStatusBarItem( d->m_statusBarIconLabel, 0, false );
01305     connect( d->m_statusBarIconLabel, SIGNAL( leftClickedURL() ), SLOT( slotSecurity() ) );
01306   } else if (d->m_statusBarIconLabel) {
01307     QToolTip::remove(d->m_statusBarIconLabel);
01308   }
01309 
01310   if (d->m_statusBarIconLabel) {
01311     if (d->m_ssl_in_use)
01312       QToolTip::add(d->m_statusBarIconLabel,
01313             i18n("Session is secured with %1 bit %2.").arg(d->m_ssl_cipher_used_bits).arg(d->m_ssl_cipher));
01314     else