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