| # khtml Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# 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 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 "misc/htmlhashes.h"
    00043 #include "misc/loader.h"
    00044 #include "xml/dom2_eventsimpl.h"
    00045 #include "xml/xml_tokenizer.h"
    00046 #include "css/cssstyleselector.h"
    00047 #include "css/csshelper.h"
    00048 using namespace DOM;
    00049
    00050 #include "khtmlview.h"
    00051 #include <kparts/partmanager.h>
    00052 #include "ecma/kjs_proxy.h"
    00053 #include "khtml_settings.h"
    00054
    00055 #include "htmlpageinfo.h"
    00056
    00057 #include <sys/types.h>
    00058 #include <assert.h>
    00059 #include <unistd.h>
    00060
    00061 #include <kstandarddirs.h>
    00062 #include <kstringhandler.h>
    00063 #include <kio/job.h>
    00064 #include <kio/global.h>
    00065 #include <kdebug.h>
    00066 #include <kiconloader.h>
    00067 #include <klocale.h>
    00068 #include <kcharsets.h>
    00069 #include <kmessagebox.h>
    00070 #include <kstdaction.h>
    00071 #include <kfiledialog.h>
    00072 #include <ktrader.h>
    00073 #include <kdatastream.h>
    00074 #include <ktempfile.h>
    00075 #include <kglobalsettings.h>
    00076 #include <kurldrag.h>
    00077 #include <kapplication.h>
    00078 #include <kparts/browserinterface.h>
    00079 #if !defined(QT_NO_DRAGANDDROP)
    00080 #include <kmultipledrag.h>
    00081 #endif
    00082 #include "../kutils/kfinddialog.h"
    00083 #include "../kutils/kfind.h"
    00084
    00085 #include <ksslcertchain.h>
    00086 #include <ksslinfodlg.h>
    00087
    00088 #include <kfileitem.h>
    00089 #include <kurifilter.h>
    00090
    00091 #include <qclipboard.h>
    00092 #include <qfile.h>
    00093 #include <qmetaobject.h>
    00094 #include <private/qucomextra_p.h>
    00095
    00096 #include "khtmlpart_p.h"
    00097
    00098 namespace khtml {
    00099     class PartStyleSheetLoader : public CachedObjectClient
    00100     {
    00101     public:
    00102         PartStyleSheetLoader(KHTMLPart *part, DOM::DOMString url, DocLoader* dl)
    00103         {
    00104             m_part = part;
    00105             m_cachedSheet = Cache::requestStyleSheet(dl, url );
    00106             if (m_cachedSheet)
    00107                 m_cachedSheet->ref( this );
    00108         }
    00109         virtual ~PartStyleSheetLoader()
    00110         {
    00111             if ( m_cachedSheet ) m_cachedSheet->deref(this);
    00112         }
    00113         virtual void setStyleSheet(const DOM::DOMString&, const DOM::DOMString &sheet)
    00114         {
    00115           if ( m_part )
    00116             m_part->setUserStyleSheet( sheet.string() );
    00117
    00118             delete this;
    00119         }
    00120         QGuardedPtr<KHTMLPart> m_part;
    00121         khtml::CachedCSSStyleSheet *m_cachedSheet;
    00122     };
    00123 }
    00124
    00125
    00126 FrameList::Iterator FrameList::find( const QString &name )
    00127 {
    00128     Iterator it = begin();
    00129     Iterator e = end();
    00130
    00131     for (; it!=e; ++it )
    00132         if ( (*it).m_name==name )
    00133             break;
    00134
    00135     return it;
    00136 }
    00137
    00138 KHTMLPart::KHTMLPart( QWidget *parentWidget, const char *widgetname, QObject *parent, const char *name,
    00139                       GUIProfile prof )
    00140 : KParts::ReadOnlyPart( parent, name )
    00141 {
    00142     d = 0;
    00143     KHTMLFactory::registerPart( this );
    00144     setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
    00145     init( new KHTMLView( this, parentWidget, widgetname ), prof );
    00146 }
    00147
    00148 KHTMLPart::KHTMLPart( KHTMLView *view, QObject *parent, const char *name, GUIProfile prof )
    00149 : KParts::ReadOnlyPart( parent, name )
    00150 {
    00151     d = 0;
    00152     KHTMLFactory::registerPart( this );
    00153     setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
    00154     assert( view );
    00155     init( view, prof );
    00156 }
    00157
    00158 void KHTMLPart::init( KHTMLView *view, GUIProfile prof )
    00159 {
    00160   if ( prof == DefaultGUI )
    00161     setXMLFile( "khtml.rc" );
    00162   else if ( prof == BrowserViewGUI )
    00163     setXMLFile( "khtml_browser.rc" );
    00164
    00165   d = new KHTMLPartPrivate(parent());
    00166
    00167   d->m_view = view;
    00168   setWidget( d->m_view );
    00169
    00170   d->m_guiProfile = prof;
    00171   d->m_extension = new KHTMLPartBrowserExtension( this );
    00172   d->m_hostExtension = new KHTMLPartBrowserHostExtension( this );
    00173
    00174   d->m_bSecurityInQuestion = false;
    00175   d->m_paLoadImages = 0;
    00176   d->m_bMousePressed = false;
    00177   d->m_bRightMousePressed = false;
    00178   d->m_paViewDocument = new KAction( i18n( "View Document Source" ), 0, this, SLOT( slotViewDocumentSource() ), actionCollection(), "viewDocumentSource" );
    00179   d->m_paViewFrame = new KAction( i18n( "View Frame Source" ), 0, this, SLOT( slotViewFrameSource() ), actionCollection(), "viewFrameSource" );
    00180   d->m_paViewInfo = new KAction( i18n( "View Document Information" ), 0, this, SLOT( slotViewPageInfo() ), actionCollection(), "viewPageInfo" );
    00181   d->m_paSaveBackground = new KAction( i18n( "Save &Background Image As..." ), 0, this, SLOT( slotSaveBackground() ), actionCollection(), "saveBackground" );
    00182   d->m_paSaveDocument = new KAction( i18n( "&Save As..." ), CTRL+Key_S, this, SLOT( slotSaveDocument() ), actionCollection(), "saveDocument" );
    00183   if ( parentPart() )
    00184       d->m_paSaveDocument->setShortcut( KShortcut() ); // avoid clashes
    00185   d->m_paSaveFrame = new KAction( i18n( "Save &Frame As..." ), 0, this, SLOT( slotSaveFrame() ), actionCollection(), "saveFrame" );
    00186   d->m_paSecurity = new KAction( i18n( "Security..." ), "decrypted", 0, this, SLOT( slotSecurity() ), actionCollection(), "security" );
    00187   d->m_paDebugRenderTree = new KAction( "Print Rendering Tree to STDOUT", 0, this, SLOT( slotDebugRenderTree() ), actionCollection(), "debugRenderTree" );
    00188   d->m_paDebugDOMTree = new KAction( "Print DOM Tree to STDOUT", 0, this, SLOT( slotDebugDOMTree() ), actionCollection(), "debugDOMTree" );
    00189
    00190   QString foo1 = i18n("Show Images");
    00191   QString foo2 = i18n("Show Animated Images");
    00192   QString foo3 = i18n("Stop Animated Images");
    00193
    00194   d->m_paSetEncoding = new KSelectAction( i18n( "Set &Encoding" ), 0, this, SLOT( slotSetEncoding() ), actionCollection(), "setEncoding" );
    00195   QStringList encodings = KGlobal::charsets()->descriptiveEncodingNames();
    00196   encodings.prepend( i18n( "Auto" ) );
    00197   d->m_paSetEncoding->setItems( encodings );
    00198   d->m_paSetEncoding->setCurrentItem(0);
    00199
    00200   d->m_paUseStylesheet = new KSelectAction( i18n( "Use S&tylesheet"), 0, this, SLOT( slotUseStylesheet() ), actionCollection(), "useStylesheet" );
    00201
    00202   d->m_paIncZoomFactor = new KHTMLZoomFactorAction( this, true, i18n( "Increase Font Sizes" ), "viewmag+", this, SLOT( slotIncZoom() ), actionCollection(), "incFontSizes" );
    00203   d->m_paDecZoomFactor = new KHTMLZoomFactorAction( this, false, i18n( "Decrease Font Sizes" ), "viewmag-", this, SLOT( slotDecZoom() ), actionCollection(), "decFontSizes" );
    00204
    00205   d->m_paFind = KStdAction::find( this, SLOT( slotFind() ), actionCollection(), "find" );
    00206   d->m_paFindNext = KStdAction::findNext( this, SLOT( slotFindNext() ), actionCollection(), "findNext" );
    00207   if ( parentPart() )
    00208   {
    00209       d->m_paFind->setShortcut( KShortcut() ); // avoid clashes
    00210       d->m_paFindNext->setShortcut( KShortcut() ); // avoid clashes
    00211   }
    00212
    00213   d->m_paPrintFrame = new KAction( i18n( "Print Frame" ), "frameprint", 0, this, SLOT( slotPrintFrame() ), actionCollection(), "printFrame" );
    00214
    00215   d->m_paSelectAll = KStdAction::selectAll( this, SLOT( slotSelectAll() ), actionCollection(), "selectAll" );
    00216   if ( parentPart() )
    00217       d->m_paSelectAll->setShortcut( KShortcut() ); // avoid clashes
    00218
    00219   // set the default java(script) flags according to the current host.
    00220   d->m_bBackRightClick = d->m_settings->isBackRightClickEnabled();
    00221   d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled();
    00222   d->m_bJScriptDebugEnabled = d->m_settings->isJavaScriptDebugEnabled();
    00223   d->m_bJavaEnabled = d->m_settings->isJavaEnabled();
    00224   d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled();
    00225
    00226   // Set the meta-refresh flag...
    00227   d->m_metaRefreshEnabled = d->m_settings->isAutoDelayedActionsEnabled ();
    00228
    00229   connect( view, SIGNAL( zoomView( int ) ), SLOT( slotZoomView( int ) ) );
    00230
    00231   connect( this, SIGNAL( completed() ),
    00232            this, SLOT( updateActions() ) );
    00233   connect( this, SIGNAL( completed( bool ) ),
    00234            this, SLOT( updateActions() ) );
    00235   connect( this, SIGNAL( started( KIO::Job * ) ),
    00236            this, SLOT( updateActions() ) );
    00237
    00238   d->m_popupMenuXML = KXMLGUIFactory::readConfigFile( locate( "data", "khtml/khtml_popupmenu.rc", KHTMLFactory::instance() ) );
    00239
    00240   connect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
    00241            this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
    00242   connect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
    00243            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
    00244   connect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
    00245            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
    00246
    00247   connect ( &d->m_progressUpdateTimer, SIGNAL( timeout() ), this, SLOT( slotProgressUpdate() ) );
    00248
    00249   findTextBegin(); //reset find variables
    00250
    00251   connect( &d->m_redirectionTimer, SIGNAL( timeout() ),
    00252            this, SLOT( slotRedirect() ) );
    00253
    00254   d->m_dcopobject = new KHTMLPartIface(this);
    00255
    00256   // "khtml" catalogue does not exist, our translations are in kdelibs.
    00257   // removing this catalogue from KGlobal::locale() prevents problems
    00258   // with changing the language in applications at runtime -Thomas Reitelbach
    00259   KGlobal::locale()->removeCatalogue("khtml");
    00260 }
    00261
    00262 KHTMLPart::~KHTMLPart()
    00263 {
    00264   //kdDebug(6050) << "KHTMLPart::~KHTMLPart " << this << endl;
    00265
    00266   delete d->m_find;
    00267   d->m_find = 0;
    00268
    00269   if ( d->m_manager )
    00270   {
    00271     d->m_manager->setActivePart( 0 );
    00272     // We specify "this" as parent qobject for d->manager, so no need to delete it.
    00273   }
    00274
    00275   stopAutoScroll();
    00276   d->m_redirectionTimer.stop();
    00277
    00278   if (!d->m_bComplete)
    00279     closeURL();
    00280
    00281   disconnect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
    00282            this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
    00283   disconnect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
    00284            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
    00285   disconnect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
    00286            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
    00287
    00288   clear();
    00289
    00290   if ( d->m_view )
    00291   {
    00292     d->m_view->hide();
    00293     d->m_view->viewport()->hide();
    00294     d->m_view->m_part = 0;
    00295   }
    00296
    00297   delete d; d = 0;
    00298   KHTMLFactory::deregisterPart( this );
    00299 }
    00300
    00301 bool KHTMLPart::restoreURL( const KURL &url )
    00302 {
    00303   kdDebug( 6050 ) << "KHTMLPart::restoreURL " << url.url() << endl;
    00304
    00305   d->m_redirectionTimer.stop();
    00306
    00307   /*
    00308    * That's not a good idea as it will call closeURL() on all
    00309    * child frames, preventing them from further loading. This
    00310    * method gets called from restoreState() in case of a full frameset
    00311    * restoral, and restoreState() calls closeURL() before restoring
    00312    * anyway.
    00313   kdDebug( 6050 ) << "closing old URL" << endl;
    00314   closeURL();
    00315   */
    00316
    00317   d->m_bComplete = false;
    00318   d->m_bLoadEventEmitted = false;
    00319   d->m_workingURL = url;
    00320
    00321   // set the java(script) flags according to the current host.
    00322   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
    00323   d->m_bJScriptDebugEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled();
    00324   d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
    00325   d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
    00326
    00327   m_url = url;
    00328
    00329   KHTMLPageCache::self()->fetchData( d->m_cacheId, this, SLOT(slotRestoreData(const QByteArray &)));
    00330
    00331   emit started( 0L );
    00332
    00333   return true;
    00334 }
    00335
    00336
    00337 bool KHTMLPart::openURL( const KURL &url )
    00338 {
    00339   kdDebug( 6050 ) << "KHTMLPart(" << this << ")::openURL " << url.url() << endl;
    00340
    00341   d->m_redirectionTimer.stop();
    00342
    00343   // check to see if this is an "error://" URL. This is caused when an error
    00344   // occurs before this part was loaded (e.g. KonqRun), and is passed to
    00345   // khtmlpart so that it can display the error.
    00346   if ( url.protocol() == "error" && url.hasSubURL() ) {
    00347     closeURL();
    00348
    00349     if(  d->m_bJScriptEnabled )
    00350       d->m_statusBarText[BarOverrideText] = d->m_statusBarText[BarDefaultText] = QString::null;
    00351
    00357     KURL::List urls = KURL::split( url );
    00358     //kdDebug(6050) << "Handling error URL. URL count:" << urls.count() << endl;
    00359
    00360     if ( urls.count() > 1 ) {
    00361       KURL mainURL = urls.first();
    00362       int error = mainURL.queryItem( "error" ).toInt();
    00363       // error=0 isn't a valid error code, so 0 means it's missing from the URL
    00364       if ( error == 0 ) error = KIO::ERR_UNKNOWN;
    00365       QString errorText = mainURL.queryItem( "errText" );
    00366       urls.pop_front();
    00367       d->m_workingURL = KURL::join( urls );
    00368       //kdDebug(6050) << "Emitting fixed URL " << d->m_workingURL.prettyURL() << endl;
    00369       emit d->m_extension->setLocationBarURL( d->m_workingURL.prettyURL() );
    00370       htmlError( error, errorText, d->m_workingURL );
    00371       return true;
    00372     }
    00373   }
    00374
    00375   KParts::URLArgs args( d->m_extension->urlArgs() );
    00376   // in case we have a) no frameset (don't test m_frames.count(), iframes get in there)
    00377   // b) the url is identical with the currently
    00378   // displayed one (except for the htmlref!) , c) the url request is not a POST
    00379   // operation and d) the caller did not request to reload the page we try to
    00380   // be smart and instead of reloading the whole document we just jump to the
    00381   // request html anchor
    00382   bool isFrameSet = false;
    00383   if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
    00384       HTMLDocumentImpl* htmlDoc = static_cast<HTMLDocumentImpl*>(d->m_doc);
    00385       isFrameSet = htmlDoc->body() && (htmlDoc->body()->id() == ID_FRAMESET);
    00386   }
    00387   if ( !isFrameSet && !args.redirectedRequest() &&
    00388        urlcmp( url.url(), m_url.url(), true, true ) &&
    00389        url.hasRef() && !args.doPost() && !args.reload )
    00390   {
    00391     kdDebug( 6050 ) << "KHTMLPart::openURL, jumping to anchor. m_url = " << url.url() << endl;
    00392     m_url = url;
    00393     emit started( 0L );
    00394
    00395     if ( !gotoAnchor( url.encodedHtmlRef()) )
    00396        gotoAnchor( url.htmlRef() );
    00397
    00398     d->m_bComplete = true;
    00399     if (d->m_doc)
    00400        d->m_doc->setParsing(false);
    00401
    00402     kdDebug( 6050 ) << "completed..." << endl;
    00403     emit completed();
    00404     return true;
    00405   }
    00406
    00407   if (!d->m_restored)
    00408   {
    00409     kdDebug( 6050 ) << "closing old URL" << endl;
    00410     closeURL();
    00411   }
    00412
    00413   // 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
    00414   // data arrives) (Simon)
    00415   m_url = url;
    00416   if(m_url.protocol().startsWith( "http" ) && !m_url.host().isEmpty() &&
    00417      m_url.path().isEmpty()) {
    00418     m_url.setPath("/");
    00419     emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
    00420   }
    00421   // copy to m_workingURL after fixing m_url above
    00422   d->m_workingURL = m_url;
    00423
    00424   args.metaData().insert("main_frame_request", parentPart() == 0 ? "TRUE" : "FALSE" );
    00425   args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
    00426   args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
    00427   args.metaData().insert("PropagateHttpHeader", "true");
    00428   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE" : "FALSE" );
    00429   args.metaData().insert("ssl_activate_warnings", "TRUE" );
    00430   if (d->m_restored)
    00431      d->m_cachePolicy = KIO::CC_Cache;
    00432   else if (args.reload)
    00433      d->m_cachePolicy = KIO::CC_Refresh;
    00434   else
    00435      d->m_cachePolicy = KIO::CC_Verify;
    00436
    00437   if ( args.doPost() && (m_url.protocol().startsWith("http")) )
    00438   {
    00439       d->m_job = KIO::http_post( m_url, args.postData, false );
    00440       d->m_job->addMetaData("content-type", args.contentType() );
    00441   }
    00442   else
    00443   {
    00444       d->m_job = KIO::get( m_url, false, false );
    00445       d->m_job->addMetaData("cache", KIO::getCacheControlString(d->m_cachePolicy));
    00446   }
    00447
    00448   if (widget())
    00449      d->m_job->setWindow(widget()->topLevelWidget());
    00450   d->m_job->addMetaData(args.metaData());
    00451
    00452   connect( d->m_job, SIGNAL( result( KIO::Job * ) ),
    00453            SLOT( slotFinished( KIO::Job * ) ) );
    00454   connect( d->m_job, SIGNAL( data( KIO::Job*, const QByteArray &)),
    00455            SLOT( slotData( KIO::Job*, const QByteArray &)));
    00456   connect ( d->m_job, SIGNAL( infoMessage( KIO::Job*,  const QString& ) ),
    00457             SLOT( slotInfoMessage(KIO::Job*, const QString& ) ) );
    00458   connect( d->m_job, SIGNAL(redirection(KIO::Job*, const KURL&) ),
    00459            SLOT( slotRedirection(KIO::Job*,const KURL&) ) );
    00460
    00461   d->m_bComplete = false;
    00462   d->m_bLoadEventEmitted = false;
    00463
    00464   // delete old status bar msg's from kjs (if it _was_ activated on last URL)
    00465   if( d->m_bJScriptEnabled )
    00466     d->m_statusBarText[BarOverrideText] = d->m_statusBarText[BarDefaultText] = QString::null;
    00467
    00468   // set the javascript flags according to the current url
    00469   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
    00470   d->m_bJScriptDebugEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled();
    00471   d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
    00472   d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
    00473
    00474
    00475   kdDebug( 6050 ) << "KHTMLPart::openURL now (before started) m_url = " << m_url.url() << endl;
    00476
    00477   connect( d->m_job, SIGNAL( speed( KIO::Job*, unsigned long ) ),
    00478            this, SLOT( slotJobSpeed( KIO::Job*, unsigned long ) ) );
    00479
    00480   connect( d->m_job, SIGNAL( percent( KIO::Job*, unsigned long ) ),
    00481            this, SLOT( slotJobPercent( KIO::Job*, unsigned long ) ) );
    00482
    00483   connect( d->m_job, SIGNAL( result( KIO::Job* ) ),
    00484            this, SLOT( slotJobDone( KIO::Job* ) ) );
    00485
    00486   d->m_jobspeed = 0;
    00487   emit started( 0L );
    00488
    00489   return true;
    00490 }
    00491
    00492 bool KHTMLPart::closeURL()
    00493 {
    00494   if ( d->m_job )
    00495   {
    00496     KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
    00497     d->m_job->kill();
    00498     d->m_job = 0;
    00499   }
    00500
    00501   if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
    00502     HTMLDocumentImpl* hdoc = static_cast<HTMLDocumentImpl*>( d->m_doc );
    00503
    00504     if ( hdoc->body() && d->m_bLoadEventEmitted ) {
    00505       hdoc->body()->dispatchWindowEvent( EventImpl::UNLOAD_EVENT, false, false );
    00506       if ( d->m_doc )
    00507         d->m_doc->updateRendering();
    00508       d->m_bLoadEventEmitted = false;
    00509     }
    00510   }
    00511
    00512   d->m_bComplete = true; // to avoid emitting completed() in slotFinishedParsing() (David)
    00513   d->m_bLoadEventEmitted = true; // don't want that one either
    00514   d->m_cachePolicy = KIO::CC_Verify; // reset cache policy
    00515
    00516   KHTMLPageCache::self()->cancelFetch(this);
    00517   if ( d->m_doc && d->m_doc->parsing() )
    00518   {
    00519     kdDebug( 6050 ) << " was still parsing... calling end " << endl;
    00520     slotFinishedParsing();
    00521     d->m_doc->setParsing(false);
    00522   }
    00523
    00524   if ( !d->m_workingURL.isEmpty() )
    00525   {
    00526     // Aborted before starting to render
    00527     kdDebug( 6050 ) << "Aborted before starting to render, reverting location bar to " << m_url.prettyURL() << endl;
    00528     emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
    00529   }
    00530
    00531   d->m_workingURL = KURL();
    00532
    00533   if ( d->m_doc && d->m_doc->docLoader() )
    00534     khtml::Cache::loader()->cancelRequests( d->m_doc->docLoader() );
    00535
    00536   // tell all subframes to stop as well
    00537   ConstFrameIt it = d->m_frames.begin();
    00538   ConstFrameIt end = d->m_frames.end();
    00539   for (; it != end; ++it )
    00540   {
    00541     if ( (*it).m_run )
    00542       (*it).m_run->abort();
    00543     if ( !( *it ).m_part.isNull() )
    00544       ( *it ).m_part->closeURL();
    00545   }
    00546
    00547   // Stop any started redirections as well!! (DA)
    00548   if ( d && d->m_redirectionTimer.isActive() )
    00549     d->m_redirectionTimer.stop();
    00550
    00551   // null node activated.
    00552   emit nodeActivated(Node());
    00553
    00554   // make sure before clear() runs, we pop out of a dialog's message loop
    00555   if ( d->m_view )
    00556     d->m_view->closeChildDialogs();
    00557
    00558   return true;
    00559 }
    00560
    00561 DOM::HTMLDocument KHTMLPart::htmlDocument() const
    00562 {
    00563   if (d->m_doc && d->m_doc->isHTMLDocument())
    00564     return static_cast<HTMLDocumentImpl*>(d->m_doc);
    00565   else
    00566     return static_cast<HTMLDocumentImpl*>(0);
    00567 }
    00568
    00569 DOM::Document KHTMLPart::document() const
    00570 {
    00571     return d->m_doc;
    00572 }
    00573
    00574
    00575 KParts::BrowserExtension *KHTMLPart::browserExtension() const
    00576 {
    00577   return d->m_extension;
    00578 }
    00579
    00580 KHTMLView *KHTMLPart::view() const
    00581 {
    00582   return d->m_view;
    00583 }
    00584
    00585 void KHTMLPart::setJScriptEnabled( bool enable )
    00586 {
    00587   if ( !enable && jScriptEnabled() && d->m_jscript ) {
    00588     d->m_jscript->clear();
    00589   }
    00590   d->m_bJScriptForce = enable;
    00591   d->m_bJScriptOverride = true;
    00592 }
    00593
    00594 bool KHTMLPart::jScriptEnabled() const
    00595 {
    00596   if ( d->m_bJScriptOverride )
    00597       return d->m_bJScriptForce;
    00598   return d->m_bJScriptEnabled;
    00599 }
    00600
    00601 void KHTMLPart::setMetaRefreshEnabled( bool enable )
    00602 {
    00603   d->m_metaRefreshEnabled = enable;
    00604 }
    00605
    00606 bool KHTMLPart::metaRefreshEnabled() const
    00607 {
    00608   return d->m_metaRefreshEnabled;
    00609 }
    00610
    00611 // Define this to disable dlopening kjs_html, when directly linking to it.
    00612 // You need to edit khtml/Makefile.am to add ./ecma/libkjs_html.la to LIBADD
    00613 // and to edit khtml/ecma/Makefile.am to s/kjs_html/libkjs_html/, remove libkhtml from LIBADD,
    00614 //        remove LDFLAGS line, and replace kde_module with either lib (shared) or noinst (static)
    00615 //        Also, change the order of "ecma" and "." in khtml's SUBDIRS line.
    00616 // OK - that's the default now, use the opposite of the above instructions to go back
    00617 // to "dlopening it" - but it breaks exception catching in kjs_binding.cpp
    00618 #define DIRECT_LINKAGE_TO_ECMA
    00619
    00620 #ifdef DIRECT_LINKAGE_TO_ECMA
    00621 extern "C" { KJSProxy *kjs_html_init(KHTMLPart *khtmlpart); }
    00622 #endif
    00623
    00624 KJSProxy *KHTMLPart::jScript()
    00625 {
    00626   if (!jScriptEnabled()) return 0;
    00627
    00628   if ( !d->m_jscript )
    00629   {
    00630 #ifndef DIRECT_LINKAGE_TO_ECMA
    00631     KLibrary *lib = KLibLoader::self()->library("kjs_html");
    00632     if ( !lib ) {
    00633       setJScriptEnabled( false );
    00634       return 0;
    00635     }
    00636     // look for plain C init function
    00637     void *sym = lib->symbol("kjs_html_init");
    00638     if ( !sym ) {
    00639       lib->unload();
    00640       setJScriptEnabled( false );
    00641       return 0;
    00642     }
    00643     typedef KJSProxy* (*initFunction)(KHTMLPart *);
    00644     initFunction initSym = (initFunction) sym;
    00645     d->m_jscript = (*initSym)(this);
    00646     d->m_kjs_lib = lib;
    00647 #else
    00648     d->m_jscript = kjs_html_init(this);
    00649     // d->m_kjs_lib remains 0L.
    00650 #endif
    00651     if (d->m_bJScriptDebugEnabled)
    00652         d->m_jscript->setDebugEnabled(true);
    00653   }
    00654
    00655   return d->m_jscript;
    00656 }
    00657
    00658 QVariant KHTMLPart::executeScript( const QString &script )
    00659 {
    00660     return executeScript( DOM::Node(), script );
    00661 }
    00662
    00663 //Enable this to see all JS scripts being executed
    00664 //#define KJS_VERBOSE
    00665
    00666 QVariant KHTMLPart::executeScript( const DOM::Node &n, const QString &script )
    00667 {
    00668 #ifdef KJS_VERBOSE
    00669   kdDebug(6070) << "KHTMLPart::executeScript n=" << n.nodeName().string().latin1() << "(" << (n.isNull() ? 0 : n.nodeType()) << ") " << script << endl;
    00670 #endif
    00671   KJSProxy *proxy = jScript();
    00672
    00673   if (!proxy || proxy->paused())
    00674     return QVariant();
    00675   d->m_runningScripts++;
    00676   QVariant ret = proxy->evaluate( QString::null, 0, script, n );
    00677   d->m_runningScripts--;
    00678   if (!d->m_runningScripts && d->m_doc && !d->m_doc->parsing() && d->m_submitForm )
    00679       submitFormAgain();
    00680
    00681 #ifdef KJS_VERBOSE
    00682   kdDebug(6070) << "KHTMLPart::executeScript - done" << endl;
    00683 #endif
    00684   return ret;
    00685 }
    00686
    00687 bool KHTMLPart::scheduleScript(const DOM::Node &n, const QString& script)
    00688 {
    00689     //kdDebug(6050) << "KHTMLPart::scheduleScript "<< script << endl;
    00690
    00691     d->scheduledScript = script;
    00692     d->scheduledScriptNode = n;
    00693
    00694     return true;
    00695 }
    00696
    00697 QVariant KHTMLPart::executeScheduledScript()
    00698 {
    00699   if( d->scheduledScript.isEmpty() )
    00700     return QVariant();
    00701
    00702   //kdDebug(6050) << "executing delayed " << d->scheduledScript << endl;
    00703
    00704   QVariant ret = executeScript( d->scheduledScriptNode, d->scheduledScript );
    00705   d->scheduledScript = QString();
    00706   d->scheduledScriptNode = DOM::Node();
    00707
    00708   return ret;
    00709 }
    00710
    00711 void KHTMLPart::setJavaEnabled( bool enable )
    00712 {
    00713   d->m_bJavaForce = enable;
    00714   d->m_bJavaOverride = true;
    00715 }
    00716
    00717 bool KHTMLPart::javaEnabled() const
    00718 {
    00719 #ifndef Q_WS_QWS
    00720   if( d->m_bJavaOverride )
    00721       return d->m_bJavaForce;
    00722   return d->m_bJavaEnabled;
    00723 #else
    00724   return false;
    00725 #endif
    00726 }
    00727
    00728 KJavaAppletContext *KHTMLPart::javaContext()
    00729 {
    00730 #ifndef Q_WS_QWS
    00731   return d->m_javaContext;
    00732 #else
    00733   return 0;
    00734 #endif
    00735 }
    00736
    00737 KJavaAppletContext *KHTMLPart::createJavaContext()
    00738 {
    00739 #ifndef Q_WS_QWS
    00740   if ( !d->m_javaContext ) {
    00741       d->m_javaContext = new KJavaAppletContext();
    00742       connect( d->m_javaContext, SIGNAL(showStatus(const QString&)),
    00743                this, SIGNAL(setStatusBarText(const QString&)) );
    00744       connect( d->m_javaContext, SIGNAL(showDocument(const QString&, const QString&)),
    00745                this, SLOT(slotShowDocument(const QString&, const QString&)) );
    00746       connect( d->m_javaContext, SIGNAL(appletLoaded()),
    00747                this, SLOT(checkCompleted()) );
    00748   }
    00749
    00750   return d->m_javaContext;
    00751 #else
    00752   return 0;
    00753 #endif
    00754 }
    00755
    00756 void KHTMLPart::setPluginsEnabled( bool enable )
    00757 {
    00758   d->m_bPluginsForce = enable;
    00759   d->m_bPluginsOverride = true;
    00760 }
    00761
    00762 bool KHTMLPart::pluginsEnabled() const
    00763 {
    00764   if ( d->m_bPluginsOverride )
    00765       return d->m_bPluginsForce;
    00766   return d->m_bPluginsEnabled;
    00767 }
    00768
    00769 void KHTMLPart::slotShowDocument( const QString &url, const QString &target )
    00770 {
    00771   // this is mostly copied from KHTMLPart::slotChildURLRequest. The better approach
    00772   // would be to put those functions into a single one.
    00773   khtml::ChildFrame *child = 0;
    00774   KParts::URLArgs args;
    00775   args.frameName = target;
    00776
    00777   QString frameName = args.frameName.lower();
    00778   if ( !frameName.isEmpty() )
    00779   {
    00780     if ( frameName == QString::fromLatin1( "_top" ) )
    00781     {
    00782       emit d->m_extension->openURLRequest( url, args );
    00783       return;
    00784     }
    00785     else if ( frameName == QString::fromLatin1( "_blank" ) )
    00786     {
    00787       emit d->m_extension->createNewWindow( url, args );
    00788       return;
    00789     }
    00790     else if ( frameName == QString::fromLatin1( "_parent" ) )
    00791     {
    00792       KParts::URLArgs newArgs( args );
    00793       newArgs.frameName = QString::null;
    00794
    00795       emit d->m_extension->openURLRequest( url, newArgs );
    00796       return;
    00797     }
    00798     else if ( frameName != QString::fromLatin1( "_self" ) )
    00799     {
    00800       khtml::ChildFrame *_frame = recursiveFrameRequest( url, args );
    00801
    00802       if ( !_frame )
    00803       {
    00804         emit d->m_extension->openURLRequest( url, args );
    00805         return;
    00806       }
    00807
    00808       child = _frame;
    00809     }
    00810   }
    00811
    00812   // TODO: handle child target correctly! currently the script are always executed fur the parent
    00813   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
    00814       executeScript( KURL::decode_string( url.right( url.length() - 11) ) );
    00815       return;
    00816   }
    00817
    00818   if ( child ) {
    00819       requestObject( child, KURL(url), args );
    00820   }  else if ( frameName == "_self" )
    00821   {
    00822       KParts::URLArgs newArgs( args );
    00823       newArgs.frameName = QString::null;
    00824       emit d->m_extension->openURLRequest( KURL(url), newArgs );
    00825   }
    00826 }
    00827
    00828 void KHTMLPart::slotDebugDOMTree()
    00829 {
    00830   if ( d->m_doc && d->m_doc->firstChild() )
    00831     qDebug("%s", d->m_doc->firstChild()->toHTML().latin1());
    00832 }
    00833
    00834 void KHTMLPart::slotDebugRenderTree()
    00835 {
    00836 #ifndef NDEBUG
    00837   if ( d->m_doc )
    00838     d->m_doc->renderer()->printTree();
    00839 #endif
    00840 }
    00841
    00842 void KHTMLPart::setAutoloadImages( bool enable )
    00843 {
    00844   if ( d->m_doc && d->m_doc->docLoader()->autoloadImages() == enable )
    00845     return;
    00846
    00847   if ( d->m_doc )
    00848     d->m_doc->docLoader()->setAutoloadImages( enable );
    00849
    00850   unplugActionList( "loadImages" );
    00851
    00852   if ( enable ) {
    00853     delete d->m_paLoadImages;
    00854     d->m_paLoadImages = 0;
    00855   }
    00856   else if ( !d->m_paLoadImages )
    00857     d->m_paLoadImages = new KAction( i18n( "Display Images on Page" ), "images_display", 0, this, SLOT( slotLoadImages() ), actionCollection(), "loadImages" );
    00858
    00859   if ( d->m_paLoadImages ) {
    00860     QPtrList<KAction> lst;
    00861     lst.append( d->m_paLoadImages );
    00862     plugActionList( "loadImages", lst );
    00863   }
    00864 }
    00865
    00866 bool KHTMLPart::autoloadImages() const
    00867 {
    00868   if ( d->m_doc )
    00869     return d->m_doc->docLoader()->autoloadImages();
    00870
    00871   return true;
    00872 }
    00873
    00874 void KHTMLPart::clear()
    00875 {
    00876   if ( d->m_bCleared )
    00877     return;
    00878   d->m_bCleared = true;
    00879
    00880   d->m_bClearing = true;
    00881
    00882   {
    00883     ConstFrameIt it = d->m_frames.begin();
    00884     ConstFrameIt end = d->m_frames.end();
    00885     for(; it != end; ++it )
    00886     {
    00887       // Stop HTMLRun jobs for frames
    00888       if ( (*it).m_run )
    00889         (*it).m_run->abort();
    00890     }
    00891   }
    00892
    00893   {
    00894     QValueList<khtml::ChildFrame>::ConstIterator it = d->m_objects.begin();
    00895     QValueList<khtml::ChildFrame>::ConstIterator end = d->m_objects.end();
    00896     for(; it != end; ++it )
    00897     {
    00898       // Stop HTMLRun jobs for objects
    00899       if ( (*it).m_run )
    00900         (*it).m_run->abort();
    00901     }
    00902   }
    00903
    00904
    00905   findTextBegin(); // resets d->m_findNode and d->m_findPos
    00906
    00907   d->m_mousePressNode = DOM::Node();
    00908
    00909
    00910   if ( d->m_doc )
    00911     d->m_doc->detach();
    00912
    00913   // Moving past doc so that onUnload works.
    00914   if ( d->m_jscript )
    00915     d->m_jscript->clear();
    00916
    00917   if ( d->m_view )
    00918     d->m_view->clear();
    00919
    00920   // do not dereference the document before the jscript and view are cleared, as some destructors
    00921   // might still try to access the document.
    00922   if ( d->m_doc )
    00923     d->m_doc->deref();
    00924   d->m_doc = 0;
    00925
    00926   delete d->m_decoder;
    00927   d->m_decoder = 0;
    00928
    00929   {
    00930     ConstFrameIt it = d->m_frames.begin();
    00931     ConstFrameIt end = d->m_frames.end();
    00932     for(; it != end; ++it )
    00933     {
    00934       if ( (*it).m_part )
    00935       {
    00936         partManager()->removePart( (*it).m_part );
    00937         delete (KParts::ReadOnlyPart *)(*it).m_part;
    00938       }
    00939     }
    00940   }
    00941
    00942   d->m_frames.clear();
    00943   d->m_objects.clear();
    00944
    00945 #ifndef Q_WS_QWS
    00946   if( d->m_javaContext )
    00947   {
    00948     d->m_javaContext->deleteLater();
    00949     d->m_javaContext = 0;
    00950   }
    00951 #endif
    00952
    00953   d->m_delayRedirect = 0;
    00954   d->m_redirectURL = QString::null;
    00955   d->m_redirectLockHistory = true;
    00956   d->m_bHTTPRefresh = false;
    00957   d->m_bClearing = false;
    00958   d->m_frameNameId = 1;
    00959   d->m_bFirstData = true;
    00960
    00961   d->m_bMousePressed = false;
    00962
    00963   d->m_selectionStart = DOM::Node();
    00964   d->m_selectionEnd = DOM::Node();
    00965   d->m_startOffset = 0;
    00966   d->m_endOffset = 0;
    00967 #ifndef QT_NO_CLIPBOARD
    00968   connect( kapp->clipboard(), SIGNAL( selectionChanged()), SLOT( slotClearSelection()));
    00969 #endif
    00970
    00971   d->m_jobPercent = 0;
    00972
    00973   if ( !d->m_haveEncoding )
    00974     d->m_encoding = QString::null;
    00975 #ifdef SPEED_DEBUG
    00976   d->m_parsetime.restart();
    00977 #endif
    00978 }
    00979
    00980 bool KHTMLPart::openFile()
    00981 {
    00982   return true;
    00983 }
    00984
    00985 DOM::HTMLDocumentImpl *KHTMLPart::docImpl() const
    00986 {
    00987     if ( d && d->m_doc && d->m_doc->isHTMLDocument() )
    00988         return static_cast<HTMLDocumentImpl*>(d->m_doc);
    00989     return 0;
    00990 }
    00991
    00992 DOM::DocumentImpl *KHTMLPart::xmlDocImpl() const
    00993 {
    00994     if ( d )
    00995         return d->m_doc;
    00996     return 0;
    00997 }
    00998
    00999 void KHTMLPart::slotInfoMessage(KIO::Job* kio_job, const QString& msg)
    01000 {
    01001   assert(d->m_job == kio_job);
    01002
    01003   if (!parentPart())
    01004     setStatusBarText(msg, BarDefaultText);
    01005 }
    01006
    01007 void KHTMLPart::slotData( KIO::Job* kio_job, const QByteArray &data )
    01008 {
    01009   assert ( d->m_job == kio_job );
    01010
    01011   //kdDebug( 6050 ) << "slotData: " << data.size() << endl;
    01012   // The first data ?
    01013   if ( !d->m_workingURL.isEmpty() )
    01014   {
    01015       //kdDebug( 6050 ) << "begin!" << endl;
    01016
    01017     d->m_job->suspend();
    01018     begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
    01019     d->m_job->resume();
    01020
    01021
    01022     d->m_doc->docLoader()->setCachePolicy(d->m_cachePolicy);
    01023     d->m_workingURL = KURL();
    01024
    01025     d->m_cacheId = KHTMLPageCache::self()->createCacheEntry();
    01026
    01027     // When the first data arrives, the metadata has just been made available
    01028     d->m_httpHeaders = d->m_job->queryMetaData("HTTP-Headers");
    01029     time_t cacheCreationDate =  d->m_job->queryMetaData("cache-creation-date").toLong();
    01030     d->m_doc->docLoader()->setCacheCreationDate(cacheCreationDate);
    01031
    01032     d->m_pageServices = d->m_job->queryMetaData("PageServices");
    01033
    01034     d->m_bSecurityInQuestion = false;
    01035     d->m_ssl_in_use = (d->m_job->queryMetaData("ssl_in_use") == "TRUE");
    01036     kdDebug(6050) << "SSL in use? " << d->m_job->queryMetaData("ssl_in_use") << endl;
    01037
    01038     {
    01039     KHTMLPart *p = parentPart();
    01040     if (p && p->d->m_ssl_in_use != d->m_ssl_in_use) {
    01041         while (p->parentPart()) p = p->parentPart();
    01042
    01043         p->d->m_paSecurity->setIcon( "halfencrypted" );
    01044         p->d->m_bSecurityInQuestion = true;
    01045         kdDebug(6050) << "parent setIcon half done." << endl;
    01046     }
    01047     }
    01048
    01049     d->m_paSecurity->setIcon( d->m_ssl_in_use ? "encrypted" : "decrypted" );
    01050     kdDebug(6050) << "setIcon " << ( d->m_ssl_in_use ? "encrypted" : "decrypted" ) << " done." << endl;
    01051
    01052     // Shouldn't all of this be done only if ssl_in_use == true ? (DF)
    01053
    01054     d->m_ssl_parent_ip = d->m_job->queryMetaData("ssl_parent_ip");
    01055     d->m_ssl_parent_cert = d->m_job->queryMetaData("ssl_parent_cert");
    01056     d->m_ssl_peer_certificate = d->m_job->queryMetaData("ssl_peer_certificate");
    01057     d->m_ssl_peer_chain = d->m_job->queryMetaData("ssl_peer_chain");
    01058     d->m_ssl_peer_ip = d->m_job->queryMetaData("ssl_peer_ip");
    01059     d->m_ssl_cipher = d->m_job->queryMetaData("ssl_cipher");
    01060     d->m_ssl_cipher_desc = d->m_job->queryMetaData("ssl_cipher_desc");
    01061     d->m_ssl_cipher_version = d->m_job->queryMetaData("ssl_cipher_version");
    01062     d->m_ssl_cipher_used_bits = d->m_job->queryMetaData("ssl_cipher_used_bits");
    01063     d->m_ssl_cipher_bits = d->m_job->queryMetaData("ssl_cipher_bits");
    01064     d->m_ssl_cert_state = d->m_job->queryMetaData("ssl_cert_state");
    01065
    01066     // Check for charset meta-data
    01067     QString qData = d->m_job->queryMetaData("charset");
    01068     if ( !qData.isEmpty() && !d->m_haveEncoding ) // only use information if the user didn't override the settings
    01069        d->m_encoding = qData;
    01070
    01071     // Support for http-refresh
    01072     qData = d->m_job->queryMetaData("http-refresh");
    01073     if( !qData.isEmpty() && d->m_metaRefreshEnabled )
    01074     {
    01075       kdDebug(6050) << "HTTP Refresh Request: " << qData << endl;
    01076       int delay;
    01077       int pos = qData.find( ';' );
    01078       if ( pos == -1 )
    01079         pos = qData.find( ',' );
    01080
    01081       if( pos == -1 )
    01082       {
    01083         delay = qData.stripWhiteSpace().toInt();
    01084         scheduleRedirection( qData.toInt(), m_url.url());
    01085       }
    01086       else
    01087       {
    01088         int end_pos = qData.length();
    01089         delay = qData.left(pos).stripWhiteSpace().toInt();
    01090         while ( qData[++pos] == ' ' );
    01091         if ( qData.find( "url", pos, false ) == pos )
    01092         {
    01093           pos += 3;
    01094           while (qData[pos] == ' ' || qData[pos] == '=' )
    01095               pos++;
    01096           if ( qData[pos] == '"' )
    01097           {
    01098               pos++;
    01099               int index = end_pos-1;
    01100               while( index > pos )
    01101               {
    01102                 if ( qData[index] == '"' )
    01103                     break;
    01104                 index--;
    01105               }
    01106               if ( index > pos )
    01107                 end_pos = index;
    01108           }
    01109         }
    01110         scheduleRedirection( delay, d->m_doc->completeURL( qData.mid( pos, end_pos ) ));
    01111       }
    01112       d->m_bHTTPRefresh = true;
    01113     }
    01114
    01115     if ( !m_url.isLocalFile() ) {
    01116         // Support for http last-modified
    01117         d->m_lastModified = d->m_job->queryMetaData("modified");
    01118     } else
    01119         d->m_lastModified = QString::null; // done on-demand by lastModified()
    01120   }
    01121
    01122   KHTMLPageCache::self()->addData(d->m_cacheId, data);
    01123   write( data.data(), data.size() );
    01124 }
    01125
    01126 void KHTMLPart::slotRestoreData(const QByteArray &data )
    01127 {
    01128   // The first data ?
    01129   if ( !d->m_workingURL.isEmpty() )
    01130   {
    01131      long saveCacheId = d->m_cacheId;
    01132      begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
    01133      d->m_cacheId = saveCacheId;
    01134      d->m_workingURL = KURL();
    01135   }
    01136
    01137   //kdDebug( 6050 ) << "slotRestoreData: " << data.size() << endl;
    01138   write( data.data(), data.size() );
    01139
    01140   if (data.size() == 0)
    01141   {
    01142       //kdDebug( 6050 ) << "slotRestoreData: <<end of data>>" << endl;
    01143      // End of data.
    01144     if (d->m_doc && d->m_doc->parsing())
    01145         end(); //will emit completed()
    01146   }
    01147 }
    01148
    01149 void KHTMLPart::showError( KIO::Job* job )
    01150 {
    01151   kdDebug(6050) << "KHTMLPart::showError d->m_bParsing=" << (d->m_doc && d->m_doc->parsing()) << " d->m_bComplete=" << d->m_bComplete
    01152                 << " d->m_bCleared=" << d->m_bCleared << endl;
    01153
    01154   if (job->error() == KIO::ERR_NO_CONTENT)
    01155         return;
    01156
    01157   if ( (d->m_doc && d->m_doc->parsing()) || d->m_workingURL.isEmpty() ) // if we got any data already
    01158     job->showErrorDialog( /*d->m_view*/ );
    01159   else
    01160   {
    01161     htmlError( job->error(), job->errorText(), d->m_workingURL );
    01162   }
    01163 }
    01164
    01165 // This is a protected method, placed here because of it's relevance to showError
    01166 void KHTMLPart::htmlError( int errorCode, const QString& text, const KURL& reqUrl )
    01167 {
    01168   kdDebug(6050) << "KHTMLPart::htmlError errorCode=" << errorCode << " text=" << text << endl;
    01169   // make sure we're not executing any embedded JS
    01170   bool bJSFO = d->m_bJScriptForce;
    01171   bool bJSOO = d->m_bJScriptOverride;
    01172   d->m_bJScriptForce = false;
    01173   d->m_bJScriptOverride = true;
    01174   begin();
    01175   QString errText = QString::fromLatin1( "<HTML><HEAD><TITLE>" );
    01176   errText += i18n( "Error while loading %1" ).arg( reqUrl.htmlURL() );
    01177   errText += QString::fromLatin1( "</TITLE></HEAD><BODY><P>" );
    01178   errText += i18n( "An error occured while loading <B>%1</B>:" ).arg( reqUrl.htmlURL() );
    01179   errText += QString::fromLatin1( "</P><P>" );
    01180   QString kioErrString = KIO::buildErrorString( errorCode, text );
    01181
    01182   kioErrString.replace(QRegExp("&"), QString("&amp;"));
    01183   kioErrString.replace(QRegExp("<"), QString("&lt;"));
    01184   kioErrString.replace(QRegExp(">"), QString("&gt;"));
    01185
    01186   // In case the error string has '\n' in it, replace with <BR/>
    01187   kioErrString.replace( QRegExp("\n"), "<BR/>" );
    01188
    01189   errText += kioErrString;
    01190   errText += QString::fromLatin1( "</P></BODY></HTML>" );
    01191   write(errText);
    01192   end();
    01193
    01194   d->m_bJScriptForce = bJSFO;
    01195   d->m_bJScriptOverride = bJSOO;
    01196
    01197   // make the working url the current url, so that reload works and
    01198   // emit the progress signals to advance one step in the history
    01199   // (so that 'back' works)
    01200   m_url = reqUrl; // same as d->m_workingURL
    01201   d->m_workingURL = KURL();
    01202   emit started( 0 );
    01203   emit completed();
    01204   return;
    01205   // following disabled until 3.1
    01206
    01207   QString errorName, techName, description;
    01208   QStringList causes, solutions;
    01209
    01210   QByteArray raw = KIO::rawErrorDetail( errorCode, text, &reqUrl );
    01211   QDataStream stream(raw, IO_ReadOnly);
    01212
    01213   stream >> errorName >> techName >> description >> causes >> solutions;
    01214
    01215   QString url, protocol, datetime;
    01216   url = reqUrl.prettyURL();
    01217   protocol = reqUrl.protocol();
    01218   datetime = KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(),
    01219                                                 false );
    01220
    01221   QString doc = QString::fromLatin1( "<html><head><title>" );
    01222   doc += i18n( "Error: " );
    01223   doc += errorName;
    01224   doc += QString::fromLatin1( " - %1</title></head><body><h1>" ).arg( url );
    01225   doc += i18n( "The requested operation could not be completed" );
    01226   doc += QString::fromLatin1( "</h1><h2>" );
    01227   doc += errorName;
    01228   doc += QString::fromLatin1( "</h2>" );
    01229   if ( techName != QString::null ) {
    01230     doc += QString::fromLatin1( "<h2>" );
    01231     doc += i18n( "Technical Reason: " );
    01232     doc += techName;
    01233     doc += QString::fromLatin1( "</h2>" );
    01234   }
    01235   doc += QString::fromLatin1( "<h3>" );
    01236   doc += i18n( "Details of the Request:" );
    01237   doc += QString::fromLatin1( "</h3><ul><li>" );
    01238   doc += i18n( "URL: %1" ).arg( url );
    01239   doc += QString::fromLatin1( "</li><li>" );
    01240   if ( protocol != QString::null ) {
    01241     // uncomment for 3.1... i18n change
    01242     // doc += i18n( "Protocol: %1" ).arg( protocol ).arg( protocol );
    01243     doc += QString::fromLatin1( "</li><li>" );
    01244   }
    01245   doc += i18n( "Date and Time: %1" ).arg( datetime );
    01246   doc += QString::fromLatin1( "</li><li>" );
    01247   doc += i18n( "Additional Information: %1" ).arg( text );
    01248   doc += QString::fromLatin1( "</li></ul><h3>" );
    01249   doc += i18n( "Description:" );
    01250   doc += QString::fromLatin1( "</h3><p>" );
    01251   doc += description;
    01252   doc += QString::fromLatin1( "</p>" );
    01253   if ( causes.count() ) {
    01254     doc += QString::fromLatin1( "<h3>" );
    01255     doc += i18n( "Possible Causes:" );
    01256     doc += QString::fromLatin1( "</h3><ul><li>" );
    01257     doc += causes.join( "</li><li>" );
    01258     doc += QString::fromLatin1( "</li></ul>" );
    01259   }
    01260   if ( solutions.count() ) {
    01261     doc += QString::fromLatin1( "<h3>" );
    01262     doc += i18n( "Possible Solutions:" );
    01263     doc += QString::fromLatin1( "</h3><ul><li>" );
    01264     doc += solutions.join( "</li><li>" );
    01265     doc += QString::fromLatin1( "</li></ul>" );
    01266   }
    01267   doc += QString::fromLatin1( "</body></html>" );
    01268
    01269   write( doc );
    01270   end();
    01271 }
    01272
    01273 void KHTMLPart::slotFinished( KIO::Job * job )
    01274 {
    01275   d->m_job = 0L;
    01276   d->m_jobspeed = 0L;
    01277
    01278   if (job->error())
    01279   {
    01280     KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
    01281     emit canceled( job->errorString() );
    01282     // TODO: what else ?
    01283     checkCompleted();
    01284     showError( job );
    01285     return;
    01286   }
    01287   //kdDebug( 6050 ) << "slotFinished" << endl;
    01288
    01289   KHTMLPageCache::self()->endData(d->m_cacheId);
    01290
    01291   if ( d->m_doc && d->m_doc->docLoader()->expireDate() && m_url.protocol().lower().startsWith("http"))
    01292       KIO::http_update_cache(m_url, false, d->m_doc->docLoader()->expireDate());
    01293
    01294   d->m_workingURL = KURL();
    01295
    01296   if (d->m_doc->parsing())
    01297     end(); //will emit completed()
    01298 }
    01299
    01300 void KHTMLPart::begin( const KURL &url, int xOffset, int yOffset )
    01301 {
    01302   clear();
    01303   d->m_bCleared = false;
    01304   d->m_cacheId = 0;
    01305   d->m_bComplete = false;
    01306   d->m_bLoadEventEmitted = false;
    01307
    01308   if(url.isValid()) {
    01309       QString urlString = url.url();
    01310       KHTMLFactory::vLinks()->insert( urlString );
    01311       QString urlString2 = url.prettyURL();
    01312       if ( urlString != urlString2 ) {
    01313           KHTMLFactory::vLinks()->insert( urlString2 );
    01314       }
    01315   }
    01316
    01317   // ###
    01318   //stopParser();
    01319
    01320   KParts::URLArgs args( d->m_extension->urlArgs() );
    01321   args.xOffset = xOffset;
    01322   args.yOffset = yOffset;
    01323   d->m_extension->setURLArgs( args );
    01324
    01325   if ( d->m_referrer != url.url() )
    01326       d->m_pageReferrer = d->m_referrer;
    01327
    01328   KURL ref(url);
    01329   ref.setRef(QString::null);
    01330   ref.setUser(QString::null);
    01331   ref.setPass(QString::null);
    01332   d->m_referrer = ref.protocol().startsWith("http") ? ref.url() : QString::fromLatin1( "" );
    01333
    01334   m_url = url;
    01335   KURL baseurl;
    01336
    01337   if ( !m_url.isEmpty() )
    01338   {
    01339     KURL::List lst = KURL::split( m_url );
    01340     if ( !lst.isEmpty() )
    01341       baseurl = *lst.begin();
    01342
    01343     KURL title( baseurl );
    01344     title.setRef( QString::null );
    01345     title.setQuery( QString::null );
    01346     emit setWindowCaption( title.prettyURL() );
    01347   }
    01348   else
    01349     emit setWindowCaption( i18n( "no title", "* Unknown *" ) );
    01350
    01351   // ### not sure if XHTML documents served as text/xml should use DocumentImpl or HTMLDocumentImpl
    01352   if (args.serviceType == "text/xml")
    01353     d->m_doc = DOMImplementationImpl::instance()->createDocument( d->m_view );
    01354   else
    01355     d->m_doc = DOMImplementationImpl::instance()->createHTMLDocument( d->m_view );
    01356
    01357   d->m_doc->ref();
    01358   if (!d->m_doc->attached())
    01359     d->m_doc->attach( );
    01360   d->m_doc->setURL( m_url.url() );
    01361   // We prefer m_baseURL over m_url because m_url changes when we are
    01362   // about to load a new page.
    01363   d->m_doc->setBaseURL( baseurl.url() );
    01364   d->m_doc->docLoader()->setShowAnimations( KHTMLFactory::defaultHTMLSettings()->showAnimations() );
    01365   emit docCreated(); // so that the parent can set the domain
    01366
    01367   d->m_paUseStylesheet->setItems(QStringList());
    01368   d->m_paUseStylesheet->setEnabled( false );
    01369
    01370   setAutoloadImages( KHTMLFactory::defaultHTMLSettings()->autoLoadImages() );
    01371   QString userStyleSheet = KHTMLFactory::defaultHTMLSettings()->userStyleSheet();
    01372   if ( !userStyleSheet.isEmpty() )
    01373     setUserStyleSheet( KURL( userStyleSheet ) );
    01374
    01375   d->m_doc->setRestoreState(args.docState);
    01376   d->m_doc->open();
    01377   // clear widget
    01378   d->m_view->resizeContents( 0, 0 );
    01379   connect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
    01380
    01381   emit d->m_extension->enableAction( "print", true );
    01382
    01383   d->m_doc->setParsing(true);
    01384 }
    01385
    01386 void KHTMLPart::write( const char *str, int len )
    01387 {
    01388     if ( !d->m_decoder ) {
    01389         d->m_decoder = new khtml::Decoder();
    01390         if(!d->m_encoding.isNull())
    01391             d->m_decoder->setEncoding(d->m_encoding.latin1(), d->m_haveEncoding);
    01392         else
    01393             d->m_decoder->setEncoding(settings()->encoding().latin1(), d->m_haveEncoding);
    01394     }
    01395   if ( len == 0 )
    01396     return;
    01397
    01398   if ( len == -1 )
    01399     len = strlen( str );
    01400
    01401   QString decoded = d->m_decoder->decode( str, len );
    01402
    01403   if(decoded.isEmpty()) return;
    01404
    01405   if(d->m_bFirstData) {
    01406       // determine the parse mode
    01407       d->m_doc->determineParseMode( decoded );
    01408       d->m_bFirstData = false;
    01409
    01410   //kdDebug(6050) << "KHTMLPart::write haveEnc = " << d->m_haveEncoding << endl;
    01411       // ### this is still quite hacky, but should work a lot better than the old solution
    01412       if(d->m_decoder->visuallyOrdered()) d->m_doc->setVisuallyOrdered();
    01413       d->m_doc->setDecoderCodec(d->m_decoder->codec());
    01414       d->m_doc->recalcStyle( NodeImpl::Force );
    01415   }
    01416
    01417   if (jScript())
    01418     jScript()->appendSourceFile(m_url.url(),decoded);
    01419   Tokenizer* t = d->m_doc->tokenizer();
    01420   if(t)
    01421     t->write( decoded, true );
    01422 }
    01423
    01424 void KHTMLPart::write( const QString &str )
    01425 {
    01426   if ( str.isNull() )
    01427     return;
    01428
    01429   if(d->m_bFirstData) {
    01430       // determine the parse mode
    01431       d->m_doc->setParseMode( DocumentImpl::Strict );
    01432       d->m_bFirstData = false;
    01433   }
    01434   if (jScript())
    01435     jScript()->appendSourceFile(m_url.url(),str);
    01436   Tokenizer* t = d->m_doc->tokenizer();
    01437   if(t)
    01438     t->write( str, true );
    01439 }
    01440
    01441 void KHTMLPart::end()
    01442 {
    01443     // make sure nothing's left in there...
    01444     if(d->m_decoder)
    01445         write(d->m_decoder->flush());
    01446     if (d->m_doc)
    01447         d->m_doc->finishParsing();
    01448 }
    01449
    01450 void KHTMLPart::paint(QPainter *p, const QRect &rc, int yOff, bool *more)
    01451 {
    01452     if (!d->m_view) return;
    01453     d->m_view->paint(p, rc, yOff, more);
    01454 }
    01455
    01456 void KHTMLPart::stopAnimations()
    01457 {
    01458   if ( d->m_doc )
    01459     d->m_doc->docLoader()->setShowAnimations( KHTMLSettings::KAnimationDisabled );
    01460
    01461   ConstFrameIt it = d->m_frames.begin();
    01462   ConstFrameIt end = d->m_frames.end();
    01463   for (; it != end; ++it )
    01464     if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
    01465       KParts::ReadOnlyPart* p = ( *it ).m_part;
    01466       static_cast<KHTMLPart*>( p )->stopAnimations();
    01467     }
    01468 }
    01469
    01470 void KHTMLPart::slotFinishedParsing()
    01471 {
    01472   d->m_doc->setParsing(false);
    01473   checkEmitLoadEvent();
    01474   disconnect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
    01475
    01476   if (!d->m_view)
    01477     return; // We are probably being destructed.
    01478   // check if the scrollbars are really needed for the content
    01479   // if not, remove them, relayout, and repaint
    01480
    01481   d->m_view->restoreScrollBar();
    01482
    01483   if ( !m_url.encodedHtmlRef().isEmpty() )
    01484     if ( !gotoAnchor( m_url.encodedHtmlRef()) )
    01485        gotoAnchor( m_url.htmlRef() );
    01486
    01487   checkCompleted();
    01488 }
    01489
    01490 void KHTMLPart::slotLoaderRequestStarted( khtml::DocLoader* dl, khtml::CachedObject *obj )
    01491 {
    01492   if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
    01493     KHTMLPart* p = this;
    01494     while ( p ) {
    01495       KHTMLPart* op = p;
    01496       p->d->m_totalObjectCount++;
    01497       p = p->parentPart();
    01498       if ( !p && op->d->m_loadedObjects <= op->d->m_totalObjectCount
    01499         && !op->d->m_progressUpdateTimer.isActive())
    01500         op->d->m_progressUpdateTimer.start( 200, true );
    01501     }
    01502   }
    01503 }
    01504
    01505 void KHTMLPart::slotLoaderRequestDone( khtml::DocLoader* dl, khtml::CachedObject *obj )
    01506 {
    01507   if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
    01508     KHTMLPart* p = this;
    01509     while ( p ) {
    01510       KHTMLPart* op = p;
    01511       p->d->m_loadedObjects++;
    01512       p = p->parentPart();
    01513       if ( !p && op->d->m_loadedObjects <= op->d->m_totalObjectCount && op->d->m_jobPercent <= 100
    01514         && !op->d->m_progressUpdateTimer.isActive())
    01515         op->d->m_progressUpdateTimer.start( 200, true );
    01516     }
    01517   }
    01518
    01519   checkCompleted();
    01520 }
    01521
    01522 void KHTMLPart::slotProgressUpdate()
    01523 {
    01524   int percent;
    01525   if ( d->m_loadedObjects < d->m_totalObjectCount )
    01526     percent = d->m_jobPercent / 4 + ( d->m_loadedObjects*300 ) / ( 4*d->m_totalObjectCount );
    01527   else
    01528     percent = d->m_jobPercent;
    01529
    01530   if( d->m_bComplete )
    01531     percent = 100;
    01532
    01533   if( d->m_bComplete )
    01534     emit d->m_extension->infoMessage( i18n( "Page loaded." ));
    01535   else if ( d->m_loadedObjects < d->m_totalObjectCount && percent >= 75 )
    01536     emit d->m_extension->infoMessage( i18n( "%n Image of %1 loaded.", "%n Images of %1 loaded.", d->m_loadedObjects).arg(d->m_totalObjectCount) );
    01537
    01538   emit d->m_extension->loadingProgress( percent );
    01539 }
    01540
    01541 void KHTMLPart::slotJobSpeed( KIO::Job* /*job*/, unsigned long speed )
    01542 {
    01543   d->m_jobspeed = speed;
    01544   if (!parentPart())
    01545     setStatusBarText(jsStatusBarText(), BarOverrideText);
    01546 }
    01547
    01548 void KHTMLPart::slotJobPercent( KIO::Job* /*job*/, unsigned long percent )
    01549 {
    01550   d->m_jobPercent = percent;
    01551
    01552   if ( !parentPart() )
    01553     d->m_progressUpdateTimer.start( 0, true );
    01554 }
    01555
    01556 void KHTMLPart::slotJobDone( KIO::Job* /*job*/ )
    01557 {
    01558   d->m_jobPercent = 100;
    01559
    01560   if ( !parentPart() )
    01561     d->m_progressUpdateTimer.start( 0, true );
    01562 }
    01563
    01564 void KHTMLPart::checkCompleted()
    01565 {
    01566   //kdDebug( 6050 ) << "KHTMLPart::checkCompleted() parsing: " << (d->m_doc && d->m_doc->parsing()) << endl;
    01567   //kdDebug( 6050 ) << "                           complete: " << d->m_bComplete << endl;
    01568
    01569   // restore the cursor position
    01570   if (d->m_doc && !d->m_doc->parsing() && !d->m_focusNodeRestored)
    01571   {
    01572       if (d->m_focusNodeNumber >= 0)
    01573           d->m_doc->setFocusNode(d->m_doc->nodeWithAbsIndex(d->m_focusNodeNumber));
    01574       else
    01575           d->m_doc->setFocusNode(0);
    01576       d->m_focusNodeRestored = true;
    01577   }
    01578
    01579   bool bPendingChildRedirection = false;
    01580   // Any frame that hasn't completed yet ?
    01581   ConstFrameIt it = d->m_frames.begin();
    01582   ConstFrameIt end = d->m_frames.end();
    01583   for (; it != end; ++it ) {
    01584     if ( !(*it).m_bCompleted )
    01585       return;
    01586     // Check for frames with pending redirections
    01587     if ( (*it).m_bPendingRedirection )
    01588       bPendingChildRedirection = true;
    01589   }
    01590
    01591   // Are we still parsing - or have we done the completed stuff already ?
    01592   if ( d->m_bComplete || (d->m_doc && d->m_doc->parsing()) )
    01593     return;
    01594
    01595   // Still waiting for images/scripts from the loader ?
    01596   int requests = 0;
    01597   if ( d->m_doc && d->m_doc->docLoader() )
    01598     requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );
    01599
    01600   if ( requests > 0 )
    01601     return;
    01602
    01603 #ifndef Q_WS_QWS
    01604   if (d->m_javaContext && !d->m_javaContext->appletsLoaded())
    01605       return;
    01606 #endif
    01607
    01608   // OK, completed.
    01609   // Now do what should be done when we are really completed.
    01610   d->m_bComplete = true;
    01611   d->m_cachePolicy = KIO::CC_Verify; // reset cache policy
    01612   d->m_totalObjectCount = 0;
    01613   d->m_loadedObjects = 0;
    01614
    01615   KHTMLPart* p = this;
    01616   while ( p ) {
    01617     KHTMLPart* op = p;
    01618     p = p->parentPart();
    01619     if ( !p && !op->d->m_progressUpdateTimer.isActive())
    01620       op->d->m_progressUpdateTimer.start( 0, true );
    01621   }
    01622
    01623   checkEmitLoadEvent(); // if we didn't do it before
    01624
    01625   // check that the view has not been moved by the user
    01626   if ( m_url.encodedHtmlRef().isEmpty() && d->m_view->contentsY() == 0 )
    01627       d->m_view->setContentsPos( d->m_extension->urlArgs().xOffset,
    01628                                  d->m_extension->urlArgs().yOffset );
    01629
    01630   d->m_view->complete();
    01631
    01632   if ( !d->m_redirectURL.isEmpty() )
    01633   {
    01634     // Do not start redirection for frames here! That action is
    01635     // deferred until the parent emits a completed signal.
    01636     if ( parentPart() == 0 )
    01637       d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
    01638
    01639     emit completed( true );
    01640   }
    01641   else
    01642   {
    01643     if ( bPendingChildRedirection )
    01644       emit completed( true );
    01645     else
    01646       emit completed();
    01647   }
    01648
    01649   // find the alternate stylesheets
    01650   QStringList sheets;
    01651   if (d->m_doc)
    01652      sheets = d->m_doc->availableStyleSheets();
    01653   d->m_paUseStylesheet->setItems( sheets );
    01654   d->m_paUseStylesheet->setEnabled( !sheets.isEmpty() );
    01655   if (!sheets.isEmpty())
    01656   {
    01657     d->m_paUseStylesheet->setCurrentItem(kMax(sheets.findIndex(d->m_sheetUsed), 0));
    01658     slotUseStylesheet();
    01659   }
    01660
    01661   setJSDefaultStatusBarText(QString::null);
    01662
    01663 #ifdef SPEED_DEBUG
    01664   kdDebug(6050) << "DONE: " <<d->m_parsetime.elapsed() << endl;
    01665 #endif
    01666 }
    01667
    01668 void KHTMLPart::checkEmitLoadEvent()
    01669 {
    01670   if ( d->m_bLoadEventEmitted || !d->m_doc || d->m_doc->parsing() ) return;
    01671
    01672   ConstFrameIt it = d->m_frames.begin();
    01673   ConstFrameIt end = d->m_frames.end();
    01674   for (; it != end; ++it )
    01675     if ( !(*it).m_bCompleted ) // still got a frame running -> too early
    01676       return;
    01677
    01678 #ifndef Q_WS_QWS
    01679   if (d->m_javaContext && !d->m_javaContext->appletsLoaded())
    01680       return;
    01681 #endif
    01682   // Still waiting for images/scripts from the loader ?
    01683   // (onload must happen afterwards, #45607)
    01684   // ## This makes this method very similar to checkCompleted. A brave soul should try merging them.
    01685   int requests = 0;
    01686   if ( d->m_doc && d->m_doc->docLoader() )
    01687     requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );
    01688
    01689   if ( requests > 0 )
    01690     return;
    01691
    01692   d->m_bLoadEventEmitted = true;
    01693   if (d->m_doc)
    01694     d->m_doc->close();
    01695 }
    01696
    01697 const KHTMLSettings *KHTMLPart::settings() const
    01698 {
    01699   return d->m_settings;
    01700 }
    01701
    01702 #ifndef KDE_NO_COMPAT
    01703 KURL KHTMLPart::baseURL() const
    01704 {
    01705   if ( !d->m_doc ) return KURL();
    01706
    01707   return d->m_doc->baseURL();
    01708 }
    01709
    01710 QString KHTMLPart::baseTarget() const
    01711 {
    01712   if ( !d->m_doc ) return QString::null;
    01713
    01714   return d->m_doc->baseTarget();
    01715 }
    01716 #endif
    01717
    01718 KURL KHTMLPart::completeURL( const QString &url )
    01719 {
    01720   if ( !d->m_doc ) return url;
    01721
    01722   if (d->m_decoder)
    01723     return KURL(d->m_doc->completeURL(url), d->m_decoder->codec()->mibEnum());
    01724
    01725   return KURL( d->m_doc->completeURL( url ) );
    01726 }
    01727
    01728 void KHTMLPart::scheduleRedirection( int delay, const QString &url, bool doLockHistory )
    01729 {
    01730   //kdDebug(6050) << "KHTMLPart::scheduleRedirection delay=" << delay << " url=" << url << endl;
    01731     if ( delay < 24*60*60 &&
    01732        ( d->m_redirectURL.isEmpty() || delay < d->m_delayRedirect ) )
    01733     {
    01734        d->m_delayRedirect = delay;
    01735        d->m_redirectURL = url;
    01736        d->m_redirectLockHistory = doLockHistory;
    01737        if ( d->m_bComplete ) {
    01738          d->m_redirectionTimer.stop();
    01739          d->m_redirectionTimer.start( kMax(0, 1000 * d->m_delayRedirect), true );
    01740        }
    01741     }
    01742 }
    01743
    01744 void KHTMLPart::slotRedirect()
    01745 {
    01746   QString u = d->m_redirectURL;
    01747   d->m_delayRedirect = 0;
    01748   d->m_redirectURL = QString::null;
    01749   d->m_pageReferrer = d->m_referrer = "";
    01750   // SYNC check with ecma/kjs_window.cpp::goURL !
    01751   if ( u.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
    01752   {
    01753     QString script = KURL::decode_string( u.right( u.length() - 11 ) );
    01754     //kdDebug( 6050 ) << "KHTMLPart::slotRedirect script=" << script << endl;
    01755     QVariant res = executeScript( script );
    01756     if ( res.type() == QVariant::String ) {
    01757       begin( url() );
    01758       write( res.asString() );
    01759       end();
    01760     }
    01761     return;
    01762   }
    01763   KParts::URLArgs args;
    01764   // Redirecting to the current URL leads to a reload.
    01765   // But jumping to an anchor never leads to a reload.
    01766   KURL cUrl( m_url );
    01767   KURL url( u );
    01768
    01769   // handle windows opened by JS
    01770   if ( openedByJS() && d->m_opener )
    01771       cUrl = d->m_opener->url();
    01772
    01773   if (!kapp || !kapp->kapp->authorizeURLAction("redirect", cUrl, url))
    01774   {
    01775     kdWarning(6050) << "KHTMLPart::scheduleRedirection: Redirection from " << cUrl.prettyURL() << " to " << url.prettyURL() << " REJECTED!" << endl;
    01776     return;
    01777   }
    01778
    01779   if ( !url.hasRef() && urlcmp( u, m_url.url(), true, true ) )
    01780   {
    01781     args.reload = true;
    01782   }
    01783
    01784   // Indicate that this request is due to a redirection.
    01785   args.setRedirectedRequest(true);
    01786
    01787   args.setLockHistory( d->m_redirectLockHistory );
    01788   // _self: make sure we don't use any <base target=>'s
    01789   urlSelected( u, 0, 0, "_self", args );
    01790 }
    01791
    01792 void KHTMLPart::slotRedirection(KIO::Job*, const KURL& url)
    01793 {
    01794   // the slave told us that we got redirected
    01795   // kdDebug( 6050 ) << "redirection by KIO to " << url.url() << endl;
    01796   emit d->m_extension->setLocationBarURL( url.prettyURL() );
    01797   d->m_workingURL = url;
    01798 }
    01799
    01800 bool KHTMLPart::setEncoding( const QString &name, bool override )
    01801 {
    01802     d->m_encoding = name;
    01803     d->m_haveEncoding = override;
    01804
    01805     if( !m_url.isEmpty() ) {
    01806         // reload document
    01807         closeURL();
    01808         KURL url = m_url;
    01809         m_url = 0;
    01810         d->m_restored = true;
    01811         openURL(url);
    01812         d->m_restored = false;
    01813     }
    01814
    01815     return true;
    01816 }
    01817
    01818 QString KHTMLPart::encoding() const
    01819 {
    01820     if(d->m_haveEncoding && !d->m_encoding.isEmpty())
    01821         return d->m_encoding;
    01822
    01823     if(d->m_decoder && d->m_decoder->encoding())
    01824         return QString(d->m_decoder->encoding());
    01825
    01826     return(settings()->encoding());
    01827 }
    01828
    01829 void KHTMLPart::setUserStyleSheet(const KURL &url)
    01830 {
    01831   if ( d->m_doc && d->m_doc->docLoader() )
    01832     (void) new khtml::PartStyleSheetLoader(this, url.url(), d->m_doc->docLoader());
    01833 }
    01834
    01835 void KHTMLPart::setUserStyleSheet(const QString &styleSheet)
    01836 {
    01837   if ( d->m_doc )
    01838     d->m_doc->setUserStyleSheet( styleSheet );
    01839 }
    01840
    01841 bool KHTMLPart::gotoAnchor( const QString &name )
    01842 {
    01843   if (!d->m_doc)
    01844     return false;
    01845
    01846   HTMLCollectionImpl *anchors =
    01847       new HTMLCollectionImpl( d->m_doc, HTMLCollectionImpl::DOC_ANCHORS);
    01848   anchors->ref();
    01849   NodeImpl *n = anchors->namedItem(name);
    01850   anchors->deref();
    01851
    01852   if(!n) {
    01853       n = d->m_doc->getElementById( name );
    01854   }
    01855
    01856   if(!n) {
    01857       kdDebug(6050) << "KHTMLPart::gotoAnchor node '" << name << "' not found" << endl;
    01858       return false;
    01859   }
    01860
    01861   int x = 0, y = 0;
    01862   int gox, dummy;
    01863   HTMLElementImpl *a = static_cast<HTMLElementImpl *>(n);
    01864
    01865   a->getUpperLeftCorner(x, y);
    01866   if (x <= d->m_view->contentsX())
    01867     gox = x - 10;
    01868   else {
    01869     gox = d->m_view->contentsX();
    01870     if ( x + 10 > d->m_view->contentsX()+d->m_view->visibleWidth()) {
    01871       a->getLowerRightCorner(x, dummy);
    01872       gox = x - d->m_view->visibleWidth() + 10;
    01873     }
    01874   }
    01875
    01876   d->m_view->setContentsPos(gox, y-20);
    01877
    01878   return true;
    01879 }
    01880
    01881 void KHTMLPart::setStandardFont( const QString &name )
    01882 {
    01883     d->m_settings->setStdFontName(name);
    01884 }
    01885
    01886 void KHTMLPart::setFixedFont( const QString &name )
    01887 {
    01888     d->m_settings->setFixedFontName(name);
    01889 }
    01890
    01891 void KHTMLPart::setURLCursor( const QCursor &c )
    01892 {
    01893   d->m_linkCursor = c;
    01894 }
    01895
    01896 QCursor KHTMLPart::urlCursor() const
    01897 {
    01898   return d->m_linkCursor;
    01899 }
    01900
    01901 bool KHTMLPart::onlyLocalReferences() const
    01902 {
    01903   return d->m_onlyLocalReferences;
    01904 }
    01905
    01906 void KHTMLPart::setOnlyLocalReferences(bool enable)
    01907 {
    01908   d->m_onlyLocalReferences = enable;
    01909 }
    01910
    01911 void KHTMLPart::findTextBegin()
    01912 {
    01913   d->m_findPos = -1;
    01914   d->m_findNode = 0;
    01915   d->m_findPosEnd = -1;
    01916   d->m_findNodeEnd= 0;
    01917   d->m_paFindNext->setEnabled( false ); // needs a 'find' first
    01918 }
    01919
    01920 bool KHTMLPart::initFindNode( bool selection, bool reverse )
    01921 {
    01922     if ( !d->m_doc )
    01923         return false;
    01924
    01925     if(!d->m_findNode) {
    01926         if (d->m_doc->isHTMLDocument())
    01927             d->m_findNode = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
    01928         else
    01929             d->m_findNode = d->m_doc;
    01930     }
    01931
    01932     if ( !d->m_findNode )
    01933     {
    01934       kdDebug(6050) << k_funcinfo << "no findNode -> return false" << endl;
    01935       return false;
    01936     }
    01937     if ( d->m_findNode->id() == ID_FRAMESET )
    01938     {
    01939       kdDebug(6050) << k_funcinfo << "FRAMESET -> return false" << endl;
    01940       return false;
    01941     }
    01942
    01943     if ( selection && hasSelection() )
    01944     {
    01945       kdDebug(6050) << k_funcinfo << "using selection" << endl;
    01946       d->m_findNode = d->m_selectionStart.handle();
    01947       d->m_findPos = d->m_startOffset;
    01948       d->m_findNodeEnd = d->m_selectionEnd.handle();
    01949       d->m_findPosEnd = d->m_endOffset;
    01950       if ( reverse ) {
    01951         qSwap( d->m_findNode, d->m_findNodeEnd );
    01952         qSwap( d->m_findPos, d->m_findPosEnd );
    01953       }
    01954     }
    01955     else // whole document
    01956     {
    01957       //kdDebug(6050) << k_funcinfo << "whole doc" << endl;
    01958       d->m_findPos = 0;
    01959       d->m_findPosEnd = -1;
    01960       d->m_findNodeEnd = 0;
    01961       if ( reverse ) {
    01962         qSwap( d->m_findPos, d->m_findPosEnd );
    01963         // Need to find out the really last object, to start from it
    01964         while ( d->m_findNode->lastChild() )
    01965           d->m_findNode = d->m_findNode->lastChild();
    01966       }
    01967     }
    01968     return true;
    01969 }
    01970
    01971 // Old method (its API limits the available features - remove in KDE-4)
    01972 bool KHTMLPart::findTextNext( const QString &str, bool forward, bool caseSensitive, bool isRegExp )
    01973 {
    01974     if ( !initFindNode( false, !forward ) )
    01975       return false;
    01976     while(1)
    01977     {
    01978         if( (d->m_findNode->nodeType() == Node::TEXT_NODE || d->m_findNode->nodeType() == Node::CDATA_SECTION_NODE) && d->m_findNode->renderer() )
    01979         {
    01980             DOMString nodeText = d->m_findNode->nodeValue();
    01981             DOMStringImpl *t = nodeText.implementation();
    01982             QConstString s(t->s, t->l);
    01983
    01984             int matchLen = 0;
    01985             if ( isRegExp ) {
    01986               QRegExp matcher( str );
    01987               matcher.setCaseSensitive( caseSensitive );
    01988               d->m_findPos = matcher.search(s.string(), d->m_findPos+1);
    01989               if ( d->m_findPos != -1 )
    01990                 matchLen = matcher.matchedLength();
    01991             }
    01992             else {
    01993               d->m_findPos = s.string().find(str, d->m_findPos+1, caseSensitive);
    01994               matchLen = str.length();
    01995             }
    01996
    01997             if(d->m_findPos != -1)
    01998             {
    01999                 int x = 0, y = 0;
    02000                 if(static_cast<khtml::RenderText *>(d->m_findNode->renderer())
    02001                   ->posOfChar(d->m_findPos, x, y))
    02002                     d->m_view->setContentsPos(x-50, y-50);
    02003
    02004                 d->m_selectionStart = d->m_findNode;
    02005                 d->m_startOffset = d->m_findPos;
    02006                 d->m_selectionEnd = d->m_findNode;
    02007                 d->m_endOffset = d->m_findPos + matchLen;
    02008                 d->m_startBeforeEnd = true;
    02009
    02010                 d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
    02011                                         d->m_selectionEnd.handle(), d->m_endOffset );
    02012                 emitSelectionChanged();
    02013                 return true;
    02014             }
    02015         }
    02016         d->m_findPos = -1;
    02017
    02018         NodeImpl *next;
    02019
    02020         if ( forward )
    02021         {
    02022           next = d->m_findNode->firstChild();
    02023
    02024           if(!next) next = d->m_findNode->nextSibling();
    02025           while(d->m_findNode && !next) {
    02026               d->m_findNode = d->m_findNode->parentNode();
    02027               if( d->m_findNode ) {
    02028                   next = d->m_findNode->nextSibling();
    02029               }
    02030           }
    02031         }
    02032         else
    02033         {
    02034           next = d->m_findNode->lastChild();
    02035
    02036           if (!next ) next = d->m_findNode->previousSibling();
    02037           while ( d->m_findNode && !next )
    02038           {
    02039             d->m_findNode = d->m_findNode->parentNode();
    02040             if( d->m_findNode )
    02041             {
    02042               next = d->m_findNode->previousSibling();
    02043             }
    02044           }
    02045         }
    02046
    02047         d->m_findNode = next;
    02048         if(!d->m_findNode) return false;
    02049     }
    02050 }
    02051
    02052
    02053 void KHTMLPart::slotFind()
    02054 {
    02055   KParts::ReadOnlyPart *part = currentFrame();
    02056   if (!part)
    02057     return;
    02058   if (!part->inherits("KHTMLPart") )
    02059   {
    02060       kdError(6000) << "slotFind: part is a " << part->className() << ", can't do a search into it" << endl;
    02061       return;
    02062   }
    02063   static_cast<KHTMLPart *>( part )->findText();
    02064 }
    02065
    02066 void KHTMLPart::slotFindNext()
    02067 {
    02068   KParts::ReadOnlyPart *part = currentFrame();
    02069   if (!part)
    02070     return;
    02071   if (!part->inherits("KHTMLPart") )
    02072   {
    02073       kdError(6000) << "slotFindNext: part is a " << part->className() << ", can't do a search into it" << endl;
    02074       return;
    02075   }
    02076   static_cast<KHTMLPart *>( part )->findTextNext();
    02077 }
    02078
    02079 void KHTMLPart::slotFindDone()
    02080 {
    02081   // ### remove me
    02082 }
    02083
    02084 void KHTMLPart::slotFindDialogDestroyed()
    02085 {
    02086   // ### remove me
    02087 }
    02088
    02089 void KHTMLPart::findText()
    02090 {
    02091   // First do some init to make sure we can search in this frame
    02092   if ( !d->m_doc )
    02093     return;
    02094
    02095   // The lineedit of the dialog would make khtml lose its selection, otherwise
    02096 #ifndef QT_NO_CLIPBOARD
    02097   disconnect( kapp->clipboard(), SIGNAL(selectionChanged()), this, SLOT(slotClearSelection()) );
    02098 #endif
    02099
    02100   // Now show the dialog in which the user can choose options.
    02101   KFindDialog optionsDialog( widget(), "khtmlfind" );
    02102   optionsDialog.setHasSelection( hasSelection() );
    02103   optionsDialog.setHasCursor( d->m_findNode != 0 );
    02104   if ( d->m_findNode ) // has a cursor -> default to 'FromCursor'
    02105     d->m_lastFindState.options |= KFindDialog::FromCursor;
    02106
    02107   // TODO? optionsDialog.setPattern( d->m_lastFindState.text );
    02108   optionsDialog.setFindHistory( d->m_lastFindState.history );
    02109   optionsDialog.setOptions( d->m_lastFindState.options );
    02110
    02111   if ( optionsDialog.exec() != QDialog::Accepted )
    02112       return;
    02113
    02114 #ifndef QT_NO_CLIPBOARD
    02115   connect( kapp->clipboard(), SIGNAL(selectionChanged()), SLOT(slotClearSelection()) );
    02116 #endif
    02117
    02118   // Save for next time
    02119   //d->m_lastFindState.text = optionsDialog.pattern();
    02120   int options = optionsDialog.options();
    02121   d->m_lastFindState.options = options;
    02122   d->m_lastFindState.history = optionsDialog.findHistory();
    02123
    02124   // Create the KFind object
    02125   delete d->m_find;
    02126   d->m_find = new KFind( optionsDialog.pattern(), options, widget() );
    02127   connect(d->m_find, SIGNAL( highlight( const QString &, int, int ) ),
    02128           this, SLOT( slotHighlight( const QString &, int, int ) ) );
    02129   connect(d->m_find, SIGNAL( findNext() ),
    02130           this, SLOT( slotFindNext() ) );
    02131
    02132   if ( options & KFindDialog::SelectedText )
    02133     Q_ASSERT( hasSelection() );
    02134
    02135   if ( (options & KFindDialog::FromCursor) == 0 )
    02136       (void) initFindNode( options & KFindDialog::SelectedText, options & KFindDialog::FindBackwards );
    02137   findTextNext();
    02138 }
    02139
    02140 // New method
    02141 void KHTMLPart::findTextNext()
    02142 {
    02143   if (!d->m_find) // shouldn't be called before find is activated
    02144         return;
    02145
    02146   long options = d->m_find->options();
    02147   KFind::Result res = KFind::NoMatch;
    02148   khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
    02149   khtml::RenderObject* end = d->m_findNodeEnd ? d->m_findNodeEnd->renderer() : 0;
    02150   //kdDebug(6050) << k_funcinfo << "obj=" << obj << " end=" << end << endl;
    02151   while( res == KFind::NoMatch )
    02152   {
    02153     if ( d->m_find->needData() )
    02154     {
    02155       if ( !obj ) {
    02156         //kdDebug(6050) << k_funcinfo << "obj=0 -> done" << endl;
    02157         break; // we're done
    02158       }
    02159       //kdDebug(6050) << k_funcinfo << " gathering data" << endl;
    02160       // First make up the QString for the current 'line' (i.e. up to \n)
    02161       // We also want to remember the DOMNode for every portion of the string.
    02162       // We store this in an index->node list.
    02163
    02164       d->m_stringPortions.clear();
    02165       int newLinePos = -1;
    02166       QString str;
    02167       DOM::NodeImpl* lastNode = d->m_findNode;
    02168       while ( obj && newLinePos == -1 )
    02169       {
    02170         // Grab text from render object
    02171         QString s;
    02172         if ( obj->isText() )
    02173         {
    02174           s = static_cast<khtml::RenderText *>(obj)->data().string();
    02175           s = s.replace(0xa0, ' ');
    02176         }
    02177         else if ( obj->isBR() )
    02178           s = '\n';
    02179         else if ( !obj->isInline() && !str.isEmpty() )
    02180           s = '\n';
    02181         if ( lastNode == d->m_findNodeEnd )
    02182           s.truncate( d->m_findPosEnd );
    02183         if ( !s.isEmpty() )
    02184         {
    02185           newLinePos = s.find( '\n' ); // did we just get a newline?
    02186           int index = str.length();
    02187           if ( newLinePos != -1 )
    02188             newLinePos += index;
    02189           str += s;
    02190           //kdDebug(6050) << "StringPortion: " << index << "-" << index+s.length()-1 << " -> " << node << endl;
    02191           d->m_stringPortions.append( KHTMLPartPrivate::StringPortion( index, lastNode ) );
    02192         }
    02193         // Compare obj and end _after_ we processed the 'end' node itself
    02194         if ( obj == end )
    02195           obj = 0L;
    02196         else
    02197         {
    02198           // Move on to next object (note: if we found a \n already, then obj (and lastNode)
    02199           // will point to the _next_ object, i.e. they are in advance.
    02200           do {
    02201             // We advance until the next RenderObject that has a NodeImpl as its element().
    02202             // Otherwise (if we keep the 'last node', and it has a '\n') we might be stuck
    02203             // on that object forever...
    02204             obj = (options & KFindDialog::FindBackwards) ? obj->objectAbove() : obj->objectBelow();
    02205           } while ( obj && !obj->element() );
    02206         }
    02207         if ( obj )
    02208           lastNode = obj->element();
    02209         else
    02210           lastNode = 0;
    02211       } // end while
    02212
    02213       if ( !str.isEmpty() )
    02214       {
    02215         //kdDebug(6050) << "str=" << str << endl;
    02216         d->m_find->setData( str, d->m_findPos );
    02217       }
    02218
    02219       d->m_findPos = -1; // not used during the findnext loops. Only during init.
    02220       d->m_findNode = lastNode;
    02221     }
    02222     if ( !d->m_find->needData() ) // happens if str was empty
    02223     {
    02224       // Let KFind inspect the text fragment, and display a dialog if a match is found
    02225       res = d->m_find->find();
    02226     }
    02227   } // end while
    02228
    02229   if ( res == KFind::NoMatch ) // i.e. we're done
    02230   {
    02231     if ( d->m_find->shouldRestart() )
    02232     {
    02233       //kdDebug(6050) << "Restarting" << endl;
    02234       initFindNode( false, options & KFindDialog::FindBackwards );
    02235       findTextNext();
    02236     }
    02237     else // really done, close 'find next' dialog
    02238     {
    02239       //kdDebug(6050) << "Finishing" << endl;
    02240       delete d->m_find;
    02241       d->m_find = 0L;
    02242       slotClearSelection();
    02243     }
    02244   }
    02245   d->m_paFindNext->setEnabled( d->m_find != 0L  ); // true, except when completely done
    02246 }
    02247
    02248 void KHTMLPart::slotHighlight( const QString &, int index, int length )
    02249 {
    02250   //kdDebug(6050) << "slotHighlight index=" << index << " length=" << length << endl;
    02251   QValueList<KHTMLPartPrivate::StringPortion>::Iterator it = d->m_stringPortions.begin();
    02252   QValueList<KHTMLPartPrivate::StringPortion>::Iterator prev = it;
    02253   // We stop at the first portion whose index is 'greater than', and then use the previous one
    02254   while ( it != d->m_stringPortions.end() && (*it).index <= index )
    02255   {
    02256     prev = it;
    02257     ++it;
    02258   }
    02259   Q_ASSERT ( prev != d->m_stringPortions.end() );
    02260   DOM::NodeImpl* node = (*prev).node;
    02261   Q_ASSERT( node );
    02262
    02263   d->m_selectionStart = node;
    02264   d->m_startOffset = index - (*prev).index;
    02265
    02266   Q_ASSERT( node->renderer() );
    02267   if ( node->renderer() )
    02268   {
    02269     int x = 0, y = 0;
    02270     if (static_cast<khtml::RenderText *>(node->renderer())
    02271       ->posOfChar(d->m_startOffset, x, y))
    02272         d->m_view->setContentsPos(x-50, y-50);
    02273   }
    02274
    02275   // Now look for end node
    02276   it = prev; // no need to start from beginning again
    02277   while ( it != d->m_stringPortions.end() && (*it).index < index + length )
    02278   {
    02279     prev = it;
    02280     ++it;
    02281   }
    02282   Q_ASSERT ( prev != d->m_stringPortions.end() );
    02283
    02284   d->m_selectionEnd = (*prev).node;
    02285   d->m_endOffset = index + length - (*prev).index;
    02286   d->m_startBeforeEnd = true;
    02287
    02288 #if 0
    02289   kdDebug(6050) << "slotHighlight: " << d->m_selectionStart.handle() << "," << d->m_startOffset << " - " <<
    02290     d->m_selectionEnd.handle() << "," << d->m_endOffset << endl;
    02291   it = d->m_stringPortions.begin();
    02292   for ( ; it != d->m_stringPortions.end() ; ++it )
    02293     kdDebug(6050) << "  StringPortion: from index=" << (*it).index << " -> node=" << (*it).node << endl;
    02294 #endif
    02295   d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
    02296                           d->m_selectionEnd.handle(), d->m_endOffset );
    02297   emitSelectionChanged();
    02298 }
    02299
    02300 QString KHTMLPart::selectedText() const
    02301 {
    02302   bool hasNewLine = true;
    02303   QString text;
    02304   DOM::Node n = d->m_selectionStart;
    02305   while(!n.isNull()) {
    02306       if(n.nodeType() == DOM::Node::TEXT_NODE && n.handle()->renderer()) {
    02307         QString str = n.nodeValue().string();
    02308         hasNewLine = false;
    02309         if(n == d->m_selectionStart && n == d->m_selectionEnd)
    02310           text = str.mid(d->m_startOffset, d->m_endOffset - d->m_startOffset);
    02311         else if(n == d->m_selectionStart)
    02312           text = str.mid(d->m_startOffset);
    02313         else if(n == d->m_selectionEnd)
    02314           text += str.left(d->m_endOffset);
    02315         else
    02316           text += str;
    02317       }
    02318       else {
    02319         // This is our simple HTML -> ASCII transformation:
    02320         unsigned short id = n.elementId();
    02321         switch(id) {
    02322           case ID_BR:
    02323             text += "\n";
    02324             hasNewLine = true;
    02325             break;
    02326
    02327           case ID_TD:
    02328           case ID_TH:
    02329           case ID_HR:
    02330           case ID_OL:
    02331           case ID_UL:
    02332           case ID_LI:
    02333           case ID_DD:
    02334           case ID_DL:
    02335           case ID_DT:
    02336           case ID_PRE:
    02337           case ID_BLOCKQUOTE:
    02338           case ID_DIV:
    02339             if (!hasNewLine)
    02340                text += "\n";
    02341             hasNewLine = true;
    02342             break;
    02343           case ID_P:
    02344           case ID_TR:
    02345           case ID_H1:
    02346           case ID_H2:
    02347           case ID_H3:
    02348           case ID_H4:
    02349           case ID_H5:
    02350           case ID_H6:
    02351             if (!hasNewLine)
    02352                text += "\n";
    02353             text += "\n";
    02354             hasNewLine = true;
    02355             break;
    02356         }
    02357       }
    02358       if(n == d->m_selectionEnd) break;
    02359       DOM::Node next = n.firstChild();
    02360       if(next.isNull()) next = n.nextSibling();
    02361       while( next.isNull() && !n.parentNode().isNull() ) {
    02362         n = n.parentNode();
    02363         next = n.nextSibling();
    02364         unsigned short id = n.elementId();
    02365         switch(id) {
    02366           case ID_TD:
    02367           case ID_TH:
    02368           case ID_HR:
    02369           case ID_OL:
    02370           case ID_UL:
    02371           case ID_LI:
    02372           case ID_DD:
    02373           case ID_DL:
    02374           case ID_DT:
    02375           case ID_PRE:
    02376           case ID_BLOCKQUOTE:
    02377           case ID_DIV:
    02378             if (!hasNewLine)
    02379                text += "\n";
    02380             hasNewLine = true;
    02381             break;
    02382           case ID_P:
    02383           case ID_TR:
    02384           case ID_H1:
    02385           case ID_H2:
    02386           case ID_H3:
    02387           case ID_H4:
    02388           case ID_H5:
    02389           case ID_H6:
    02390             if (!hasNewLine)
    02391                text += "\n";
    02392             text += "\n";
    02393             hasNewLine = true;
    02394             break;
    02395         }
    02396       }
    02397
    02398       n = next;
    02399     }
    02400
    02401     if(text.isEmpty())
    02402         return QString::null;
    02403
    02404     int start = 0;
    02405     int end = text.length();
    02406
    02407     // Strip leading LFs
    02408     while ((start < end) && (text[start] == '\n'))
    02409        start++;
    02410
    02411     // Strip excessive trailing LFs
    02412     while ((start < (end-1)) && (text[end-1] == '\n') && (text[end-2] == '\n'))
    02413        end--;
    02414
    02415     return text.mid(start, end-start);
    02416 }
    02417
    02418 bool KHTMLPart::hasSelection() const
    02419 {
    02420   if ( d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() )
    02421       return false;
    02422   if ( d->m_selectionStart == d->m_selectionEnd &&
    02423        d->m_startOffset == d->m_endOffset )
    02424       return false; // empty
    02425   return true;
    02426 }
    02427
    02428 DOM::Range KHTMLPart::selection() const
    02429 {
    02430     DOM::Range r = document().createRange();DOM::Range();
    02431     r.setStart( d->m_selectionStart, d->m_startOffset );
    02432     r.setEnd( d->m_selectionEnd, d->m_endOffset );
    02433     return r;
    02434 }
    02435
    02436
    02437 void KHTMLPart::setSelection( const DOM::Range &r )
    02438 {
    02439     d->m_selectionStart = r.startContainer();
    02440     d->m_startOffset = r.startOffset();
    02441     d->m_selectionEnd = r.endContainer();
    02442     d->m_endOffset = r.endOffset();
    02443     d->m_doc->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
    02444                            d->m_selectionEnd.handle(),d->m_endOffset);
    02445 }
    02446
    02447 void KHTMLPart::slotClearSelection()
    02448 {
    02449     bool hadSelection = hasSelection();
    02450     d->m_selectionStart = 0;
    02451     d->m_startOffset = 0;
    02452     d->m_selectionEnd = 0;
    02453     d->m_endOffset = 0;
    02454     if ( d->m_doc ) d->m_doc->clearSelection();
    02455     if ( hadSelection )
    02456       emitSelectionChanged();
    02457 }
    02458
    02459 void KHTMLPart::overURL( const QString &url, const QString &target, bool /*shiftPressed*/ )
    02460 {
    02461   KURL u = completeURL(url);
    02462
    02463   // special case for <a href="">
    02464   if ( url.isEmpty() )
    02465     u.setFileName( url );
    02466
    02467   emit onURL( url );
    02468
    02469   if ( url.isEmpty() ) {
    02470     setStatusBarText(u.htmlURL(), BarHoverText);
    02471     return;
    02472   }
    02473
    02474   if (url.find( QString::fromLatin1( "javascript:" ),0, false ) != -1 ) {
    02475     QString jscode = KURL::decode_string( url.mid( url.find( "javascript:", 0, false ) ) );
    02476     jscode = KStringHandler::rsqueeze( jscode, 80 ); // truncate if too long
    02477     setStatusBarText( QStyleSheet::escape( jscode ), BarHoverText );
    02478     return;
    02479   }
    02480
    02481   KFileItem item(u, QString::null, KFileItem::Unknown);
    02482   emit d->m_extension->mouseOverInfo(&item);
    02483
    02484   QString com;
    02485
    02486   KMimeType::Ptr typ = KMimeType::findByURL( u );
    02487
    02488   if ( typ )
    02489     com = typ->comment( u, false );
    02490
    02491   if ( u.isMalformed() ) {
    02492     setStatusBarText(u.htmlURL(), BarHoverText);
    02493     return;
    02494   }
    02495
    02496   if ( u.isLocalFile() )
    02497   {
    02498     // TODO : use KIO::stat() and create a KFileItem out of its result,
    02499     // to use KFileItem::statusBarText()
    02500     QCString path = QFile::encodeName( u.path() );
    02501
    02502     struct stat buff;
    02503     bool ok = !stat( path.data(), &buff );
    02504
    02505     struct stat lbuff;
    02506     if (ok) ok = !lstat( path.data(), &lbuff );
    02507
    02508     QString text = u.htmlURL();
    02509     QString text2 = text;
    02510
    02511     if (ok && S_ISLNK( lbuff.st_mode ) )
    02512     {
    02513       QString tmp;
    02514       if ( com.isNull() )
    02515         tmp = i18n( "Symbolic Link");
    02516       else
    02517         tmp = i18n("%1 (Link)").arg(com);
    02518       char buff_two[1024];
    02519       text += " -> ";
    02520       int n = readlink ( path.data(), buff_two, 1022);
    02521       if (n == -1)
    02522       {
    02523         text2 += "  ";
    02524         text2 += tmp;
    02525         setStatusBarText(text2, BarHoverText);
    02526         return;
    02527       }
    02528       buff_two[n] = 0;
    02529
    02530       text += buff_two;
    02531       text += "  ";
    02532       text += tmp;
    02533     }
    02534     else if ( ok && S_ISREG( buff.st_mode ) )
    02535     {
    02536       if (buff.st_size < 1024)
    02537         text = i18n("%2 (%1 bytes)").arg((long) buff.st_size).arg(text2); // always put the URL last, in case it contains '%'
    02538       else
    02539       {
    02540         float d = (float) buff.st_size/1024.0;
    02541         text = i18n("%1 (%2 K)").arg(text2).arg(KGlobal::locale()->formatNumber(d, 2)); // was %.2f
    02542       }
    02543       text += "  ";
    02544       text += com;
    02545     }
    02546     else if ( ok && S_ISDIR( buff.st_mode ) )
    02547     {
    02548       text += "  ";
    02549       text += com;
    02550     }
    02551     else
    02552     {
    02553       text += "  ";
    02554       text += com;
    02555     }
    02556     setStatusBarText(text, BarHoverText);
    02557   }
    02558   else
    02559   {
    02560     QString extra;
    02561     if (target.lower() == "_blank")
    02562     {
    02563       extra = i18n(" (In new window)");
    02564     }
    02565     else if (!target.isEmpty() &&
    02566              (target.lower() != "_top") &&
    02567              (target.lower() != "_self") &&
    02568              (target.lower() != "_parent"))
    02569     {
    02570       extra = i18n(" (In other frame)");
    02571     }
    02572
    02573     if (u.protocol() == QString::fromLatin1("mailto")) {
    02574       QString mailtoMsg /* = QString::fromLatin1("<img src=%1>").arg(locate("icon", QString::fromLatin1("locolor/16x16/actions/mail_send.png")))*/;
    02575       mailtoMsg += i18n("Email to: ") + KURL::decode_string(u.path());
    02576       QStringList queries = QStringList::split('&', u.query().mid(1));
    02577       for (QStringList::Iterator it = queries.begin(); it != queries.end(); ++it)
    02578         if ((*it).startsWith(QString::fromLatin1("subject=")))
    02579           mailtoMsg += i18n(" - Subject: ") + KURL::decode_string((*it).mid(8));
    02580         else if ((*it).startsWith(QString::fromLatin1("cc=")))
    02581           mailtoMsg += i18n(" - CC: ") + KURL::decode_string((*it).mid(3));
    02582         else if ((*it).startsWith(QString::fromLatin1("bcc=")))
    02583           mailtoMsg += i18n(" - BCC: ") + KURL::decode_string((*it).mid(4));
    02584       mailtoMsg.replace(QRegExp("&"), QString("&amp;"));
    02585       mailtoMsg.replace(QRegExp("<"), QString("&lt;"));
    02586       mailtoMsg.replace(QRegExp(">"), QString("&gt;"));
    02587       mailtoMsg.replace(QRegExp("([\n\r\t]|[ ]{10})"), "");
    02588       setStatusBarText("<qt>"+mailtoMsg, BarHoverText);
    02589       return;
    02590     }
    02591    // Is this check neccessary at all? (Frerich)
    02592 #if 0
    02593     else if (u.protocol() == QString::fromLatin1("http")) {
    02594         DOM::Node hrefNode = nodeUnderMouse().parentNode();
    02595         while (hrefNode.nodeName().string() != QString::fromLatin1("A") && !hrefNode.isNull())
    02596           hrefNode = hrefNode.parentNode();
    02597
    02598         if (!hrefNode.isNull()) {
    02599           DOM::Node hreflangNode = hrefNode.attributes().getNamedItem("HREFLANG");
    02600           if (!hreflangNode.isNull()) {
    02601             QString countryCode = hreflangNode.nodeValue().string().lower();
    02602             // Map the language code to an appropriate country code.
    02603             if (countryCode == QString::fromLatin1("en"))
    02604               countryCode = QString::fromLatin1("gb");
    02605             QString flagImg = QString::fromLatin1("<img src=%1>").arg(
    02606                 locate("locale", QString::fromLatin1("l10n/")
    02607                 + countryCode
    02608                 + QString::fromLatin1("/flag.png")));
    02609             emit setStatusBarText(flagImg + u.prettyURL() + extra);
    02610           }
    02611         }
    02612       }
    02613 #endif
    02614     setStatusBarText(u.htmlURL() + extra, BarHoverText);
    02615   }
    02616 }
    02617
    02618 void KHTMLPart::urlSelected( const QString &url, int button, int state, const QString &_target,
    02619                              KParts::URLArgs args )
    02620 {
    02621   bool hasTarget = false;
    02622
    02623   QString target = _target;
    02624   if ( target.isEmpty() && d->m_doc )
    02625     target = d->m_doc->baseTarget();
    02626   if ( !target.isEmpty() )
    02627       hasTarget = true;
    02628
    02629   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
    02630   {
    02631     executeScript( KURL::decode_string( url.right( url.length() - 11 ) ) );
    02632     return;
    02633   }
    02634
    02635   KURL cURL = completeURL(url);
    02636   // special case for <a href="">  (IE removes filename, mozilla doesn't)
    02637   if ( url.isEmpty() )
    02638     cURL.setFileName( url ); // removes filename
    02639
    02640   if ( !cURL.isValid() )
    02641     // ### ERROR HANDLING
    02642     return;
    02643
    02644   //kdDebug( 6000 ) << "urlSelected: complete URL:" << cURL.url() << " target = " << target << endl;
    02645
    02646   if ( button == LeftButton && ( state & ShiftButton ) )
    02647   {
    02648     KIO::MetaData metaData;
    02649     metaData["referrer"] = d->m_referrer;
    02650     KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As..." ), cURL, metaData );
    02651     return;
    02652   }
    02653
    02654   if (!checkLinkSecurity(cURL,
    02655                          i18n( "<qt>The link <B>%1</B><BR>leads from this untrusted page to your local filesystem.<BR>Do you want to follow the link?" ),
    02656                          i18n( "Follow" )))
    02657     return;
    02658
    02659   args.frameName = target;
    02660
    02661   if ( d->m_bHTTPRefresh )
    02662   {
    02663     d->m_bHTTPRefresh = false;
    02664     args.metaData()["cache"] = "refresh";
    02665   }
    02666
    02667   args.metaData().insert("main_frame_request",
    02668                          parentPart() == 0 ? "TRUE":"FALSE");
    02669   args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
    02670   args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
    02671   args.metaData().insert("PropagateHttpHeader", "true");
    02672   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
    02673   args.metaData().insert("ssl_activate_warnings", "TRUE");
    02674
    02675   if ( hasTarget )
    02676   {
    02677     // unknown frame names should open in a new window.
    02678     khtml::ChildFrame *frame = recursiveFrameRequest( cURL, args, false );
    02679     if ( frame )
    02680     {
    02681       args.metaData()["referrer"] = d->m_referrer;
    02682       requestObject( frame, cURL, args );
    02683       return;
    02684     }
    02685   }
    02686
    02687   if ( !d->m_bComplete && !hasTarget )
    02688     closeURL();
    02689
    02690   if (!d->m_referrer.isEmpty())
    02691     args.metaData()["referrer"] = d->m_referrer;
    02692
    02693   if ( button == MidButton && (state & ShiftButton) )
    02694   {
    02695     KParts::WindowArgs winArgs;
    02696     winArgs.lowerWindow = true;
    02697     KParts::ReadOnlyPart *newPart = 0;
    02698     emit d->m_extension->createNewWindow( cURL, args, winArgs, newPart );
    02699     return;
    02700   }
    02701
    02702   if ( button == LeftButton && (state & ControlButton) )
    02703   {
    02704     args.setNewTab(true);
    02705     emit d->m_extension->createNewWindow( cURL, args );
    02706     return;
    02707   }
    02708
    02709   view()->viewport()->unsetCursor();
    02710   emit d->m_extension->openURLRequest( cURL, args );
    02711 }
    02712
    02713 void KHTMLPart::slotViewDocumentSource()
    02714 {
    02715   KURL url(m_url);
    02716   if (!(url.isLocalFile()) && KHTMLPageCache::self()->isValid(d->m_cacheId))
    02717   {
    02718      KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
    02719      if (sourceFile.status() == 0)
    02720      {
    02721         KHTMLPageCache::self()->saveData(d->m_cacheId, sourceFile.dataStream());
    02722         url = KURL();
    02723         url.setPath(sourceFile.name());
    02724      }
    02725   }
    02726
    02727   //  emit d->m_extension->openURLRequest( m_url, KParts::URLArgs( false, 0, 0, QString::fromLatin1( "text/plain" ) ) );
    02728   (void) KRun::runURL( url, QString::fromLatin1("text/plain") );
    02729 }
    02730
    02731 void KHTMLPart::slotViewPageInfo()
    02732 {
    02733   KHTMLInfoDlg *dlg = new KHTMLInfoDlg(NULL, "KHTML Page Info Dialog", false, WDestructiveClose);
    02734
    02735   if (d->m_doc)
    02736      dlg->_title->setText(d->m_doc->title().string());
    02737
    02738   // If it's a frame, set the caption to "Frame Information"
    02739   if ( parentPart() && d->m_doc && d->m_doc->isHTMLDocument() ) {
    02740      dlg->setCaption(i18n("Frame Information"));
    02741   }
    02742
    02743   QString editStr = QString::null;
    02744
    02745   if (!d->m_pageServices.isEmpty())
    02746     editStr = i18n("   <a href=\"%1\">[Properties]</a>").arg(d->m_pageServices);
    02747
    02748   dlg->_url->setText(QString("<a href=\"%1\">%2</a>%3").arg(url().url()).arg(url().prettyURL()).arg(editStr));
    02749   dlg->_lastModified->setText(lastModified());
    02750
    02751   /* populate the list view now */
    02752   QStringList headers = QStringList::split("\n", d->m_httpHeaders);
    02753
    02754   for (QStringList::Iterator it = headers.begin(); it != headers.end(); ++it) {
    02755     QStringList header = QStringList::split(QRegExp(":[ ]+"), *it);
    02756     if (header.count() != 2)
    02757        continue;
    02758     new QListViewItem(dlg->_headers, header[0], header[1]);
    02759   }
    02760
    02761   dlg->show();
    02762   /* put no code here */
    02763 }
    02764
    02765
    02766 void KHTMLPart::slotViewFrameSource()
    02767 {
    02768   KParts::ReadOnlyPart *frame = currentFrame();
    02769   if ( !frame )
    02770     return;
    02771
    02772   KURL url = frame->url();
    02773   if (!(url.isLocalFile()) && frame->inherits("KHTMLPart"))
    02774   {
    02775        long cacheId = static_cast<KHTMLPart *>(frame)->d->m_cacheId;
    02776
    02777        if (KHTMLPageCache::self()->isValid(cacheId))
    02778        {
    02779            KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
    02780            if (sourceFile.status() == 0)
    02781            {
    02782                KHTMLPageCache::self()->saveData(cacheId, sourceFile.dataStream());
    02783                url = KURL();
    02784                url.setPath(sourceFile.name());
    02785            }
    02786      }
    02787   }
    02788
    02789   (void) KRun::runURL( url, QString::fromLatin1("text/plain") );
    02790 }
    02791
    02792 KURL KHTMLPart::backgroundURL() const
    02793 {
    02794   // ### what about XML documents? get from CSS?
    02795   if (!d->m_doc || !d->m_doc->isHTMLDocument())
    02796     return KURL();
    02797
    02798   QString relURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
    02799
    02800   return KURL( m_url, relURL );
    02801 }
    02802
    02803 void KHTMLPart::slotSaveBackground()
    02804 {
    02805   KIO::MetaData metaData;
    02806   metaData["referrer"] = d->m_referrer;
    02807   KHTMLPopupGUIClient::saveURL( d->m_view, i18n("Save background image as"), backgroundURL(), metaData );
    02808 }
    02809
    02810 void KHTMLPart::slotSaveDocument()
    02811 {
    02812   KURL srcURL( m_url );
    02813
    02814   if ( srcURL.fileName(false).isEmpty() )
    02815     srcURL.setFileName( "index.html" );
    02816
    02817   KIO::MetaData metaData;
    02818   // Referre unknown?
    02819   KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, i18n("*.html *.htm|HTML files"), d->m_cacheId );
    02820 }
    02821
    02822 void KHTMLPart::slotSecurity()
    02823 {
    02824 //   kdDebug( 6050 ) << "Meta Data:" << endl
    02825 //                   << d->m_ssl_peer_cert_subject
    02826 //                   << endl
    02827 //                   << d->m_ssl_peer_cert_issuer
    02828 //                   << endl
    02829 //                   << d->m_ssl_cipher
    02830 //                   << endl
    02831 //                   << d->m_ssl_cipher_desc
    02832 //                   << endl
    02833 //                   << d->m_ssl_cipher_version
    02834 //                   << endl
    02835 //                   << d->m_ssl_good_from
    02836 //                   << endl
    02837 //                   << d->m_ssl_good_until
    02838 //                   << endl
    02839 //                   << d->m_ssl_cert_state
    02840 //                   << endl;
    02841
    02842   KSSLInfoDlg *kid = new KSSLInfoDlg(d->m_ssl_in_use, widget(), "kssl_info_dlg", true );
    02843
    02844   if (d->m_bSecurityInQuestion)
    02845           kid->setSecurityInQuestion(true);
    02846
    02847   if (d->m_ssl_in_use) {
    02848     KSSLCertificate *x = KSSLCertificate::fromString(d->m_ssl_peer_certificate.local8Bit());
    02849     if (x) {
    02850        // Set the chain back onto the certificate
    02851        QStringList cl = QStringList::split(QString("\n"), d->m_ssl_peer_chain);
    02852        QPtrList<KSSLCertificate> ncl;
    02853
    02854        ncl.setAutoDelete(true);
    02855        for (QStringList::Iterator it = cl.begin(); it != cl.end(); ++it) {
    02856           KSSLCertificate *y = KSSLCertificate::fromString((*it).local8Bit());
    02857           if (y) ncl.append(y);
    02858        }
    02859
    02860        if (ncl.count() > 0)
    02861           x->chain().setChain(ncl);
    02862
    02863        kid->setup(x,
    02864                   d->m_ssl_peer_ip,
    02865                   m_url.url(),
    02866                   d->m_ssl_cipher,
    02867                   d->m_ssl_cipher_desc,
    02868                   d->m_ssl_cipher_version,
    02869                   d->m_ssl_cipher_used_bits.toInt(),
    02870                   d->m_ssl_cipher_bits.toInt(),
    02871                   (KSSLCertificate::KSSLValidation) d->m_ssl_cert_state.toInt()
    02872                   );
    02873         kid->exec();
    02874         delete x;
    02875      } else kid->exec();
    02876   } else kid->exec();
    02877 }
    02878
    02879 void KHTMLPart::slotSaveFrame()
    02880 {
    02881     if ( !d->m_activeFrame )
    02882         return; // should never be the case, but one never knows :-)
    02883
    02884     KURL srcURL( static_cast<KParts::ReadOnlyPart *>( d->m_activeFrame )->url() );
    02885
    02886     if ( srcURL.fileName(false).isEmpty() )
    02887         srcURL.setFileName( "index.html" );
    02888
    02889     KIO::MetaData metaData;
    02890     // Referrer unknown?
    02891     KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, i18n("*.html *.htm|HTML files") );
    02892 }
    02893
    02894 void KHTMLPart::slotSetEncoding()
    02895 {
    02896     // first Item is always auto
    02897     if(d->m_paSetEncoding->currentItem() == 0)
    02898         setEncoding(QString::null, false);
    02899     else {
    02900         // strip of the language to get the raw encoding again.
    02901         QString enc = KGlobal::charsets()->encodingForName(d->m_paSetEncoding->currentText());
    02902         setEncoding(enc, true);
    02903     }
    02904 }
    02905
    02906 void KHTMLPart::slotUseStylesheet()
    02907 {
    02908   if (d->m_doc && d->m_paUseStylesheet->currentText() != d->m_sheetUsed) {
    02909     d->m_sheetUsed = d->m_paUseStylesheet->currentText();
    02910     d->m_doc->updateStyleSelector();
    02911   }
    02912 }
    02913
    02914 void KHTMLPart::updateActions()
    02915 {
    02916   bool frames = false;
    02917
    02918   QValueList<khtml::ChildFrame>::ConstIterator it = d->m_frames.begin();
    02919   QValueList<khtml::ChildFrame>::ConstIterator end = d->m_frames.end();
    02920   for (; it != end; ++it )
    02921       if ( (*it).m_type == khtml::ChildFrame::Frame )
    02922       {
    02923           frames = true;
    02924           break;
    02925       }
    02926
    02927   d->m_paViewFrame->setEnabled( frames );
    02928   d->m_paSaveFrame->setEnabled( frames );
    02929
    02930   if ( frames )
    02931     d->m_paFind->setText( i18n( "&Find in Frame..." ) );
    02932   else
    02933     d->m_paFind->setText( i18n( "&Find..." ) );
    02934
    02935   KParts::Part *frame = 0;
    02936
    02937   if ( frames )
    02938     frame = currentFrame();
    02939
    02940   bool enableFindAndSelectAll = true;
    02941
    02942   if ( frame )
    02943     enableFindAndSelectAll = frame->inherits( "KHTMLPart" );
    02944
    02945   d->m_paFind->setEnabled( enableFindAndSelectAll );
    02946   d->m_paFindNext->setEnabled( false ); // needs a 'find' first
    02947   d->m_paSelectAll->setEnabled( enableFindAndSelectAll );
    02948
    02949   bool enablePrintFrame = false;
    02950
    02951   if ( frame )
    02952   {
    02953     QObject *ext = KParts::BrowserExtension::childObject( frame );
    02954     if ( ext )
    02955       enablePrintFrame = ext->metaObject()->slotNames().contains( "print()" );
    02956   }
    02957
    02958   d->m_paPrintFrame->setEnabled( enablePrintFrame );
    02959
    02960   QString bgURL;
    02961
    02962   // ### frames
    02963   if ( d->m_doc && d->m_doc->isHTMLDocument() && static_cast<HTMLDocumentImpl*>(d->m_doc)->body() && !d->m_bClearing )
    02964     bgURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
    02965
    02966   d->m_paSaveBackground->setEnabled( !bgURL.isEmpty() );
    02967 }
    02968
    02969 KParts::LiveConnectExtension *KHTMLPart::liveConnectExtension( const khtml::RenderPart *frame) const {
    02970     QValueList<khtml::ChildFrame>::ConstIterator it = d->m_objects.begin();
    02971     QValueList<khtml::ChildFrame>::ConstIterator end = d->m_objects.end();
    02972     for(; it != end; ++it )
    02973         if ((*it).m_frame == frame)
    02974             return (*it).m_liveconnect;
    02975     return 0L;
    02976 }
    02977
    02978 bool KHTMLPart::requestFrame( khtml::RenderPart *frame, const QString &url, const QString &frameName,
    02979                               const QStringList &params, bool isIFrame )
    02980 {
    02981 //  kdDebug( 6050 ) << "childRequest( ..., " << url << ", " << frameName << " )" << endl;
    02982   FrameIt it = d->m_frames.find( frameName );
    02983   if ( it == d->m_frames.end() )
    02984   {
    02985     khtml::ChildFrame child;
    02986 //    kdDebug( 6050 ) << "inserting new frame into frame map " << frameName << endl;
    02987     child.m_name = frameName;
    02988     it = d->m_frames.append( child );
    02989   }
    02990
    02991   (*it).m_type = isIFrame ? khtml::ChildFrame::IFrame : khtml::ChildFrame::Frame;
    02992   (*it).m_frame = frame;
    02993   (*it).m_params = params;
    02994
    02995   // Support for <frame src="javascript:string">
    02996   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
    02997   {
    02998       QVariant res = executeScript( DOM::Node(frame->element()), KURL::decode_string( url.right( url.length() - 11) ) );
    02999       KURL myurl;
    03000       myurl.setProtocol("javascript");
    03001       if ( res.type() == QVariant::String )
    03002         myurl.setPath(res.asString());
    03003       return processObjectRequest(&(*it), myurl, QString("text/html") );
    03004   }
    03005   KURL u = url.isEmpty() ? KURL() : completeURL( url );
    03006   return requestObject( &(*it), u );
    03007 }
    03008
    03009 QString KHTMLPart::requestFrameName()
    03010 {
    03011    return QString::fromLatin1("<!--frame %1-->").arg(d->m_frameNameId++);
    03012 }
    03013
    03014 bool KHTMLPart::requestObject( khtml::RenderPart *frame, const QString &url, const QString &serviceType,
    03015                                const QStringList &params )
    03016 {
    03017   khtml::ChildFrame child;
    03018   QValueList<khtml::ChildFrame>::Iterator it = d->m_objects.append( child );
    03019   (*it).m_frame = frame;
    03020   (*it).m_type = khtml::ChildFrame::Object;
    03021   (*it).m_params = params;
    03022
    03023   KParts::URLArgs args;
    03024   args.serviceType = serviceType;
    03025   return requestObject( &(*it), completeURL( url ), args );
    03026 }
    03027
    03028 bool KHTMLPart::requestObject( khtml::ChildFrame *child, const KURL &url, const KParts::URLArgs &_args )
    03029 {
    03030   if (!checkLinkSecurity(url))
    03031     return false;
    03032   if ( child->m_bPreloaded )
    03033   {
    03034     // kdDebug(6005) << "KHTMLPart::requestObject preload" << endl;
    03035     if ( child->m_frame && child->m_part )
    03036       child->m_frame->setWidget( child->m_part->widget() );
    03037
    03038     child->m_bPreloaded = false;
    03039     return true;
    03040   }
    03041
    03042   KParts::URLArgs args( _args );
    03043
    03044   if ( child->m_run )
    03045     child->m_run->abort();
    03046
    03047   if ( child->m_part && !args.reload && urlcmp( child->m_part->url().url(), url.url(), true, true ) )
    03048     args.serviceType = child->m_serviceType;
    03049
    03050   child->m_args = args;
    03051   child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload) || (d->m_cachePolicy == KIO::CC_Refresh);
    03052   child->m_serviceName = QString::null;
    03053   if (!d->m_referrer.isEmpty() && !child->m_args.metaData().contains( "referrer" ))
    03054     child->m_args.metaData()["referrer"] = d->m_referrer;
    03055
    03056   child->m_args.metaData().insert("PropagateHttpHeader", "true");
    03057   child->m_args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
    03058   child->m_args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
    03059   child->m_args.metaData().insert("main_frame_request",
    03060                                   parentPart() == 0 ? "TRUE":"FALSE");
    03061   child->m_args.metaData().insert("ssl_was_in_use",
    03062                                   d->m_ssl_in_use ? "TRUE":"FALSE");
    03063   child->m_args.metaData().insert("ssl_activate_warnings", "TRUE");
    03064
    03065   // We want a KHTMLPart if the HTML says <frame src=""> or <frame src="about:blank">
    03066   if ((url.isEmpty() || url.url() == "about:blank") && args.serviceType.isEmpty())
    03067     args.serviceType = QString::fromLatin1( "text/html" );
    03068
    03069   if ( args.serviceType.isEmpty() ) {
    03070     child->m_run = new KHTMLRun( this, child, url, child->m_args,
    03071                                  child->m_type != khtml::ChildFrame::Frame );
    03072     return false;
    03073   } else {
    03074     return processObjectRequest( child, url, args.serviceType );
    03075   }
    03076 }
    03077
    03078 bool KHTMLPart::processObjectRequest( khtml::ChildFrame *child, const KURL &_url, const QString &mimetype )
    03079 {
    03080   //kdDebug( 6050 ) << "KHTMLPart::processObjectRequest trying to create part for " << mimetype << endl;
    03081
    03082   // IMPORTANT: create a copy of the url here, because it is just a reference, which was likely to be given
    03083   // by an emitting frame part (emit openURLRequest( blahurl, ... ) . A few lines below we delete the part
    03084   // though -> the reference becomes invalid -> crash is likely
    03085   KURL url( _url );
    03086
    03087   // khtmlrun called us this way to indicate a loading error
    03088   if ( d->m_onlyLocalReferences || ( url.isEmpty() && mimetype.isEmpty() ) )
    03089   {
    03090       checkEmitLoadEvent();
    03091       child->m_bCompleted = true;
    03092       return true;
    03093   }
    03094
    03095   if (child->m_bNotify)
    03096   {
    03097       child->m_bNotify = false;
    03098       if ( !child->m_args.lockHistory() )
    03099           emit d->m_extension->openURLNotify();
    03100   }
    03101
    03102   if ( child->m_serviceType != mimetype )
    03103   {
    03104     QStringList dummy; // the list of servicetypes handled by the part is now unused.
    03105     KParts::ReadOnlyPart *part = createPart( d->m_view->viewport(), child->m_name.ascii(), this, child->m_name.ascii(), mimetype, child->m_serviceName, dummy, child->m_params );
    03106
    03107     if ( !part )
    03108     {
    03109         if ( child->m_frame )
    03110           if (child->m_frame->partLoadingErrorNotify( child, url, mimetype ))
    03111             return true; // we succeeded after all (a fallback was used)
    03112
    03113         checkEmitLoadEvent();
    03114         return false;
    03115     }
    03116
    03117     //CRITICAL STUFF
    03118     if ( child->m_part )
    03119     {
    03120       partManager()->removePart( (KParts::ReadOnlyPart *)child->m_part );
    03121       delete (KParts::ReadOnlyPart *)child->m_part;
    03122     }
    03123
    03124     child->m_serviceType = mimetype;
    03125     if ( child->m_frame )
    03126       child->m_frame->setWidget( part->widget() );
    03127
    03128     if ( child->m_type != khtml::ChildFrame::Object )
    03129       partManager()->addPart( part, false );
    03130 //  else
    03131 //      kdDebug(6005) << "AH! NO FRAME!!!!!" << endl;
    03132
    03133     child->m_part = part;
    03134     assert( ((void*) child->m_part) != 0);
    03135
    03136     if ( child->m_type != khtml::ChildFrame::Object )
    03137     {
    03138       connect( part, SIGNAL( started( KIO::Job *) ),
    03139                this, SLOT( slotChildStarted( KIO::Job *) ) );
    03140       connect( part, SIGNAL( completed() ),
    03141                this, SLOT( slotChildCompleted() ) );
    03142       connect( part, SIGNAL( completed(bool) ),
    03143                this, SLOT( slotChildCompleted(bool) ) );
    03144       connect( part, SIGNAL( setStatusBarText( const QString & ) ),
    03145                this, SIGNAL( setStatusBarText( const QString & ) ) );
    03146       if ( part->inherits( "KHTMLPart" ) )
    03147       {
    03148           connect( this, SIGNAL( completed() ),
    03149                    part, SLOT( slotParentCompleted() ) );
    03150           connect( this, SIGNAL( completed(bool) ),
    03151                    part, SLOT( slotParentCompleted() ) );
    03152           // As soon as the child's document is created, we need to set its domain
    03153           // (but we do so only once, so it can't be simply done in the child)
    03154           connect( part, SIGNAL( docCreated() ),
    03155                    this, SLOT( slotChildDocCreated() ) );
    03156       }
    03157     }
    03158
    03159     child->m_extension = KParts::BrowserExtension::childObject( part );
    03160
    03161     if ( child->m_extension )
    03162     {
    03163       connect( child->m_extension, SIGNAL( openURLNotify() ),
    03164                d->m_extension, SIGNAL( openURLNotify() ) );
    03165
    03166       connect( child->m_extension, SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ),
    03167                this, SLOT( slotChildURLRequest( const KURL &, const KParts::URLArgs & ) ) );
    03168
    03169       connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ),
    03170                d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ) );
    03171       connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs &, const KParts::WindowArgs &, KParts::ReadOnlyPart *& ) ),
    03172                d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & , const KParts::WindowArgs &, KParts::ReadOnlyPart *&) ) );
    03173
    03174       connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ),
    03175                d->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ) );
    03176       connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ),
    03177                d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ) );
    03178       connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ),
    03179                d->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ) );
    03180       connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ),
    03181                d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ) );
    03182
    03183       connect( child->m_extension, SIGNAL( infoMessage( const QString & ) ),
    03184                d->m_extension, SIGNAL( infoMessage( const QString & ) ) );
    03185
    03186       child->m_extension->setBrowserInterface( d->m_extension->browserInterface() );
    03187     }
    03188     child->m_liveconnect = KParts::LiveConnectExtension::childObject( part );
    03189   }
    03190
    03191   checkEmitLoadEvent();
    03192   // Some JS code in the load event may have destroyed the part
    03193   // In that case, abort
    03194   if ( !child->m_part )
    03195     return false;
    03196
    03197   if ( child->m_bPreloaded )
    03198   {
    03199     if ( child->m_frame && child->m_part )
    03200       child->m_frame->setWidget( child->m_part->widget() );
    03201
    03202     child->m_bPreloaded = false;
    03203     return true;
    03204   }
    03205
    03206   child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload) || (d->m_cachePolicy == KIO::CC_Refresh);
    03207
    03208   // make sure the part has a way to find out about the mimetype.
    03209   // we actually set it in child->m_args in requestObject already,
    03210   // but it's useless if we had to use a KHTMLRun instance, as the
    03211   // point the run object is to find out exactly the mimetype.
    03212   child->m_args.serviceType = mimetype;
    03213
    03214   child->m_bCompleted = false;
    03215   if ( child->m_extension )
    03216     child->m_extension->setURLArgs( child->m_args );
    03217
    03218   if(url.protocol() == "javascript" || url.url() == "about:blank") {
    03219       if (!child->m_part->inherits("KHTMLPart"))
    03220           return false;
    03221
    03222       KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>(child->m_part));
    03223
    03224       p->begin();
    03225       if (d->m_doc && p->d->m_doc)
    03226         p->d->m_doc->setBaseURL(d->m_doc->baseURL());
    03227       if (!url.url().startsWith("about:")) {
    03228         p->write(url.path());
    03229       } else {
    03230         p->m_url = url;
    03231         // we need a body element. testcase: <iframe id="a"></iframe><script>alert(a.document.body);</script>
    03232         p->write("<HTML><BODY></BODY></HTML>");
    03233       }
    03234       p->end();
    03235       return true;
    03236   }
    03237   else if ( !url.isEmpty() )
    03238   {
    03239       //kdDebug( 6050 ) << "opening " << url.url() << " in frame " << child->m_part << endl;
    03240       return child->m_part->openURL( url );
    03241   }
    03242   else
    03243       return true;
    03244 }
    03245
    03246 KParts::ReadOnlyPart *KHTMLPart::createPart( QWidget *parentWidget, const char *widgetName,
    03247                                              QObject *parent, const char *name, const QString &mimetype,
    03248                                              QString &serviceName, QStringList &serviceTypes,
    03249                                              const QStringList &params )
    03250 {
    03251   QString constr;
    03252   if ( !serviceName.isEmpty() )
    03253     constr.append( QString::fromLatin1( "Name == '%1'" ).arg( serviceName ) );
    03254
    03255   KTrader::OfferList offers = KTrader::self()->query( mimetype, "KParts/ReadOnlyPart", constr, QString::null );
    03256
    03257   if ( offers.isEmpty() )
    03258     return 0L;
    03259
    03260   KService::Ptr service = *offers.begin();
    03261
    03262   KLibFactory *factory = KLibLoader::self()->factory( QFile::encodeName(service->library()) );
    03263
    03264   if ( !factory )
    03265     return 0L;
    03266
    03267   KParts::ReadOnlyPart *res = 0L;
    03268
    03269   const char *className = "KParts::ReadOnlyPart";
    03270   if ( service->serviceTypes().contains( "Browser/View" ) )
    03271     className = "Browser/View";
    03272
    03273   if ( factory->inherits( "KParts::Factory" ) )
    03274     res = static_cast<KParts::ReadOnlyPart *>(static_cast<KParts::Factory *>( factory )->createPart( parentWidget, widgetName, parent, name, className, params ));
    03275   else
    03276   res = static_cast<KParts::ReadOnlyPart *>(factory->create( parentWidget, widgetName, className ));
    03277
    03278   if ( !res )
    03279     return res;
    03280
    03281   serviceTypes = service->serviceTypes();
    03282   serviceName = service->name();
    03283
    03284   return res;
    03285 }
    03286
    03287 KParts::PartManager *KHTMLPart::partManager()
    03288 {
    03289   if ( !d->m_manager )
    03290   {
    03291     d->m_manager = new KParts::PartManager( d->m_view->topLevelWidget(), this, "khtml part manager" );
    03292     d->m_manager->setAllowNestedParts( true );
    03293     connect( d->m_manager, SIGNAL( activePartChanged( KParts::Part * ) ),
    03294              this, SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
    03295     connect( d->m_manager, SIGNAL( partRemoved( KParts::Part * ) ),
    03296              this, SLOT( slotPartRemoved( KParts::Part * ) ) );
    03297   }
    03298
    03299   return d->m_manager;
    03300 }
    03301
    03302 void KHTMLPart::submitFormAgain()
    03303 {
    03304   if( d->m_doc && !d->m_doc->parsing() && d->m_submitForm)
    03305     KHTMLPart::submitForm( d->m_submitForm->submitAction, d->m_submitForm->submitUrl, d->m_submitForm->submitFormData, d->m_submitForm->target, d->m_submitForm->submitContentType, d->m_submitForm->submitBoundary );
    03306
    03307   delete d->m_submitForm;
    03308   d->m_submitForm = 0;
    03309   disconnect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
    03310 }
    03311
    03312 void KHTMLPart::submitForm( const char *action, const QString &url, const QByteArray &formData, const QString &_target, const QString& contentType, const QString& boundary )
    03313 {
    03314   kdDebug(6000) << this << ": KHTMLPart::submitForm target=" << _target << " url=" << url << endl;
    03315   KURL u = completeURL( url );
    03316
    03317   if ( !u.isValid() )
    03318   {
    03319     // ### ERROR HANDLING!
    03320     return;
    03321   }
    03322
    03323   // Form security checks
    03324   //
    03325   /*
    03326    * If these form security checks are still in this place in a month or two
    03327    * I'm going to simply delete them.
    03328    */
    03329
    03330   /* This is separate for a reason.  It has to be _before_ all script, etc,
    03331    * AND I don't want to break anything that uses checkLinkSecurity() in
    03332    * other places.
    03333    */
    03334
    03335   if (!d->m_submitForm) {
    03336     if (u.protocol() != "https" && u.protocol() != "mailto") {
    03337       if (d->m_ssl_in_use) {    // Going from SSL -> nonSSL
    03338         int rc = KMessageBox::warningContinueCancel(NULL, i18n("Warning:  This is a secure form but it is attempting to send your data back unencrypted."
    03339                                                                "\nA third party may be able to intercept and view this information."
    03340                                                                "\nAre you sure you wish to continue?"),
    03341                                                     i18n("SSL"));
    03342         if (rc == KMessageBox::Cancel)
    03343           return;
    03344       } else {                  // Going from nonSSL -> nonSSL
    03345         KSSLSettings kss(true);
    03346         if (kss.warnOnUnencrypted()) {
    03347           int rc = KMessageBox::warningContinueCancel(NULL,
    03348                                                       i18n("Warning: Your data is about to be transmitted across the network unencrypted."
    03349                                                            "\nAre you sure you wish to continue?"),
    03350                                                       i18n("KDE"),
    03351                                                       QString::null,
    03352                                                       "WarnOnUnencryptedForm");
    03353           // Move this setting into KSSL instead
    03354           KConfig *config = kapp->config();
    03355           QString grpNotifMsgs = QString::fromLatin1("Notification Messages");
    03356           KConfigGroupSaver saver( config, grpNotifMsgs );
    03357
    03358           if (!config->readBoolEntry("WarnOnUnencryptedForm", true)) {
    03359             config->deleteEntry("WarnOnUnencryptedForm");
    03360             config->sync();
    03361             kss.setWarnOnUnencrypted(false);
    03362             kss.save();
    03363           }
    03364           if (rc == KMessageBox::Cancel)
    03365             return;
    03366         }
    03367       }
    03368     }
    03369
    03370     if (u.protocol() == "mailto") {
    03371       int rc = KMessageBox::warningContinueCancel(NULL,
    03372                                                   i18n("This site is attempting to submit form data via email.\n"
    03373                                                        "Do you want to continue?"),
    03374                                                   i18n("KDE"),
    03375                                                   QString::null,
    03376                                                   "WarnTriedEmailSubmit");
    03377
    03378       if (rc == KMessageBox::Cancel) {
    03379         return;
    03380       }
    03381     }
    03382   }
    03383
    03384   // End form security checks
    03385   //
    03386
    03387   QString urlstring = u.url();
    03388
    03389   if ( urlstring.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
    03390     urlstring = KURL::decode_string(urlstring);
    03391     executeScript( urlstring.right( urlstring.length() - 11) );
    03392     return;
    03393   }
    03394
    03395   if (!checkLinkSecurity(u,
    03396                          i18n( "<qt>The form will be submitted to <BR><B>%1</B><BR>on your local filesystem.<BR>Do you want to submit the form?" ),
    03397                          i18n( "Submit" )))
    03398     return;
    03399
    03400   KParts::URLArgs args;
    03401
    03402   if (!d->m_referrer.isEmpty())
    03403      args.metaData()["referrer"] = d->m_referrer;
    03404
    03405   args.metaData().insert("PropagateHttpHeader", "true");
    03406   args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
    03407   args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
    03408   args.metaData().insert("main_frame_request",
    03409                          parentPart() == 0 ? "TRUE":"FALSE");
    03410   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
    03411   args.metaData().insert("ssl_activate_warnings", "TRUE");
    03412   args.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;
    03413
    03414   // Handle mailto: forms
    03415   if (u.protocol() == "mailto") {
    03416       // 1)  Check for attach= and strip it
    03417       QString q = u.query().mid(1);
    03418       QStringList nvps = QStringList::split("&", q);
    03419       bool triedToAttach = false;
    03420
    03421       for (QStringList::Iterator nvp = nvps.begin(); nvp != nvps.end(); ++nvp) {
    03422          QStringList pair = QStringList::split("=", *nvp);
    03423          if (pair.count() >= 2) {
    03424             if (pair.first().lower() == "attach") {
    03425                nvp = nvps.remove(nvp);
    03426                triedToAttach = true;
    03427             }
    03428          }
    03429       }
    03430
    03431       if (triedToAttach)
    03432          KMessageBox::information(NULL, i18n("This site attempted to attach a file from your computer in the form submission. The attachment was removed for your protection."), i18n("KDE"), "WarnTriedAttach");
    03433
    03434       // 2)  Append body=
    03435       QString bodyEnc;
    03436       if (contentType.lower() == "multipart/form-data") {
    03437          // FIXME: is this correct?  I suspect not
    03438          bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(),
    03439                                                            formData.size()));
    03440       } else if (contentType.lower() == "text/plain") {
    03441          // Convention seems to be to decode, and s/&/\n/
    03442          QString tmpbody = QString::fromLatin1(formData.data(),
    03443                                                formData.size());
    03444          tmpbody.replace(QRegExp("[&]"), "\n");
    03445          tmpbody.replace(QRegExp("[+]"), " ");
    03446          tmpbody = KURL::decode_string(tmpbody);  // Decode the rest of it
    03447          bodyEnc = KURL::encode_string(tmpbody);  // Recode for the URL
    03448       } else {
    03449          bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(),
    03450                                                            formData.size()));
    03451       }
    03452
    03453       nvps.append(QString("body=%1").arg(bodyEnc));
    03454       q = nvps.join("&");
    03455       u.setQuery(q);
    03456   }
    03457
    03458   if ( strcmp( action, "get" ) == 0 ) {
    03459     if (u.protocol() != "mailto")
    03460        u.setQuery( QString::fromLatin1( formData.data(), formData.size() ) );
    03461     args.setDoPost( false );
    03462   }
    03463   else {
    03464     args.postData = formData;
    03465     args.setDoPost( true );
    03466
    03467     // construct some user headers if necessary
    03468     if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
    03469       args.setContentType( "Content-Type: application/x-www-form-urlencoded" );
    03470     else // contentType must be "multipart/form-data"
    03471       args.setContentType( "Content-Type: " + contentType + "; boundary=" + boundary );
    03472   }
    03473
    03474   if ( d->m_doc->parsing() || d->m_runningScripts > 0 ) {
    03475     if( d->m_submitForm ) {
    03476       kdDebug(6000) << "KHTMLPart::submitForm ABORTING!" << endl;
    03477       return;
    03478     }
    03479     d->m_submitForm = new KHTMLPartPrivate::SubmitForm;
    03480     d->m_submitForm->submitAction = action;
    03481     d->m_submitForm->submitUrl = url;
    03482     d->m_submitForm->submitFormData = formData;
    03483     d->m_submitForm->target = _target;
    03484     d->m_submitForm->submitContentType = contentType;
    03485     d->m_submitForm->submitBoundary = boundary;
    03486     connect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
    03487   }
    03488   else
    03489   {
    03490     emit d->m_extension->openURLRequest( u, args );
    03491   }
    03492 }
    03493
    03494 void KHTMLPart::popupMenu( const QString &linkUrl )
    03495 {
    03496   KURL popupURL;
    03497   KURL linkKURL;
    03498   if ( linkUrl.isEmpty() ) // click on background
    03499     popupURL = this->url();
    03500   else {               // click on link
    03501     popupURL = completeURL( linkUrl );
    03502     linkKURL = popupURL;
    03503   }
    03504
    03505   KXMLGUIClient *client = new KHTMLPopupGUIClient( this, d->m_popupMenuXML, linkKURL );
    03506
    03507   emit d->m_extension->popupMenu( client, QCursor::pos(), popupURL,
    03508                                   QString::fromLatin1( "text/html" ), S_IFREG /*always a file*/ );
    03509
    03510   delete client;
    03511
    03512   emit popupMenu(linkUrl, QCursor::pos());
    03513 }
    03514
    03515 void KHTMLPart::slotParentCompleted()
    03516 {
    03517   if ( !d->m_redirectURL.isEmpty() && !d->m_redirectionTimer.isActive() )
    03518   {
    03519     // kdDebug(6050) << this << ": Child redirection -> " << d->m_redirectURL << endl;
    03520     d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
    03521   }
    03522 }
    03523
    03524 void KHTMLPart::slotChildStarted( KIO::Job *job )
    03525 {
    03526   khtml::ChildFrame *child = frame( sender() );
    03527
    03528   assert( child );
    03529
    03530   child->m_bCompleted = false;
    03531
    03532   if ( d->m_bComplete )
    03533   {
    03534 #if 0
    03535     // WABA: Looks like this belongs somewhere else
    03536     if ( !parentPart() ) // "toplevel" html document? if yes, then notify the hosting browser about the document (url) changes
    03537     {
    03538       emit d->m_extension->openURLNotify();
    03539     }
    03540 #endif
    03541     d->m_bComplete = false;
    03542     emit started( job );
    03543   }
    03544 }
    03545
    03546 void KHTMLPart::slotChildCompleted()
    03547 {
    03548   slotChildCompleted( false );
    03549 }
    03550
    03551 void KHTMLPart::slotChildCompleted( bool pendingAction )
    03552 {
    03553   khtml::ChildFrame *child = frame( sender() );
    03554
    03555   assert( child );
    03556
    03557   child->m_bCompleted = true;
    03558   child->m_bPendingRedirection = pendingAction;
    03559   child->m_args = KParts::URLArgs();
    03560
    03561   checkCompleted();
    03562 }
    03563
    03564 void KHTMLPart::slotChildDocCreated()
    03565 {
    03566   const KHTMLPart* htmlFrame = static_cast<const KHTMLPart *>(sender());
    03567   // Set domain to the frameset's domain
    03568   // This must only be done when loading the frameset initially (#22039),
    03569   // not when following a link in a frame (#44162).
    03570   if ( d->m_doc && d->m_doc->isHTMLDocument() )
    03571   {
    03572     if ( sender()->inherits("KHTMLPart") )
    03573     {
    03574       DOMString domain = static_cast<HTMLDocumentImpl*>(d->m_doc)->domain();
    03575       if (htmlFrame->d->m_doc && htmlFrame->d->m_doc->isHTMLDocument() )
    03576         //kdDebug(6050) << "KHTMLPart::slotChildDocCreated: url: " << htmlFrame->m_url.url() << endl;
    03577         static_cast<HTMLDocumentImpl*>(htmlFrame->d->m_doc)->setDomain( domain );
    03578     }
    03579   }
    03580   // So it only happens once
    03581   disconnect( htmlFrame, SIGNAL( docCreated() ), this, SLOT( slotChildDocCreated() ) );
    03582 }
    03583
    03584 void KHTMLPart::slotChildURLRequest( const KURL &url, const KParts::URLArgs &args )
    03585 {
    03586   khtml::ChildFrame *child = frame( sender()->parent() );
    03587
    03588   // TODO: handle child target correctly! currently the script are always executed fur the parent
    03589   QString urlStr = url.url();
    03590   if ( urlStr.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
    03591       QString script = KURL::decode_string( urlStr.right( urlStr.length() - 11 ) );
    03592       executeScript( script );
    03593       return;
    03594   }
    03595
    03596   QString frameName = args.frameName.lower();
    03597   if ( !frameName.isEmpty() )
    03598   {
    03599     if ( frameName == QString::fromLatin1( "_top" ) )
    03600     {
    03601       emit d->m_extension->openURLRequest( url, args );
    03602       return;
    03603     }
    03604     else if ( frameName == QString::fromLatin1( "_blank" ) )
    03605     {
    03606       emit d->m_extension->createNewWindow( url, args );
    03607       return;
    03608     }
    03609     else if ( frameName == QString::fromLatin1( "_parent" ) )
    03610     {
    03611       KParts::URLArgs newArgs( args );
    03612       newArgs.frameName = QString::null;
    03613
    03614       emit d->m_extension->openURLRequest( url, newArgs );
    03615       return;
    03616     }
    03617     else if ( frameName != QString::fromLatin1( "_self" ) )
    03618     {
    03619       khtml::ChildFrame *_frame = recursiveFrameRequest( url, args );
    03620
    03621       if ( !_frame )
    03622       {
    03623         emit d->m_extension->openURLRequest( url, args );
    03624         return;
    03625       }
    03626
    03627       child = _frame;
    03628     }
    03629   }
    03630
    03631   if ( child ) {
    03632       // Inform someone that we are about to show something else.
    03633       child->m_bNotify = true;
    03634       requestObject( child, url, args );
    03635   }  else if ( frameName== "_self" ) // this is for embedded objects (via <object>) which want to replace the current document
    03636   {
    03637       KParts::URLArgs newArgs( args );
    03638       newArgs.frameName = QString::null;
    03639       emit d->m_extension->openURLRequest( url, newArgs );
    03640   }
    03641 }
    03642
    03643 khtml::ChildFrame *KHTMLPart::frame( const QObject *obj )
    03644 {
    03645     assert( obj->inherits( "KParts::ReadOnlyPart" ) );
    03646     const KParts::ReadOnlyPart *part = static_cast<const KParts::ReadOnlyPart *>( obj );
    03647
    03648     FrameIt it = d->m_frames.begin();
    03649     FrameIt end = d->m_frames.end();
    03650     for (; it != end; ++it )
    03651       if ( (KParts::ReadOnlyPart *)(*it).m_part == part )
    03652         return &(*it);
    03653
    03654     return 0L;
    03655 }
    03656
    03657 //#define DEBUG_FINDFRAME
    03658
    03659 KHTMLPart *KHTMLPart::findFrame( const QString &f )
    03660 {
    03661 #ifdef DEBUG_FINDFRAME
    03662   kdDebug(6050) << "KHTMLPart::findFrame '" << f << "'" << endl;
    03663   FrameIt it2 = d->m_frames.begin();
    03664   FrameIt end = d->m_frames.end();
    03665   for (; it2 != end; ++it2 )
    03666       kdDebug(6050) << "  - having frame '" << (*it2).m_name << "'" << endl;
    03667 #endif
    03668   // ### http://www.w3.org/TR/html4/appendix/notes.html#notes-frames
    03669   ConstFrameIt it = d->m_frames.find( f );
    03670   if ( it == d->m_frames.end() )
    03671   {
    03672 #ifdef DEBUG_FINDFRAME
    03673     kdDebug(6050) << "KHTMLPart::findFrame frame " << f << " not found" << endl;
    03674 #endif
    03675     return 0L;
    03676   }
    03677   else {
    03678     KParts::ReadOnlyPart *p = (*it).m_part;
    03679     if ( p && p->inherits( "KHTMLPart" ))
    03680     {
    03681 #ifdef DEBUG_FINDFRAME
    03682       kdDebug(6050) << "KHTMLPart::findFrame frame " << f << " is a KHTMLPart, ok" << endl;
    03683 #endif
    03684       return (KHTMLPart*)p;
    03685     }
    03686     else
    03687     {
    03688 #ifdef DEBUG_FINDFRAME
    03689       if (p)
    03690         kdWarning() << "KHTMLPart::findFrame frame " << f << " found but isn't a KHTMLPart ! " << p->className() << endl;
    03691       else
    03692         kdWarning() << "KHTMLPart::findFrame frame " << f << " found but m_part=0L" << endl;
    03693 #endif
    03694       return 0L;
    03695     }
    03696   }
    03697 }
    03698
    03699 KParts::ReadOnlyPart *KHTMLPart::currentFrame() const
    03700 {
    03701   KParts::ReadOnlyPart* part = (KParts::ReadOnlyPart*)(this);
    03702   // Find active part in our frame manager, in case we are a frameset
    03703   // and keep doing that (in case of nested framesets).
    03704   // Just realized we could also do this recursively, calling part->currentFrame()...
    03705   while ( part && part->inherits("KHTMLPart") &&
    03706           static_cast<KHTMLPart *>(part)->d->m_frames.count() > 0 ) {
    03707     KHTMLPart* frameset = static_cast<KHTMLPart *>(part);
    03708     part = static_cast<KParts::ReadOnlyPart *>(frameset->partManager()->activePart());
    03709     if ( !part ) return frameset;
    03710   }
    03711   return part;
    03712 }
    03713
    03714 bool KHTMLPart::frameExists( const QString &frameName )
    03715 {
    03716   ConstFrameIt it = d->m_frames.find( frameName );
    03717   if ( it == d->m_frames.end() )
    03718     return false;
    03719
    03720   // WABA: We only return true if the child actually has a frame
    03721   // set. Otherwise we might find our preloaded-selve.
    03722   // This happens when we restore the frameset.
    03723   return (!(*it).m_frame.isNull());
    03724 }
    03725
    03726 KHTMLPart *KHTMLPart::parentPart()
    03727 {
    03728   if ( !parent() || !parent()->inherits( "KHTMLPart" ) )
    03729     return 0L;
    03730
    03731   return (KHTMLPart *)parent();
    03732 }
    03733
    03734 khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( const KURL &url, const KParts::URLArgs &args,
    03735                                                      bool callParent )
    03736 {
    03737   FrameIt it = d->m_frames.find( args.frameName );
    03738
    03739   if ( it != d->m_frames.end() )
    03740     return &(*it);
    03741
    03742   it = d->m_frames.begin();
    03743   FrameIt end = d->m_frames.end();
    03744   for (; it != end; ++it )
    03745     if ( (*it).m_part && (*it).m_part->inherits( "KHTMLPart" ) )
    03746     {
    03747       KHTMLPart *childPart = (KHTMLPart *)(KParts::ReadOnlyPart *)(*it).m_part;
    03748
    03749       khtml::ChildFrame *res = childPart->recursiveFrameRequest( url, args, false );
    03750       if ( !res )
    03751         continue;
    03752
    03753       childPart->requestObject( res, url, args );
    03754       return 0L;
    03755     }
    03756
    03757   if ( parentPart() && callParent )
    03758   {
    03759     khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( url, args );
    03760
    03761     if ( res )
    03762       parentPart()->requestObject( res, url, args );
    03763
    03764     return 0L;
    03765   }
    03766
    03767   return 0L;
    03768 }
    03769
    03770 void KHTMLPart::saveState( QDataStream &stream )
    03771 {
    03772   kdDebug( 6050 ) << "KHTMLPart::saveState saving URL " << m_url.url() << endl;
    03773
    03774   stream << m_url << (Q_INT32)d->m_view->contentsX() << (Q_INT32)d->m_view->contentsY()
    03775          << (Q_INT32) d->m_view->contentsWidth() << (Q_INT32) d->m_view->contentsHeight() << (Q_INT32) d->m_view->marginWidth() << (Q_INT32) d->m_view->marginHeight();
    03776
    03777   // save link cursor position
    03778   int focusNodeNumber;
    03779   if (!d->m_focusNodeRestored)
    03780       focusNodeNumber = d->m_focusNodeNumber;
    03781   else if (d->m_doc && d->m_doc->focusNode())
    03782       focusNodeNumber = d->m_doc->nodeAbsIndex(d->m_doc->focusNode());
    03783   else
    03784       focusNodeNumber = -1;
    03785   stream << focusNodeNumber;
    03786
    03787   // Save the doc's cache id.
    03788   stream << d->m_cacheId;
    03789
    03790   // Save the state of the document (Most notably the state of any forms)
    03791   QStringList docState;
    03792   if (d->m_doc)
    03793   {
    03794      docState = d->m_doc->docState();
    03795   }
    03796   stream << d->m_encoding << d->m_sheetUsed << docState;
    03797
    03798   stream << d->m_zoomFactor;
    03799
    03800   stream << d->m_httpHeaders;
    03801   stream << d->m_pageServices;
    03802
    03803   // Save ssl data
    03804   stream << d->m_ssl_in_use
    03805          << d->m_ssl_peer_certificate
    03806          << d->m_ssl_peer_chain
    03807          << d->m_ssl_peer_ip
    03808          << d->m_ssl_cipher
    03809          << d->m_ssl_cipher_desc
    03810          << d->m_ssl_cipher_version
    03811          << d->m_ssl_cipher_used_bits
    03812          << d->m_ssl_cipher_bits
    03813          << d->m_ssl_cert_state
    03814          << d->m_ssl_parent_ip
    03815          << d->m_ssl_parent_cert;
    03816
    03817
    03818   QStringList frameNameLst, frameServiceTypeLst, frameServiceNameLst;
    03819   KURL::List frameURLLst;
    03820   QValueList<QByteArray> frameStateBufferLst;
    03821
    03822   ConstFrameIt it = d->m_frames.begin();
    03823   ConstFrameIt end = d->m_frames.end();
    03824   for (; it != end; ++it )
    03825   {
    03826     if ( !(*it).m_part )
    03827        continue;
    03828
    03829     frameNameLst << (*it).m_name;
    03830     frameServiceTypeLst << (*it).m_serviceType;
    03831     frameServiceNameLst << (*it).m_serviceName;
    03832     frameURLLst << (*it).m_part->url();
    03833
    03834     QByteArray state;
    03835     QDataStream frameStream( state, IO_WriteOnly );
    03836
    03837     if ( (*it).m_extension )
    03838       (*it).m_extension->saveState( frameStream );
    03839
    03840     frameStateBufferLst << state;
    03841   }
    03842
    03843   // Save frame data
    03844   stream << (Q_UINT32) frameNameLst.count();
    03845   stream << frameNameLst << frameServiceTypeLst << frameServiceNameLst << frameURLLst << frameStateBufferLst;
    03846 }
    03847
    03848 void KHTMLPart::restoreState( QDataStream &stream )
    03849 {
    03850   KURL u;
    03851   Q_INT32 xOffset, yOffset, wContents, hContents, mWidth, mHeight;
    03852   Q_UINT32 frameCount;
    03853   QStringList frameNames, frameServiceTypes, docState, frameServiceNames;
    03854   KURL::List frameURLs;
    03855   QValueList<QByteArray> frameStateBuffers;
    03856   QValueList<int> fSizes;
    03857   QString encoding, sheetUsed;
    03858   long old_cacheId = d->m_cacheId;
    03859
    03860   stream >> u >> xOffset >> yOffset >> wContents >> hContents >> mWidth >> mHeight;
    03861
    03862   d->m_view->setMarginWidth( mWidth );
    03863   d->m_view->setMarginHeight( mHeight );
    03864
    03865   // restore link cursor position
    03866   // nth node is active. value is set in checkCompleted()
    03867   stream >> d->m_focusNodeNumber;
    03868   d->m_focusNodeRestored = false;
    03869   kdDebug(6050)<<"new focus Node number is:"<<d->m_focusNodeNumber<<endl;
    03870
    03871   stream >> d->m_cacheId;
    03872
    03873   stream >> encoding >> sheetUsed >> docState;
    03874
    03875   d->m_encoding = encoding;
    03876   d->m_sheetUsed = sheetUsed;
    03877
    03878   int zoomFactor;
    03879   stream >> zoomFactor;
    03880   setZoomFactor(zoomFactor);
    03881
    03882   stream >> d->m_httpHeaders;
    03883   stream >> d->m_pageServices;
    03884
    03885   // Restore ssl data
    03886   stream >> d->m_ssl_in_use
    03887          >> d->m_ssl_peer_certificate
    03888          >> d->m_ssl_peer_chain
    03889          >> d->m_ssl_peer_ip
    03890          >> d->m_ssl_cipher
    03891          >> d->m_ssl_cipher_desc
    03892          >> d->m_ssl_cipher_version
    03893          >> d->m_ssl_cipher_used_bits
    03894          >> d->m_ssl_cipher_bits
    03895          >> d->m_ssl_cert_state
    03896          >> d->m_ssl_parent_ip
    03897          >> d->m_ssl_parent_cert;
    03898
    03899   d->m_paSecurity->setIcon( d->m_ssl_in_use ? "encrypted" : "decrypted" );
    03900
    03901   stream >> frameCount >> frameNames >> frameServiceTypes >> frameServiceNames
    03902          >> frameURLs >> frameStateBuffers;
    03903
    03904   d->m_bComplete = false;
    03905   d->m_bLoadEventEmitted = false;
    03906
    03907 //   kdDebug( 6050 ) << "restoreStakte() docState.count() = " << docState.count() << endl;
    03908 //   kdDebug( 6050 ) << "m_url " << m_url.url() << " <-> " << u.url() << endl;
    03909 //   kdDebug( 6050 ) << "m_frames.count() " << d->m_frames.count() << " <-> " << frameCount << endl;
    03910
    03911   if (d->m_cacheId == old_cacheId)
    03912   {
    03913     // Partial restore
    03914     d->m_redirectionTimer.stop();
    03915
    03916     FrameIt fIt = d->m_frames.begin();
    03917     FrameIt fEnd = d->m_frames.end();
    03918
    03919     for (; fIt != fEnd; ++fIt )
    03920         (*fIt).m_bCompleted = false;
    03921
    03922     fIt = d->m_frames.begin();
    03923
    03924     QStringList::ConstIterator fNameIt = frameNames.begin();
    03925     QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
    03926     QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
    03927     KURL::List::ConstIterator fURLIt = frameURLs.begin();
    03928     QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
    03929
    03930     for (; fIt != fEnd; ++fIt, ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
    03931     {
    03932       khtml::ChildFrame *child = &(*fIt);
    03933
    03934 //      kdDebug( 6050 ) <<  *fNameIt  << " ---- " <<  *fServiceTypeIt << endl;
    03935
    03936       if ( child->m_name != *fNameIt || child->m_serviceType != *fServiceTypeIt )
    03937       {
    03938         child->m_bPreloaded = true;
    03939         child->m_name = *fNameIt;
    03940         child->m_serviceName = *fServiceNameIt;
    03941         processObjectRequest( child, *fURLIt, *fServiceTypeIt );
    03942       }
    03943
    03944       if ( child->m_part )
    03945       {
    03946         child->m_bCompleted = false;
    03947         if ( child->m_extension && !(*fBufferIt).isEmpty() )
    03948         {
    03949           QDataStream frameStream( *fBufferIt, IO_ReadOnly );
    03950           child->m_extension->restoreState( frameStream );
    03951         }
    03952         else
    03953           child->m_part->openURL( *fURLIt );
    03954       }
    03955     }
    03956
    03957     KParts::URLArgs args( d->m_extension->urlArgs() );
    03958     args.xOffset = xOffset;
    03959     args.yOffset = yOffset;
    03960     args.docState = docState;
    03961     d->m_extension->setURLArgs( args );
    03962
    03963     d->m_view->resizeContents( wContents,  hContents);
    03964     d->m_view->setContentsPos( xOffset, yOffset );
    03965   }
    03966   else
    03967   {
    03968     // Full restore.
    03969     closeURL();
    03970     // We must force a clear because we want to be sure to delete all
    03971     // frames.
    03972     d->m_bCleared = false;
    03973     clear();
    03974     d->m_encoding = encoding;
    03975     d->m_sheetUsed = sheetUsed;
    03976
    03977     QStringList::ConstIterator fNameIt = frameNames.begin();
    03978     QStringList::ConstIterator fNameEnd = frameNames.end();
    03979
    03980     QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
    03981     QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
    03982     KURL::List::ConstIterator fURLIt = frameURLs.begin();
    03983     QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
    03984
    03985     for (; fNameIt != fNameEnd; ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
    03986     {
    03987       khtml::ChildFrame newChild;
    03988       newChild.m_bPreloaded = true;
    03989       newChild.m_name = *fNameIt;
    03990       newChild.m_serviceName = *fServiceNameIt;
    03991
    03992 //      kdDebug( 6050 ) << *fNameIt << " ---- " << *fServiceTypeIt << endl;
    03993
    03994       FrameIt childFrame = d->m_frames.append( newChild );
    03995
    03996       processObjectRequest( &(*childFrame), *fURLIt, *fServiceTypeIt );
    03997
    03998       (*childFrame).m_bPreloaded = true;
    03999
    04000       if ( (*childFrame).m_part )
    04001       {
    04002         if ( (*childFrame).m_extension )
    04003         if ( (*childFrame).m_extension && !(*fBufferIt).isEmpty() )
    04004         {
    04005           QDataStream frameStream( *fBufferIt, IO_ReadOnly );
    04006           (*childFrame).m_extension->restoreState( frameStream );
    04007         }
    04008         else
    04009           (*childFrame).m_part->openURL( *fURLIt );
    04010       }
    04011     }
    04012
    04013     KParts::URLArgs args( d->m_extension->urlArgs() );
    04014     args.xOffset = xOffset;
    04015     args.yOffset = yOffset;
    04016     args.docState = docState;
    04017     d->m_extension->setURLArgs( args );
    04018     if (!KHTMLPageCache::self()->isValid(d->m_cacheId))
    04019     {
    04020        d->m_restored = true;
    04021        openURL( u );
    04022        d->m_restored = false;
    04023     }
    04024     else
    04025     {
    04026        restoreURL( u );
    04027     }
    04028   }
    04029
    04030 }
    04031
    04032 void KHTMLPart::show()
    04033 {
    04034   if ( d->m_view )
    04035     d->m_view->show();
    04036 }
    04037
    04038 void KHTMLPart::hide()
    04039 {
    04040   if ( d->m_view )
    04041     d->m_view->hide();
    04042 }
    04043
    04044 DOM::Node KHTMLPart::nodeUnderMouse() const
    04045 {
    04046     return d->m_view->nodeUnderMouse();
    04047 }
    04048
    04049 void KHTMLPart::emitSelectionChanged()
    04050 {
    04051   emit d->m_extension->enableAction( "copy", hasSelection() );
    04052   emit d->m_extension->selectionInfo( selectedText() );
    04053   emit selectionChanged();
    04054 }
    04055
    04056 int KHTMLPart::zoomFactor() const
    04057 {
    04058   return d->m_zoomFactor;
    04059 }
    04060
    04061 // ### make the list configurable ?
    04062 static const int zoomSizes[] = { 20, 40, 60, 80, 90, 95, 100, 105, 110, 120, 140, 160, 180, 200, 250, 300 };
    04063 static const int zoomSizeCount = (sizeof(zoomSizes) / sizeof(int));
    04064 static const int minZoom = 20;
    04065 static const int maxZoom = 300;
    04066
    04067 void KHTMLPart::slotIncZoom()
    04068 {
    04069   int zoomFactor = d->m_zoomFactor;
    04070
    04071   if (zoomFactor < maxZoom) {
    04072     // find the entry nearest to the given zoomsizes
    04073     for (int i = 0; i < zoomSizeCount; ++i)
    04074       if (zoomSizes[i] > zoomFactor) {
    04075         zoomFactor = zoomSizes[i];
    04076         break;
    04077       }
    04078     setZoomFactor(zoomFactor);
    04079   }
    04080 }
    04081
    04082 void KHTMLPart::slotDecZoom()
    04083 {
    04084     int zoomFactor = d->m_zoomFactor;
    04085     if (zoomFactor > minZoom) {
    04086       // find the entry nearest to the given zoomsizes
    04087       for (int i = zoomSizeCount-1; i >= 0; --i)
    04088         if (zoomSizes[i] < zoomFactor) {
    04089           zoomFactor = zoomSizes[i];
    04090           break;
    04091         }
    04092       setZoomFactor(zoomFactor);
    04093     }
    04094 }
    04095
    04096 void KHTMLPart::setZoomFactor (int percent)
    04097 {
    04098   if (percent < minZoom) percent = minZoom;
    04099   if (percent > maxZoom) percent = maxZoom;
    04100   if (d->m_zoomFactor == percent) return;
    04101   d->m_zoomFactor = percent;
    04102
    04103   if(d->m_doc) {
    04104       QApplication::setOverrideCursor( waitCursor );
    04105     if (d->m_doc->styleSelector())
    04106       d->m_doc->styleSelector()->computeFontSizes(d->m_doc->paintDeviceMetrics(), d->m_zoomFactor);
    04107     d->m_doc->recalcStyle( NodeImpl::Force );
    04108     QApplication::restoreOverrideCursor();
    04109   }
    04110
    04111   ConstFrameIt it = d->m_frames.begin();
    04112   ConstFrameIt end = d->m_frames.end();
    04113   for (; it != end; ++it )
    04114     if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
    04115       KParts::ReadOnlyPart* p = ( *it ).m_part;
    04116       static_cast<KHTMLPart*>( p )->setZoomFactor(d->m_zoomFactor);
    04117     }
    04118
    04119   d->m_paDecZoomFactor->setEnabled( d->m_zoomFactor > minZoom );
    04120   d->m_paIncZoomFactor->setEnabled( d->m_zoomFactor < maxZoom );
    04121 }
    04122
    04123 void KHTMLPart::slotZoomView( int delta )
    04124 {
    04125   if ( delta < 0 )
    04126     slotIncZoom();
    04127   else
    04128     slotDecZoom();
    04129 }
    04130
    04131 void KHTMLPart::setStatusBarText( const QString& text, StatusBarPriority p)
    04132 {
    04133   d->m_statusBarText[p] = text;
    04134
    04135   // shift handling ?
    04136   QString tobe = d->m_statusBarText[BarHoverText];
    04137   if (tobe.isEmpty())
    04138     tobe = d->m_statusBarText[BarOverrideText];
    04139   if (tobe.isEmpty()) {
    04140     tobe = d->m_statusBarText[BarDefaultText];
    04141     if (!tobe.isEmpty() && d->m_jobspeed)
    04142       tobe += " ";
    04143     if (d->m_jobspeed)
    04144       tobe += i18n( "(%1/s)" ).arg( KIO::convertSize( d->m_jobspeed ) );
    04145   }
    04146   tobe = "<qt>"+tobe;
    04147
    04148   emit ReadOnlyPart::setStatusBarText(tobe);
    04149 }
    04150
    04151
    04152 void KHTMLPart::setJSStatusBarText( const QString &text )
    04153 {
    04154   setStatusBarText(text, BarOverrideText);
    04155 }
    04156
    04157 void KHTMLPart::setJSDefaultStatusBarText( const QString &text )
    04158 {
    04159   setStatusBarText(text, BarDefaultText);
    04160 }
    04161
    04162 QString KHTMLPart::jsStatusBarText() const
    04163 {
    04164     return d->m_statusBarText[BarOverrideText];
    04165 }
    04166
    04167 QString KHTMLPart::jsDefaultStatusBarText() const
    04168 {
    04169    return d->m_statusBarText[BarDefaultText];
    04170 }
    04171
    04172 QString KHTMLPart::referrer() const
    04173 {
    04174    return d->m_referrer;
    04175 }
    04176
    04177 QString KHTMLPart::pageReferrer() const
    04178 {
    04179    KURL referrerURL = d->m_pageReferrer;
    04180    if (referrerURL.isValid())
    04181    {
    04182       QString protocol = referrerURL.protocol();
    04183
    04184       if ((protocol == "http") ||
    04185          ((protocol == "https") && (m_url.protocol() == "https")))
    04186       {
    04187           referrerURL.setRef(QString::null);
    04188           referrerURL.setUser(QString::null);
    04189           referrerURL.setPass(QString::null);
    04190           return referrerURL.url();
    04191       }
    04192    }
    04193
    04194    return QString::null;
    04195 }
    04196
    04197 QString KHTMLPart::lastModified() const
    04198 {
    04199   if ( d->m_lastModified.isEmpty() && m_url.isLocalFile() ) {
    04200     // Local file: set last-modified from the file's mtime.
    04201     // Done on demand to save time when this isn't needed - but can lead
    04202     // to slightly wrong results if updating the file on disk w/o reloading.
    04203     QDateTime lastModif = QFileInfo( m_url.path() ).lastModified();
    04204     d->m_lastModified = lastModif.toString( Qt::LocalDate );
    04205   }
    04206   //kdDebug(6050) << "KHTMLPart::lastModified: " << d->m_lastModified << endl;
    04207   return d->m_lastModified;
    04208 }
    04209
    04210 void KHTMLPart::slotLoadImages()
    04211 {
    04212   if (d->m_doc )
    04213     d->m_doc->docLoader()->setAutoloadImages( !d->m_doc->docLoader()->autoloadImages() );
    04214
    04215   ConstFrameIt it = d->m_frames.begin();
    04216   ConstFrameIt end = d->m_frames.end();
    04217   for (; it != end; ++it )
    04218     if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
    04219       KParts::ReadOnlyPart* p = ( *it ).m_part;
    04220       static_cast<KHTMLPart*>( p )->slotLoadImages();
    04221     }
    04222 }
    04223
    04224 void KHTMLPart::reparseConfiguration()
    04225 {
    04226   KHTMLSettings *settings = KHTMLFactory::defaultHTMLSettings();
    04227   settings->init();
    04228
    04229   setAutoloadImages( settings->autoLoadImages() );
    04230   if (d->m_doc)
    04231      d->m_doc->docLoader()->setShowAnimations( settings->showAnimations() );
    04232
    04233   d->m_bBackRightClick = settings->isBackRightClickEnabled();
    04234   d->m_bJScriptEnabled = settings->isJavaScriptEnabled(m_url.host());
    04235   d->m_bJScriptDebugEnabled = settings->isJavaScriptDebugEnabled();
    04236   d->m_bJavaEnabled = settings->isJavaEnabled(m_url.host());
    04237   d->m_bPluginsEnabled = settings->isPluginsEnabled(m_url.host());
    04238   d->m_metaRefreshEnabled = settings->isAutoDelayedActionsEnabled ();
    04239
    04240   delete d->m_settings;
    04241   d->m_settings = new KHTMLSettings(*KHTMLFactory::defaultHTMLSettings());
    04242
    04243   QApplication::setOverrideCursor( waitCursor );
    04244   if(d->m_doc) d->m_doc->updateStyleSelector();
    04245   QApplication::restoreOverrideCursor();
    04246 }
    04247
    04248 QStringList KHTMLPart::frameNames() const
    04249 {
    04250   QStringList res;
    04251
    04252   ConstFrameIt it = d->m_frames.begin();
    04253   ConstFrameIt end = d->m_frames.end();
    04254   for (; it != end; ++it )
    04255     if (!(*it).m_bPreloaded)
    04256       res += (*it).m_name;
    04257
    04258   return res;
    04259 }
    04260
    04261 QPtrList<KParts::ReadOnlyPart> KHTMLPart::frames() const
    04262 {
    04263   QPtrList<KParts::ReadOnlyPart> res;
    04264
    04265   ConstFrameIt it = d->m_frames.begin();
    04266   ConstFrameIt end = d->m_frames.end();
    04267   for (; it != end; ++it )
    04268     if (!(*it).m_bPreloaded)
    04269       res.append( (*it).m_part );
    04270
    04271   return res;
    04272 }
    04273
    04274 bool KHTMLPart::openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs )
    04275 {
    04276   FrameIt it = d->m_frames.find( urlArgs.frameName );
    04277
    04278   if ( it == d->m_frames.end() )
    04279     return false;
    04280
    04281   // Inform someone that we are about to show something else.
    04282   if ( !urlArgs.lockHistory() )
    04283       emit d->m_extension->openURLNotify();
    04284
    04285   requestObject( &(*it), url, urlArgs );
    04286
    04287   return true;
    04288 }
    04289
    04290 void KHTMLPart::setDNDEnabled( bool b )
    04291 {
    04292   d->m_bDnd = b;
    04293 }
    04294
    04295 bool KHTMLPart::dndEnabled() const
    04296 {
    04297   return d->m_bDnd;
    04298 }
    04299
    04300 void KHTMLPart::customEvent( QCustomEvent *event )
    04301 {
    04302   if ( khtml::MousePressEvent::test( event ) )
    04303   {
    04304     khtmlMousePressEvent( static_cast<khtml::MousePressEvent *>( event ) );
    04305     return;
    04306   }
    04307
    04308   if ( khtml::MouseDoubleClickEvent::test( event ) )
    04309   {
    04310     khtmlMouseDoubleClickEvent( static_cast<khtml::MouseDoubleClickEvent *>( event ) );
    04311     return;
    04312   }
    04313
    04314   if ( khtml::MouseMoveEvent::test( event ) )
    04315   {
    04316     khtmlMouseMoveEvent( static_cast<khtml::MouseMoveEvent *>( event ) );
    04317     return;
    04318   }
    04319
    04320   if ( khtml::MouseReleaseEvent::test( event ) )
    04321   {
    04322     khtmlMouseReleaseEvent( static_cast<khtml::MouseReleaseEvent *>( event ) );
    04323     return;
    04324   }
    04325
    04326   if ( khtml::DrawContentsEvent::test( event ) )
    04327   {
    04328     khtmlDrawContentsEvent( static_cast<khtml::DrawContentsEvent *>( event ) );
    04329     return;
    04330   }
    04331
    04332   KParts::ReadOnlyPart::customEvent( event );
    04333 }
    04334
    04335 void KHTMLPart::khtmlMousePressEvent( khtml::MousePressEvent *event )
    04336 {
    04337   DOM::DOMString url = event->url();
    04338   QMouseEvent *_mouse = event->qmouseEvent();
    04339   DOM::Node innerNode = event->innerNode();
    04340   d->m_mousePressNode = innerNode;
    04341
    04342    d->m_dragStartPos = _mouse->pos();
    04343
    04344    if ( !event->url().isNull() ) {
    04345      d->m_strSelectedURL = event->url().string();
    04346      d->m_strSelectedURLTarget = event->target().string();
    04347    }
    04348    else
    04349      d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
    04350
    04351   if ( _mouse->button() == LeftButton ||
    04352        _mouse->button() == MidButton )
    04353   {
    04354     d->m_bMousePressed = true;
    04355
    04356 #ifndef KHTML_NO_SELECTION
    04357     if ( _mouse->button() == LeftButton )
    04358     {
    04359       if ( !innerNode.isNull()  && innerNode.handle()->renderer()) {
    04360           int offset = 0;
    04361           DOM::NodeImpl* node = 0;
    04362           innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
    04363                                                                event->absX()-innerNode.handle()->renderer()->xPos(),
    04364                                                                event->absY()-innerNode.handle()->renderer()->yPos(), node, offset);
    04365
    04366           d->m_selectionStart = node;
    04367           d->m_startOffset = offset;
    04368           //if ( node )
    04369           //  kdDebug(6005) << "KHTMLPart::khtmlMousePressEvent selectionStart=" << d->m_selectionStart.handle()->renderer()
    04370           //                << " offset=" << d->m_startOffset << endl;
    04371           //else
    04372           //  kdDebug(6005) << "KHTML::khtmlMousePressEvent selectionStart=(nil)" << endl;
    04373           d->m_selectionEnd = d->m_selectionStart;
    04374           d->m_endOffset = d->m_startOffset;
    04375           d->m_doc->clearSelection();
    04376       }
    04377       else
    04378       {
    04379         d->m_selectionStart = DOM::Node();
    04380         d->m_selectionEnd = DOM::Node();
    04381       }
    04382       emitSelectionChanged();
    04383       startAutoScroll();
    04384     }
    04385 #else
    04386     d->m_dragLastPos = _mouse->globalPos();
    04387 #endif
    04388   }
    04389
    04390   if ( _mouse->button() == RightButton && parentPart() != 0 && d->m_bBackRightClick )
    04391   {
    04392     d->m_bRightMousePressed = true;
    04393   } else if ( _mouse->button() == RightButton )
    04394   {
    04395     popupMenu( d->m_strSelectedURL );
    04396     d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
    04397   }
    04398 }
    04399
    04400 void KHTMLPart::khtmlMouseDoubleClickEvent( khtml::MouseDoubleClickEvent *event )
    04401 {
    04402   QMouseEvent *_mouse = event->qmouseEvent();
    04403   if ( _mouse->button() == LeftButton )
    04404   {
    04405     d->m_bMousePressed = true;
    04406     DOM::Node innerNode = event->innerNode();
    04407     // Find selectionStart again, khtmlMouseReleaseEvent lost it
    04408     if ( !innerNode.isNull() && innerNode.handle()->renderer()) {
    04409       int offset = 0;
    04410       DOM::NodeImpl* node = 0;
    04411       innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
    04412                                                            event->absX()-innerNode.handle()->renderer()->xPos(),
    04413                                                            event->absY()-innerNode.handle()->renderer()->yPos(), node, offset);
    04414
    04415       //kdDebug() << k_funcinfo << "checkSelectionPoint returned node=" << node << " offset=" << offset << endl;
    04416
    04417       if ( node && node->renderer() )
    04418       {
    04419         // Extend selection to a complete word (double-click) or paragraph (triple-click)
    04420         bool selectParagraph = (event->clickCount() == 3);
    04421
    04422         // Extend to the left
    04423         extendSelection( node, offset, d->m_selectionStart, d->m_startOffset, false, selectParagraph );
    04424         // Extend to the right
    04425         extendSelection( node, offset, d->m_selectionEnd, d->m_endOffset, true, selectParagraph );
    04426
    04427         d->m_endOffset++; // the last char must be in
    04428         //kdDebug() << d->m_selectionStart.handle() << " " << d->m_startOffset << "  -  " <<
    04429         //  d->m_selectionEnd.handle() << " " << d->m_endOffset << endl;
    04430
    04431         d->m_startBeforeEnd = true;
    04432         emitSelectionChanged();
    04433         d->m_doc
    04434           ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
    04435                          d->m_selectionEnd.handle(),d->m_endOffset);
    04436       }
    04437     }
    04438   }
    04439 }
    04440
    04441 void KHTMLPart::extendSelection( DOM::NodeImpl* node, long offset, DOM::Node& selectionNode, long& selectionOffset, bool right, bool selectParagraph )
    04442 {
    04443   khtml::RenderObject* obj = node->renderer();
    04444   QString str;
    04445   int len = 0;
    04446   if ( obj->isText() ) { // can be false e.g. when double-clicking on a disabled submit button
    04447     str = static_cast<khtml::RenderText *>(obj)->data().string();
    04448     len = str.length();
    04449   }
    04450   //kdDebug() << "extendSelection right=" << right << " offset=" << offset << " len=" << len << " Starting at obj=" << obj << endl;
    04451   QChar ch;
    04452   do {
    04453     // Last char was ok, point to it
    04454     if ( node ) {
    04455       selectionNode = node;
    04456       selectionOffset = offset;
    04457     }
    04458
    04459     // Get another char
    04460     while ( obj && ( (right && offset >= len-1) || (!right && offset <= 0) ) )
    04461     {
    04462       obj = right ? obj->objectBelow() : obj->objectAbove();
    04463       //kdDebug() << "obj=" << obj << endl;
    04464       if ( obj ) {
    04465         //kdDebug() << "isText=" << obj->isText() << endl;
    04466         str = QString::null;
    04467         if ( obj->isText() )
    04468           str = static_cast<khtml::RenderText *>(obj)->data().string();
    04469         else if ( obj->isBR() )
    04470           str = '\n';
    04471         else if ( !obj->isInline() ) {
    04472           obj = 0L; // parag limit -> done
    04473           break;
    04474         }
    04475         len = str.length();
    04476         //kdDebug() << "str=" << str << " length=" << len << endl;
    04477         // set offset - note that the first thing will be a ++ or -- on it.
    04478         if ( right )
    04479           offset = -1;
    04480         else
    04481           offset = len;
    04482       }
    04483     }
    04484     if ( !obj ) // end of parag or document
    04485       break;
    04486     node = obj->element();
    04487     if ( right )
    04488     {
    04489       Q_ASSERT( offset < len-1 );
    04490       offset++;
    04491     }
    04492     else
    04493     {
    04494       Q_ASSERT( offset > 0 );
    04495       offset--;
    04496     }
    04497
    04498     // Test that char
    04499     ch = str[ offset ];
    04500     //kdDebug() << " offset=" << offset << " ch=" << QString(ch) << endl;
    04501   } while ( selectParagraph || (!ch.isSpace() && !ch.isPunct()) );
    04502 }
    04503
    04504 void KHTMLPart::khtmlMouseMoveEvent( khtml::MouseMoveEvent *event )
    04505 {
    04506   QMouseEvent *_mouse = event->qmouseEvent();
    04507
    04508   if( d->m_bRightMousePressed && parentPart() != 0 && d->m_bBackRightClick )
    04509   {
    04510     popupMenu( d->m_strSelectedURL );
    04511     d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
    04512     d->m_bRightMousePressed = false;
    04513   }
    04514 #ifndef QT_NO_DRAGANDDROP
    04515   if( d->m_bDnd && d->m_bMousePressed &&
    04516       (!d->m_strSelectedURL.isEmpty() || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) ) &&
    04517       ( d->m_dragStartPos - _mouse->pos() ).manhattanLength() > KGlobalSettings::dndEventDelay()) {
    04518
    04519       QPixmap p;
    04520       QDragObject *drag = 0;
    04521       if( !d->m_strSelectedURL.isEmpty() ) {
    04522           KURL u( completeURL( d->m_strSelectedURL) );
    04523           KURLDrag* urlDrag = KURLDrag::newDrag( u, d->m_view->viewport() );
    04524           if ( !d->m_referrer.isEmpty() )
    04525             urlDrag->metaData()["referrer"] = d->m_referrer;
    04526           drag = urlDrag;
    04527           p = KMimeType::pixmapForURL(u, 0, KIcon::Desktop, KIcon::SizeMedium);
    04528       } else {
    04529           HTMLImageElementImpl *i = static_cast<HTMLImageElementImpl *>(d->m_mousePressNode.handle());
    04530           if( i ) {
    04531             KMultipleDrag *mdrag = new KMultipleDrag( d->m_view->viewport() );
    04532             mdrag->addDragObject( new QImageDrag( i->currentImage(), 0L ) );
    04533             KURL u( completeURL( khtml::parseURL(i->getAttribute(ATTR_SRC)).string() ) );
    04534             KURLDrag* urlDrag = KURLDrag::newDrag( u, 0L );
    04535             if ( !d->m_referrer.isEmpty() )
    04536               urlDrag->metaData()["referrer"] = d->m_referrer;
    04537             mdrag->addDragObject( urlDrag );
    04538             drag = mdrag;
    04539             p = KMimeType::mimeType("image/png")->pixmap(KIcon::Desktop);
    04540           }
    04541       }
    04542
    04543     if ( !p.isNull() )
    04544       drag->setPixmap(p);
    04545
    04546     stopAutoScroll();
    04547     if(drag)
    04548         drag->drag();
    04549
    04550     // when we finish our drag, we need to undo our mouse press
    04551     d->m_bMousePressed = false;
    04552     d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
    04553     return;
    04554   }
    04555 #endif
    04556
    04557   DOM::DOMString url = event->url();
    04558   DOM::DOMString target = event->target();
    04559   DOM::Node innerNode = event->innerNode();
    04560
    04561   // Not clicked -> mouse over stuff
    04562   if ( !d->m_bMousePressed )
    04563   {
    04564     // The mouse is over something
    04565     if ( url.length() )
    04566     {
    04567       bool shiftPressed = ( _mouse->state() & ShiftButton );
    04568
    04569       // Image map
    04570       if ( !innerNode.isNull() && innerNode.elementId() == ID_IMG )
    04571       {
    04572         HTMLImageElementImpl *i = static_cast<HTMLImageElementImpl *>(innerNode.handle());
    04573         if ( i && i->isServerMap() )
    04574         {
    04575           khtml::RenderObject *r = i->renderer();
    04576           if(r)
    04577           {
    04578             int absx, absy, vx, vy;
    04579             r->absolutePosition(absx, absy);
    04580             view()->contentsToViewport( absx, absy, vx, vy );
    04581
    04582             int x(_mouse->x() - vx), y(_mouse->y() - vy);
    04583
    04584             d->m_overURL = url.string() + QString("?%1,%2").arg(x).arg(y);
    04585             d->m_overURLTarget = target.string();
    04586             overURL( d->m_overURL, target.string(), shiftPressed );
    04587             return;
    04588           }
    04589         }
    04590       }
    04591
    04592       // normal link
    04593       if ( d->m_overURL.isEmpty() || d->m_overURL != url || d->m_overURLTarget != target )
    04594       {
    04595         d->m_overURL = url.string();
    04596         d->m_overURLTarget = target.string();
    04597         overURL( d->m_overURL, target.string(), shiftPressed );
    04598       }
    04599     }
    04600     else  // Not over a link...
    04601     {
    04602       if( !d->m_overURL.isEmpty() ) // and we were over a link  -> reset to "default statusbar text"
    04603       {
    04604         d->m_overURL = d->m_overURLTarget = QString::null;
    04605         emit onURL( QString::null );
    04606         // revert to default statusbar text
    04607         setStatusBarText(QString::null, BarHoverText);
    04608         emit d->m_extension->mouseOverInfo(0);
    04609      }
    04610     }
    04611   }
    04612   else {
    04613 #ifndef KHTML_NO_SELECTION
    04614     // selection stuff
    04615     if( d->m_bMousePressed && innerNode.handle() && innerNode.handle()->renderer() &&
    04616         ( _mouse->state() == LeftButton )) {
    04617       int offset;
    04618       //kdDebug(6000) << "KHTMLPart::khtmlMouseMoveEvent x=" << event->x() << " y=" << event->y() << endl;
    04619       DOM::NodeImpl* node=0;
    04620       innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
    04621                                                            event->absX()-innerNode.handle()->renderer()->xPos(),
    04622                                                            event->absY()-innerNode.handle()->renderer()->yPos(), node, offset);
    04623       d->m_selectionEnd = node;
    04624       d->m_endOffset = offset;
    04625       //kdDebug( 6000 ) << "setting end of selection to " << d->m_selectionEnd.handle() << "/" << d->m_endOffset << endl;
    04626
    04627       // we have to get to know if end is before start or not...
    04628       DOM::Node n = d->m_selectionStart;
    04629       d->m_startBeforeEnd = false;
    04630       while(!n.isNull()) {
    04631         if(n == d->m_selectionEnd) {
    04632           d->m_startBeforeEnd = true;
    04633           break;
    04634         }
    04635         DOM::Node next = n.firstChild();
    04636         if(next.isNull()) next = n.nextSibling();
    04637         while( next.isNull() && !n.parentNode().isNull() ) {
    04638           n = n.parentNode();
    04639           next = n.nextSibling();
    04640         }
    04641         n = next;
    04642         //d->m_view->viewport()->repaint(false);
    04643       }
    04644
    04645       if ( !d->m_selectionStart.isNull() && !d->m_selectionEnd.isNull() )
    04646       {
    04647         if (d->m_selectionEnd == d->m_selectionStart && d->m_endOffset < d->m_startOffset)
    04648           d->m_doc
    04649             ->setSelection(d->m_selectionStart.handle(),d->m_endOffset,
    04650                            d->m_selectionEnd.handle(),d->m_startOffset);
    04651         else if (d->m_startBeforeEnd)
    04652           d->m_doc
    04653             ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
    04654                            d->m_selectionEnd.handle(),d->m_endOffset);
    04655         else
    04656           d->m_doc
    04657             ->setSelection(d->m_selectionEnd.handle(),d->m_endOffset,
    04658                            d->m_selectionStart.handle(),d->m_startOffset);
    04659       }
    04660 #else
    04661       if ( d->m_doc && d->m_view ) {
    04662         QPoint diff( _mouse->globalPos() - d->m_dragLastPos );
    04663
    04664         if ( abs( diff.x() ) > 64 || abs( diff.y() ) > 64 ) {
    04665           d->m_view->scrollBy( -diff.x(), -diff.y() );
    04666           d->m_dragLastPos = _mouse->globalPos();
    04667         }
    04668 #endif
    04669     }
    04670   }
    04671
    04672 }
    04673
    04674 void KHTMLPart::khtmlMouseReleaseEvent( khtml::MouseReleaseEvent *event )
    04675 {
    04676   DOM::Node innerNode = event->innerNode();
    04677   d->m_mousePressNode = DOM::Node();
    04678
    04679   if ( d->m_bMousePressed ) {
    04680     setStatusBarText(QString::null, BarHoverText);
    04681     stopAutoScroll();
    04682   }
    04683
    04684   // Used to prevent mouseMoveEvent from initiating a drag before
    04685   // the mouse is pressed again.
    04686   d->m_bMousePressed = false;
    04687
    04688   QMouseEvent *_mouse = event->qmouseEvent();
    04689   if ( _mouse->button() == RightButton && parentPart() != 0 && d->m_bBackRightClick )
    04690   {
    04691     d->m_bRightMousePressed = false;
    04692     KParts::BrowserInterface *tmp_iface = d->m_extension->browserInterface();
    04693     if( tmp_iface ) {
    04694       tmp_iface->callMethod( "goHistory(int)", -1 );
    04695     }
    04696   }
    04697 #ifndef QT_NO_CLIPBOARD
    04698   if ((d->m_guiProfile == BrowserViewGUI) && (_mouse->button() == MidButton) && (event->url().isNull()))
    04699   {
    04700     QClipboard *cb = QApplication::clipboard();
    04701     cb->setSelectionMode( true );
    04702     QCString plain("plain");
    04703     QString url = cb->text(plain).stripWhiteSpace();
    04704
    04705     // Check if it's a URL
    04706     KURIFilterData m_filterData;
    04707     m_filterData.setData( url );
    04708     if (KURIFilter::self()->filterURI(m_filterData))
    04709     {
    04710       int uriType = m_filterData.uriType();
    04711       if ( uriType == KURIFilterData::LOCAL_FILE
    04712            || uriType == KURIFilterData::LOCAL_DIR
    04713            || uriType == KURIFilterData::NET_PROTOCOL )
    04714         emit d->m_extension->openURLRequest( m_filterData.uri().url() );
    04715     }
    04716   }
    04717 #endif
    04718
    04719 #ifndef KHTML_NO_SELECTION
    04720   // delete selection in case start and end position are at the same point
    04721   if(d->m_selectionStart == d->m_selectionEnd && d->m_startOffset == d->m_endOffset) {
    04722     d->m_selectionStart = 0;
    04723     d->m_selectionEnd = 0;
    04724     d->m_startOffset = 0;
    04725     d->m_endOffset = 0;
    04726     emitSelectionChanged();
    04727   } else {
    04728     // we have to get to know if end is before start or not...
    04729     DOM::Node n = d->m_selectionStart;
    04730     d->m_startBeforeEnd = false;
    04731     if( d->m_selectionStart == d->m_selectionEnd ) {
    04732       if( d->m_startOffset < d->m_endOffset )
    04733         d->m_startBeforeEnd = true;
    04734     } else {
    04735       while(!n.isNull()) {
    04736         if(n == d->m_selectionEnd) {
    04737           d->m_startBeforeEnd = true;
    04738           break;
    04739         }
    04740         DOM::Node next = n.firstChild();
    04741         if(next.isNull()) next = n.nextSibling();
    04742         while( next.isNull() && !n.parentNode().isNull() ) {
    04743           n = n.parentNode();
    04744           next = n.nextSibling();
    04745         }
    04746         n = next;
    04747       }
    04748     }
    04749     if(!d->m_startBeforeEnd)
    04750     {
    04751       DOM::Node tmpNode = d->m_selectionStart;
    04752       int tmpOffset = d->m_startOffset;
    04753       d->m_selectionStart = d->m_selectionEnd;
    04754       d->m_startOffset = d->m_endOffset;
    04755       d->m_selectionEnd = tmpNode;
    04756       d->m_endOffset = tmpOffset;
    04757       d->m_startBeforeEnd = true;
    04758     }
    04759     // get selected text and paste to the clipboard
    04760 #ifndef QT_NO_CLIPBOARD
    04761     QString text = selectedText();
    04762     text.replace(QRegExp(QChar(0xa0)), " ");
    04763     QClipboard *cb = QApplication::clipboard();
    04764     cb->setSelectionMode( true );
    04765     disconnect( kapp->clipboard(), SIGNAL( selectionChanged()), this, SLOT( slotClearSelection()));
    04766     cb->setText(text);
    04767     connect( kapp->clipboard(), SIGNAL( selectionChanged()), SLOT( slotClearSelection()));
    04768     cb->setSelectionMode( false );
    04769 #endif
    04770     //kdDebug( 6000 ) << "selectedText = " << text << endl;
    04771     emitSelectionChanged();
    04772   }
    04773 #endif
    04774
    04775 }
    04776
    04777 void KHTMLPart::khtmlDrawContentsEvent( khtml::DrawContentsEvent * )
    04778 {
    04779 }
    04780
    04781 void KHTMLPart::guiActivateEvent( KParts::GUIActivateEvent *event )
    04782 {
    04783   if ( event->activated() )
    04784   {
    04785     emitSelectionChanged();
    04786     emit d->m_extension->enableAction( "print", d->m_doc != 0 );
    04787
    04788     if ( !d->m_settings->autoLoadImages() && d->m_paLoadImages )
    04789     {
    04790         QPtrList<KAction> lst;
    04791         lst.append( d->m_paLoadImages );
    04792         plugActionList( "loadImages", lst );
    04793     }
    04794   }
    04795 }
    04796
    04797 void KHTMLPart::slotPrintFrame()
    04798 {
    04799   if ( d->m_frames.count() == 0 )
    04800     return;
    04801
    04802   KParts::ReadOnlyPart *frame = currentFrame();
    04803   if (!frame)
    04804     return;
    04805
    04806   KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject( frame );
    04807
    04808   if ( !ext )
    04809     return;
    04810
    04811   QMetaObject *mo = ext->metaObject();
    04812
    04813   int idx = mo->findSlot( "print()", TRUE );
    04814   if ( idx >= 0 ) {
    04815     QUObject o[ 1 ];
    04816     ext->qt_invoke( idx, o );
    04817   }
    04818 }
    04819
    04820 void KHTMLPart::slotSelectAll()
    04821 {
    04822   KParts::ReadOnlyPart *part = currentFrame();
    04823   if (part && part->inherits("KHTMLPart"))
    04824     static_cast<KHTMLPart *>(part)->selectAll();
    04825 }
    04826
    04827 void KHTMLPart::startAutoScroll()
    04828 {
    04829    connect(&d->m_scrollTimer, SIGNAL( timeout() ), this, SLOT( slotAutoScroll() ));
    04830    d->m_scrollTimer.start(100, false);
    04831 }
    04832
    04833 void KHTMLPart::stopAutoScroll()
    04834 {
    04835    disconnect(&d->m_scrollTimer, SIGNAL( timeout() ), this, SLOT( slotAutoScroll() ));
    04836    if (d->m_scrollTimer.isActive())
    04837        d->m_scrollTimer.stop();
    04838 }
    04839
    04840
    04841 void KHTMLPart::slotAutoScroll()
    04842 {
    04843     if (d->m_view)
    04844       d->m_view->doAutoScroll();
    04845     else
    04846       stopAutoScroll(); // Safety
    04847 }
    04848
    04849 void KHTMLPart::selectAll()
    04850 {
    04851   if (!d->m_doc) return;
    04852
    04853   NodeImpl *first;
    04854   if (d->m_doc->isHTMLDocument())
    04855     first = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
    04856   else
    04857     first = d->m_doc;
    04858   NodeImpl *next;
    04859
    04860   // Look for first text/cdata node that has a renderer
    04861   while ( first && !((first->nodeType() == Node::TEXT_NODE || first->nodeType() == Node::CDATA_SECTION_NODE) && first->renderer()) )
    04862   {
    04863     next = first->firstChild();
    04864     if ( !next ) next = first->nextSibling();
    04865     while( first && !next )
    04866     {
    04867       first = first->parentNode();
    04868       if ( first )
    04869         next = first->nextSibling();
    04870     }
    04871     first = next;
    04872   }
    04873
    04874   NodeImpl *last;
    04875   if (d->m_doc->isHTMLDocument())
    04876     last = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
    04877   else
    04878     last = d->m_doc;
    04879   // Look for last text/cdata node that has a renderer
    04880   while ( last && !((last->nodeType() == Node::TEXT_NODE || last->nodeType() == Node::CDATA_SECTION_NODE) && last->renderer()) )
    04881   {
    04882     next = last->lastChild();
    04883     if ( !next ) next = last->previousSibling();
    04884     while ( last && !next )
    04885     {
    04886       last = last->parentNode();
    04887       if ( last )
    04888         next = last->previousSibling();
    04889     }
    04890     last = next;
    04891   }
    04892
    04893   if ( !first || !last )
    04894     return;
    04895   Q_ASSERT(first->renderer());
    04896   Q_ASSERT(last->renderer());
    04897   d->m_selectionStart = first;
    04898   d->m_startOffset = 0;
    04899   d->m_selectionEnd = last;
    04900   d->m_endOffset = last->nodeValue().length();
    04901   d->m_startBeforeEnd = true;
    04902
    04903   d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
    04904                           d->m_selectionEnd.handle(), d->m_endOffset );
    04905
    04906   emitSelectionChanged();
    04907 }
    04908
    04909 bool KHTMLPart::checkLinkSecurity(const KURL &linkURL,const QString &message, const QString &button)
    04910 {
    04911   // Security check on the link.
    04912   // KURL u( url ); Wrong!! Relative URL could be mis-interpreted!!! (DA)
    04913   QString linkProto = linkURL.protocol().lower();
    04914   QString proto = m_url.protocol().lower();
    04915
    04916   if ( !linkProto.isEmpty() && !proto.isEmpty() &&
    04917        ( linkProto == "cgi" || linkProto == "file" ) &&
    04918        proto != "file" && proto != "cgi" && proto != "man" && proto != "about")
    04919   {
    04920     Tokenizer *tokenizer = d->m_doc->tokenizer();
    04921     if (tokenizer)
    04922       tokenizer->setOnHold(true);
    04923
    04924     int response = KMessageBox::Cancel;
    04925     if (!message.isEmpty())
    04926     {
    04927             response = KMessageBox::warningContinueCancel( 0,
    04928                                                            message.arg(linkURL.url()),
    04929                                                            i18n( "Security Warning" ),
    04930                                                            button);
    04931     }
    04932     else
    04933     {
    04934             KMessageBox::error( 0,
    04935                                 i18n( "<qt>This untrusted page contains a link<BR><B>%1</B><BR>to your local file system.").arg(linkURL.url()),
    04936                                 i18n( "Security Alert" ));
    04937     }
    04938
    04939     if (tokenizer)
    04940        tokenizer->setOnHold(false);
    04941     return (response==KMessageBox::Continue);
    04942   }
    04943   return true;
    04944 }
    04945
    04946 QVariant KHTMLPart::executeScript(QString filename, int baseLine, const DOM::Node &n, const QString &script)
    04947 {
    04948 #ifdef KJS_VERBOSE
    04949   kdDebug(6070) << "executeScript: filename=" << filename << " baseLine=" << baseLine << " script=" << script << endl;
    04950 #endif
    04951   KJSProxy *proxy = jScript();
    04952
    04953   if (!proxy || proxy->paused())
    04954     return QVariant();
    04955   QVariant ret = proxy->evaluate(filename,baseLine,script, n );
    04956   return ret;
    04957 }
    04958
    04959 void KHTMLPart::slotPartRemoved( KParts::Part *part )
    04960 {
    04961 //    kdDebug(6050) << "KHTMLPart::slotPartRemoved " << part << endl;
    04962     if ( part == d->m_activeFrame )
    04963     {
    04964         d->m_activeFrame = 0L;
    04965         if ( !part->inherits( "KHTMLPart" ) )
    04966         {
    04967             if (factory()) {
    04968                 factory()->removeClient( part );
    04969             }
    04970             removeChildClient( part );
    04971         }
    04972     }
    04973 }
    04974
    04975 void KHTMLPart::slotActiveFrameChanged( KParts::Part *part )
    04976 {
    04977 //    kdDebug(6050) << "KHTMLPart::slotActiveFrameChanged part=" << part << endl;
    04978     if ( part == this )
    04979     {
    04980         kdError(6050) << "strange error! we activated ourselves" << endl;
    04981         assert( false );
    04982         return;
    04983     }
    04984 //    kdDebug(6050) << "KHTMLPart::slotActiveFrameChanged d->m_activeFrame=" << d->m_activeFrame << endl;
    04985     if ( d->m_activeFrame && d->m_activeFrame->widget() && d->m_activeFrame->widget()->inherits( "QFrame" ) )
    04986     {
    04987         QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
    04988         if (frame->frameStyle() != QFrame::NoFrame)
    04989         {
    04990            frame->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken);
    04991            frame->repaint();
    04992         }
    04993     }
    04994
    04995     if( d->m_activeFrame && !d->m_activeFrame->inherits( "KHTMLPart" ) )
    04996     {
    04997         if (factory()) {
    04998             factory()->removeClient( d->m_activeFrame );
    04999         }
    05000         removeChildClient( d->m_activeFrame );
    05001     }
    05002     if( part && !part->inherits( "KHTMLPart" ) )
    05003     {
    05004         if (factory()) {
    05005             factory()->addClient( part );
    05006         }
    05007         insertChildClient( part );
    05008     }
    05009
    05010
    05011     d->m_activeFrame = part;
    05012
    05013     if ( d->m_activeFrame && d->m_activeFrame->widget()->inherits( "QFrame" ) )
    05014     {
    05015         QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
    05016         if (frame->frameStyle() != QFrame::NoFrame)
    05017         {
    05018            frame->setFrameStyle( QFrame::StyledPanel | QFrame::Plain);
    05019            frame->repaint();
    05020         }
    05021         kdDebug(6050) << "new active frame " << d->m_activeFrame << endl;
    05022     }
    05023
    05024     updateActions();
    05025
    05026     // (note: childObject returns 0 if the argument is 0)
    05027     d->m_extension->setExtensionProxy( KParts::BrowserExtension::childObject( d->m_activeFrame ) );
    05028 }
    05029
    05030 void KHTMLPart::setActiveNode(const DOM::Node &node)
    05031 {
    05032     if (!d->m_doc || !d->m_view)
    05033         return;
    05034
    05035     // Set the document's active node
    05036     d->m_doc->setFocusNode(node.handle());
    05037
    05038     // Scroll the view if necessary to ensure that the new focus node is visible
    05039     QRect rect  = node.handle()->getRect();
    05040     d->m_view->ensureVisible(rect.right(), rect.bottom());
    05041     d->m_view->ensureVisible(rect.left(), rect.top());
    05042 }
    05043
    05044 DOM::Node KHTMLPart::activeNode() const
    05045 {
    05046     return DOM::Node(d->m_doc?d->m_doc->focusNode():0);
    05047 }
    05048
    05049 DOM::EventListener *KHTMLPart::createHTMLEventListener( QString code )
    05050 {
    05051   KJSProxy *proxy = jScript();
    05052
    05053   if (!proxy)
    05054     return 0;
    05055
    05056   return proxy->createHTMLEventHandler( m_url.url(), code );
    05057 }
    05058
    05059 KHTMLPart *KHTMLPart::opener()
    05060 {
    05061     return d->m_opener;
    05062 }
    05063
    05064 void KHTMLPart::setOpener(KHTMLPart *_opener)
    05065 {
    05066     d->m_opener = _opener;
    05067 }
    05068
    05069 bool KHTMLPart::openedByJS()
    05070 {
    05071     return d->m_openedByJS;
    05072 }
    05073
    05074 void KHTMLPart::setOpenedByJS(bool _openedByJS)
    05075 {
    05076     d->m_openedByJS = _openedByJS;
    05077 }
    05078
    05079 void KHTMLPart::preloadStyleSheet(const QString &url, const QString &stylesheet)
    05080 {
    05081     khtml::Cache::preloadStyleSheet(url, stylesheet);
    05082 }
    05083
    05084 void KHTMLPart::preloadScript(const QString &url, const QString &script)
    05085 {
    05086     khtml::Cache::preloadScript(url, script);
    05087 }
    05088
    05089 QCString KHTMLPart::dcopObjectId() const
    05090 {
    05091   QCString id;
    05092   id.sprintf("html-widget%d", d->m_dcop_counter);
    05093   return id;
    05094 }
    05095
    05096 long KHTMLPart::cacheId() const
    05097 {
    05098   return d->m_cacheId;
    05099 }
    05100
    05101 bool KHTMLPart::restored() const
    05102 {
    05103   return d->m_restored;
    05104 }
    05105
    05106 bool KHTMLPart::pluginPageQuestionAsked(const QString& mimetype) const
    05107 {
    05108   // parentPart() should be const!
    05109   KHTMLPart* parent = const_cast<KHTMLPart *>(this)->parentPart();
    05110   if ( parent )
    05111     return parent->pluginPageQuestionAsked(mimetype);
    05112
    05113   return d->m_pluginPageQuestionAsked.contains(mimetype);
    05114 }
    05115
    05116 void KHTMLPart::setPluginPageQuestionAsked(const QString& mimetype)
    05117 {
    05118   if ( parentPart() )
    05119     parentPart()->setPluginPageQuestionAsked(mimetype);
    05120
    05121   d->m_pluginPageQuestionAsked.append(mimetype);
    05122 }
    05123
    05124 using namespace KParts;
    05125 #include "khtml_part.moc"

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:34:08 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001