JavaScriptCore:
[WebKit-https.git] / WebCore / khtml / khtml_part.cpp
1 // -*- c-basic-offset: 2 -*-
2 /* This file is part of the KDE project
3  *
4  * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
5  *                     1999 Lars Knoll <knoll@kde.org>
6  *                     1999 Antti Koivisto <koivisto@kde.org>
7  *                     2000 Simon Hausmann <hausmann@kde.org>
8  *                     2000 Stefan Schimanski <1Stein@gmx.de>
9  *                     2001 George Staikos <staikos@kde.org>
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public License
22  * along with this library; see the file COPYING.LIB.  If not, write to
23  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24  * Boston, MA 02111-1307, USA.
25  */
26
27 #define SPEED_DEBUG
28 #include "khtml_part.h"
29
30 #ifdef APPLE_CHANGES
31 #define DIRECT_LINKAGE_TO_ECMA
32 #define QT_NO_CLIPBOARD
33 #define QT_NO_DRAGANDDROP
34 #endif
35
36 #include "khtml_pagecache.h"
37
38 #include "dom/dom_string.h"
39 #include "dom/dom_element.h"
40 #include "html/html_documentimpl.h"
41 #include "html/html_baseimpl.h"
42 #include "html/html_miscimpl.h"
43 #include "html/html_imageimpl.h"
44 #include "rendering/render_text.h"
45 #include "rendering/render_frames.h"
46 #include "misc/htmlhashes.h"
47 #include "misc/loader.h"
48 #include "xml/dom2_eventsimpl.h"
49 #include "xml/xml_tokenizer.h"
50 #include "css/cssstyleselector.h"
51 #include "css/csshelper.h"
52 using namespace DOM;
53
54 #include "khtmlview.h"
55 #include <kparts/partmanager.h>
56 #include "ecma/kjs_proxy.h"
57 #include "khtml_settings.h"
58
59 #include <sys/types.h>
60 #include <assert.h>
61 #include <unistd.h>
62
63 #include <kstandarddirs.h>
64 #include <kio/job.h>
65 #include <kio/global.h>
66 #include <kdebug.h>
67 #include <kiconloader.h>
68 #include <klocale.h>
69 #include <kcharsets.h>
70 #include <kmessagebox.h>
71 #include <kstdaction.h>
72 #include <kfiledialog.h>
73 #include <ktrader.h>
74 #include <kdatastream.h>
75 #include <ktempfile.h>
76 #include <kglobalsettings.h>
77 #include <kurldrag.h>
78 #include <kapplication.h>
79 #if !defined(QT_NO_DRAGANDDROP)
80 #include <kmultipledrag.h>
81 #endif
82
83 #include <ksslcertchain.h>
84 #include <ksslinfodlg.h>
85
86
87 #include <qclipboard.h>
88 #include <qfile.h>
89 #include <qmetaobject.h>
90 #include <private/qucomextra_p.h>
91
92 #include "khtmlpart_p.h"
93
94 #ifndef APPLE_CHANGES
95
96 namespace khtml {
97     class PartStyleSheetLoader : public CachedObjectClient
98     {
99     public:
100         PartStyleSheetLoader(KHTMLPart *part, DOM::DOMString url, DocLoader* dl)
101         {
102             m_part = part;
103             m_cachedSheet = Cache::requestStyleSheet(dl, url );
104             if (m_cachedSheet)
105                 m_cachedSheet->ref( this );
106         }
107         virtual ~PartStyleSheetLoader()
108         {
109             if ( m_cachedSheet ) m_cachedSheet->deref(this);
110         }
111         virtual void setStyleSheet(const DOM::DOMString&, const DOM::DOMString &sheet)
112         {
113           if ( m_part )
114             m_part->setUserStyleSheet( sheet.string() );
115
116             delete this;
117         }
118         QGuardedPtr<KHTMLPart> m_part;
119         khtml::CachedCSSStyleSheet *m_cachedSheet;
120     };
121 };
122
123
124 FrameList::Iterator FrameList::find( const QString &name )
125 {
126     Iterator it = begin();
127     Iterator e = end();
128
129     for (; it!=e; ++it )
130         if ( (*it).m_name==name )
131             break;
132
133     return it;
134 }
135
136 #endif // APPLE_CHANGES
137
138 KHTMLPart::KHTMLPart( QWidget *parentWidget, const char *widgetname, QObject *parent, const char *name,
139                       GUIProfile prof )
140 : KParts::ReadOnlyPart( parent, name )
141 {
142     d = 0;
143     KHTMLFactory::registerPart( this );
144     setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
145 #ifdef APPLE_CHANGES
146     // The widget is made outside this class in our case.
147     init( 0, prof );
148 #else
149     init( new KHTMLView( this, parentWidget, widgetname ), prof );
150 #endif
151 }
152
153 #ifndef APPLE_CHANGES
154
155 KHTMLPart::KHTMLPart( KHTMLView *view, QObject *parent, const char *name, GUIProfile prof )
156 : KParts::ReadOnlyPart( parent, name )
157 {
158     d = 0;
159     KHTMLFactory::registerPart( this );
160     setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
161     assert( view );
162     init( view, prof );
163 }
164
165 #endif // APPLE_CHANGES
166
167 void KHTMLPart::init( KHTMLView *view, GUIProfile prof )
168 {
169   if ( prof == DefaultGUI )
170     setXMLFile( "khtml.rc" );
171   else if ( prof == BrowserViewGUI )
172     setXMLFile( "khtml_browser.rc" );
173
174   d = new KHTMLPartPrivate(parent());
175
176   d->m_view = view;
177   setWidget( d->m_view );
178
179   d->m_guiProfile = prof;
180   d->m_extension = new KHTMLPartBrowserExtension( this );
181   d->m_hostExtension = new KHTMLPartBrowserHostExtension( this );
182
183   d->m_bSecurityInQuestion = false;
184   d->m_paLoadImages = 0;
185   d->m_bMousePressed = false;
186 #ifndef APPLE_CHANGES
187   d->m_paViewDocument = new KAction( i18n( "View Document Source" ), 0, this, SLOT( slotViewDocumentSource() ), actionCollection(), "viewDocumentSource" );
188   d->m_paViewFrame = new KAction( i18n( "View Frame Source" ), 0, this, SLOT( slotViewFrameSource() ), actionCollection(), "viewFrameSource" );
189   d->m_paSaveBackground = new KAction( i18n( "Save &Background Image As..." ), 0, this, SLOT( slotSaveBackground() ), actionCollection(), "saveBackground" );
190   d->m_paSaveDocument = new KAction( i18n( "&Save As..." ), CTRL+Key_S, this, SLOT( slotSaveDocument() ), actionCollection(), "saveDocument" );
191   if ( parentPart() )
192       d->m_paSaveDocument->setShortcut( KShortcut() ); // avoid clashes
193   d->m_paSaveFrame = new KAction( i18n( "Save &Frame As..." ), 0, this, SLOT( slotSaveFrame() ), actionCollection(), "saveFrame" );
194   d->m_paSecurity = new KAction( i18n( "Security..." ), "decrypted", 0, this, SLOT( slotSecurity() ), actionCollection(), "security" );
195   d->m_paDebugRenderTree = new KAction( "print rendering tree to stdout", 0, this, SLOT( slotDebugRenderTree() ), actionCollection(), "debugRenderTree" );
196   d->m_paDebugDOMTree = new KAction( "print DOM tree to stdout", 0, this, SLOT( slotDebugDOMTree() ), actionCollection(), "debugDOMTree" );
197
198   QString foo1 = i18n("Show Images");
199   QString foo2 = i18n("Show Animated Images");
200   QString foo3 = i18n("Stop Animated Images");
201
202   d->m_paSetEncoding = new KSelectAction( i18n( "Set &Encoding" ), 0, this, SLOT( slotSetEncoding() ), actionCollection(), "setEncoding" );
203   QStringList encodings = KGlobal::charsets()->descriptiveEncodingNames();
204   encodings.prepend( i18n( "Auto" ) );
205   d->m_paSetEncoding->setItems( encodings );
206   d->m_paSetEncoding->setCurrentItem(0);
207
208   d->m_paUseStylesheet = new KSelectAction( i18n( "&Use Stylesheet"), 0, this, SLOT( slotUseStylesheet() ), actionCollection(), "useStylesheet" );
209
210   d->m_paIncZoomFactor = new KHTMLZoomFactorAction( this, true, i18n( "Increase Font Sizes" ), "viewmag+", this, SLOT( slotIncZoom() ), actionCollection(), "incFontSizes" );
211   d->m_paDecZoomFactor = new KHTMLZoomFactorAction( this, false, i18n( "Decrease Font Sizes" ), "viewmag-", this, SLOT( slotDecZoom() ), actionCollection(), "decFontSizes" );
212
213   d->m_paFind = KStdAction::find( this, SLOT( slotFind() ), actionCollection(), "find" );
214   if ( parentPart() )
215       d->m_paFind->setShortcut( KShortcut() ); // avoid clashes
216
217   d->m_paPrintFrame = new KAction( i18n( "Print Frame" ), "frameprint", 0, this, SLOT( slotPrintFrame() ), actionCollection(), "printFrame" );
218
219   d->m_paSelectAll = KStdAction::selectAll( this, SLOT( slotSelectAll() ), actionCollection(), "selectAll" );
220   if ( parentPart() )
221       d->m_paSelectAll->setShortcut( KShortcut() ); // avoid clashes
222 #endif
223
224   // set the default java(script) flags according to the current host.
225   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled();
226   d->m_bJScriptDebugEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled();
227   d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled();
228   d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled();
229
230 #ifndef APPLE_CHANGES
231   connect( this, SIGNAL( completed() ),
232            this, SLOT( updateActions() ) );
233   connect( this, SIGNAL( completed( bool ) ),
234            this, SLOT( updateActions() ) );
235   connect( this, SIGNAL( started( KIO::Job * ) ),
236            this, SLOT( updateActions() ) );
237
238   d->m_popupMenuXML = KXMLGUIFactory::readConfigFile( locate( "data", "khtml/khtml_popupmenu.rc", KHTMLFactory::instance() ) );
239 #endif
240
241   connect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
242            this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
243   connect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
244            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
245   connect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
246            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
247
248 #ifndef APPLE_CHANGES
249   findTextBegin(); //reset find variables
250
251   connect( &d->m_redirectionTimer, SIGNAL( timeout() ),
252            this, SLOT( slotRedirect() ) );
253
254   d->m_dcopobject = new KHTMLPartIface(this);
255 #endif
256
257 #ifdef APPLE_CHANGES
258   impl = new KWQKHTMLPartImpl(this);
259 #endif
260 }
261
262 KHTMLPart::~KHTMLPart()
263 {
264   //kdDebug(6050) << "KHTMLPart::~KHTMLPart " << this << endl;
265 #ifndef APPLE_CHANGES
266   if ( d->m_findDialog )
267       disconnect( d->m_findDialog, SIGNAL( destroyed() ),
268                   this, SLOT( slotFindDialogDestroyed() ) );
269
270   if ( d->m_manager )
271   {
272     d->m_manager->setActivePart( 0 );
273     // Shouldn't we delete d->m_manager here ? (David)
274     // No need to, I would say. We specify "this" as parent qobject
275     // in ::partManager() (Simon)
276   }
277 #endif
278
279   stopAutoScroll();
280 #ifndef APPLE_CHANGES
281   d->m_redirectionTimer.stop();
282 #endif
283
284   if (!d->m_bComplete)
285     closeURL();
286
287   disconnect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
288            this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
289   disconnect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
290            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
291   disconnect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
292            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
293
294   clear();
295
296   if ( d->m_view )
297   {
298     d->m_view->hide();
299     d->m_view->viewport()->hide();
300     d->m_view->m_part = 0;
301   }
302   
303 #ifdef APPLE_CHANGES
304   delete impl;
305
306   delete d->m_hostExtension;
307 #endif
308
309   delete d; d = 0;
310   KHTMLFactory::deregisterPart( this );
311 }
312
313 bool KHTMLPart::restoreURL( const KURL &url )
314 {
315   kdDebug( 6050 ) << "KHTMLPart::restoreURL " << url.url() << endl;
316
317 #ifndef APPLE_CHANGES
318   d->m_redirectionTimer.stop();
319 #endif
320
321   /*
322    * That's not a good idea as it will call closeURL() on all
323    * child frames, preventing them from further loading. This
324    * method gets called from restoreState() in case of a full frameset
325    * restoral, and restoreState() calls closeURL() before restoring
326    * anyway.
327   kdDebug( 6050 ) << "closing old URL" << endl;
328   closeURL();
329   */
330
331   d->m_bComplete = false;
332   d->m_bLoadEventEmitted = false;
333   d->m_workingURL = url;
334
335   // set the java(script) flags according to the current host.
336   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
337   d->m_bJScriptDebugEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled();
338   d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
339   d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
340
341   m_url = url;
342
343   KHTMLPageCache::self()->fetchData( d->m_cacheId, this, SLOT(slotRestoreData(const QByteArray &)));
344
345 #ifndef APPLE_CHANGES
346   emit started( 0L );
347 #endif
348
349   return true;
350 }
351
352
353 bool KHTMLPart::openURL( const KURL &url )
354 {
355 #ifdef APPLE_CHANGES
356   impl->openURL(url);
357   return true;
358 #else
359   kdDebug( 6050 ) << "KHTMLPart(" << this << ")::openURL " << url.url() << endl;
360
361   d->m_redirectionTimer.stop();
362
363   // check to see if this is an "error://" URL. This is caused when an error
364   // occurs before this part was loaded (e.g. KonqRun), and is passed to
365   // khtmlpart so that it can display the error.
366   if ( url.protocol() == "error" && url.hasSubURL() ) {
367     closeURL();
368     /**
369      * The format of the error url is that two variables are passed in the query:
370      * error = int kio error code, errText = QString error text from kio
371      * and the URL where the error happened is passed as a sub URL.
372      */
373     KURL::List urls = KURL::split( url );
374     //kdDebug() << "Handling error URL. URL count:" << urls.count() << endl;
375
376     if ( urls.count() > 1 ) {
377       KURL mainURL = urls.first();
378       int error = mainURL.queryItem( "error" ).toInt();
379       // error=0 isn't a valid error code, so 0 means it's missing from the URL
380       if ( error == 0 ) error = KIO::ERR_UNKNOWN;
381       QString errorText = mainURL.queryItem( "errText" );
382       urls.pop_front();
383       d->m_workingURL = KURL::join( urls );
384       //kdDebug() << "Emitting fixed URL " << d->m_workingURL.prettyURL() << endl;
385       emit d->m_extension->setLocationBarURL( d->m_workingURL.prettyURL() );
386       htmlError( error, errorText, d->m_workingURL );
387       return true;
388     }
389   }
390
391   KParts::URLArgs args( d->m_extension->urlArgs() );
392   // in case we have a) no frameset (don't test m_frames.count(), iframes get in there)
393   // b) the url is identical with the currently
394   // displayed one (except for the htmlref!) , c) the url request is not a POST
395   // operation and d) the caller did not request to reload the page we try to
396   // be smart and instead of reloading the whole document we just jump to the
397   // request html anchor
398   bool isFrameSet = false;
399   if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
400       HTMLDocumentImpl* htmlDoc = static_cast<HTMLDocumentImpl*>(d->m_doc);
401       isFrameSet = htmlDoc->body() && (htmlDoc->body()->id() == ID_FRAMESET);
402   }
403   if ( !isFrameSet &&
404        urlcmp( url.url(), m_url.url(), true, true ) &&
405        url.hasRef() && !args.doPost() && !args.reload )
406   {
407     kdDebug( 6050 ) << "KHTMLPart::openURL, jumping to anchor. m_url = " << url.url() << endl;
408     m_url = url;
409     emit started( 0L );
410
411     if ( !gotoAnchor( url.encodedHtmlRef()) )
412        gotoAnchor( url.htmlRef() );
413
414     d->m_bComplete = true;
415     d->m_doc->setParsing(false);
416
417     kdDebug( 6050 ) << "completed..." << endl;
418     emit completed();
419     return true;
420   }
421
422   if (!d->m_restored)
423   {
424     kdDebug( 6050 ) << "closing old URL" << endl;
425     closeURL();
426   }
427
428   args.metaData().insert("main_frame_request", parentPart() == 0 ? "TRUE" : "FALSE" );
429   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE" : "FALSE" );
430   args.metaData().insert("ssl_activate_warnings", "TRUE" );
431   if (d->m_restored)
432      d->m_cachePolicy = KIO::CC_Cache;
433   else if (args.reload)
434      d->m_cachePolicy = KIO::CC_Refresh;
435   else
436      d->m_cachePolicy = KIO::CC_Verify;
437
438   if ( args.doPost() && (url.protocol().startsWith("http")) )
439   {
440       d->m_job = KIO::http_post( url, args.postData, false );
441       d->m_job->addMetaData("content-type", args.contentType() );
442   }
443   else
444   {
445       d->m_job = KIO::get( url, false, false );
446       d->m_job->addMetaData("cache", KIO::getCacheControlString(d->m_cachePolicy));
447   }
448
449   d->m_job->addMetaData(args.metaData());
450
451   connect( d->m_job, SIGNAL( result( KIO::Job * ) ),
452            SLOT( slotFinished( KIO::Job * ) ) );
453   connect( d->m_job, SIGNAL( data( KIO::Job*, const QByteArray &)),
454            SLOT( slotData( KIO::Job*, const QByteArray &)));
455
456   connect( d->m_job, SIGNAL(redirection(KIO::Job*, const KURL&) ),
457            SLOT( slotRedirection(KIO::Job*,const KURL&) ) );
458
459   d->m_bComplete = false;
460   d->m_bLoadEventEmitted = false;
461
462   // delete old status bar msg's from kjs (if it _was_ activated on last URL)
463   if( d->m_bJScriptEnabled )
464   {
465      d->m_kjsStatusBarText = QString::null;
466      d->m_kjsDefaultStatusBarText = QString::null;
467   }
468
469   // set the javascript flags according to the current url
470   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
471   d->m_bJScriptDebugEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled();
472   d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
473   d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
474
475   // 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
476   // data arrives) (Simon)
477   m_url = url;
478   if(m_url.protocol().startsWith( "http" ) && !m_url.host().isEmpty() &&
479      m_url.path().isEmpty()) {
480     m_url.setPath("/");
481     emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
482   }
483   // copy to m_workingURL after fixing m_url above
484   d->m_workingURL = m_url;
485
486   kdDebug( 6050 ) << "KHTMLPart::openURL now (before started) m_url = " << m_url.url() << endl;
487
488   connect( d->m_job, SIGNAL( speed( KIO::Job*, unsigned long ) ),
489            this, SLOT( slotJobSpeed( KIO::Job*, unsigned long ) ) );
490
491   connect( d->m_job, SIGNAL( percent( KIO::Job*, unsigned long ) ),
492            this, SLOT( slotJobPercent( KIO::Job*, unsigned long ) ) );
493
494   emit started( 0L );
495
496   return true;
497 #endif // APPLE_CHANGES
498 }
499
500
501 bool KHTMLPart::closeURL()
502 {
503   if ( d->m_job )
504   {
505     KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
506     d->m_job->kill();
507     d->m_job = 0;
508   }
509
510   if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
511     HTMLDocumentImpl* hdoc = static_cast<HTMLDocumentImpl*>( d->m_doc );
512
513     if ( hdoc->body() && d->m_bLoadEventEmitted ) {
514       hdoc->body()->dispatchWindowEvent( EventImpl::UNLOAD_EVENT, false, false );
515       if ( d->m_doc )
516         d->m_doc->updateRendering();
517       d->m_bLoadEventEmitted = false;
518     }
519   }
520
521   d->m_bComplete = true; // to avoid emitting completed() in slotFinishedParsing() (David)
522   d->m_bLoadEventEmitted = true; // don't want that one either
523   d->m_cachePolicy = KIO::CC_Verify; // Why here?
524
525   KHTMLPageCache::self()->cancelFetch(this);
526   if ( d->m_doc && d->m_doc->parsing() )
527   {
528     kdDebug( 6050 ) << " was still parsing... calling end " << endl;
529 #ifndef APPLE_CHANGES
530     slotFinishedParsing();
531 #endif
532     d->m_doc->setParsing(false);
533   }
534
535   if ( !d->m_workingURL.isEmpty() )
536   {
537     // Aborted before starting to render
538     kdDebug( 6050 ) << "Aborted before starting to render, reverting location bar to " << m_url.prettyURL() << endl;
539     emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
540   }
541
542   d->m_workingURL = KURL();
543
544   if ( d->m_doc && d->m_doc->docLoader() )
545     khtml::Cache::loader()->cancelRequests( d->m_doc->docLoader() );
546
547 #ifndef APPLE_CHANGES
548   // tell all subframes to stop as well
549   ConstFrameIt it = d->m_frames.begin();
550   ConstFrameIt end = d->m_frames.end();
551   for (; it != end; ++it )
552     if ( !( *it ).m_part.isNull() )
553       ( *it ).m_part->closeURL();
554 #endif
555
556   d->m_bPendingChildRedirection = false;
557
558 #ifndef APPLE_CHANGES
559   // Stop any started redirections as well!! (DA)
560   if ( d && d->m_redirectionTimer.isActive() )
561     d->m_redirectionTimer.stop();
562 #endif
563
564   // null node activated.
565   emit nodeActivated(Node());
566
567   return true;
568 }
569
570 DOM::HTMLDocument KHTMLPart::htmlDocument() const
571 {
572   if (d->m_doc && d->m_doc->isHTMLDocument())
573     return static_cast<HTMLDocumentImpl*>(d->m_doc);
574   else
575     return static_cast<HTMLDocumentImpl*>(0);
576 }
577
578 DOM::Document KHTMLPart::document() const
579 {
580     return d->m_doc;
581 }
582
583
584 KParts::BrowserExtension *KHTMLPart::browserExtension() const
585 {
586   return d->m_extension;
587 }
588
589 KHTMLView *KHTMLPart::view() const
590 {
591   return d->m_view;
592 }
593
594 void KHTMLPart::setJScriptEnabled( bool enable )
595 {
596   if ( !enable && jScriptEnabled() && d->m_jscript ) {
597     d->m_jscript->clear();
598   }
599   d->m_bJScriptForce = enable;
600   d->m_bJScriptOverride = true;
601 }
602
603 bool KHTMLPart::jScriptEnabled() const
604 {
605   if ( d->m_bJScriptOverride )
606       return d->m_bJScriptForce;
607   return d->m_bJScriptEnabled;
608 }
609
610 void KHTMLPart::setMetaRefreshEnabled( bool enable )
611 {
612   d->m_metaRefreshEnabled = enable;
613 }
614
615 bool KHTMLPart::metaRefreshEnabled() const
616 {
617   return d->m_metaRefreshEnabled;
618 }
619
620 // Define this to disable dlopening kjs_html, when directly linking to it.
621 // You need to edit khtml/Makefile.am to add ./ecma/libkjs_html.la to LIBADD
622 // and to edit khtml/ecma/Makefile.am to s/kjs_html/libkjs_html/, remove libkhtml from LIBADD,
623 //        remove LDFLAGS line, and replace kde_module with either lib (shared) or noinst (static)
624 //#define DIRECT_LINKAGE_TO_ECMA
625
626 #ifdef DIRECT_LINKAGE_TO_ECMA
627 extern "C" { KJSProxy *kjs_html_init(KHTMLPart *khtmlpart); }
628 #endif
629
630 KJSProxy *KHTMLPart::jScript()
631 {
632   if (!jScriptEnabled()) return 0;
633
634   if ( !d->m_jscript )
635   {
636 #ifndef DIRECT_LINKAGE_TO_ECMA
637     KLibrary *lib = KLibLoader::self()->library("kjs_html");
638     if ( !lib ) {
639       setJScriptEnabled( false );
640       return 0;
641     }
642     // look for plain C init function
643     void *sym = lib->symbol("kjs_html_init");
644     if ( !sym ) {
645       lib->unload();
646       setJScriptEnabled( false );
647       return 0;
648     }
649     typedef KJSProxy* (*initFunction)(KHTMLPart *);
650     initFunction initSym = (initFunction) sym;
651     d->m_jscript = (*initSym)(this);
652     d->m_kjs_lib = lib;
653 #else
654     d->m_jscript = kjs_html_init(this);
655     // d->m_kjs_lib remains 0L.
656 #endif
657     if (d->m_bJScriptDebugEnabled)
658         d->m_jscript->setDebugEnabled(true);
659   }
660
661   return d->m_jscript;
662 }
663
664 QVariant KHTMLPart::executeScript( const QString &script )
665 {
666     return executeScript( DOM::Node(), script );
667 }
668
669 //Enable this to see all JS scripts being executed
670 //#define KJS_VERBOSE
671
672 QVariant KHTMLPart::executeScript( const DOM::Node &n, const QString &script )
673 {
674 #ifdef KJS_VERBOSE
675   kdDebug(6070) << "KHTMLPart::executeScript n=" << n.nodeName().string().latin1() << "(" << (n.isNull() ? 0 : n.nodeType()) << ") " << script << endl;
676 #endif
677   KJSProxy *proxy = jScript();
678
679   if (!proxy || proxy->paused())
680     return QVariant();
681   d->m_runningScripts++;
682   QVariant ret = proxy->evaluate( QString::null, 0, script, n );
683   d->m_runningScripts--;
684   if (!d->m_runningScripts && d->m_doc && !d->m_doc->parsing() && d->m_submitForm )
685       submitFormAgain();
686     DocumentImpl::updateDocumentsRendering();
687
688 #ifdef KJS_VERBOSE
689   kdDebug(6070) << "KHTMLPart::executeScript - done" << endl;
690 #endif
691   return ret;
692 }
693
694 bool KHTMLPart::scheduleScript(const DOM::Node &n, const QString& script)
695 {
696     //kdDebug(6050) << "KHTMLPart::scheduleScript "<< script << endl;
697
698     d->scheduledScript = script;
699     d->scheduledScriptNode = n;
700
701     return true;
702 }
703
704 QVariant KHTMLPart::executeScheduledScript()
705 {
706   if( d->scheduledScript.isEmpty() )
707     return QVariant();
708
709   //kdDebug(6050) << "executing delayed " << d->scheduledScript << endl;
710
711   QVariant ret = executeScript( d->scheduledScriptNode, d->scheduledScript );
712   d->scheduledScript = QString();
713   d->scheduledScriptNode = DOM::Node();
714
715   return ret;
716 }
717
718 void KHTMLPart::setJavaEnabled( bool enable )
719 {
720   d->m_bJavaForce = enable;
721   d->m_bJavaOverride = true;
722 }
723
724 bool KHTMLPart::javaEnabled() const
725 {
726 #ifndef Q_WS_QWS
727   if( d->m_bJavaOverride )
728       return d->m_bJavaForce;
729   return d->m_bJavaEnabled;
730 #else
731   return false;
732 #endif
733 }
734
735 KJavaAppletContext *KHTMLPart::javaContext()
736 {
737 #ifndef Q_WS_QWS
738   return d->m_javaContext;
739 #else
740   return 0;
741 #endif
742 }
743
744 KJavaAppletContext *KHTMLPart::createJavaContext()
745 {
746 #ifndef Q_WS_QWS
747   if ( !d->m_javaContext ) {
748       d->m_javaContext = new KJavaAppletContext(d->m_dcopobject);
749       connect( d->m_javaContext, SIGNAL(showStatus(const QString&)),
750                this, SIGNAL(setStatusBarText(const QString&)) );
751       connect( d->m_javaContext, SIGNAL(showDocument(const QString&, const QString&)),
752                this, SLOT(slotShowDocument(const QString&, const QString&)) );
753   }
754
755   return d->m_javaContext;
756 #else
757   return 0;
758 #endif
759 }
760
761 void KHTMLPart::setPluginsEnabled( bool enable )
762 {
763   d->m_bPluginsForce = enable;
764   d->m_bPluginsOverride = true;
765 }
766
767 bool KHTMLPart::pluginsEnabled() const
768 {
769   if ( d->m_bPluginsOverride )
770       return d->m_bPluginsForce;
771   return d->m_bPluginsEnabled;
772 }
773
774 #ifndef APPLE_CHANGES
775
776 void KHTMLPart::slotShowDocument( const QString &url, const QString &target )
777 {
778   // this is mostly copied from KHTMLPart::slotChildURLRequest. The better approach
779   // would be to put those functions into a single one.
780   khtml::ChildFrame *child = 0;
781   KParts::URLArgs args;
782   args.frameName = target;
783
784   QString frameName = args.frameName.lower();
785   if ( !frameName.isEmpty() )
786   {
787     if ( frameName == QString::fromLatin1( "_top" ) )
788     {
789       emit d->m_extension->openURLRequest( url, args );
790       return;
791     }
792     else if ( frameName == QString::fromLatin1( "_blank" ) )
793     {
794       emit d->m_extension->createNewWindow( url, args );
795       return;
796     }
797     else if ( frameName == QString::fromLatin1( "_parent" ) )
798     {
799       KParts::URLArgs newArgs( args );
800       newArgs.frameName = QString::null;
801
802       emit d->m_extension->openURLRequest( url, newArgs );
803       return;
804     }
805     else if ( frameName != QString::fromLatin1( "_self" ) )
806     {
807       khtml::ChildFrame *_frame = recursiveFrameRequest( url, args );
808
809       if ( !_frame )
810       {
811         emit d->m_extension->openURLRequest( url, args );
812         return;
813       }
814
815       child = _frame;
816     }
817   }
818
819   // TODO: handle child target correctly! currently the script are always executed fur the parent
820   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
821       executeScript( url.right( url.length() - 11) );
822       return;
823   }
824
825   if ( child ) {
826       requestObject( child, KURL(url), args );
827   }  else if ( frameName==QString::fromLatin1("_self") ) // this is for embedded objects (via <object>) which want to replace the current document
828   {
829       KParts::URLArgs newArgs( args );
830       newArgs.frameName = QString::null;
831       emit d->m_extension->openURLRequest( KURL(url), newArgs );
832   }
833 }
834
835 #endif // APPLE_CHANGES
836
837 void KHTMLPart::slotDebugDOMTree()
838 {
839   if ( d->m_doc && d->m_doc->firstChild() )
840     qDebug("%s", d->m_doc->firstChild()->toHTML().latin1());
841 }
842
843 void KHTMLPart::slotDebugRenderTree()
844 {
845 #ifndef NDEBUG
846   if ( d->m_doc )
847     d->m_doc->renderer()->printTree();
848 #endif
849 }
850
851 void KHTMLPart::setAutoloadImages( bool enable )
852 {
853   if ( d->m_doc && d->m_doc->docLoader()->autoloadImages() == enable )
854     return;
855
856   if ( d->m_doc )
857     d->m_doc->docLoader()->setAutoloadImages( enable );
858
859 #ifndef APPLE_CHANGES
860   unplugActionList( "loadImages" );
861
862   if ( enable ) {
863     delete d->m_paLoadImages;
864     d->m_paLoadImages = 0;
865   }
866   else if ( !d->m_paLoadImages )
867     d->m_paLoadImages = new KAction( i18n( "Display Images on Page" ), "images_display", 0, this, SLOT( slotLoadImages() ), actionCollection(), "loadImages" );
868
869   if ( d->m_paLoadImages ) {
870     QPtrList<KAction> lst;
871     lst.append( d->m_paLoadImages );
872     plugActionList( "loadImages", lst );
873   }
874 #endif
875 }
876
877 bool KHTMLPart::autoloadImages() const
878 {
879   if ( d->m_doc )
880     return d->m_doc->docLoader()->autoloadImages();
881
882   return true;
883 }
884
885 void KHTMLPart::clear()
886 {
887   if ( d->m_bCleared )
888     return;
889   d->m_bCleared = true;
890
891   d->m_bClearing = true;
892
893 #ifndef APPLE_CHANGES
894   {
895     ConstFrameIt it = d->m_frames.begin();
896     ConstFrameIt end = d->m_frames.end();
897     for(; it != end; ++it )
898     {
899       // Stop HTMLRun jobs for frames
900       if ( (*it).m_run )
901         (*it).m_run->abort();
902     }
903   }
904
905   {
906     QValueList<khtml::ChildFrame>::ConstIterator it = d->m_objects.begin();
907     QValueList<khtml::ChildFrame>::ConstIterator end = d->m_objects.end();
908     for(; it != end; ++it )
909     {
910       // Stop HTMLRun jobs for objects
911       if ( (*it).m_run )
912         (*it).m_run->abort();
913     }
914   }
915
916
917   findTextBegin(); // resets d->m_findNode and d->m_findPos
918 #endif
919
920   d->m_mousePressNode = DOM::Node();
921
922
923   if ( d->m_doc )
924     d->m_doc->detach();
925
926   // Moving past doc so that onUnload works.
927   if ( d->m_jscript )
928     d->m_jscript->clear();
929
930   if ( d->m_view )
931     d->m_view->clear();
932
933   // do not dereference the document before the jscript and view are cleared, as some destructors
934   // might still try to access the document.
935   if ( d->m_doc )
936     d->m_doc->deref();
937   d->m_doc = 0;
938
939   delete d->m_decoder;
940   d->m_decoder = 0;
941
942 #ifndef APPLE_CHANGES
943   {
944     ConstFrameIt it = d->m_frames.begin();
945     ConstFrameIt end = d->m_frames.end();
946     for(; it != end; ++it )
947     {
948       if ( (*it).m_part )
949       {
950         partManager()->removePart( (*it).m_part );
951         delete (KParts::ReadOnlyPart *)(*it).m_part;
952       }
953     }
954   }
955
956   d->m_frames.clear();
957   d->m_objects.clear();
958 #endif
959
960 #ifndef Q_WS_QWS
961   delete d->m_javaContext;
962   d->m_javaContext = 0;
963 #endif
964
965   d->m_delayRedirect = 0;
966   d->m_redirectURL = QString::null;
967   d->m_redirectLockHistory = true;
968   d->m_bHTTPRefresh = false;
969   d->m_bClearing = false;
970   d->m_frameNameId = 1;
971   d->m_bFirstData = true;
972
973   d->m_bMousePressed = false;
974
975   d->m_selectionStart = DOM::Node();
976   d->m_selectionEnd = DOM::Node();
977   d->m_startOffset = 0;
978   d->m_endOffset = 0;
979 #ifndef QT_NO_CLIPBOARD
980   connect( kapp->clipboard(), SIGNAL( selectionChanged()), SLOT( slotClearSelection()));
981 #endif
982
983   d->m_totalObjectCount = 0;
984   d->m_loadedObjects = 0;
985   d->m_jobPercent = 0;
986
987   if ( !d->m_haveEncoding )
988     d->m_encoding = QString::null;
989 #ifdef SPEED_DEBUG
990   d->m_parsetime.restart();
991 #endif
992 }
993
994 bool KHTMLPart::openFile()
995 {
996   return true;
997 }
998
999 DOM::HTMLDocumentImpl *KHTMLPart::docImpl() const
1000 {
1001     if ( d && d->m_doc && d->m_doc->isHTMLDocument() )
1002         return static_cast<HTMLDocumentImpl*>(d->m_doc);
1003     return 0;
1004 }
1005
1006 DOM::DocumentImpl *KHTMLPart::xmlDocImpl() const
1007 {
1008     if ( d )
1009         return d->m_doc;
1010     return 0;
1011 }
1012
1013 /*bool KHTMLPart::isSSLInUse() const
1014 {
1015   return d->m_ssl_in_use;
1016 }*/
1017
1018 void KHTMLPart::slotData( KIO::Job* kio_job, const QByteArray &data )
1019 {
1020   assert ( d->m_job == kio_job );
1021
1022   //kdDebug( 6050 ) << "slotData: " << data.size() << endl;
1023   // The first data ?
1024   if ( !d->m_workingURL.isEmpty() )
1025   {
1026       //kdDebug( 6050 ) << "begin!" << endl;
1027
1028     begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
1029
1030
1031     d->m_doc->docLoader()->setCachePolicy(d->m_cachePolicy);
1032     d->m_workingURL = KURL();
1033
1034     d->m_cacheId = KHTMLPageCache::self()->createCacheEntry();
1035
1036     // When the first data arrives, the metadata has just been made available
1037     d->m_bSecurityInQuestion = false;
1038     d->m_ssl_in_use = (d->m_job->queryMetaData("ssl_in_use") == "TRUE");
1039     kdDebug(6050) << "SSL in use? " << d->m_job->queryMetaData("ssl_in_use") << endl;
1040
1041     {
1042     KHTMLPart *p = parentPart();
1043     if (p && p->d->m_ssl_in_use != d->m_ssl_in_use) {
1044         while (p->parentPart()) p = p->parentPart();
1045
1046 #ifndef APPLE_CHANGES
1047         p->d->m_paSecurity->setIcon( "halfencrypted" );
1048 #endif
1049         p->d->m_bSecurityInQuestion = true;
1050         kdDebug(6050) << "parent setIcon half done." << endl;
1051     }
1052     }
1053
1054 #ifndef APPLE_CHANGES
1055     d->m_paSecurity->setIcon( d->m_ssl_in_use ? "encrypted" : "decrypted" );
1056     kdDebug(6050) << "setIcon " << ( d->m_ssl_in_use ? "encrypted" : "decrypted" ) << " done." << endl;
1057 #endif
1058
1059     // Shouldn't all of this be done only if ssl_in_use == true ? (DF)
1060
1061     d->m_ssl_peer_certificate = d->m_job->queryMetaData("ssl_peer_certificate");
1062     d->m_ssl_peer_chain = d->m_job->queryMetaData("ssl_peer_chain");
1063     d->m_ssl_peer_ip = d->m_job->queryMetaData("ssl_peer_ip");
1064     d->m_ssl_cipher = d->m_job->queryMetaData("ssl_cipher");
1065     d->m_ssl_cipher_desc = d->m_job->queryMetaData("ssl_cipher_desc");
1066     d->m_ssl_cipher_version = d->m_job->queryMetaData("ssl_cipher_version");
1067     d->m_ssl_cipher_used_bits = d->m_job->queryMetaData("ssl_cipher_used_bits");
1068     d->m_ssl_cipher_bits = d->m_job->queryMetaData("ssl_cipher_bits");
1069     d->m_ssl_cert_state = d->m_job->queryMetaData("ssl_cert_state");
1070
1071     // Check for charset meta-data
1072     QString qData = d->m_job->queryMetaData("charset");
1073     if ( !qData.isEmpty() && !d->m_haveEncoding ) // only use information if the user didn't override the settings
1074        d->m_encoding = qData;
1075
1076     // Support for http-refresh
1077     qData = d->m_job->queryMetaData("http-refresh");
1078     if( !qData.isEmpty() && d->m_metaRefreshEnabled )
1079     {
1080       kdDebug(6050) << "HTTP Refresh Request: " << qData << endl;
1081       int delay;
1082       int pos = qData.find( ';' );
1083       if ( pos == -1 )
1084         pos = qData.find( ',' );
1085
1086       if( pos == -1 )
1087       {
1088         delay = qData.stripWhiteSpace().toInt();
1089         scheduleRedirection( qData.toInt(), m_url.url());
1090       }
1091       else
1092       {
1093         int end_pos = qData.length();
1094         delay = qData.left(pos).stripWhiteSpace().toInt();
1095         while ( qData[++pos] == ' ' );
1096         if ( qData.find( "url", pos, false ) == pos )
1097         {
1098           pos += 3;
1099           while (qData[pos] == ' ' || qData[pos] == '=' )
1100               pos++;
1101           if ( qData[pos] == '"' )
1102           {
1103               pos++;
1104               int index = end_pos-1;
1105               while( index > pos )
1106               {
1107                 if ( qData[index] == '"' )
1108                     break;
1109                 index--;
1110               }
1111               if ( index > pos )
1112                 end_pos = index;
1113           }
1114         }
1115         scheduleRedirection( delay, d->m_doc->completeURL( qData.mid( pos, end_pos ) ));
1116       }
1117       d->m_bHTTPRefresh = true;
1118     }
1119
1120     // Support for http last-modified
1121     d->m_lastModified = d->m_job->queryMetaData("modified");
1122     //kdDebug() << "KHTMLPart::slotData metadata modified: " << d->m_lastModified << endl;
1123   }
1124
1125   KHTMLPageCache::self()->addData(d->m_cacheId, data);
1126   write( data.data(), data.size() );
1127 }
1128
1129 void KHTMLPart::slotRestoreData(const QByteArray &data )
1130 {
1131   // The first data ?
1132   if ( !d->m_workingURL.isEmpty() )
1133   {
1134      long saveCacheId = d->m_cacheId;
1135      begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
1136      d->m_cacheId = saveCacheId;
1137      d->m_workingURL = KURL();
1138   }
1139
1140   //kdDebug( 6050 ) << "slotRestoreData: " << data.size() << endl;
1141   write( data.data(), data.size() );
1142
1143   if (data.size() == 0)
1144   {
1145       //kdDebug( 6050 ) << "slotRestoreData: <<end of data>>" << endl;
1146      // End of data.
1147     if (d->m_doc && d->m_doc->parsing())
1148         end(); //will emit completed()
1149   }
1150 }
1151
1152 #ifndef APPLE_CHANGES
1153
1154 void KHTMLPart::showError( KIO::Job* job )
1155 {
1156   kdDebug() << "KHTMLPart::showError d->m_bParsing=" << (d->m_doc && d->m_doc->parsing()) << " d->m_bComplete=" << d->m_bComplete
1157             << " d->m_bCleared=" << d->m_bCleared << endl;
1158
1159   if (job->error() == KIO::ERR_NO_CONTENT)
1160         return;
1161
1162   if ( (d->m_doc && d->m_doc->parsing()) || d->m_workingURL.isEmpty() ) // if we got any data already
1163     job->showErrorDialog( /*d->m_view*/ );
1164   else
1165   {
1166     htmlError( job->error(), job->errorText(), d->m_workingURL );
1167   }
1168 }
1169
1170 // This is a protected method, placed here because of it's relevance to showError
1171 void KHTMLPart::htmlError( int errorCode, const QString& text, const KURL& reqUrl )
1172 {
1173   kdDebug(6050) << "KHTMLPart::htmlError errorCode=" << errorCode << " text=" << text << endl;
1174   // make sure we're not executing any embedded JS
1175   bool bJSFO = d->m_bJScriptForce;
1176   bool bJSOO = d->m_bJScriptOverride;
1177   d->m_bJScriptForce = false;
1178   d->m_bJScriptOverride = true;
1179   begin();
1180   QString errText = QString::fromLatin1( "<HTML><HEAD><TITLE>" );
1181   errText += i18n( "Error while loading %1" ).arg( reqUrl.htmlURL() );
1182   errText += QString::fromLatin1( "</TITLE></HEAD><BODY><P>" );
1183   errText += i18n( "An error occured while loading <B>%1</B>:" ).arg( reqUrl.htmlURL() );
1184   errText += QString::fromLatin1( "</P><P>" );
1185   QString kioErrString = KIO::buildErrorString( errorCode, text );
1186
1187   kioErrString.replace(QRegExp("&"), QString("&amp;"));
1188   kioErrString.replace(QRegExp("<"), QString("&lt;"));
1189   kioErrString.replace(QRegExp(">"), QString("&gt;"));
1190
1191   // In case the error string has '\n' in it, replace with <BR/>
1192   kioErrString.replace( QRegExp("\n"), "<BR/>" );
1193
1194   errText += kioErrString;
1195   errText += QString::fromLatin1( "</P></BODY></HTML>" );
1196   write(errText);
1197   end();
1198
1199   d->m_bJScriptForce = bJSFO;
1200   d->m_bJScriptOverride = bJSOO;
1201
1202   // make the working url the current url, so that reload works and
1203   // emit the progress signals to advance one step in the history
1204   // (so that 'back' works)
1205   m_url = reqUrl; // same as d->m_workingURL
1206   d->m_workingURL = KURL();
1207   emit started( 0 );
1208   emit completed();
1209   return;
1210   // following disabled until 3.1
1211
1212   QString errorName, techName, description;
1213   QStringList causes, solutions;
1214
1215   QByteArray raw = KIO::rawErrorDetail( errorCode, text, &reqUrl );
1216   QDataStream stream(raw, IO_ReadOnly);
1217
1218   stream >> errorName >> techName >> description >> causes >> solutions;
1219
1220   QString url, protocol, datetime;
1221   url = reqUrl.prettyURL();
1222   protocol = reqUrl.protocol();
1223   datetime = KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(),
1224                                                 false );
1225
1226   QString doc = QString::fromLatin1( "<html><head><title>" );
1227   doc += i18n( "Error: " );
1228   doc += errorName;
1229   doc += QString::fromLatin1( " - %1</title></head><body><h1>" ).arg( url );
1230   doc += i18n( "The requested operation could not be completed" );
1231   doc += QString::fromLatin1( "</h1><h2>" );
1232   doc += errorName;
1233   doc += QString::fromLatin1( "</h2>" );
1234   if ( techName != QString::null ) {
1235     doc += QString::fromLatin1( "<h2>" );
1236     doc += i18n( "Technical Reason: " );
1237     doc += techName;
1238     doc += QString::fromLatin1( "</h2>" );
1239   }
1240   doc += QString::fromLatin1( "<h3>" );
1241   doc += i18n( "Details of the Request:" );
1242   doc += QString::fromLatin1( "</h3><ul><li>" );
1243   doc += i18n( "URL: %1" ).arg( url );
1244   doc += QString::fromLatin1( "</li><li>" );
1245   if ( protocol != QString::null ) {
1246     // uncomment for 3.1... i18n change
1247     // doc += i18n( "Protocol: %1" ).arg( protocol ).arg( protocol );
1248     doc += QString::fromLatin1( "</li><li>" );
1249   }
1250   doc += i18n( "Date and Time: %1" ).arg( datetime );
1251   doc += QString::fromLatin1( "</li><li>" );
1252   doc += i18n( "Additional Information: %1" ).arg( text );
1253   doc += QString::fromLatin1( "</li></ul><h3>" );
1254   doc += i18n( "Description:" );
1255   doc += QString::fromLatin1( "</h3><p>" );
1256   doc += description;
1257   doc += QString::fromLatin1( "</p>" );
1258   if ( causes.count() ) {
1259     doc += QString::fromLatin1( "<h3>" );
1260     doc += i18n( "Possible Causes:" );
1261     doc += QString::fromLatin1( "</h3><ul><li>" );
1262     doc += causes.join( "</li><li>" );
1263     doc += QString::fromLatin1( "</li></ul>" );
1264   }
1265   if ( solutions.count() ) {
1266     doc += QString::fromLatin1( "<h3>" );
1267     doc += i18n( "Possible Solutions:" );
1268     doc += QString::fromLatin1( "</h3><ul><li>" );
1269     doc += solutions.join( "</li><li>" );
1270     doc += QString::fromLatin1( "</li></ul>" );
1271   }
1272   doc += QString::fromLatin1( "</body></html>" );
1273
1274   write( doc );
1275   end();
1276 }
1277
1278 #endif
1279
1280 void KHTMLPart::slotFinished( KIO::Job * job )
1281 {
1282   if (job->error())
1283   {
1284     KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
1285     d->m_job = 0L;
1286 #ifndef APPLE_CHANGES
1287     emit canceled( job->errorString() );
1288 #endif
1289     // TODO: what else ?
1290     checkCompleted();
1291 #ifndef APPLE_CHANGES
1292     showError( job );
1293 #endif
1294     return;
1295   }
1296   //kdDebug( 6050 ) << "slotFinished" << endl;
1297
1298   KHTMLPageCache::self()->endData(d->m_cacheId);
1299
1300   if ( d->m_doc && d->m_doc->docLoader()->expireDate() && m_url.protocol().lower().startsWith("http"))
1301       KIO::http_update_cache(m_url, false, d->m_doc->docLoader()->expireDate());
1302
1303   d->m_workingURL = KURL();
1304   d->m_job = 0L;
1305
1306   if (d->m_doc->parsing())
1307     end(); //will emit completed()
1308 }
1309
1310 void KHTMLPart::begin( const KURL &url, int xOffset, int yOffset )
1311 {
1312 #ifdef APPLE_CHANGES
1313   impl->begin(url, xOffset, xOffset);
1314 #else
1315   clear();
1316   d->m_bCleared = false;
1317   d->m_cacheId = 0;
1318   d->m_bComplete = false;
1319   d->m_bLoadEventEmitted = false;
1320
1321   if(url.isValid()) {
1322       QString urlString = url.url();
1323       KHTMLFactory::vLinks()->insert( urlString );
1324       QString urlString2 = url.prettyURL();
1325       if ( urlString != urlString2 ) {
1326           KHTMLFactory::vLinks()->insert( urlString2 );
1327       }
1328   }
1329
1330   // ###
1331   //stopParser();
1332
1333   KParts::URLArgs args( d->m_extension->urlArgs() );
1334   args.xOffset = xOffset;
1335   args.yOffset = yOffset;
1336   d->m_extension->setURLArgs( args );
1337
1338   d->m_referrer = url.url();
1339   m_url = url;
1340   KURL baseurl;
1341
1342   if ( !m_url.isEmpty() )
1343   {
1344     KURL::List lst = KURL::split( m_url );
1345     if ( !lst.isEmpty() )
1346       baseurl = *lst.begin();
1347
1348     KURL title( baseurl );
1349     title.setRef( QString::null );
1350     title.setQuery( QString::null );
1351     emit setWindowCaption( title.url() );
1352   }
1353   else
1354     emit setWindowCaption( i18n( "no title", "* Unknown *" ) );
1355
1356   // ### not sure if XHTML documents served as text/xml should use DocumentImpl or HTMLDocumentImpl
1357   if (args.serviceType == "text/xml")
1358     d->m_doc = DOMImplementationImpl::instance()->createDocument( d->m_view );
1359   else
1360     d->m_doc = DOMImplementationImpl::instance()->createHTMLDocument( d->m_view );
1361
1362   d->m_doc->ref();
1363   if (!d->m_doc->attached())
1364     d->m_doc->attach( );
1365   d->m_doc->setURL( m_url.url() );
1366   // We prefer m_baseURL over m_url because m_url changes when we are
1367   // about to load a new page.
1368   d->m_doc->setBaseURL( baseurl.url() );
1369   d->m_doc->docLoader()->setShowAnimations( KHTMLFactory::defaultHTMLSettings()->showAnimations() );
1370
1371   d->m_paUseStylesheet->setItems(QStringList());
1372   d->m_paUseStylesheet->setEnabled( false );
1373
1374   setAutoloadImages( KHTMLFactory::defaultHTMLSettings()->autoLoadImages() );
1375   QString userStyleSheet = KHTMLFactory::defaultHTMLSettings()->userStyleSheet();
1376   if ( !userStyleSheet.isEmpty() )
1377     setUserStyleSheet( KURL( userStyleSheet ) );
1378
1379   d->m_doc->setRestoreState(args.docState);
1380   d->m_doc->open();
1381   // clear widget
1382   d->m_view->resizeContents( 0, 0 );
1383   connect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
1384
1385   emit d->m_extension->enableAction( "print", true );
1386
1387   d->m_doc->setParsing(true);
1388 #endif // APPLE_CHANGES
1389 }
1390
1391 void KHTMLPart::write( const char *str, int len )
1392 {
1393 #ifdef APPLE_CHANGES
1394   impl->write(str, len);
1395 #else
1396     if ( !d->m_decoder ) {
1397         d->m_decoder = new khtml::Decoder();
1398         if(d->m_encoding != QString::null)
1399             d->m_decoder->setEncoding(d->m_encoding.latin1(), d->m_haveEncoding);
1400         else
1401             d->m_decoder->setEncoding(settings()->encoding().latin1(), d->m_haveEncoding);
1402     }
1403   if ( len == 0 )
1404     return;
1405
1406   if ( len == -1 )
1407     len = strlen( str );
1408
1409   QString decoded = d->m_decoder->decode( str, len );
1410
1411   if(decoded.isEmpty()) return;
1412
1413   if(d->m_bFirstData) {
1414       // determine the parse mode
1415       d->m_doc->determineParseMode( decoded );
1416       d->m_bFirstData = false;
1417
1418   //kdDebug(6050) << "KHTMLPart::write haveEnc = " << d->m_haveEncoding << endl;
1419       // ### this is still quite hacky, but should work a lot better than the old solution
1420       if(d->m_decoder->visuallyOrdered()) d->m_doc->setVisuallyOrdered();
1421       d->m_doc->recalcStyle( NodeImpl::Force );
1422   }
1423
1424   if (jScript())
1425     jScript()->appendSourceFile(m_url.url(),decoded);
1426   Tokenizer* t = d->m_doc->tokenizer();
1427   if(t)
1428     t->write( decoded, true );
1429 #endif // APPLE_CHANGES
1430 }
1431
1432 void KHTMLPart::write( const QString &str )
1433 {
1434   if ( str.isNull() )
1435     return;
1436
1437   if(d->m_bFirstData) {
1438       // determine the parse mode
1439       d->m_doc->setParseMode( DocumentImpl::Strict );
1440       d->m_bFirstData = false;
1441   }
1442   if (jScript())
1443     jScript()->appendSourceFile(m_url.url(),str);
1444   Tokenizer* t = d->m_doc->tokenizer();
1445   if(t)
1446     t->write( str, true );
1447 }
1448
1449 void KHTMLPart::end()
1450 {
1451 #ifdef APPLE_CHANGES
1452   impl->end();
1453 #else
1454     // make sure nothing's left in there...
1455     if(d->m_decoder)
1456         write(d->m_decoder->flush());
1457     if (d->m_doc)
1458         d->m_doc->finishParsing();
1459 #endif
1460 }
1461
1462 #ifndef APPLE_CHANGES
1463
1464 void KHTMLPart::paint(QPainter *p, const QRect &rc, int yOff, bool *more)
1465 {
1466     if (!d->m_view) return;
1467     d->m_view->paint(p, rc, yOff, more);
1468 }
1469
1470 #endif
1471
1472 void KHTMLPart::stopAnimations()
1473 {
1474 #ifndef APPLE_CHANGES
1475   if ( d->m_doc )
1476     d->m_doc->docLoader()->setShowAnimations( KHTMLSettings::KAnimationDisabled );
1477
1478   ConstFrameIt it = d->m_frames.begin();
1479   ConstFrameIt end = d->m_frames.end();
1480   for (; it != end; ++it )
1481     if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
1482       KParts::ReadOnlyPart* p = ( *it ).m_part;
1483       static_cast<KHTMLPart*>( p )->stopAnimations();
1484     }
1485 #endif
1486 }
1487
1488 void KHTMLPart::slotFinishedParsing()
1489 {
1490   d->m_doc->setParsing(false);
1491   checkEmitLoadEvent();
1492   disconnect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
1493
1494   if (!d->m_view)
1495     return; // We are probably being destructed.
1496   // check if the scrollbars are really needed for the content
1497   // if not, remove them, relayout, and repaint
1498
1499   d->m_view->restoreScrollBar();
1500
1501   if ( !m_url.encodedHtmlRef().isEmpty() )
1502     if ( !gotoAnchor( m_url.encodedHtmlRef()) )
1503        gotoAnchor( m_url.htmlRef() );
1504
1505   checkCompleted();
1506 }
1507
1508 void KHTMLPart::slotLoaderRequestStarted( khtml::DocLoader* dl, khtml::CachedObject *obj )
1509 {
1510   if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
1511     KHTMLPart* p = this;
1512     while ( p ) {
1513       KHTMLPart* op = p;
1514       p->d->m_totalObjectCount++;
1515       p = p->parentPart();
1516       if ( !p && d->m_loadedObjects <= d->m_totalObjectCount )
1517         QTimer::singleShot( 200, op, SLOT( slotProgressUpdate() ) );
1518     }
1519   }
1520 }
1521
1522 void KHTMLPart::slotLoaderRequestDone( khtml::DocLoader* dl, khtml::CachedObject *obj )
1523 {
1524   if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
1525     KHTMLPart* p = this;
1526     while ( p ) {
1527       KHTMLPart* op = p;
1528       p->d->m_loadedObjects++;
1529       p = p->parentPart();
1530       if ( !p && d->m_loadedObjects <= d->m_totalObjectCount && d->m_jobPercent >= 100 )
1531         QTimer::singleShot( 200, op, SLOT( slotProgressUpdate() ) );
1532     }
1533   }
1534
1535   checkCompleted();
1536 }
1537
1538 #ifndef APPLE_CHANGES
1539
1540 void KHTMLPart::slotProgressUpdate()
1541 {
1542   int percent;
1543   if ( d->m_loadedObjects < d->m_totalObjectCount )
1544     percent = d->m_jobPercent / 4 + ( d->m_loadedObjects*300 ) / ( 4*d->m_totalObjectCount );
1545   else
1546     percent = d->m_jobPercent;
1547
1548   if ( d->m_loadedObjects < d->m_totalObjectCount && percent >= 75 )
1549     emit d->m_extension->infoMessage( i18n( "%1 of 1 Image loaded", "%1 of %n Images loaded", d->m_totalObjectCount ).arg( d->m_loadedObjects ) );
1550
1551   emit d->m_extension->loadingProgress( percent );
1552 }
1553
1554 void KHTMLPart::slotJobSpeed( KIO::Job* /*job*/, unsigned long speed )
1555 {
1556   emit d->m_extension->speedProgress( speed );
1557 }
1558
1559 void KHTMLPart::slotJobPercent( KIO::Job* /*job*/, unsigned long percent )
1560 {
1561   d->m_jobPercent = percent;
1562
1563   if ( !parentPart() )
1564     QTimer::singleShot( 0, this, SLOT( slotProgressUpdate() ) );
1565 }
1566
1567 #endif
1568
1569 void KHTMLPart::checkCompleted()
1570 {
1571 //   kdDebug( 6050 ) << "KHTMLPart::checkCompleted() parsing: " << d->m_doc->parsing() << endl;
1572 //   kdDebug( 6050 ) << "                           complete: " << d->m_bComplete << endl;
1573
1574   // restore the cursor position
1575   if (d->m_doc && !d->m_doc->parsing() && !d->m_focusNodeRestored)
1576   {
1577       if (d->m_focusNodeNumber >= 0)
1578           d->m_doc->setFocusNode(d->m_doc->nodeWithAbsIndex(d->m_focusNodeNumber));
1579       else
1580           d->m_doc->setFocusNode(0);
1581       d->m_focusNodeRestored = true;
1582   }
1583
1584 #ifndef APPLE_CHANGES
1585   // Any frame that hasn't completed yet ?
1586   ConstFrameIt it = d->m_frames.begin();
1587   ConstFrameIt end = d->m_frames.end();
1588   for (; it != end; ++it )
1589     if ( !(*it).m_bCompleted )
1590       return;
1591 #endif
1592
1593   // Are we still parsing - or have we done the completed stuff already ?
1594   if ( d->m_bComplete || (d->m_doc && d->m_doc->parsing()) )
1595     return;
1596
1597   // Still waiting for images/scripts from the loader ?
1598   int requests = 0;
1599   if ( d->m_doc && d->m_doc->docLoader() )
1600     requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );
1601
1602   if ( requests > 0 )
1603     return;
1604
1605   // OK, completed.
1606   // Now do what should be done when we are really completed.
1607   d->m_bComplete = true;
1608
1609   checkEmitLoadEvent(); // if we didn't do it before
1610
1611   // check that the view has not been moved by the user
1612   if ( m_url.encodedHtmlRef().isEmpty() && d->m_view->contentsY() == 0 )
1613       d->m_view->setContentsPos( d->m_extension->urlArgs().xOffset,
1614                                  d->m_extension->urlArgs().yOffset );
1615
1616   d->m_view->complete();
1617
1618 #ifndef APPLE_CHANGES
1619   if ( !d->m_redirectURL.isEmpty() )
1620   {
1621     // Do not start redirection for frames here! That action is
1622     // deferred until the parent emits a completed signal.
1623     if ( parentPart() == 0 )
1624       d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
1625
1626     emit completed( true );
1627   }
1628   else
1629   {
1630     if ( d->m_bPendingChildRedirection )
1631       emit completed ( true );
1632     else
1633       emit completed();
1634   }
1635 #endif
1636
1637   // find the alternate stylesheets
1638   QStringList sheets;
1639   if (d->m_doc)
1640      sheets = d->m_doc->availableStyleSheets();
1641 #ifndef APPLE_CHANGES
1642   d->m_paUseStylesheet->setItems( sheets );
1643   d->m_paUseStylesheet->setEnabled( !sheets.isEmpty() );
1644   if (!sheets.isEmpty())
1645   {
1646     d->m_paUseStylesheet->setCurrentItem(kMax(sheets.findIndex(d->m_sheetUsed), 0));
1647     slotUseStylesheet();
1648   }
1649
1650   if (!parentPart())
1651       emit setStatusBarText(i18n("Done."));
1652 #endif
1653
1654 #ifdef SPEED_DEBUG
1655   kdDebug(6050) << "DONE: " <<d->m_parsetime.elapsed() << endl;
1656 #endif
1657 }
1658
1659 void KHTMLPart::checkEmitLoadEvent()
1660 {
1661   if ( d->m_bLoadEventEmitted || !d->m_doc || d->m_doc->parsing() ) return;
1662
1663 #ifndef APPLE_CHANGES
1664   ConstFrameIt it = d->m_frames.begin();
1665   ConstFrameIt end = d->m_frames.end();
1666   for (; it != end; ++it )
1667     if ( !(*it).m_bCompleted ) // still got a frame running -> too early
1668       return;
1669
1670
1671   // All frames completed -> set their domain to the frameset's domain
1672   // This must only be done when loading the frameset initially (#22039),
1673   // not when following a link in a frame (#44162).
1674   if ( d->m_doc && d->m_doc->isHTMLDocument() )
1675   {
1676     DOMString domain = static_cast<HTMLDocumentImpl*>(d->m_doc)->domain();
1677     ConstFrameIt it = d->m_frames.begin();
1678     ConstFrameIt end = d->m_frames.end();
1679     for (; it != end; ++it )
1680     {
1681       KParts::ReadOnlyPart *p = (*it).m_part;
1682       if ( p && p->inherits( "KHTMLPart" ))
1683       {
1684         KHTMLPart* htmlFrame = static_cast<KHTMLPart *>(p);
1685         if (htmlFrame->d->m_doc && htmlFrame->d->m_doc->isHTMLDocument() )
1686         {
1687           kdDebug() << "KHTMLPart::checkCompleted setting frame domain to " << domain.string() << endl;
1688           static_cast<HTMLDocumentImpl*>(htmlFrame->d->m_doc)->setDomain( domain, true );
1689         }
1690       }
1691     }
1692   }
1693 #endif
1694
1695   d->m_bLoadEventEmitted = true;
1696   if (d->m_doc)
1697     d->m_doc->close();
1698 }
1699
1700 const KHTMLSettings *KHTMLPart::settings() const
1701 {
1702   return d->m_settings;
1703 }
1704
1705 #ifndef KDE_NO_COMPAT
1706 KURL KHTMLPart::baseURL() const
1707 {
1708   if ( !d->m_doc ) return KURL();
1709
1710   return d->m_doc->baseURL();
1711 }
1712
1713 QString KHTMLPart::baseTarget() const
1714 {
1715   if ( !d->m_doc ) return QString::null;
1716
1717   return d->m_doc->baseTarget();
1718 }
1719 #endif
1720
1721 KURL KHTMLPart::completeURL( const QString &url )
1722 {
1723   if ( !d->m_doc ) return url;
1724
1725   if (d->m_decoder)
1726     return KURL(d->m_doc->completeURL(url), d->m_decoder->codec()->mibEnum());
1727
1728   return KURL( d->m_doc->completeURL( url ) );
1729 }
1730
1731 void KHTMLPart::scheduleRedirection( int delay, const QString &url, bool doLockHistory )
1732 {
1733 #ifdef APPLE_CHANGES
1734   impl->scheduleRedirection(delay, url);
1735 #else
1736     kdDebug(6050) << "KHTMLPart::scheduleRedirection delay=" << delay << " url=" << url << endl;
1737     if( d->m_redirectURL.isEmpty() || delay < d->m_delayRedirect )
1738     {
1739        d->m_delayRedirect = delay;
1740        d->m_redirectURL = url;
1741        d->m_redirectLockHistory = doLockHistory;
1742        if ( d->m_bComplete ) {
1743          d->m_redirectionTimer.stop();
1744          d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
1745        }
1746     }
1747 #endif // APPLE_CHANGES
1748 }
1749
1750 void KHTMLPart::slotRedirect()
1751 {
1752   QString u = d->m_redirectURL;
1753   d->m_delayRedirect = 0;
1754   d->m_redirectURL = QString::null;
1755   if ( u.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
1756   {
1757     QString script = KURL::decode_string( u.right( u.length() - 11 ) );
1758     //kdDebug( 6050 ) << "KHTMLPart::slotRedirect script=" << script << endl;
1759     QVariant res = executeScript( script );
1760     if ( res.type() == QVariant::String ) {
1761 #ifndef APPLE_CHANGES
1762       begin( url() );
1763       write( res.asString() );
1764       end();
1765 #endif
1766     }
1767     return;
1768   }
1769 #ifndef APPLE_CHANGES
1770   KParts::URLArgs args;
1771   if ( urlcmp( u, m_url.url(), true, true ) )
1772     args.reload = true;
1773
1774   args.setLockHistory( d->m_redirectLockHistory );
1775   urlSelected( u, 0, 0, "_self", args );
1776 #endif
1777 }
1778
1779 void KHTMLPart::slotRedirection(KIO::Job*, const KURL& url)
1780 {
1781   // the slave told us that we got redirected
1782   // kdDebug( 6050 ) << "redirection by KIO to " << url.url() << endl;
1783   emit d->m_extension->setLocationBarURL( url.prettyURL() );
1784   d->m_workingURL = url;
1785 }
1786
1787 bool KHTMLPart::setEncoding( const QString &name, bool override )
1788 {
1789     d->m_encoding = name;
1790     d->m_haveEncoding = override;
1791
1792 #ifndef APPLE_CHANGES
1793     if( !m_url.isEmpty() ) {
1794         // reload document
1795         closeURL();
1796         KURL url = m_url;
1797         m_url = 0;
1798         d->m_restored = true;
1799         openURL(url);
1800         d->m_restored = false;
1801     }
1802 #endif
1803
1804     return true;
1805 }
1806
1807 QString KHTMLPart::encoding() const
1808 {
1809     if(d->m_haveEncoding && !d->m_encoding.isEmpty())
1810         return d->m_encoding;
1811
1812     if(d->m_decoder && d->m_decoder->encoding())
1813         return QString(d->m_decoder->encoding());
1814
1815     return(settings()->encoding());
1816 }
1817
1818 void KHTMLPart::setUserStyleSheet(const KURL &url)
1819 {
1820 #ifndef APPLE_CHANGES
1821   if ( d->m_doc && d->m_doc->docLoader() )
1822     (void) new khtml::PartStyleSheetLoader(this, url.url(), d->m_doc->docLoader());
1823 #endif
1824 }
1825
1826 void KHTMLPart::setUserStyleSheet(const QString &styleSheet)
1827 {
1828   if ( d->m_doc )
1829     d->m_doc->setUserStyleSheet( styleSheet );
1830 }
1831
1832 bool KHTMLPart::gotoAnchor( const QString &name )
1833 {
1834   if (!d->m_doc)
1835     return false;
1836
1837   HTMLCollectionImpl *anchors =
1838       new HTMLCollectionImpl( d->m_doc, HTMLCollectionImpl::DOC_ANCHORS);
1839   anchors->ref();
1840   NodeImpl *n = anchors->namedItem(name);
1841   anchors->deref();
1842
1843   if(!n) {
1844       kdDebug(6050) << "KHTMLPart::gotoAnchor node '" << name << "' not found" << endl;
1845       return false;
1846   }
1847
1848   int x = 0, y = 0;
1849   HTMLElementImpl *a = static_cast<HTMLElementImpl *>(n);
1850   a->getUpperLeftCorner(x, y);
1851   d->m_view->setContentsPos(x-50, y-50);
1852
1853   return true;
1854 }
1855
1856 void KHTMLPart::setStandardFont( const QString &name )
1857 {
1858     d->m_settings->setStdFontName(name);
1859 }
1860
1861 void KHTMLPart::setFixedFont( const QString &name )
1862 {
1863     d->m_settings->setFixedFontName(name);
1864 }
1865
1866 void KHTMLPart::setURLCursor( const QCursor &c )
1867 {
1868   d->m_linkCursor = c;
1869 }
1870
1871 QCursor KHTMLPart::urlCursor() const
1872 {
1873   return d->m_linkCursor;
1874 }
1875
1876 bool KHTMLPart::onlyLocalReferences() const
1877 {
1878   return d->m_onlyLocalReferences;
1879 }
1880
1881 void KHTMLPart::setOnlyLocalReferences(bool enable)
1882 {
1883   d->m_onlyLocalReferences = enable;
1884 }
1885
1886 #ifndef APPLE_CHANGES
1887
1888 void KHTMLPart::findTextBegin()
1889 {
1890   d->m_findPos = -1;
1891   d->m_findNode = 0;
1892 }
1893
1894 bool KHTMLPart::findTextNext( const QString &str, bool forward, bool caseSensitive, bool isRegExp )
1895 {
1896     if ( !d->m_doc )
1897         return false;
1898
1899     if(!d->m_findNode) {
1900         if (d->m_doc->isHTMLDocument())
1901             d->m_findNode = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
1902         else
1903             d->m_findNode = d->m_doc;
1904     }
1905
1906     if ( !d->m_findNode )
1907     {
1908       kdDebug() << "KHTMLPart::findTextNext no findNode -> return false" << endl;
1909       return false;
1910     }
1911     if ( d->m_findNode->id() == ID_FRAMESET )
1912     {
1913       kdDebug() << "KHTMLPart::findTextNext FRAMESET -> return false" << endl;
1914       return false;
1915     }
1916
1917     while(1)
1918     {
1919         if( (d->m_findNode->nodeType() == Node::TEXT_NODE || d->m_findNode->nodeType() == Node::CDATA_SECTION_NODE) && d->m_findNode->renderer() )
1920         {
1921             DOMString nodeText = d->m_findNode->nodeValue();
1922             DOMStringImpl *t = nodeText.implementation();
1923             QConstString s(t->s, t->l);
1924
1925             int matchLen = 0;
1926             if ( isRegExp ) {
1927               QRegExp matcher( str );
1928               matcher.setCaseSensitive( caseSensitive );
1929               d->m_findPos = matcher.search(s.string(), d->m_findPos+1);
1930               if ( d->m_findPos != -1 )
1931                 matchLen = matcher.matchedLength();
1932             }
1933             else {
1934               d->m_findPos = s.string().find(str, d->m_findPos+1, caseSensitive);
1935               matchLen = str.length();
1936             }
1937
1938             if(d->m_findPos != -1)
1939             {
1940                 int x = 0, y = 0;
1941                 static_cast<khtml::RenderText *>(d->m_findNode->renderer())
1942                   ->posOfChar(d->m_findPos, x, y);
1943                 d->m_view->setContentsPos(x-50, y-50);
1944
1945                 d->m_selectionStart = d->m_findNode;
1946                 d->m_startOffset = d->m_findPos;
1947                 d->m_selectionEnd = d->m_findNode;
1948                 d->m_endOffset = d->m_findPos + matchLen;
1949                 d->m_startBeforeEnd = true;
1950
1951                 d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
1952                                         d->m_selectionEnd.handle(), d->m_endOffset );
1953                 emitSelectionChanged();
1954                 return true;
1955             }
1956         }
1957         d->m_findPos = -1;
1958
1959         NodeImpl *next;
1960
1961         if ( forward )
1962         {
1963           next = d->m_findNode->firstChild();
1964
1965           if(!next) next = d->m_findNode->nextSibling();
1966           while(d->m_findNode && !next) {
1967               d->m_findNode = d->m_findNode->parentNode();
1968               if( d->m_findNode ) {
1969                   next = d->m_findNode->nextSibling();
1970               }
1971           }
1972         }
1973         else
1974         {
1975           next = d->m_findNode->lastChild();
1976
1977           if (!next ) next = d->m_findNode->previousSibling();
1978           while ( d->m_findNode && !next )
1979           {
1980             d->m_findNode = d->m_findNode->parentNode();
1981             if( d->m_findNode )
1982             {
1983               next = d->m_findNode->previousSibling();
1984             }
1985           }
1986         }
1987
1988         d->m_findNode = next;
1989         if(!d->m_findNode) return false;
1990     }
1991 }
1992
1993 #endif
1994
1995 QString KHTMLPart::selectedText() const
1996 {
1997   bool hasNewLine = true;
1998   QString text;
1999   DOM::Node n = d->m_selectionStart;
2000   while(!n.isNull()) {
2001       if(n.nodeType() == DOM::Node::TEXT_NODE) {
2002         QString str = n.nodeValue().string();
2003         hasNewLine = false;
2004         if(n == d->m_selectionStart && n == d->m_selectionEnd)
2005           text = str.mid(d->m_startOffset, d->m_endOffset - d->m_startOffset);
2006         else if(n == d->m_selectionStart)
2007           text = str.mid(d->m_startOffset);
2008         else if(n == d->m_selectionEnd)
2009           text += str.left(d->m_endOffset);
2010         else
2011           text += str;
2012       }
2013       else {
2014         // This is our simple HTML -> ASCII transformation:
2015         unsigned short id = n.elementId();
2016         switch(id) {
2017           case ID_BR:
2018             text += "\n";
2019             hasNewLine = true;
2020             break;
2021
2022           case ID_TD:
2023           case ID_TH:
2024           case ID_HR:
2025           case ID_OL:
2026           case ID_UL:
2027           case ID_LI:
2028           case ID_DD:
2029           case ID_DL:
2030           case ID_DT:
2031           case ID_PRE:
2032           case ID_BLOCKQUOTE:
2033           case ID_DIV:
2034             if (!hasNewLine)
2035                text += "\n";
2036             hasNewLine = true;
2037             break;
2038           case ID_P:
2039           case ID_TR:
2040           case ID_H1:
2041           case ID_H2:
2042           case ID_H3:
2043           case ID_H4:
2044           case ID_H5:
2045           case ID_H6:
2046             if (!hasNewLine)
2047                text += "\n";
2048             text += "\n";
2049             hasNewLine = true;
2050             break;
2051         }
2052       }
2053       if(n == d->m_selectionEnd) break;
2054       DOM::Node next = n.firstChild();
2055       if(next.isNull()) next = n.nextSibling();
2056       while( next.isNull() && !n.parentNode().isNull() ) {
2057         n = n.parentNode();
2058         next = n.nextSibling();
2059         unsigned short id = n.elementId();
2060         switch(id) {
2061           case ID_TD:
2062           case ID_TH:
2063           case ID_HR:
2064           case ID_OL:
2065           case ID_UL:
2066           case ID_LI:
2067           case ID_DD:
2068           case ID_DL:
2069           case ID_DT:
2070           case ID_PRE:
2071           case ID_BLOCKQUOTE:
2072           case ID_DIV:
2073             if (!hasNewLine)
2074                text += "\n";
2075             hasNewLine = true;
2076             break;
2077           case ID_P:
2078           case ID_TR:
2079           case ID_H1:
2080           case ID_H2:
2081           case ID_H3:
2082           case ID_H4:
2083           case ID_H5:
2084           case ID_H6:
2085             if (!hasNewLine)
2086                text += "\n";
2087             // An extra newline is needed at the start, not the end, of these types of tags,
2088             // so don't add another here.
2089             hasNewLine = true;
2090             break;
2091         }
2092       }
2093
2094       n = next;
2095     }
2096     int start = 0;
2097     int end = text.length();
2098
2099     // Strip leading LFs
2100     while ((start < end) && (text[start] == '\n'))
2101        start++;
2102
2103     // Strip excessive trailing LFs
2104     while ((start < (end-1)) && (text[end-1] == '\n') && (text[end-2] == '\n'))
2105        end--;
2106        
2107     return text.mid(start, end-start);
2108 }
2109
2110 bool KHTMLPart::hasSelection() const
2111 {
2112   return ( !d->m_selectionStart.isNull() &&
2113            !d->m_selectionEnd.isNull() );
2114 }
2115
2116 DOM::Range KHTMLPart::selection() const
2117 {
2118     DOM::Range r = document().createRange();DOM::Range();
2119     r.setStart( d->m_selectionStart, d->m_startOffset );
2120     r.setEnd( d->m_selectionEnd, d->m_endOffset );
2121     return r;
2122 }
2123
2124
2125 void KHTMLPart::setSelection( const DOM::Range &r )
2126 {
2127     d->m_selectionStart = r.startContainer();
2128     d->m_startOffset = r.startOffset();
2129     d->m_selectionEnd = r.endContainer();
2130     d->m_endOffset = r.endOffset();
2131     d->m_doc->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
2132                            d->m_selectionEnd.handle(),d->m_endOffset);
2133 }
2134
2135 void KHTMLPart::slotClearSelection()
2136 {
2137     d->m_selectionStart = 0;
2138     d->m_startOffset = 0;
2139     d->m_selectionEnd = 0;
2140     d->m_endOffset = 0;
2141     if ( d->m_doc ) d->m_doc->clearSelection();
2142     emitSelectionChanged();
2143 }
2144
2145 #ifdef APPLE_CHANGES
2146 void KHTMLPart::overURL( const QString &url, const QString &target, int modifierState )
2147 #else
2148 void KHTMLPart::overURL( const QString &url, const QString &target, bool shiftPressed )
2149 #endif
2150 {
2151 #ifdef APPLE_CHANGES
2152   impl->overURL(url, target, modifierState);
2153 #else
2154   if ( !d->m_kjsStatusBarText.isEmpty() && !shiftPressed ) {
2155     emit onURL( url );
2156     emit setStatusBarText( d->m_kjsStatusBarText );
2157     d->m_kjsStatusBarText = QString::null;
2158     return;
2159   }
2160
2161   emit onURL( url );
2162
2163   if ( url.isEmpty() )
2164   {
2165     emit setStatusBarText(completeURL(url).htmlURL());
2166     return;
2167   }
2168
2169   if (url.find( QString::fromLatin1( "javascript:" ),0, false ) != -1 )
2170   {
2171     emit setStatusBarText( url.mid( url.find( "javascript:", 0, false ) ) );
2172     return;
2173   }
2174
2175   KURL u = completeURL(url);
2176
2177   // special case for <a href="">
2178   if ( url.isEmpty() )
2179     u.setFileName( url );
2180
2181   QString com;
2182
2183   KMimeType::Ptr typ = KMimeType::findByURL( u );
2184
2185   if ( typ )
2186     com = typ->comment( u, false );
2187
2188   if ( u.isMalformed() )
2189   {
2190     emit setStatusBarText(u.htmlURL());
2191     return;
2192   }
2193
2194   if ( u.isLocalFile() )
2195   {
2196     // TODO : use KIO::stat() and create a KFileItem out of its result,
2197     // to use KFileItem::statusBarText()
2198     QCString path = QFile::encodeName( u.path() );
2199
2200     struct stat buff;
2201     bool ok = !stat( path.data(), &buff );
2202
2203     struct stat lbuff;
2204     if (ok) ok = !lstat( path.data(), &lbuff );
2205
2206     QString text = u.htmlURL();
2207     QString text2 = text;
2208
2209     if (ok && S_ISLNK( lbuff.st_mode ) )
2210     {
2211       QString tmp;
2212       if ( com.isNull() )
2213         tmp = i18n( "Symbolic Link");
2214       else
2215         tmp = i18n("%1 (Link)").arg(com);
2216       char buff_two[1024];
2217       text += " -> ";
2218       int n = readlink ( path.data(), buff_two, 1022);
2219       if (n == -1)
2220       {
2221         text2 += "  ";
2222         text2 += tmp;
2223         emit setStatusBarText(text2);
2224         return;
2225       }
2226       buff_two[n] = 0;
2227
2228       text += buff_two;
2229       text += "  ";
2230       text += tmp;
2231     }
2232     else if ( ok && S_ISREG( buff.st_mode ) )
2233     {
2234       if (buff.st_size < 1024)
2235         text = i18n("%2 (%1 bytes)").arg((long) buff.st_size).arg(text2); // always put the URL last, in case it contains '%'
2236       else
2237       {
2238         float d = (float) buff.st_size/1024.0;
2239         text = i18n("%1 (%2 K)").arg(text2).arg(KGlobal::locale()->formatNumber(d, 2)); // was %.2f
2240       }
2241       text += "  ";
2242       text += com;
2243     }
2244     else if ( ok && S_ISDIR( buff.st_mode ) )
2245     {
2246       text += "  ";
2247       text += com;
2248     }
2249     else
2250     {
2251       text += "  ";
2252       text += com;
2253     }
2254     emit setStatusBarText(text);
2255   }
2256   else
2257   {
2258     QString extra;
2259     if (target == QString::fromLatin1("_blank"))
2260     {
2261       extra = i18n(" (In new window)");
2262     }
2263     else if (!target.isEmpty() &&
2264              (target != QString::fromLatin1("_top")) &&
2265              (target != QString::fromLatin1("_self")) &&
2266              (target != QString::fromLatin1("_parent")))
2267     {
2268       extra = i18n(" (In other frame)");
2269     }
2270
2271     if (u.protocol() == QString::fromLatin1("mailto")) {
2272       QString mailtoMsg/* = QString::fromLatin1("<img src=%1>").arg(locate("icon", QString::fromLatin1("locolor/16x16/actions/mail_send.png")))*/;
2273       mailtoMsg += i18n("Email to: ") + KURL::decode_string(u.path());
2274       QStringList queries = QStringList::split('&', u.query().mid(1));
2275       for (QStringList::Iterator it = queries.begin(); it != queries.end(); ++it)
2276         if ((*it).startsWith(QString::fromLatin1("subject=")))
2277           mailtoMsg += i18n(" - Subject: ") + KURL::decode_string((*it).mid(8));
2278         else if ((*it).startsWith(QString::fromLatin1("cc=")))
2279           mailtoMsg += i18n(" - CC: ") + KURL::decode_string((*it).mid(3));
2280         else if ((*it).startsWith(QString::fromLatin1("bcc=")))
2281           mailtoMsg += i18n(" - BCC: ") + KURL::decode_string((*it).mid(4));
2282       mailtoMsg.replace(QRegExp("&"), QString("&amp;"));
2283       mailtoMsg.replace(QRegExp("<"), QString("&lt;"));
2284       mailtoMsg.replace(QRegExp(">"), QString("&gt;"));
2285       mailtoMsg.replace(QRegExp("([\n\r\t]|[ ]{10})"), "");
2286       emit setStatusBarText(mailtoMsg);
2287       return;
2288     }
2289    // Is this check neccessary at all? (Frerich)
2290 #if 0
2291     else if (u.protocol() == QString::fromLatin1("http")) {
2292         DOM::Node hrefNode = nodeUnderMouse().parentNode();
2293         while (hrefNode.nodeName().string() != QString::fromLatin1("A") && !hrefNode.isNull())
2294           hrefNode = hrefNode.parentNode();
2295
2296         if (!hrefNode.isNull()) {
2297           DOM::Node hreflangNode = hrefNode.attributes().getNamedItem("HREFLANG");
2298           if (!hreflangNode.isNull()) {
2299             QString countryCode = hreflangNode.nodeValue().string().lower();
2300             // Map the language code to an appropriate country code.
2301             if (countryCode == QString::fromLatin1("en"))
2302               countryCode = QString::fromLatin1("gb");
2303             QString flagImg = QString::fromLatin1("<img src=%1>").arg(
2304                 locate("locale", QString::fromLatin1("l10n/")
2305                 + countryCode
2306                 + QString::fromLatin1("/flag.png")));
2307             emit setStatusBarText(flagImg + u.prettyURL() + extra);
2308           }
2309         }
2310       }
2311 #endif
2312     emit setStatusBarText(u.htmlURL() + extra);
2313   }
2314 #endif
2315 }
2316
2317 void KHTMLPart::urlSelected( const QString &url, int button, int state, const QString &_target,
2318                              KParts::URLArgs args )
2319 {
2320 #ifdef APPLE_CHANGES
2321   impl->urlSelected(url, button, state, _target, args);
2322 #else
2323   bool hasTarget = false;
2324
2325   QString target = _target;
2326   if ( target.isEmpty() && d->m_doc )
2327     target = d->m_doc->baseTarget();
2328   if ( !target.isEmpty() )
2329       hasTarget = true;
2330
2331   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
2332   {
2333     executeScript( url.right( url.length() - 11) );
2334     return;
2335   }
2336
2337   KURL cURL = completeURL(url);
2338   // special case for <a href="">
2339   if ( url.isEmpty() )
2340     cURL.setFileName( url );
2341
2342   if ( !cURL.isValid() )
2343     // ### ERROR HANDLING
2344     return;
2345
2346   //kdDebug( 6000 ) << "urlSelected: complete URL:" << cURL.url() << " target = " << target << endl;
2347
2348   if ( button == LeftButton && ( state & ShiftButton ) )
2349   {
2350     KIO::MetaData metaData;
2351     metaData["referrer"] = d->m_referrer;
2352     KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As..." ), cURL, metaData );
2353     return;
2354   }
2355
2356   if (!checkLinkSecurity(cURL,
2357                          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?" ),
2358                          i18n( "Follow" )))
2359     return;
2360
2361   args.frameName = target;
2362
2363   if ( d->m_bHTTPRefresh )
2364   {
2365     d->m_bHTTPRefresh = false;
2366     args.metaData()["cache"] = "refresh";
2367   }
2368
2369   args.metaData().insert("main_frame_request",
2370                          parentPart() == 0 ? "TRUE":"FALSE");
2371   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
2372   args.metaData().insert("ssl_activate_warnings", "TRUE");
2373
2374   if ( hasTarget )
2375   {
2376     // unknown frame names should open in a new window.
2377     khtml::ChildFrame *frame = recursiveFrameRequest( cURL, args, false );
2378     if ( frame )
2379     {
2380       args.metaData()["referrer"] = d->m_referrer;
2381       requestObject( frame, cURL, args );
2382       return;
2383     }
2384   }
2385
2386   if ( !d->m_bComplete && !hasTarget )
2387     closeURL();
2388
2389   if (!d->m_referrer.isEmpty())
2390     args.metaData()["referrer"] = d->m_referrer;
2391
2392   if ( button == MidButton && (state & ShiftButton) )
2393   {
2394     KParts::WindowArgs winArgs;
2395     winArgs.lowerWindow = true;
2396     KParts::ReadOnlyPart *newPart = 0;
2397     emit d->m_extension->createNewWindow( cURL, args, winArgs, newPart );
2398     return;
2399   }
2400   emit d->m_extension->openURLRequest( cURL, args );
2401 #endif // APPLE_CHANGES
2402 }
2403
2404 #ifndef APPLE_CHANGES
2405
2406 void KHTMLPart::slotViewDocumentSource()
2407 {
2408   KURL url(m_url);
2409   if (!(url.isLocalFile()) && KHTMLPageCache::self()->isValid(d->m_cacheId))
2410   {
2411      KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
2412      if (sourceFile.status() == 0)
2413      {
2414         KHTMLPageCache::self()->saveData(d->m_cacheId, sourceFile.dataStream());
2415         url = KURL();
2416         url.setPath(sourceFile.name());
2417      }
2418   }
2419
2420   //  emit d->m_extension->openURLRequest( m_url, KParts::URLArgs( false, 0, 0, QString::fromLatin1( "text/plain" ) ) );
2421   (void) KRun::runURL( url, QString::fromLatin1("text/plain") );
2422 }
2423
2424 void KHTMLPart::slotViewFrameSource()
2425 {
2426   KParts::ReadOnlyPart *frame = currentFrame();
2427   if ( !frame )
2428     return;
2429
2430   KURL url = frame->url();
2431   if (!(url.isLocalFile()) && frame->inherits("KHTMLPart"))
2432   {
2433        long cacheId = static_cast<KHTMLPart *>(frame)->d->m_cacheId;
2434
2435        if (KHTMLPageCache::self()->isValid(cacheId))
2436        {
2437            KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
2438            if (sourceFile.status() == 0)
2439            {
2440                KHTMLPageCache::self()->saveData(cacheId, sourceFile.dataStream());
2441                url = KURL();
2442                url.setPath(sourceFile.name());
2443            }
2444      }
2445   }
2446
2447   (void) KRun::runURL( url, QString::fromLatin1("text/plain") );
2448 }
2449
2450 KURL KHTMLPart::backgroundURL() const
2451 {
2452   // ### what about XML documents? get from CSS?
2453   if (!d->m_doc || !d->m_doc->isHTMLDocument())
2454     return KURL();
2455
2456   QString relURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
2457
2458   return KURL( m_url, relURL );
2459 }
2460
2461 void KHTMLPart::slotSaveBackground()
2462 {
2463   KIO::MetaData metaData;
2464   metaData["referrer"] = d->m_referrer;
2465   KHTMLPopupGUIClient::saveURL( d->m_view, i18n("Save background image as"), backgroundURL(), metaData );
2466 }
2467
2468 void KHTMLPart::slotSaveDocument()
2469 {
2470   KURL srcURL( m_url );
2471
2472   if ( srcURL.fileName(false).isEmpty() )
2473     srcURL.setFileName( "index.html" );
2474
2475   KIO::MetaData metaData;
2476   // Referre unknown?
2477   KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, i18n("*.html *.htm|HTML files"), d->m_cacheId );
2478 }
2479
2480 void KHTMLPart::slotSecurity()
2481 {
2482 //   kdDebug( 6050 ) << "Meta Data:" << endl
2483 //                   << d->m_ssl_peer_cert_subject
2484 //                   << endl
2485 //                   << d->m_ssl_peer_cert_issuer
2486 //                   << endl
2487 //                   << d->m_ssl_cipher
2488 //                   << endl
2489 //                   << d->m_ssl_cipher_desc
2490 //                   << endl
2491 //                   << d->m_ssl_cipher_version
2492 //                   << endl
2493 //                   << d->m_ssl_good_from
2494 //                   << endl
2495 //                   << d->m_ssl_good_until
2496 //                   << endl
2497 //                   << d->m_ssl_cert_state
2498 //                   << endl;
2499
2500   KSSLInfoDlg *kid = new KSSLInfoDlg(d->m_ssl_in_use, widget(), "kssl_info_dlg", true );
2501
2502   if (d->m_bSecurityInQuestion)
2503           kid->setSecurityInQuestion(true);
2504
2505   if (d->m_ssl_in_use) {
2506     KSSLCertificate *x = KSSLCertificate::fromString(d->m_ssl_peer_certificate.local8Bit());
2507     if (x) {
2508        // Set the chain back onto the certificate
2509        QStringList cl = QStringList::split(QString("\n"), d->m_ssl_peer_chain);
2510        QPtrList<KSSLCertificate> ncl;
2511
2512        ncl.setAutoDelete(true);
2513        for (QStringList::Iterator it = cl.begin(); it != cl.end(); ++it) {
2514           KSSLCertificate *y = KSSLCertificate::fromString((*it).local8Bit());
2515           if (y) ncl.append(y);
2516        }
2517
2518        if (ncl.count() > 0)
2519           x->chain().setChain(ncl);
2520
2521        kid->setup(x,
2522                   d->m_ssl_peer_ip,
2523                   m_url.url(),
2524                   d->m_ssl_cipher,
2525                   d->m_ssl_cipher_desc,
2526                   d->m_ssl_cipher_version,
2527                   d->m_ssl_cipher_used_bits.toInt(),
2528                   d->m_ssl_cipher_bits.toInt(),
2529                   (KSSLCertificate::KSSLValidation) d->m_ssl_cert_state.toInt()
2530                   );
2531         kid->exec();
2532         delete x;
2533      } else kid->exec();
2534   } else kid->exec();
2535 }
2536
2537 void KHTMLPart::slotSaveFrame()
2538 {
2539     if ( !d->m_activeFrame )
2540         return; // should never be the case, but one never knows :-)
2541
2542     KURL srcURL( static_cast<KParts::ReadOnlyPart *>( d->m_activeFrame )->url() );
2543
2544     if ( srcURL.fileName(false).isEmpty() )
2545         srcURL.setFileName( "index.html" );
2546
2547     KIO::MetaData metaData;
2548     // Referrer unknown?
2549     KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, i18n("*.html *.htm|HTML files") );
2550 }
2551
2552 void KHTMLPart::slotSetEncoding()
2553 {
2554     // first Item is always auto
2555     if(d->m_paSetEncoding->currentItem() == 0)
2556         setEncoding(QString::null, false);
2557     else {
2558         // strip of the language to get the raw encoding again.
2559         QString enc = KGlobal::charsets()->encodingForName(d->m_paSetEncoding->currentText());
2560         setEncoding(enc, true);
2561     }
2562 }
2563
2564 void KHTMLPart::slotUseStylesheet()
2565 {
2566   if (d->m_doc && d->m_paUseStylesheet->currentText() != d->m_sheetUsed) {
2567     d->m_sheetUsed = d->m_paUseStylesheet->currentText();
2568     d->m_doc->updateStyleSelector();
2569   }
2570 }
2571
2572 void KHTMLPart::updateActions()
2573 {
2574   bool frames = false;
2575
2576   QValueList<khtml::ChildFrame>::ConstIterator it = d->m_frames.begin();
2577   QValueList<khtml::ChildFrame>::ConstIterator end = d->m_frames.end();
2578   for (; it != end; ++it )
2579       if ( (*it).m_type == khtml::ChildFrame::Frame )
2580       {
2581           frames = true;
2582           break;
2583       }
2584
2585   d->m_paViewFrame->setEnabled( frames );
2586   d->m_paSaveFrame->setEnabled( frames );
2587
2588   if ( frames )
2589     d->m_paFind->setText( i18n( "&Find in Frame..." ) );
2590   else
2591     d->m_paFind->setText( i18n( "&Find..." ) );
2592
2593   KParts::Part *frame = 0;
2594
2595   if ( frames )
2596     frame = currentFrame();
2597
2598   bool enableFindAndSelectAll = true;
2599
2600   if ( frame )
2601     enableFindAndSelectAll = frame->inherits( "KHTMLPart" );
2602
2603   d->m_paFind->setEnabled( enableFindAndSelectAll );
2604   d->m_paSelectAll->setEnabled( enableFindAndSelectAll );
2605
2606   bool enablePrintFrame = false;
2607
2608   if ( frame )
2609   {
2610     QObject *ext = KParts::BrowserExtension::childObject( frame );
2611     if ( ext )
2612       enablePrintFrame = ext->metaObject()->slotNames().contains( "print()" );
2613   }
2614
2615   d->m_paPrintFrame->setEnabled( enablePrintFrame );
2616
2617   QString bgURL;
2618
2619   // ### frames
2620   if ( d->m_doc && d->m_doc->isHTMLDocument() && static_cast<HTMLDocumentImpl*>(d->m_doc)->body() && !d->m_bClearing )
2621     bgURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
2622
2623   d->m_paSaveBackground->setEnabled( !bgURL.isEmpty() );
2624 }
2625
2626 #endif
2627
2628 bool KHTMLPart::requestFrame( khtml::RenderPart *frame, const QString &url, const QString &frameName,
2629                               const QStringList &params, bool isIFrame )
2630 {
2631 #ifdef APPLE_CHANGES
2632   return impl->requestFrame(frame, url, frameName, params, isIFrame);
2633 #else
2634 //  kdDebug( 6050 ) << "childRequest( ..., " << url << ", " << frameName << " )" << endl;
2635   FrameIt it = d->m_frames.find( frameName );
2636   if ( it == d->m_frames.end() )
2637   {
2638     khtml::ChildFrame child;
2639 //    kdDebug( 6050 ) << "inserting new frame into frame map " << frameName << endl;
2640     child.m_name = frameName;
2641     it = d->m_frames.append( child );
2642   }
2643
2644   (*it).m_type = isIFrame ? khtml::ChildFrame::IFrame : khtml::ChildFrame::Frame;
2645   (*it).m_frame = frame;
2646   (*it).m_params = params;
2647
2648   // Support for <frame src="javascript:string">
2649   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
2650   {
2651       QVariant res = executeScript( DOM::Node(frame->element()), url.right( url.length() - 11) );
2652       KURL myurl;
2653       myurl.setProtocol("javascript");
2654       if ( res.type() == QVariant::String )
2655         myurl.setPath(res.asString());
2656       return processObjectRequest(&(*it), myurl, QString("text/html") );
2657   }
2658   return requestObject( &(*it), completeURL( url ));
2659 #endif // APPLE_CHANGES
2660 }
2661
2662 QString KHTMLPart::requestFrameName()
2663 {
2664    return QString::fromLatin1("<!--frame %1-->").arg(d->m_frameNameId++);
2665 }
2666
2667 bool KHTMLPart::requestObject( khtml::RenderPart *frame, const QString &url, const QString &serviceType,
2668                                const QStringList &params )
2669 {
2670 #ifdef APPLE_CHANGES
2671   return impl->requestObject(frame, url, serviceType, params);
2672 #else
2673   if (url.isEmpty())
2674     return false;
2675   khtml::ChildFrame child;
2676   QValueList<khtml::ChildFrame>::Iterator it = d->m_objects.append( child );
2677   (*it).m_frame = frame;
2678   (*it).m_type = khtml::ChildFrame::Object;
2679   (*it).m_params = params;
2680
2681   KParts::URLArgs args;
2682   args.serviceType = serviceType;
2683   return requestObject( &(*it), completeURL( url ), args );
2684 #endif
2685 }
2686
2687 bool KHTMLPart::requestObject( khtml::ChildFrame *child, const KURL &url, const KParts::URLArgs &_args )
2688 {
2689 #ifdef APPLE_CHANGES
2690   return false;
2691 #else
2692   if (!checkLinkSecurity(url))
2693     return false;
2694   if ( child->m_bPreloaded )
2695   {
2696     // kdDebug(6005) << "KHTMLPart::requestObject preload" << endl;
2697     if ( child->m_frame && child->m_part )
2698       child->m_frame->setWidget( child->m_part->widget() );
2699
2700     child->m_bPreloaded = false;
2701     return true;
2702   }
2703
2704   KParts::URLArgs args( _args );
2705
2706   if ( child->m_run )
2707     child->m_run->abort();
2708
2709   if ( child->m_part && !args.reload && urlcmp( child->m_part->url().url(), url.url(), true, true ) )
2710     args.serviceType = child->m_serviceType;
2711
2712   child->m_args = args;
2713   child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload) || (d->m_cachePolicy == KIO::CC_Refresh);
2714   child->m_serviceName = QString::null;
2715   if (!d->m_referrer.isEmpty() && !child->m_args.metaData().contains( "referrer" ))
2716     child->m_args.metaData()["referrer"] = d->m_referrer;
2717
2718   child->m_args.metaData().insert("main_frame_request",
2719                                   parentPart() == 0 ? "TRUE":"FALSE");
2720   child->m_args.metaData().insert("ssl_was_in_use",
2721                                   d->m_ssl_in_use ? "TRUE":"FALSE");
2722   child->m_args.metaData().insert("ssl_activate_warnings", "TRUE");
2723
2724   // We want a KHTMLPart if the HTML says <frame src=""> or <frame src="about:blank">
2725   if ((url.isEmpty() || url.url() == "about:blank") && args.serviceType.isEmpty())
2726     args.serviceType = QString::fromLatin1( "text/html" );
2727
2728   if ( args.serviceType.isEmpty() ) {
2729     child->m_run = new KHTMLRun( this, child, url, child->m_args,
2730                                  child->m_type != khtml::ChildFrame::Frame );
2731     return false;
2732   } else {
2733     return processObjectRequest( child, url, args.serviceType );
2734   }
2735 #endif
2736 }
2737
2738 #ifndef APPLE_CHANGES
2739
2740 bool KHTMLPart::processObjectRequest( khtml::ChildFrame *child, const KURL &_url, const QString &mimetype )
2741 {
2742   //kdDebug( 6050 ) << "KHTMLPart::processObjectRequest trying to create part for " << mimetype << endl;
2743
2744   // IMPORTANT: create a copy of the url here, because it is just a reference, which was likely to be given
2745   // by an emitting frame part (emit openURLRequest( blahurl, ... ) . A few lines below we delete the part
2746   // though -> the reference becomes invalid -> crash is likely
2747   KURL url( _url );
2748
2749   // khtmlrun called us this way to indicate a loading error
2750   if ( d->m_onlyLocalReferences || ( url.isEmpty() && mimetype.isEmpty() ) )
2751   {
2752       checkEmitLoadEvent();
2753       child->m_bCompleted = true;
2754       return true;
2755   }
2756
2757   if (child->m_bNotify)
2758   {
2759       child->m_bNotify = false;
2760       if ( !child->m_args.lockHistory() )
2761           emit d->m_extension->openURLNotify();
2762   }
2763
2764   if ( !child->m_services.contains( mimetype ) )
2765   {
2766     KParts::ReadOnlyPart *part = createPart( d->m_view->viewport(), child->m_name.ascii(), this, child->m_name.ascii(), mimetype, child->m_serviceName, child->m_services, child->m_params );
2767
2768     if ( !part )
2769     {
2770         if ( child->m_frame )
2771           if (child->m_frame->partLoadingErrorNotify( child, url, mimetype ))
2772             return true; // we succeeded after all (a fallback was used)
2773
2774         checkEmitLoadEvent();
2775         return false;
2776     }
2777
2778     //CRITICAL STUFF
2779     if ( child->m_part )
2780     {
2781       partManager()->removePart( (KParts::ReadOnlyPart *)child->m_part );
2782       delete (KParts::ReadOnlyPart *)child->m_part;
2783     }
2784
2785     child->m_serviceType = mimetype;
2786     if ( child->m_frame )
2787       child->m_frame->setWidget( part->widget() );
2788
2789     if ( child->m_type != khtml::ChildFrame::Object )
2790       partManager()->addPart( part, false );
2791 //  else
2792 //      kdDebug(6005) << "AH! NO FRAME!!!!!" << endl;
2793
2794     child->m_part = part;
2795     assert( ((void*) child->m_part) != 0);
2796
2797     if ( child->m_type != khtml::ChildFrame::Object )
2798     {
2799       connect( part, SIGNAL( started( KIO::Job *) ),
2800                this, SLOT( slotChildStarted( KIO::Job *) ) );
2801       connect( part, SIGNAL( completed() ),
2802                this, SLOT( slotChildCompleted() ) );
2803       connect( part, SIGNAL( completed(bool) ),
2804                this, SLOT( slotChildCompleted(bool) ) );
2805       connect( part, SIGNAL( setStatusBarText( const QString & ) ),
2806                this, SIGNAL( setStatusBarText( const QString & ) ) );
2807       connect( this, SIGNAL( completed() ),
2808                part, SLOT( slotParentCompleted() ) );
2809       connect( this, SIGNAL( completed(bool) ),
2810                part, SLOT( slotParentCompleted() ) );
2811     }
2812
2813     child->m_extension = KParts::BrowserExtension::childObject( part );
2814
2815     if ( child->m_extension )
2816     {
2817       connect( child->m_extension, SIGNAL( openURLNotify() ),
2818                d->m_extension, SIGNAL( openURLNotify() ) );
2819
2820       connect( child->m_extension, SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ),
2821                this, SLOT( slotChildURLRequest( const KURL &, const KParts::URLArgs & ) ) );
2822
2823       connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ),
2824                d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ) );
2825       connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs &, const KParts::WindowArgs &, KParts::ReadOnlyPart *& ) ),
2826                d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & , const KParts::WindowArgs &, KParts::ReadOnlyPart *&) ) );
2827
2828       connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ),
2829                d->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ) );
2830       connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ),
2831                d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ) );
2832       connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ),
2833                d->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ) );
2834       connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ),
2835                d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ) );
2836
2837       connect( child->m_extension, SIGNAL( infoMessage( const QString & ) ),
2838                d->m_extension, SIGNAL( infoMessage( const QString & ) ) );
2839
2840       child->m_extension->setBrowserInterface( d->m_extension->browserInterface() );
2841     }
2842   }
2843
2844   checkEmitLoadEvent();
2845   // Some JS code in the load event may have destroyed the part
2846   // In that case, abort
2847   if ( !child->m_part )
2848     return false;
2849
2850   if ( child->m_bPreloaded )
2851   {
2852     if ( child->m_frame && child->m_part )
2853       child->m_frame->setWidget( child->m_part->widget() );
2854
2855     child->m_bPreloaded = false;
2856     return true;
2857   }
2858
2859   child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload) || (d->m_cachePolicy == KIO::CC_Refresh);
2860
2861   // make sure the part has a way to find out about the mimetype.
2862   // we actually set it in child->m_args in requestObject already,
2863   // but it's useless if we had to use a KHTMLRun instance, as the
2864   // point the run object is to find out exactly the mimetype.
2865   child->m_args.serviceType = mimetype;
2866
2867   child->m_bCompleted = false;
2868   if ( child->m_extension )
2869     child->m_extension->setURLArgs( child->m_args );
2870
2871   if(url.protocol() == "javascript" || url.url() == "about:blank") {
2872       if (!child->m_part->inherits("KHTMLPart"))
2873           return false;
2874
2875       KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>(child->m_part));
2876
2877       p->begin();
2878       if (d->m_doc && p->d->m_doc)
2879         p->d->m_doc->setBaseURL(d->m_doc->baseURL());
2880       if (!url.url().startsWith("about:")) {
2881         p->write(url.path());
2882       } else {
2883         p->m_url = url;
2884       }
2885       p->end();
2886       return true;
2887   }
2888   else if ( !url.isEmpty() )
2889   {
2890       //kdDebug( 6050 ) << "opening " << url.url() << " in frame " << child->m_part << endl;
2891       return child->m_part->openURL( url );
2892   }
2893   else
2894       return true;
2895 }
2896
2897 KParts::ReadOnlyPart *KHTMLPart::createPart( QWidget *parentWidget, const char *widgetName,
2898                                              QObject *parent, const char *name, const QString &mimetype,
2899                                              QString &serviceName, QStringList &serviceTypes,
2900                                              const QStringList &params )
2901 {
2902   QString constr;
2903   if ( !serviceName.isEmpty() )
2904     constr.append( QString::fromLatin1( "Name == '%1'" ).arg( serviceName ) );
2905
2906   KTrader::OfferList offers = KTrader::self()->query( mimetype, "KParts/ReadOnlyPart", constr, QString::null );
2907
2908   if ( offers.isEmpty() )
2909     return 0L;
2910
2911   KService::Ptr service = *offers.begin();
2912
2913   KLibFactory *factory = KLibLoader::self()->factory( QFile::encodeName(service->library()) );
2914
2915   if ( !factory )
2916     return 0L;
2917
2918   KParts::ReadOnlyPart *res = 0L;
2919
2920   const char *className = "KParts::ReadOnlyPart";
2921   if ( service->serviceTypes().contains( "Browser/View" ) )
2922     className = "Browser/View";
2923
2924   if ( factory->inherits( "KParts::Factory" ) )
2925     res = static_cast<KParts::ReadOnlyPart *>(static_cast<KParts::Factory *>( factory )->createPart( parentWidget, widgetName, parent, name, className, params ));
2926   else
2927   res = static_cast<KParts::ReadOnlyPart *>(factory->create( parentWidget, widgetName, className ));
2928
2929   if ( !res )
2930     return res;
2931
2932   serviceTypes = service->serviceTypes();
2933   serviceName = service->name();
2934
2935   return res;
2936 }
2937
2938 KParts::PartManager *KHTMLPart::partManager()
2939 {
2940   if ( !d->m_manager )
2941   {
2942     d->m_manager = new KParts::PartManager( d->m_view->topLevelWidget(), this, "khtml part manager" );
2943     d->m_manager->setAllowNestedParts( true );
2944     connect( d->m_manager, SIGNAL( activePartChanged( KParts::Part * ) ),
2945              this, SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
2946     connect( d->m_manager, SIGNAL( partRemoved( KParts::Part * ) ),
2947              this, SLOT( slotPartRemoved( KParts::Part * ) ) );
2948   }
2949
2950   return d->m_manager;
2951 }
2952
2953 #endif
2954
2955 void KHTMLPart::submitFormAgain()
2956 {
2957   if( d->m_doc && !d->m_doc->parsing() && d->m_submitForm)
2958     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 );
2959
2960   delete d->m_submitForm;
2961   d->m_submitForm = 0;
2962   disconnect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
2963 }
2964
2965 void KHTMLPart::submitForm( const char *action, const QString &url, const QByteArray &formData, const QString &_target, const QString& contentType, const QString& boundary )
2966 {
2967 #ifdef APPLE_CHANGES
2968   impl->submitForm(action, url, formData, _target, contentType, boundary);
2969 #else
2970   kdDebug(6000) << this << ": KHTMLPart::submitForm target=" << _target << " url=" << url << endl;
2971   KURL u = completeURL( url );
2972
2973   if ( !u.isValid() )
2974   {
2975     // ### ERROR HANDLING!
2976     return;
2977   }
2978
2979   // Form security checks
2980   //
2981
2982   /* This is separate for a reason.  It has to be _before_ all script, etc,
2983    * AND I don't want to break anything that uses checkLinkSecurity() in
2984    * other places.
2985    */
2986
2987   // This causes crashes... needs to be fixed.
2988   if (!d->m_submitForm && u.protocol() != "https" && u.protocol() != "mailto") {
2989         if (d->m_ssl_in_use) {    // Going from SSL -> nonSSL
2990                 int rc = KMessageBox::warningContinueCancel(NULL, i18n("Warning:  This is a secure form but it is attempting to send your data back unencrypted."
2991                                         "\nA third party may be able to intercept and view this information."
2992                                         "\nAre you sure you wish to continue?"),
2993                                 i18n("SSL"));
2994                 if (rc == KMessageBox::Cancel)
2995                         return;
2996         } else {                  // Going from nonSSL -> nonSSL
2997                 KSSLSettings kss(true);
2998                 if (kss.warnOnUnencrypted()) {
2999                         int rc = KMessageBox::warningContinueCancel(NULL,
3000                                         i18n("Warning: Your data is about to be transmitted across the network unencrypted."
3001                                         "\nAre you sure you wish to continue?"),
3002                                         i18n("KDE"),
3003                                                                     QString::null,
3004                                         "WarnOnUnencryptedForm");
3005                         // Move this setting into KSSL instead
3006                         KConfig *config = kapp->config();
3007                         QString grpNotifMsgs = QString::fromLatin1("Notification Messages");
3008                         KConfigGroupSaver saver( config, grpNotifMsgs );
3009
3010                         if (!config->readBoolEntry("WarnOnUnencryptedForm", true)) {
3011                                 config->deleteEntry("WarnOnUnencryptedForm");
3012                                 config->sync();
3013                                 kss.setWarnOnUnencrypted(false);
3014                                 kss.save();
3015                         }
3016                         if (rc == KMessageBox::Cancel)
3017                           return;
3018         }
3019     }
3020   }
3021
3022   if (!d->m_submitForm && u.protocol() == "mailto") {
3023      int rc = KMessageBox::warningContinueCancel(NULL, 
3024                  i18n("This site is attempting to submit form data via email."),
3025                  i18n("KDE"), 
3026                  QString::null, 
3027                  "WarnTriedEmailSubmit");
3028
3029      if (rc == KMessageBox::Cancel) {
3030          return;
3031      }
3032   }
3033
3034   // End form security checks
3035   //
3036
3037   QString urlstring = u.url();
3038
3039   if ( urlstring.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
3040     urlstring = KURL::decode_string(urlstring);
3041     executeScript( urlstring.right( urlstring.length() - 11) );
3042     return;
3043   }
3044
3045   if (!checkLinkSecurity(u,
3046                          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?" ),
3047                          i18n( "Submit" )))
3048     return;
3049
3050   KParts::URLArgs args;
3051
3052   if (!d->m_referrer.isEmpty())
3053      args.metaData()["referrer"] = d->m_referrer;
3054
3055   args.metaData().insert("main_frame_request",
3056                          parentPart() == 0 ? "TRUE":"FALSE");
3057   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
3058   args.metaData().insert("ssl_activate_warnings", "TRUE");
3059   args.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;
3060
3061   // Handle mailto: forms
3062   if (u.protocol() == "mailto") {
3063       // 1)  Check for attach= and strip it
3064       QString q = u.query().mid(1);
3065       QStringList nvps = QStringList::split("&", q);
3066       bool triedToAttach = false;
3067
3068       for (QStringList::Iterator nvp = nvps.begin(); nvp != nvps.end(); ++nvp) {
3069          QStringList pair = QStringList::split("=", *nvp);
3070          if (pair.count() >= 2) {
3071             if (pair.first().lower() == "attach") {
3072                nvp = nvps.remove(nvp);
3073                triedToAttach = true;
3074             }
3075          }
3076       }
3077
3078       if (triedToAttach)
3079          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");
3080
3081       // 2)  Append body=
3082       QString bodyEnc;
3083       if (contentType.lower() == "multipart/form-data") {
3084          // FIXME: is this correct?  I suspect not
3085          bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(), 
3086                                                            formData.size()));
3087       } else if (contentType.lower() == "text/plain") {
3088          // Convention seems to be to decode, and s/&/\n/
3089          QString tmpbody = QString::fromLatin1(formData.data(), 
3090                                                formData.size());
3091          tmpbody.replace(QRegExp("[&]"), "\n");
3092          tmpbody.replace(QRegExp("[+]"), " ");
3093          tmpbody = KURL::decode_string(tmpbody);  // Decode the rest of it
3094          bodyEnc = KURL::encode_string(tmpbody);  // Recode for the URL
3095       } else {
3096          bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(), 
3097                                                            formData.size()));
3098       }
3099
3100       nvps.append(QString("body=%1").arg(bodyEnc));
3101       q = nvps.join("&");
3102       u.setQuery(q);
3103   } 
3104
3105   if ( strcmp( action, "get" ) == 0 ) {
3106     if (u.protocol() != "mailto")
3107        u.setQuery( QString::fromLatin1( formData.data(), formData.size() ) );
3108     args.setDoPost( false );
3109   }
3110   else {
3111     args.postData = formData;
3112     args.setDoPost( true );
3113
3114     // construct some user headers if necessary
3115     if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
3116       args.setContentType( "Content-Type: application/x-www-form-urlencoded" );
3117     else // contentType must be "multipart/form-data"
3118       args.setContentType( "Content-Type: " + contentType + "; boundary=" + boundary );
3119   }
3120
3121   if ( d->m_doc->parsing() || d->m_runningScripts > 0 ) {
3122     if( d->m_submitForm ) {
3123       kdDebug(6000) << "KHTMLPart::submitForm ABORTING!" << endl;
3124       return;
3125     }
3126     d->m_submitForm = new KHTMLPartPrivate::SubmitForm;
3127     d->m_submitForm->submitAction = action;
3128     d->m_submitForm->submitUrl = url;
3129     d->m_submitForm->submitFormData = formData;
3130     d->m_submitForm->target = _target;
3131     d->m_submitForm->submitContentType = contentType;
3132     d->m_submitForm->submitBoundary = boundary;
3133     connect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
3134   }
3135   else
3136   {
3137     emit d->m_extension->openURLRequest( u, args );
3138   }
3139 #endif // APPLE_CHANGES
3140 }
3141
3142 void KHTMLPart::popupMenu( const QString &linkUrl )
3143 {
3144 #ifndef APPLE_CHANGES
3145   KURL popupURL;
3146   KURL linkKURL;
3147   if ( linkUrl.isEmpty() ) // click on background
3148     popupURL = this->url();
3149   else {               // click on link
3150     popupURL = completeURL( linkUrl );
3151     linkKURL = popupURL;
3152   }
3153
3154   KXMLGUIClient *client = new KHTMLPopupGUIClient( this, d->m_popupMenuXML, linkKURL );
3155
3156   emit d->m_extension->popupMenu( client, QCursor::pos(), popupURL,
3157                                   QString::fromLatin1( "text/html" ), S_IFREG /*always a file*/ );
3158
3159   delete client;
3160
3161   emit popupMenu(linkUrl, QCursor::pos());
3162 #endif
3163 }
3164
3165 #ifndef APPLE_CHANGES
3166
3167 void KHTMLPart::slotParentCompleted()
3168 {
3169   if ( !d->m_redirectURL.isEmpty() && !d->m_redirectionTimer.isActive() )
3170   {
3171     // kdDebug(6050) << this << ": Child redirection -> " << d->m_redirectURL << endl;
3172     d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
3173   }
3174 }
3175
3176 void KHTMLPart::slotChildStarted( KIO::Job *job )
3177 {
3178   khtml::ChildFrame *child = frame( sender() );
3179
3180   assert( child );
3181
3182   child->m_bCompleted = false;
3183
3184   if ( d->m_bComplete )
3185   {
3186 #if 0
3187     // WABA: Looks like this belongs somewhere else
3188     if ( !parentPart() ) // "toplevel" html document? if yes, then notify the hosting browser about the document (url) changes
3189     {
3190       emit d->m_extension->openURLNotify();
3191     }
3192 #endif
3193     d->m_bComplete = false;
3194     emit started( job );
3195   }
3196 }
3197
3198 void KHTMLPart::slotChildCompleted()
3199 {
3200   slotChildCompleted( false );
3201 }
3202
3203 void KHTMLPart::slotChildCompleted( bool complete )
3204 {
3205   khtml::ChildFrame *child = frame( sender() );
3206
3207   assert( child );
3208
3209   child->m_bCompleted = true;
3210   child->m_args = KParts::URLArgs();
3211
3212   if ( parentPart() == 0 )
3213     d->m_bPendingChildRedirection = (d->m_bPendingChildRedirection || complete);
3214
3215   checkCompleted();
3216 }
3217
3218 void KHTMLPart::slotChildURLRequest( const KURL &url, const KParts::URLArgs &args )
3219 {
3220   khtml::ChildFrame *child = frame( sender()->parent() );
3221
3222   QString frameName = args.frameName.lower();
3223   if ( !frameName.isEmpty() )
3224   {
3225     if ( frameName == QString::fromLatin1( "_top" ) )
3226     {
3227       emit d->m_extension->openURLRequest( url, args );
3228       return;
3229     }
3230     else if ( frameName == QString::fromLatin1( "_blank" ) )
3231     {
3232       emit d->m_extension->createNewWindow( url, args );
3233       return;
3234     }
3235     else if ( frameName == QString::fromLatin1( "_parent" ) )
3236     {
3237       KParts::URLArgs newArgs( args );
3238       newArgs.frameName = QString::null;
3239
3240       emit d->m_extension->openURLRequest( url, newArgs );
3241       return;
3242     }
3243     else if ( frameName != QString::fromLatin1( "_self" ) )
3244     {
3245       khtml::ChildFrame *_frame = recursiveFrameRequest( url, args );
3246
3247       if ( !_frame )
3248       {
3249         emit d->m_extension->openURLRequest( url, args );
3250         return;
3251       }
3252
3253       child = _frame;
3254     }
3255   }
3256
3257   // TODO: handle child target correctly! currently the script are always executed fur the parent
3258   QString urlStr = url.url();
3259   if ( urlStr.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
3260       executeScript( urlStr.right( urlStr.length() - 11) );
3261       return;
3262   }
3263
3264   if ( child ) {
3265       // Inform someone that we are about to show something else.
3266       child->m_bNotify = true;
3267       requestObject( child, url, args );
3268   }  else if ( frameName==QString::fromLatin1("_self") ) // this is for embedded objects (via <object>) which want to replace the current document
3269   {
3270       KParts::URLArgs newArgs( args );
3271       newArgs.frameName = QString::null;
3272       emit d->m_extension->openURLRequest( url, newArgs );
3273   }
3274 }
3275
3276 khtml::ChildFrame *KHTMLPart::frame( const QObject *obj )
3277 {
3278     assert( obj->inherits( "KParts::ReadOnlyPart" ) );
3279     const KParts::ReadOnlyPart *part = static_cast<const KParts::ReadOnlyPart *>( obj );
3280
3281     FrameIt it = d->m_frames.begin();
3282     FrameIt end = d->m_frames.end();
3283     for (; it != end; ++it )
3284       if ( (KParts::ReadOnlyPart *)(*it).m_part == part )
3285         return &(*it);
3286
3287     return 0L;
3288 }
3289
3290 #endif // APPLE_CHANGES
3291
3292 KHTMLPart *KHTMLPart::findFrame( const QString &f )
3293 {
3294 #ifdef APPLE_CHANGES
3295     return impl->findFrame(f);
3296 #else
3297 #if 0
3298   kdDebug() << "KHTMLPart::findFrame '" << f << "'" << endl;
3299   FrameIt it2 = d->m_frames.begin();
3300   FrameIt end = d->m_frames.end();
3301   for (; it2 != end; ++it2 )
3302       kdDebug() << "  - having frame '" << (*it2).m_name << "'" << endl;
3303 #endif
3304   // ### http://www.w3.org/TR/html4/appendix/notes.html#notes-frames
3305   ConstFrameIt it = d->m_frames.find( f );
3306   if ( it == d->m_frames.end() )
3307   {
3308     //kdDebug() << "KHTMLPart::findFrame frame " << f << " not found" << endl;
3309     return 0L;
3310   }
3311   else {
3312     KParts::ReadOnlyPart *p = (*it).m_part;
3313     if ( p && p->inherits( "KHTMLPart" ))
3314     {
3315       //kdDebug() << "KHTMLPart::findFrame frame " << f << " is a KHTMLPart, ok" << endl;
3316       return (KHTMLPart*)p;
3317     }
3318     else
3319     {
3320 #if 0
3321       if (p)
3322         kdWarning() << "KHTMLPart::findFrame frame " << f << " found but isn't a KHTMLPart ! " << p->className() << endl;
3323       else
3324         kdWarning() << "KHTMLPart::findFrame frame " << f << " found but m_part=0L" << endl;
3325 #endif
3326       return 0L;
3327     }
3328   }
3329 #endif
3330 }
3331
3332 #ifndef APPLE_CHANGES
3333
3334 KParts::ReadOnlyPart *KHTMLPart::currentFrame() const
3335 {
3336   KParts::ReadOnlyPart* part = (KParts::ReadOnlyPart*)(this);
3337   // Find active part in our frame manager, in case we are a frameset
3338   // and keep doing that (in case of nested framesets).
3339   // Just realized we could also do this recursively, calling part->currentFrame()...
3340   while ( part && part->inherits("KHTMLPart") &&
3341           static_cast<KHTMLPart *>(part)->d->m_frames.count() > 0 ) {
3342     KHTMLPart* frameset = static_cast<KHTMLPart *>(part);
3343     part = static_cast<KParts::ReadOnlyPart *>(frameset->partManager()->activePart());
3344     if ( !part ) return frameset;
3345   }
3346   return part;
3347 }
3348
3349 #endif // APPLE_CHANGES
3350
3351 bool KHTMLPart::frameExists( const QString &frameName )
3352 {
3353 #ifdef APPLE_CHANGES
3354   return impl->frameExists(frameName);
3355 #else
3356   ConstFrameIt it = d->m_frames.find( frameName );
3357   if ( it == d->m_frames.end() )
3358     return false;
3359
3360   // WABA: We only return true if the child actually has a frame
3361   // set. Otherwise we might find our preloaded-selve.
3362   // This happens when we restore the frameset.
3363   return (!(*it).m_frame.isNull());
3364 #endif
3365 }
3366
3367 KHTMLPart *KHTMLPart::parentPart()
3368 {
3369 #ifdef APPLE_CHANGES
3370   return impl->parentPart();
3371 #else
3372   if ( !parent() || !parent()->inherits( "KHTMLPart" ) )
3373     return 0L;
3374
3375   return (KHTMLPart *)parent();
3376 #endif
3377 }
3378
3379 #ifndef APPLE_CHANGES
3380
3381 khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( const KURL &url, const KParts::URLArgs &args,
3382                                                      bool callParent )
3383 {
3384   FrameIt it = d->m_frames.find( args.frameName );
3385
3386   if ( it != d->m_frames.end() )
3387     return &(*it);
3388
3389   it = d->m_frames.begin();
3390   FrameIt end = d->m_frames.end();
3391   for (; it != end; ++it )
3392     if ( (*it).m_part && (*it).m_part->inherits( "KHTMLPart" ) )
3393     {
3394       KHTMLPart *childPart = (KHTMLPart *)(KParts::ReadOnlyPart *)(*it).m_part;
3395
3396       khtml::ChildFrame *res = childPart->recursiveFrameRequest( url, args, false );
3397       if ( !res )
3398         continue;
3399
3400       childPart->requestObject( res, url, args );
3401       return 0L;
3402     }
3403
3404   if ( parentPart() && callParent )
3405   {
3406     khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( url, args );
3407
3408     if ( res )
3409       parentPart()->requestObject( res, url, args );
3410
3411     return 0L;
3412   }
3413
3414   return 0L;
3415 }
3416
3417 void KHTMLPart::saveState( QDataStream &stream )
3418 {
3419   kdDebug( 6050 ) << "KHTMLPart::saveState saving URL " << m_url.url() << endl;
3420
3421   stream << m_url << (Q_INT32)d->m_view->contentsX() << (Q_INT32)d->m_view->contentsY()
3422          << (Q_INT32) d->m_view->contentsWidth() << (Q_INT32) d->m_view->contentsHeight() << (Q_INT32) d->m_view->marginWidth() << (Q_INT32) d->m_view->marginHeight();
3423
3424   // save link cursor position
3425   int focusNodeNumber;
3426   if (!d->m_focusNodeRestored)
3427       focusNodeNumber = d->m_focusNodeNumber;
3428   else if (d->m_doc->focusNode())
3429       focusNodeNumber = d->m_doc->nodeAbsIndex(d->m_doc->focusNode());
3430   else
3431       focusNodeNumber = -1;
3432   stream << focusNodeNumber;
3433
3434   // Save the doc's cache id.
3435   stream << d->m_cacheId;
3436
3437   // Save the state of the document (Most notably the state of any forms)
3438   QStringList docState;
3439   if (d->m_doc)
3440   {
3441      docState = d->m_doc->docState();
3442   }
3443   stream << d->m_encoding << d->m_sheetUsed << docState;
3444
3445   stream << d->m_zoomFactor;
3446
3447   // Save ssl data
3448   stream << d->m_ssl_in_use
3449          << d->m_ssl_peer_certificate
3450          << d->m_ssl_peer_chain
3451          << d->m_ssl_peer_ip
3452          << d->m_ssl_cipher
3453          << d->m_ssl_cipher_desc
3454          << d->m_ssl_cipher_version
3455          << d->m_ssl_cipher_used_bits
3456          << d->m_ssl_cipher_bits
3457          << d->m_ssl_cert_state;
3458
3459
3460   QStringList frameNameLst, frameServiceTypeLst, frameServiceNameLst;
3461   KURL::List frameURLLst;
3462   QValueList<QByteArray> frameStateBufferLst;
3463
3464   ConstFrameIt it = d->m_frames.begin();
3465   ConstFrameIt end = d->m_frames.end();
3466   for (; it != end; ++it )
3467   {
3468     if ( !(*it).m_part )
3469        continue;
3470
3471     frameNameLst << (*it).m_name;
3472     frameServiceTypeLst << (*it).m_serviceType;
3473     frameServiceNameLst << (*it).m_serviceName;
3474     frameURLLst << (*it).m_part->url();
3475
3476     QByteArray state;
3477     QDataStream frameStream( state, IO_WriteOnly );
3478
3479     if ( (*it).m_extension )
3480       (*it).m_extension->saveState( frameStream );
3481
3482     frameStateBufferLst << state;
3483   }
3484
3485   // Save frame data
3486   stream << (Q_UINT32) frameNameLst.count();
3487   stream << frameNameLst << frameServiceTypeLst << frameServiceNameLst << frameURLLst << frameStateBufferLst;
3488 }
3489
3490 void KHTMLPart::restoreState( QDataStream &stream )
3491 {
3492   KURL u;
3493   Q_INT32 xOffset, yOffset, wContents, hContents, mWidth, mHeight;
3494   Q_UINT32 frameCount;
3495   QStringList frameNames, frameServiceTypes, docState, frameServiceNames;
3496   KURL::List frameURLs;
3497   QValueList<QByteArray> frameStateBuffers;
3498   QValueList<int> fSizes;
3499   QString encoding, sheetUsed;
3500   long old_cacheId = d->m_cacheId;
3501
3502   stream >> u >> xOffset >> yOffset >> wContents >> hContents >> mWidth >> mHeight;
3503
3504   d->m_view->setMarginWidth( mWidth );
3505   d->m_view->setMarginHeight( mHeight );
3506
3507   // restore link cursor position
3508   // nth node is active. value is set in checkCompleted()
3509   stream >> d->m_focusNodeNumber;
3510   d->m_focusNodeRestored = false;
3511   kdDebug(6050)<<"new focus Node number is:"<<d->m_focusNodeNumber<<endl;
3512
3513   stream >> d->m_cacheId;
3514
3515   stream >> encoding >> sheetUsed >> docState;
3516   d->m_encoding = encoding;
3517   d->m_sheetUsed = sheetUsed;
3518
3519   int zoomFactor;
3520   stream >> zoomFactor;
3521   setZoomFactor(zoomFactor);
3522
3523   // Restore ssl data
3524   stream >> d->m_ssl_in_use
3525          >> d->m_ssl_peer_certificate
3526          >> d->m_ssl_peer_chain
3527          >> d->m_ssl_peer_ip
3528          >> d->m_ssl_cipher
3529          >> d->m_ssl_cipher_desc
3530          >> d->m_ssl_cipher_version
3531          >> d->m_ssl_cipher_used_bits
3532          >> d->m_ssl_cipher_bits
3533          >> d->m_ssl_cert_state;
3534
3535 #ifndef APPLE_CHANGES
3536   d->m_paSecurity->setIcon( d->m_ssl_in_use ? "encrypted" : "decrypted" );
3537 #endif
3538
3539   stream >> frameCount >> frameNames >> frameServiceTypes >> frameServiceNames
3540          >> frameURLs >> frameStateBuffers;
3541
3542   d->m_bComplete = false;
3543   d->m_bLoadEventEmitted = false;
3544
3545 //   kdDebug( 6050 ) << "restoreStakte() docState.count() = " << docState.count() << endl;
3546 //   kdDebug( 6050 ) << "m_url " << m_url.url() << " <-> " << u.url() << endl;
3547 //   kdDebug( 6050 ) << "m_frames.count() " << d->m_frames.count() << " <-> " << frameCount << endl;
3548
3549   if (d->m_cacheId == old_cacheId)
3550   {
3551     // Partial restore
3552     d->m_redirectionTimer.stop();
3553
3554     FrameIt fIt = d->m_frames.begin();
3555     FrameIt fEnd = d->m_frames.end();
3556
3557     for (; fIt != fEnd; ++fIt )
3558         (*fIt).m_bCompleted = false;
3559
3560     fIt = d->m_frames.begin();
3561
3562     QStringList::ConstIterator fNameIt = frameNames.begin();
3563     QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
3564     QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
3565     KURL::List::ConstIterator fURLIt = frameURLs.begin();
3566     QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
3567
3568     for (; fIt != fEnd; ++fIt, ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
3569     {
3570       khtml::ChildFrame *child = &(*fIt);
3571
3572 //      kdDebug( 6050 ) <<  *fNameIt  << " ---- " <<  *fServiceTypeIt << endl;
3573
3574       if ( child->m_name != *fNameIt || child->m_serviceType != *fServiceTypeIt )
3575       {
3576         child->m_bPreloaded = true;
3577         child->m_name = *fNameIt;
3578         child->m_serviceName = *fServiceNameIt;
3579         processObjectRequest( child, *fURLIt, *fServiceTypeIt );
3580       }
3581
3582       if ( child->m_part )
3583       {
3584         child->m_bCompleted = false;
3585         if ( child->m_extension && !(*fBufferIt).isEmpty() )
3586         {
3587           QDataStream frameStream( *fBufferIt, IO_ReadOnly );
3588           child->m_extension->restoreState( frameStream );
3589         }
3590         else
3591           child->m_part->openURL( *fURLIt );
3592       }
3593     }
3594
3595     KParts::URLArgs args( d->m_extension->urlArgs() );
3596     args.xOffset = xOffset;
3597     args.yOffset = yOffset;
3598     args.docState = docState; // WABA: How are we going to restore this??
3599     d->m_extension->setURLArgs( args );
3600
3601     d->m_view->resizeContents( wContents,  hContents);
3602     d->m_view->setContentsPos( xOffset, yOffset );
3603   }
3604   else
3605   {
3606     // Full restore.
3607     closeURL();
3608     // We must force a clear because we want to be sure to delete all
3609     // frames.
3610     d->m_bCleared = false;
3611     clear();
3612     d->m_encoding = encoding;
3613     d->m_sheetUsed = sheetUsed;
3614
3615     QStringList::ConstIterator fNameIt = frameNames.begin();
3616     QStringList::ConstIterator fNameEnd = frameNames.end();
3617
3618     QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
3619     QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
3620     KURL::List::ConstIterator fURLIt = frameURLs.begin();
3621     QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
3622
3623     for (; fNameIt != fNameEnd; ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
3624     {
3625       khtml::ChildFrame newChild;
3626       newChild.m_bPreloaded = true;
3627       newChild.m_name = *fNameIt;
3628       newChild.m_serviceName = *fServiceNameIt;
3629
3630 //      kdDebug( 6050 ) << *fNameIt << " ---- " << *fServiceTypeIt << endl;
3631
3632       FrameIt childFrame = d->m_frames.append( newChild );
3633
3634       processObjectRequest( &(*childFrame), *fURLIt, *fServiceTypeIt );
3635
3636       (*childFrame).m_bPreloaded = true;
3637
3638       if ( (*childFrame).m_part )
3639       {
3640         if ( (*childFrame).m_extension )
3641         if ( (*childFrame).m_extension && !(*fBufferIt).isEmpty() )
3642         {
3643           QDataStream frameStream( *fBufferIt, IO_ReadOnly );
3644           (*childFrame).m_extension->restoreState( frameStream );
3645         }
3646         else
3647           (*childFrame).m_part->openURL( *fURLIt );
3648       }
3649     }
3650
3651     KParts::URLArgs args( d->m_extension->urlArgs() );
3652     args.xOffset = xOffset;
3653     args.yOffset = yOffset;
3654     args.docState = docState;
3655     d->m_extension->setURLArgs( args );
3656     if (!KHTMLPageCache::self()->isValid(d->m_cacheId))
3657     {
3658        d->m_restored = true;
3659        openURL( u );
3660        d->m_restored = false;
3661     }
3662     else
3663     {
3664        restoreURL( u );
3665     }
3666   }
3667
3668 }
3669
3670 #endif
3671
3672 void KHTMLPart::show()
3673 {
3674   if ( d->m_view )
3675     d->m_view->show();
3676 }
3677
3678 void KHTMLPart::hide()
3679 {
3680   if ( d->m_view )
3681     d->m_view->hide();
3682 }
3683
3684 DOM::Node KHTMLPart::nodeUnderMouse() const