8c4d457854eac3f988b73505523b4f5bee25ed49
[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::DocumentImpl *KHTMLPart::xmlDocImpl() const
1099 {
1100     if ( d )
1101         return d->m_doc;
1102     return 0;
1103 }
1104
1105 void KHTMLPart::replaceDocImpl(DocumentImpl* newDoc)
1106 {
1107     if (d) {
1108         if (d->m_doc) {
1109             d->m_doc->detach();
1110             d->m_doc->deref();
1111         }
1112         d->m_doc = newDoc;
1113         if (newDoc)
1114             newDoc->ref();
1115     }
1116 }
1117
1118 /*bool KHTMLPart::isSSLInUse() const
1119 {
1120   return d->m_ssl_in_use;
1121 }*/
1122
1123 void KHTMLPart::receivedFirstData()
1124 {
1125     // Leave indented one extra for easier merging.
1126     
1127       //kdDebug( 6050 ) << "begin!" << endl;
1128
1129     begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
1130
1131
1132     d->m_doc->docLoader()->setCachePolicy(d->m_cachePolicy);
1133     d->m_workingURL = KURL();
1134
1135     d->m_cacheId = KHTMLPageCache::self()->createCacheEntry();
1136
1137     // When the first data arrives, the metadata has just been made available
1138 #if APPLE_CHANGES
1139     QString qData;
1140 #else
1141     d->m_bSecurityInQuestion = false;
1142     d->m_ssl_in_use = (d->m_job->queryMetaData("ssl_in_use") == "TRUE");
1143     kdDebug(6050) << "SSL in use? " << d->m_job->queryMetaData("ssl_in_use") << endl;
1144
1145     {
1146     KHTMLPart *p = parentPart();
1147     if (p && p->d->m_ssl_in_use != d->m_ssl_in_use) {
1148         while (p->parentPart()) p = p->parentPart();
1149
1150         p->d->m_paSecurity->setIcon( "halfencrypted" );
1151         p->d->m_bSecurityInQuestion = true;
1152         kdDebug(6050) << "parent setIcon half done." << endl;
1153     }
1154     }
1155
1156     d->m_paSecurity->setIcon( d->m_ssl_in_use ? "encrypted" : "decrypted" );
1157     kdDebug(6050) << "setIcon " << ( d->m_ssl_in_use ? "encrypted" : "decrypted" ) << " done." << endl;
1158
1159     // Shouldn't all of this be done only if ssl_in_use == true ? (DF)
1160
1161     d->m_ssl_peer_certificate = d->m_job->queryMetaData("ssl_peer_certificate");
1162     d->m_ssl_peer_chain = d->m_job->queryMetaData("ssl_peer_chain");
1163     d->m_ssl_peer_ip = d->m_job->queryMetaData("ssl_peer_ip");
1164     d->m_ssl_cipher = d->m_job->queryMetaData("ssl_cipher");
1165     d->m_ssl_cipher_desc = d->m_job->queryMetaData("ssl_cipher_desc");
1166     d->m_ssl_cipher_version = d->m_job->queryMetaData("ssl_cipher_version");
1167     d->m_ssl_cipher_used_bits = d->m_job->queryMetaData("ssl_cipher_used_bits");
1168     d->m_ssl_cipher_bits = d->m_job->queryMetaData("ssl_cipher_bits");
1169     d->m_ssl_cert_state = d->m_job->queryMetaData("ssl_cert_state");
1170
1171     // Check for charset meta-data
1172     QString qData = d->m_job->queryMetaData("charset");
1173     if ( !qData.isEmpty() && !d->m_haveEncoding ) // only use information if the user didn't override the settings
1174        d->m_encoding = qData;
1175 #endif // APPLE_CHANGES
1176
1177     // Support for http-refresh
1178     qData = d->m_job->queryMetaData("http-refresh");
1179     if( !qData.isEmpty() && d->m_metaRefreshEnabled )
1180     {
1181       kdDebug(6050) << "HTTP Refresh Request: " << qData << endl;
1182       double delay;
1183       int pos = qData.find( ';' );
1184       if ( pos == -1 )
1185         pos = qData.find( ',' );
1186
1187       if( pos == -1 )
1188       {
1189         delay = qData.stripWhiteSpace().toDouble();
1190 #if APPLE_CHANGES
1191         // We want a new history item if the refresh timeout > 1 second
1192         scheduleRedirection( delay, m_url.url(), delay <= 1);
1193 #else
1194         scheduleRedirection( delay, m_url.url());
1195 #endif
1196       }
1197       else
1198       {
1199         int end_pos = qData.length();
1200         delay = qData.left(pos).stripWhiteSpace().toDouble();
1201         while ( qData[++pos] == ' ' );
1202         if ( qData.find( "url", pos, false ) == pos )
1203         {
1204           pos += 3;
1205           while (qData[pos] == ' ' || qData[pos] == '=' )
1206               pos++;
1207           if ( qData[pos] == '"' )
1208           {
1209               pos++;
1210               int index = end_pos-1;
1211               while( index > pos )
1212               {
1213                 if ( qData[index] == '"' )
1214                     break;
1215                 index--;
1216               }
1217               if ( index > pos )
1218                 end_pos = index;
1219           }
1220         }
1221 #if APPLE_CHANGES
1222         // We want a new history item if the refresh timeout > 1 second
1223         scheduleRedirection( delay, d->m_doc->completeURL( qData.mid( pos, end_pos ) ), delay <= 1);
1224 #else
1225         scheduleRedirection( delay, d->m_doc->completeURL( qData.mid( pos, end_pos ) ));
1226 #endif
1227       }
1228       d->m_bHTTPRefresh = true;
1229     }
1230
1231     // Support for http last-modified
1232     d->m_lastModified = d->m_job->queryMetaData("modified");
1233     //kdDebug() << "KHTMLPart::slotData metadata modified: " << d->m_lastModified << endl;
1234 }
1235
1236 #if !APPLE_CHANGES
1237
1238 void KHTMLPart::slotData( KIO::Job* kio_job, const QByteArray &data )
1239 {
1240   assert ( d->m_job == kio_job );
1241
1242   //kdDebug( 6050 ) << "slotData: " << data.size() << endl;
1243   // The first data ?
1244   if ( !d->m_workingURL.isEmpty() )
1245     receivedFirstData( );
1246
1247   KHTMLPageCache::self()->addData(d->m_cacheId, data);
1248   write( data.data(), data.size() );
1249 }
1250
1251 void KHTMLPart::slotRestoreData(const QByteArray &data )
1252 {
1253   // The first data ?
1254   if ( !d->m_workingURL.isEmpty() )
1255   {
1256      long saveCacheId = d->m_cacheId;
1257      begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
1258      d->m_cacheId = saveCacheId;
1259      d->m_workingURL = KURL();
1260   }
1261
1262   //kdDebug( 6050 ) << "slotRestoreData: " << data.size() << endl;
1263   write( data.data(), data.size() );
1264
1265   if (data.size() == 0)
1266   {
1267       //kdDebug( 6050 ) << "slotRestoreData: <<end of data>>" << endl;
1268      // End of data.
1269     if (d->m_doc && d->m_doc->parsing())
1270         end(); //will emit completed()
1271   }
1272 }
1273
1274 void KHTMLPart::showError( KIO::Job* job )
1275 {
1276   kdDebug() << "KHTMLPart::showError d->m_bParsing=" << (d->m_doc && d->m_doc->parsing()) << " d->m_bComplete=" << d->m_bComplete
1277             << " d->m_bCleared=" << d->m_bCleared << endl;
1278
1279   if (job->error() == KIO::ERR_NO_CONTENT)
1280         return;
1281
1282   if ( (d->m_doc && d->m_doc->parsing()) || d->m_workingURL.isEmpty() ) // if we got any data already
1283     job->showErrorDialog( /*d->m_view*/ );
1284   else
1285   {
1286     htmlError( job->error(), job->errorText(), d->m_workingURL );
1287   }
1288 }
1289
1290 // This is a protected method, placed here because of it's relevance to showError
1291 void KHTMLPart::htmlError( int errorCode, const QString& text, const KURL& reqUrl )
1292 {
1293   kdDebug(6050) << "KHTMLPart::htmlError errorCode=" << errorCode << " text=" << text << endl;
1294   // make sure we're not executing any embedded JS
1295   bool bJSFO = d->m_bJScriptForce;
1296   bool bJSOO = d->m_bJScriptOverride;
1297   d->m_bJScriptForce = false;
1298   d->m_bJScriptOverride = true;
1299   begin();
1300   QString errText = QString::fromLatin1( "<HTML><HEAD><TITLE>" );
1301   errText += i18n( "Error while loading %1" ).arg( reqUrl.htmlURL() );
1302   errText += QString::fromLatin1( "</TITLE></HEAD><BODY><P>" );
1303   errText += i18n( "An error occured while loading <B>%1</B>:" ).arg( reqUrl.htmlURL() );
1304   errText += QString::fromLatin1( "</P><P>" );
1305   QString kioErrString = KIO::buildErrorString( errorCode, text );
1306
1307   kioErrString.replace(QRegExp("&"), QString("&amp;"));
1308   kioErrString.replace(QRegExp("<"), QString("&lt;"));
1309   kioErrString.replace(QRegExp(">"), QString("&gt;"));
1310
1311   // In case the error string has '\n' in it, replace with <BR/>
1312   kioErrString.replace( QRegExp("\n"), "<BR/>" );
1313
1314   errText += kioErrString;
1315   errText += QString::fromLatin1( "</P></BODY></HTML>" );
1316   write(errText);
1317   end();
1318
1319   d->m_bJScriptForce = bJSFO;
1320   d->m_bJScriptOverride = bJSOO;
1321
1322   // make the working url the current url, so that reload works and
1323   // emit the progress signals to advance one step in the history
1324   // (so that 'back' works)
1325   m_url = reqUrl; // same as d->m_workingURL
1326   d->m_workingURL = KURL();
1327   emit started( 0 );
1328   emit completed();
1329   return;
1330   // following disabled until 3.1
1331
1332   QString errorName, techName, description;
1333   QStringList causes, solutions;
1334
1335   QByteArray raw = KIO::rawErrorDetail( errorCode, text, &reqUrl );
1336   QDataStream stream(raw, IO_ReadOnly);
1337
1338   stream >> errorName >> techName >> description >> causes >> solutions;
1339
1340   QString url, protocol, datetime;
1341   url = reqUrl.prettyURL();
1342   protocol = reqUrl.protocol();
1343   datetime = KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(),
1344                                                 false );
1345
1346   QString doc = QString::fromLatin1( "<html><head><title>" );
1347   doc += i18n( "Error: " );
1348   doc += errorName;
1349   doc += QString::fromLatin1( " - %1</title></head><body><h1>" ).arg( url );
1350   doc += i18n( "The requested operation could not be completed" );
1351   doc += QString::fromLatin1( "</h1><h2>" );
1352   doc += errorName;
1353   doc += QString::fromLatin1( "</h2>" );
1354   if ( techName != QString::null ) {
1355     doc += QString::fromLatin1( "<h2>" );
1356     doc += i18n( "Technical Reason: " );
1357     doc += techName;
1358     doc += QString::fromLatin1( "</h2>" );
1359   }
1360   doc += QString::fromLatin1( "<h3>" );
1361   doc += i18n( "Details of the Request:" );
1362   doc += QString::fromLatin1( "</h3><ul><li>" );
1363   doc += i18n( "URL: %1" ).arg( url );
1364   doc += QString::fromLatin1( "</li><li>" );
1365   if ( protocol != QString::null ) {
1366     // uncomment for 3.1... i18n change
1367     // doc += i18n( "Protocol: %1" ).arg( protocol ).arg( protocol );
1368     doc += QString::fromLatin1( "</li><li>" );
1369   }
1370   doc += i18n( "Date and Time: %1" ).arg( datetime );
1371   doc += QString::fromLatin1( "</li><li>" );
1372   doc += i18n( "Additional Information: %1" ).arg( text );
1373   doc += QString::fromLatin1( "</li></ul><h3>" );
1374   doc += i18n( "Description:" );
1375   doc += QString::fromLatin1( "</h3><p>" );
1376   doc += description;
1377   doc += QString::fromLatin1( "</p>" );
1378   if ( causes.count() ) {
1379     doc += QString::fromLatin1( "<h3>" );
1380     doc += i18n( "Possible Causes:" );
1381     doc += QString::fromLatin1( "</h3><ul><li>" );
1382     doc += causes.join( "</li><li>" );
1383     doc += QString::fromLatin1( "</li></ul>" );
1384   }
1385   if ( solutions.count() ) {
1386     doc += QString::fromLatin1( "<h3>" );
1387     doc += i18n( "Possible Solutions:" );
1388     doc += QString::fromLatin1( "</h3><ul><li>" );
1389     doc += solutions.join( "</li><li>" );
1390     doc += QString::fromLatin1( "</li></ul>" );
1391   }
1392   doc += QString::fromLatin1( "</body></html>" );
1393
1394   write( doc );
1395   end();
1396 }
1397
1398 #endif
1399
1400 void KHTMLPart::slotFinished( KIO::Job * job )
1401 {
1402   if (job->error())
1403   {
1404     KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
1405     d->m_job = 0L;
1406 #if !APPLE_CHANGES
1407     emit canceled( job->errorString() );
1408 #endif
1409     // TODO: what else ?
1410     checkCompleted();
1411 #if !APPLE_CHANGES
1412     showError( job );
1413 #endif
1414     return;
1415   }
1416   //kdDebug( 6050 ) << "slotFinished" << endl;
1417
1418   KHTMLPageCache::self()->endData(d->m_cacheId);
1419
1420   if ( d->m_doc && d->m_doc->docLoader()->expireDate() && m_url.protocol().lower().startsWith("http"))
1421       KIO::http_update_cache(m_url, false, d->m_doc->docLoader()->expireDate());
1422
1423   d->m_workingURL = KURL();
1424   d->m_job = 0L;
1425
1426   if (d->m_doc->parsing())
1427       end(); //will emit completed()
1428 }
1429
1430 #if APPLE_CHANGES
1431 void KHTMLPart::childBegin()
1432 {
1433     // We need to do this when the child is created so as to avoid the bogus state of the parent's
1434     // child->m_bCompleted being false but the child's m_bComplete being true.  If the child gets
1435     // an error early on, we had trouble where checkingComplete on the child was a NOP because
1436     // it thought it was already complete, and thus the parent was never signaled, and never set
1437     // its child->m_bComplete.
1438     d->m_bComplete = false;
1439 }
1440 #endif
1441
1442 void KHTMLPart::begin( const KURL &url, int xOffset, int yOffset )
1443 {
1444 #if APPLE_CHANGES
1445   // If we aren't loading an actual URL, then we need to make sure
1446   // that we have at least an empty document. createEmptyDocument will
1447   // do that if we don't have a document already.
1448   if (d->m_workingURL.isEmpty()) {
1449     KWQ(this)->createEmptyDocument();
1450   }
1451 #endif
1452
1453   clear();
1454
1455 #if APPLE_CHANGES
1456   KWQ(this)->partClearedInBegin();
1457 #endif
1458
1459   // Only do this after clearing the part, so that JavaScript can
1460   // clean up properly if it was on for the last load.
1461 #if !APPLE_CHANGES
1462   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
1463 #else
1464   d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled(url.host());
1465 #endif
1466
1467   d->m_bCleared = false;
1468   d->m_cacheId = 0;
1469   d->m_bComplete = false;
1470   d->m_bLoadEventEmitted = false;
1471
1472   if(url.isValid()) {
1473 #if APPLE_CHANGES
1474       KHTMLFactory::vLinks()->insert( KWQ(this)->requestedURLString() );
1475 #else
1476       QString urlString = url.url();
1477       KHTMLFactory::vLinks()->insert( urlString );
1478       QString urlString2 = url.prettyURL();
1479       if ( urlString != urlString2 ) {
1480           KHTMLFactory::vLinks()->insert( urlString2 );
1481       }
1482 #endif
1483   }
1484
1485   // ###
1486   //stopParser();
1487
1488   KParts::URLArgs args( d->m_extension->urlArgs() );
1489   args.xOffset = xOffset;
1490   args.yOffset = yOffset;
1491   d->m_extension->setURLArgs( args );
1492
1493   KURL ref(url);
1494   ref.setUser(QSTRING_NULL);
1495   ref.setPass(QSTRING_NULL);
1496   ref.setRef(QSTRING_NULL);
1497   d->m_referrer = ref.protocol().startsWith("http") ? ref.url() : "";
1498   m_url = url;
1499   KURL baseurl;
1500
1501 #if APPLE_CHANGES
1502   // We don't need KDE chained URI handling or window caption setting
1503   if ( !m_url.isEmpty() )
1504   {
1505     baseurl = m_url;
1506   }
1507 #else
1508   if ( !m_url.isEmpty() )
1509   {
1510     KURL::List lst = KURL::split( m_url );
1511     if ( !lst.isEmpty() )
1512       baseurl = *lst.begin();
1513
1514     KURL title( baseurl );
1515     title.setRef( QString::null );
1516     title.setQuery( QString::null );
1517     emit setWindowCaption( title.url() );
1518   }
1519   else
1520     emit setWindowCaption( i18n( "no title", "* Unknown *" ) );
1521 #endif
1522
1523   if (args.serviceType == "text/xml" || args.serviceType == "application/xml" || args.serviceType == "application/xhtml+xml" ||
1524       args.serviceType == "text/xsl" || args.serviceType == "application/rss+xml" || args.serviceType == "application/atom+xml")
1525     d->m_doc = DOMImplementationImpl::instance()->createDocument( d->m_view );
1526   else
1527     d->m_doc = DOMImplementationImpl::instance()->createHTMLDocument( d->m_view );
1528
1529   d->m_doc->ref();
1530   if (!d->m_doc->attached())
1531     d->m_doc->attach( );
1532   d->m_doc->setURL( m_url.url() );
1533   // We prefer m_baseURL over m_url because m_url changes when we are
1534   // about to load a new page.
1535   d->m_doc->setBaseURL( baseurl.url() );
1536 #if APPLE_CHANGES
1537   if (d->m_decoder)
1538     d->m_doc->setDecoder(d->m_decoder);
1539 #endif
1540 #if !APPLE_CHANGES
1541   d->m_doc->docLoader()->setShowAnimations( KHTMLFactory::defaultHTMLSettings()->showAnimations() );
1542 #else
1543   d->m_doc->docLoader()->setShowAnimations( d->m_settings->showAnimations() );
1544 #endif
1545
1546 #if APPLE_CHANGES
1547   KWQ(this)->updatePolicyBaseURL();
1548 #endif
1549
1550 #if !APPLE_CHANGES
1551   d->m_paUseStylesheet->setItems(QStringList());
1552   d->m_paUseStylesheet->setEnabled( false );
1553 #endif
1554
1555 #if !APPLE_CHANGES
1556   setAutoloadImages( KHTMLFactory::defaultHTMLSettings()->autoLoadImages() );
1557   QString userStyleSheet = KHTMLFactory::defaultHTMLSettings()->userStyleSheet();
1558 #else
1559   setAutoloadImages( d->m_settings->autoLoadImages() );
1560   QString userStyleSheet = d->m_settings->userStyleSheet();
1561 #endif
1562
1563   if ( !userStyleSheet.isEmpty() )
1564     setUserStyleSheet( KURL( userStyleSheet ) );
1565
1566 #if APPLE_CHANGES
1567   KWQ(this)->restoreDocumentState();
1568 #else
1569   d->m_doc->setRestoreState(args.docState);
1570 #endif
1571
1572   d->m_doc->open();
1573   // clear widget
1574   if (d->m_view)
1575     d->m_view->resizeContents( 0, 0 );
1576   connect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
1577
1578 #if !APPLE_CHANGES
1579   emit d->m_extension->enableAction( "print", true );
1580 #endif
1581
1582   d->m_doc->setParsing(true);
1583 }
1584
1585 void KHTMLPart::write( const char *str, int len )
1586 {
1587     if ( !d->m_decoder ) {
1588         d->m_decoder = new Decoder;
1589         if (!d->m_encoding.isNull())
1590             d->m_decoder->setEncoding(d->m_encoding.latin1(),
1591                 d->m_haveEncoding ? Decoder::UserChosenEncoding : Decoder::EncodingFromHTTPHeader);
1592         else {
1593             // Inherit the default encoding from the parent frame if there is one.
1594             const char *defaultEncoding = (parentPart() && parentPart()->d->m_decoder)
1595                 ? parentPart()->d->m_decoder->encoding() : settings()->encoding().latin1();
1596             d->m_decoder->setEncoding(defaultEncoding, Decoder::DefaultEncoding);
1597         }
1598 #if APPLE_CHANGES
1599         if (d->m_doc)
1600             d->m_doc->setDecoder(d->m_decoder);
1601 #endif
1602     }
1603   if ( len == 0 )
1604     return;
1605
1606   if ( len == -1 )
1607     len = strlen( str );
1608
1609   QString decoded = d->m_decoder->decode( str, len );
1610
1611   if(decoded.isEmpty()) return;
1612
1613   if(d->m_bFirstData) {
1614       // determine the parse mode
1615       d->m_doc->determineParseMode( decoded );
1616       d->m_bFirstData = false;
1617
1618   //kdDebug(6050) << "KHTMLPart::write haveEnc = " << d->m_haveEncoding << endl;
1619       // ### this is still quite hacky, but should work a lot better than the old solution
1620       if(d->m_decoder->visuallyOrdered()) d->m_doc->setVisuallyOrdered();
1621       d->m_doc->recalcStyle( NodeImpl::Force );
1622   }
1623
1624   if (jScript())
1625     jScript()->appendSourceFile(m_url.url(),decoded);
1626   Tokenizer* t = d->m_doc->tokenizer();
1627
1628   if(t)
1629     t->write( decoded, true );
1630 }
1631
1632 void KHTMLPart::write( const QString &str )
1633 {
1634   if ( str.isNull() )
1635     return;
1636
1637   if(d->m_bFirstData) {
1638       // determine the parse mode
1639       d->m_doc->setParseMode( DocumentImpl::Strict );
1640       d->m_bFirstData = false;
1641   }
1642   if (jScript())
1643     jScript()->appendSourceFile(m_url.url(),str);
1644   Tokenizer* t = d->m_doc->tokenizer();
1645   if(t)
1646     t->write( str, true );
1647 }
1648
1649 void KHTMLPart::end()
1650 {
1651     // make sure nothing's left in there...
1652     if (d->m_decoder)
1653         write(d->m_decoder->flush());
1654     if (d->m_doc)
1655         d->m_doc->finishParsing();
1656     else
1657         // WebKit partially uses WebCore when loading non-HTML docs.  In these cases doc==nil, but
1658         // WebCore is enough involved that we need to checkCompleted() in order for m_bComplete to
1659         // become true.  An example is when a subframe is a pure text doc, and that subframe is the
1660         // last one to complete.
1661         checkCompleted();
1662 }
1663
1664 void KHTMLPart::stop()
1665 {
1666     // make sure nothing's left in there...
1667     Tokenizer* t = d->m_doc ? d->m_doc->tokenizer() : 0;
1668     if (t)
1669         t->stopped();
1670     if (d->m_doc)
1671         d->m_doc->finishParsing();
1672     else
1673         // WebKit partially uses WebCore when loading non-HTML docs.  In these cases doc==nil, but
1674         // WebCore is enough involved that we need to checkCompleted() in order for m_bComplete to
1675         // become true.  An example is when a subframe is a pure text doc, and that subframe is the
1676         // last one to complete.
1677         checkCompleted();
1678 }
1679
1680 #if !APPLE_CHANGES
1681
1682 void KHTMLPart::paint(QPainter *p, const QRect &rc, int yOff, bool *more)
1683 {
1684     if (!d->m_view) return;
1685     d->m_view->paint(p, rc, yOff, more);
1686 }
1687
1688 #endif
1689
1690 void KHTMLPart::stopAnimations()
1691 {
1692   if ( d->m_doc )
1693     d->m_doc->docLoader()->setShowAnimations( KHTMLSettings::KAnimationDisabled );
1694
1695   ConstFrameIt it = d->m_frames.begin();
1696   ConstFrameIt end = d->m_frames.end();
1697   for (; it != end; ++it )
1698     if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
1699       KParts::ReadOnlyPart* p = ( *it ).m_part;
1700       static_cast<KHTMLPart*>( p )->stopAnimations();
1701     }
1702 }
1703
1704 void KHTMLPart::gotoAnchor()
1705 {
1706     if (m_url.hasRef()) {
1707         QString ref = m_url.encodedHtmlRef();
1708         if (!gotoAnchor(ref)) {
1709             // Can't use htmlRef() here because it doesn't know which encoding to use to decode.
1710             // Decoding here has to match encoding in completeURL, which means it has to use the
1711             // page's encoding rather than UTF-8.
1712             if (d->m_decoder)
1713 #if !APPLE_CHANGES
1714                 gotoAnchor(KURL::decode_string(ref, d->m_decoder->codec()->mibEnum()));
1715 #else
1716                 gotoAnchor(KURL::decode_string(ref, d->m_decoder->codec()));
1717 #endif
1718         }
1719     }
1720 }
1721
1722 void KHTMLPart::slotFinishedParsing()
1723 {
1724   d->m_doc->setParsing(false);
1725   disconnect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
1726
1727   if (!d->m_view)
1728     return; // We are probably being destructed.
1729     
1730   checkCompleted();
1731
1732   if (!d->m_view)
1733     return; // We are being destroyed by something checkCompleted called.
1734
1735   // check if the scrollbars are really needed for the content
1736   // if not, remove them, relayout, and repaint
1737
1738   d->m_view->restoreScrollBar();
1739   gotoAnchor();
1740 }
1741
1742 void KHTMLPart::slotLoaderRequestStarted( khtml::DocLoader* dl, khtml::CachedObject *obj )
1743 {
1744 #if !APPLE_CHANGES
1745   if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
1746     KHTMLPart* p = this;
1747     while ( p ) {
1748       KHTMLPart* op = p;
1749       p->d->m_totalObjectCount++;
1750       p = p->parentPart();
1751       if ( !p && d->m_loadedObjects <= d->m_totalObjectCount )
1752         QTimer::singleShot( 200, op, SLOT( slotProgressUpdate() ) );
1753     }
1754   }
1755 #endif
1756 }
1757
1758 void KHTMLPart::slotLoaderRequestDone( khtml::DocLoader* dl, khtml::CachedObject *obj )
1759 {
1760 #if !APPLE_CHANGES
1761   if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
1762     KHTMLPart* p = this;
1763     while ( p ) {
1764       KHTMLPart* op = p;
1765       p->d->m_loadedObjects++;
1766       p = p->parentPart();
1767       if ( !p && d->m_loadedObjects <= d->m_totalObjectCount && d->m_jobPercent >= 100 )
1768         QTimer::singleShot( 200, op, SLOT( slotProgressUpdate() ) );
1769     }
1770   }
1771 #endif
1772
1773   checkCompleted();
1774 }
1775
1776 #if !APPLE_CHANGES
1777
1778 void KHTMLPart::slotProgressUpdate()
1779 {
1780   int percent;
1781   if ( d->m_loadedObjects < d->m_totalObjectCount )
1782     percent = d->m_jobPercent / 4 + ( d->m_loadedObjects*300 ) / ( 4*d->m_totalObjectCount );
1783   else
1784     percent = d->m_jobPercent;
1785
1786   if ( d->m_loadedObjects < d->m_totalObjectCount && percent >= 75 )
1787     emit d->m_extension->infoMessage( i18n( "%1 of 1 Image loaded", "%1 of %n Images loaded", d->m_totalObjectCount ).arg( d->m_loadedObjects ) );
1788
1789   emit d->m_extension->loadingProgress( percent );
1790 }
1791
1792 void KHTMLPart::slotJobSpeed( KIO::Job* /*job*/, unsigned long speed )
1793 {
1794   emit d->m_extension->speedProgress( speed );
1795 }
1796
1797 void KHTMLPart::slotJobPercent( KIO::Job* /*job*/, unsigned long percent )
1798 {
1799   d->m_jobPercent = percent;
1800
1801   if ( !parentPart() )
1802     QTimer::singleShot( 0, this, SLOT( slotProgressUpdate() ) );
1803 }
1804
1805 #endif
1806
1807 void KHTMLPart::checkCompleted()
1808 {
1809 //   kdDebug( 6050 ) << "KHTMLPart::checkCompleted() parsing: " << d->m_doc->parsing() << endl;
1810 //   kdDebug( 6050 ) << "                           complete: " << d->m_bComplete << endl;
1811
1812 #if !APPLE_CHANGES
1813   // restore the cursor position
1814   if (d->m_doc && !d->m_doc->parsing() && !d->m_focusNodeRestored)
1815   {
1816       if (d->m_focusNodeNumber >= 0)
1817           d->m_doc->setFocusNode(d->m_doc->nodeWithAbsIndex(d->m_focusNodeNumber));
1818       else
1819           d->m_doc->setFocusNode(0);
1820       d->m_focusNodeRestored = true;
1821   }
1822 #endif
1823
1824   // Any frame that hasn't completed yet ?
1825   ConstFrameIt it = d->m_frames.begin();
1826   ConstFrameIt end = d->m_frames.end();
1827   for (; it != end; ++it )
1828     if ( !(*it).m_bCompleted )
1829       return;
1830
1831   // Are we still parsing - or have we done the completed stuff already ?
1832   if ( d->m_bComplete || (d->m_doc && d->m_doc->parsing()) )
1833     return;
1834
1835   // Still waiting for images/scripts from the loader ?
1836   int requests = 0;
1837   if ( d->m_doc && d->m_doc->docLoader() )
1838     requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );
1839
1840   if ( requests > 0 )
1841     return;
1842
1843   // OK, completed.
1844   // Now do what should be done when we are really completed.
1845   d->m_bComplete = true;
1846
1847   checkEmitLoadEvent(); // if we didn't do it before
1848
1849 #if !APPLE_CHANGES
1850   // check that the view has not been moved by the user  
1851   if ( !m_url.hasRef() && d->m_view->contentsY() == 0 )
1852       d->m_view->setContentsPos( d->m_extension->urlArgs().xOffset,
1853                                  d->m_extension->urlArgs().yOffset );
1854 #endif
1855
1856   if ( d->m_scheduledRedirection != noRedirectionScheduled )
1857   {
1858     // Do not start redirection for frames here! That action is
1859     // deferred until the parent emits a completed signal.
1860     if ( parentPart() == 0 )
1861       d->m_redirectionTimer.start( (int)(1000 * d->m_delayRedirect), true );
1862
1863     emit completed( true );
1864   }
1865   else
1866   {
1867     if ( d->m_bPendingChildRedirection )
1868       emit completed ( true );
1869     else
1870       emit completed();
1871   }
1872
1873 #if !APPLE_CHANGES
1874   // find the alternate stylesheets
1875   QStringList sheets;
1876   if (d->m_doc)
1877      sheets = d->m_doc->availableStyleSheets();
1878   d->m_paUseStylesheet->setItems( sheets );
1879   d->m_paUseStylesheet->setEnabled( !sheets.isEmpty() );
1880   if (!sheets.isEmpty())
1881   {
1882     d->m_paUseStylesheet->setCurrentItem(kMax(sheets.findIndex(d->m_sheetUsed), 0));
1883     slotUseStylesheet();
1884   }
1885
1886   if (!parentPart())
1887       emit setStatusBarText(i18n("Done."));
1888 #endif
1889
1890 #ifdef SPEED_DEBUG
1891   kdDebug(6050) << "DONE: " <<d->m_parsetime.elapsed() << endl;
1892 #endif
1893 }
1894
1895 void KHTMLPart::checkEmitLoadEvent()
1896 {
1897   if ( d->m_bLoadEventEmitted || !d->m_doc || d->m_doc->parsing() ) return;
1898
1899   ConstFrameIt it = d->m_frames.begin();
1900   ConstFrameIt end = d->m_frames.end();
1901   for (; it != end; ++it )
1902     if ( !(*it).m_bCompleted ) // still got a frame running -> too early
1903       return;
1904
1905
1906   // All frames completed -> set their domain to the frameset's domain
1907   // This must only be done when loading the frameset initially (#22039),
1908   // not when following a link in a frame (#44162).
1909   if ( d->m_doc )
1910   {
1911     DOMString domain = d->m_doc->domain();
1912     ConstFrameIt it = d->m_frames.begin();
1913     ConstFrameIt end = d->m_frames.end();
1914     for (; it != end; ++it )
1915     {
1916       KParts::ReadOnlyPart *p = (*it).m_part;
1917       if ( p && p->inherits( "KHTMLPart" ))
1918       {
1919         KHTMLPart* htmlFrame = static_cast<KHTMLPart *>(p);
1920         if (htmlFrame->d->m_doc)
1921         {
1922           kdDebug() << "KHTMLPart::checkCompleted setting frame domain to " << domain.string() << endl;
1923           htmlFrame->d->m_doc->setDomain( domain );
1924         }
1925       }
1926     }
1927   }
1928
1929   d->m_bLoadEventEmitted = true;
1930   d->m_bUnloadEventEmitted = false;
1931   if (d->m_doc)
1932     d->m_doc->close();
1933 }
1934
1935 const KHTMLSettings *KHTMLPart::settings() const
1936 {
1937   return d->m_settings;
1938 }
1939
1940 #ifndef KDE_NO_COMPAT
1941 KURL KHTMLPart::baseURL() const
1942 {
1943   if ( !d->m_doc ) return KURL();
1944
1945   return d->m_doc->baseURL();
1946 }
1947
1948 QString KHTMLPart::baseTarget() const
1949 {
1950   if ( !d->m_doc ) return QString::null;
1951
1952   return d->m_doc->baseTarget();
1953 }
1954 #endif
1955
1956 KURL KHTMLPart::completeURL( const QString &url )
1957 {
1958   if ( !d->m_doc ) return url;
1959
1960 #if !APPLE_CHANGES
1961   if (d->m_decoder)
1962     return KURL(d->m_doc->completeURL(url), d->m_decoder->codec()->mibEnum());
1963 #endif
1964
1965   return KURL( d->m_doc->completeURL( url ) );
1966 }
1967
1968 void KHTMLPart::scheduleRedirection( double delay, const QString &url, bool doLockHistory)
1969 {
1970     kdDebug(6050) << "KHTMLPart::scheduleRedirection delay=" << delay << " url=" << url << endl;
1971     if (delay < 0 || delay > INT_MAX / 1000)
1972       return;
1973     if ( d->m_scheduledRedirection == noRedirectionScheduled || delay <= d->m_delayRedirect )
1974     {
1975        d->m_scheduledRedirection = redirectionScheduled;
1976        d->m_delayRedirect = delay;
1977        d->m_redirectURL = url;
1978        d->m_redirectLockHistory = doLockHistory;
1979        d->m_redirectUserGesture = false;
1980
1981        d->m_redirectionTimer.stop();
1982        if ( d->m_bComplete )
1983          d->m_redirectionTimer.start( (int)(1000 * d->m_delayRedirect), true );
1984     }
1985 }
1986
1987 void KHTMLPart::scheduleLocationChange(const QString &url, bool lockHistory, bool userGesture)
1988 {
1989     // Handle a location change of a page with no document as a special case.
1990     // This may happen when a frame changes the location of another frame.
1991     d->m_scheduledRedirection = d->m_doc ? locationChangeScheduled : locationChangeScheduledDuringLoad;
1992     d->m_delayRedirect = 0;
1993     d->m_redirectURL = url;
1994     d->m_redirectLockHistory = lockHistory;
1995     d->m_redirectUserGesture = userGesture;
1996     d->m_redirectionTimer.stop();
1997     if (d->m_bComplete)
1998         d->m_redirectionTimer.start(0, true);
1999 }
2000
2001 bool KHTMLPart::isScheduledLocationChangePending() const
2002 {
2003     switch (d->m_scheduledRedirection) {
2004         case noRedirectionScheduled:
2005         case redirectionScheduled:
2006             return false;
2007         case historyNavigationScheduled:
2008         case locationChangeScheduled:
2009         case locationChangeScheduledDuringLoad:
2010             return true;
2011     }
2012     return false;
2013 }
2014
2015 void KHTMLPart::scheduleHistoryNavigation( int steps )
2016 {
2017 #if APPLE_CHANGES
2018     // navigation will always be allowed in the 0 steps case, which is OK because
2019     // that's supposed to force a reload.
2020     if (!KWQ(this)->canGoBackOrForward(steps)) {
2021         cancelRedirection();
2022         return;
2023     }
2024 #endif
2025
2026     d->m_scheduledRedirection = historyNavigationScheduled;
2027     d->m_delayRedirect = 0;
2028     d->m_redirectURL = QString::null;
2029     d->m_scheduledHistoryNavigationSteps = steps;
2030     d->m_redirectionTimer.stop();
2031     if (d->m_bComplete)
2032         d->m_redirectionTimer.start(0, true);
2033 }
2034
2035 void KHTMLPart::cancelRedirection(bool cancelWithLoadInProgress)
2036 {
2037     if (d) {
2038         d->m_cancelWithLoadInProgress = cancelWithLoadInProgress;
2039         d->m_scheduledRedirection = noRedirectionScheduled;
2040         d->m_redirectionTimer.stop();
2041     }
2042 }
2043
2044 void KHTMLPart::slotRedirect()
2045 {
2046     if (d->m_scheduledRedirection == historyNavigationScheduled) {
2047         d->m_scheduledRedirection = noRedirectionScheduled;
2048
2049         // Special case for go(0) from a frame -> reload only the frame
2050         // go(i!=0) from a frame navigates into the history of the frame only,
2051         // in both IE and NS (but not in Mozilla).... we can't easily do that
2052         // in Konqueror...
2053         if (d->m_scheduledHistoryNavigationSteps == 0) // add && parentPart() to get only frames, but doesn't matter
2054             openURL( url() ); /// ## need args.reload=true?
2055         else {
2056             if (d->m_extension) {
2057                 BrowserInterface *interface = d->m_extension->browserInterface();
2058                 if (interface)
2059                     interface->callMethod( "goHistory(int)", d->m_scheduledHistoryNavigationSteps );
2060             }
2061         }
2062         return;
2063     }
2064   
2065   QString u = d->m_redirectURL;
2066   d->m_scheduledRedirection = noRedirectionScheduled;
2067   d->m_delayRedirect = 0;
2068   d->m_redirectURL = QString::null;
2069   if ( u.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
2070   {
2071     QString script = KURL::decode_string( u.right( u.length() - 11 ) );
2072     //kdDebug( 6050 ) << "KHTMLPart::slotRedirect script=" << script << endl;
2073     QVariant res = executeScript( script, d->m_redirectUserGesture );
2074     if ( res.type() == QVariant::String ) {
2075       begin( url() );
2076       write( res.asString() );
2077       end();
2078     }
2079     return;
2080   }
2081   KParts::URLArgs args;
2082   if ( urlcmp( u, m_url.url(), true, false ) )
2083     args.reload = true;
2084
2085   args.setLockHistory( d->m_redirectLockHistory );
2086   urlSelected( u, 0, 0, "_self", args );
2087 }
2088
2089 void KHTMLPart::slotRedirection(KIO::Job*, const KURL& url)
2090 {
2091   // the slave told us that we got redirected
2092   // kdDebug( 6050 ) << "redirection by KIO to " << url.url() << endl;
2093   emit d->m_extension->setLocationBarURL( url.prettyURL() );
2094   d->m_workingURL = url;
2095 }
2096
2097 #if !APPLE_CHANGES
2098
2099 bool KHTMLPart::setEncoding( const QString &name, bool override )
2100 {
2101     d->m_encoding = name;
2102     d->m_haveEncoding = override;
2103
2104     if( !m_url.isEmpty() ) {
2105         // reload document
2106         closeURL();
2107         KURL url = m_url;
2108         m_url = 0;
2109         d->m_restored = true;
2110         openURL(url);
2111         d->m_restored = false;
2112     }
2113
2114     return true;
2115 }
2116
2117 #endif
2118
2119 QString KHTMLPart::encoding() const
2120 {
2121     if(d->m_haveEncoding && !d->m_encoding.isEmpty())
2122         return d->m_encoding;
2123
2124     if(d->m_decoder && d->m_decoder->encoding())
2125         return QString(d->m_decoder->encoding());
2126
2127     return(settings()->encoding());
2128 }
2129
2130 void KHTMLPart::setUserStyleSheet(const KURL &url)
2131 {
2132   if ( d->m_doc && d->m_doc->docLoader() )
2133     (void) new khtml::PartStyleSheetLoader(this, url.url(), d->m_doc->docLoader());
2134 }
2135
2136 void KHTMLPart::setUserStyleSheet(const QString &styleSheet)
2137 {
2138   if ( d->m_doc )
2139     d->m_doc->setUserStyleSheet( styleSheet );
2140 }
2141
2142 bool KHTMLPart::gotoAnchor( const QString &name )
2143 {
2144   if (!d->m_doc)
2145     return false;
2146
2147   NodeImpl *n = d->m_doc->getElementById(name);
2148   if (!n) {
2149     HTMLCollectionImpl *anchors =
2150         new HTMLCollectionImpl( d->m_doc, HTMLCollectionImpl::DOC_ANCHORS);
2151     anchors->ref();
2152     n = anchors->namedItem(name, !d->m_doc->inCompatMode());
2153     anchors->deref();
2154   }
2155
2156   d->m_doc->setCSSTarget(n); // Setting to null will clear the current target.
2157   
2158   // Implement the rule that "" and "top" both mean top of page as in other browsers.
2159   if (!n && !(name.isEmpty() || name.lower() == "top")) {
2160     kdDebug(6050) << "KHTMLPart::gotoAnchor node '" << name << "' not found" << endl;
2161     return false;
2162   }
2163
2164   // We need to update the layout before scrolling, otherwise we could
2165   // really mess things up if an anchor scroll comes at a bad moment.
2166   if ( d->m_doc ) {
2167     d->m_doc->updateRendering();
2168     // Only do a layout if changes have occurred that make it necessary.      
2169     if ( d->m_view && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout() ) {
2170       d->m_view->layout();
2171     }
2172   }
2173   
2174   int x = 0, y = 0;
2175   if (n) {
2176     static_cast<HTMLElementImpl *>(n)->getUpperLeftCorner(x, y);
2177   }
2178   // Scroll to actual top left of element with no slop, since some pages expect anchors to be exactly scrolled to.
2179 #if APPLE_CHANGES
2180   // Call recursive version so this will expose correctly from within nested frames.
2181   d->m_view->setContentsPosRecursive(x, y);
2182 #else
2183   d->m_view->setContentsPos(x, y);
2184 #endif
2185
2186   return true;
2187 }
2188
2189 void KHTMLPart::setStandardFont( const QString &name )
2190 {
2191     d->m_settings->setStdFontName(name);
2192 }
2193
2194 void KHTMLPart::setFixedFont( const QString &name )
2195 {
2196     d->m_settings->setFixedFontName(name);
2197 }
2198
2199 #if !APPLE_CHANGES
2200
2201 void KHTMLPart::setURLCursor( const QCursor &c )
2202 {
2203   d->m_linkCursor = c;
2204 }
2205
2206 #endif
2207
2208 QCursor KHTMLPart::urlCursor() const
2209 {
2210 #if APPLE_CHANGES
2211   // Don't load the link cursor until it's actually used.
2212   // Also, we don't need setURLCursor.
2213   // This speeds up startup time.
2214   return KCursor::handCursor();
2215 #else
2216   return d->m_linkCursor;
2217 #endif
2218 }
2219
2220 bool KHTMLPart::onlyLocalReferences() const
2221 {
2222   return d->m_onlyLocalReferences;
2223 }
2224
2225 void KHTMLPart::setOnlyLocalReferences(bool enable)
2226 {
2227   d->m_onlyLocalReferences = enable;
2228 }
2229
2230 #if !APPLE_CHANGES
2231
2232 void KHTMLPart::findTextBegin(NodeImpl *startNode, int startPos)
2233 {
2234     d->m_findPos = startPos;
2235     d->m_findNode = startNode;
2236 }
2237
2238 bool KHTMLPart::findTextNext( const QString &str, bool forward, bool caseSensitive, bool isRegExp )
2239 {
2240     if ( !d->m_doc )
2241         return false;
2242
2243     if(!d->m_findNode) {
2244         if (d->m_doc->isHTMLDocument())
2245             d->m_findNode = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
2246         else
2247             d->m_findNode = d->m_doc;
2248     }
2249
2250     if ( !d->m_findNode )
2251     {
2252       kdDebug() << "KHTMLPart::findTextNext no findNode -> return false" << endl;
2253       return false;
2254     }
2255     if ( d->m_findNode->id() == ID_FRAMESET )
2256     {
2257       kdDebug() << "KHTMLPart::findTextNext FRAMESET -> return false" << endl;
2258       return false;
2259     }
2260
2261     while(1)
2262     {
2263         if( (d->m_findNode->nodeType() == Node::TEXT_NODE || d->m_findNode->nodeType() == Node::CDATA_SECTION_NODE) && d->m_findNode->renderer() )
2264         {
2265             DOMString nodeText = d->m_findNode->nodeValue();
2266             DOMStringImpl *t = nodeText.implementation();
2267             QConstString s(t->s, t->l);
2268
2269             int matchLen = 0;
2270             if ( isRegExp ) {
2271               QRegExp matcher( str );
2272               matcher.setCaseSensitive( caseSensitive );
2273               d->m_findPos = matcher.search(s.string(), d->m_findPos+1);
2274               if ( d->m_findPos != -1 )
2275                 matchLen = matcher.matchedLength();
2276             }
2277             else {
2278               d->m_findPos = s.string().find(str, d->m_findPos+1, caseSensitive);
2279               matchLen = str.length();
2280             }
2281
2282             if(d->m_findPos != -1)
2283             {
2284                 int x = 0, y = 0;
2285                 static_cast<khtml::RenderText *>(d->m_findNode->renderer())
2286                   ->posOfChar(d->m_findPos, x, y);
2287                 d->m_view->setContentsPos(x-50, y-50);
2288                 Position p1(d->m_findNode, d->m_findPos);
2289                 Position p2(d->m_findNode, d->m_findPos + matchLen);
2290                 setSelection(Selection(p1, p2));
2291                 return true;
2292             }
2293         }
2294         d->m_findPos = -1;
2295
2296         NodeImpl *next;
2297
2298         if ( forward )
2299         {
2300           next = d->m_findNode->firstChild();
2301
2302           if(!next) next = d->m_findNode->nextSibling();
2303           while(d->m_findNode && !next) {
2304               d->m_findNode = d->m_findNode->parentNode();
2305               if( d->m_findNode ) {
2306                   next = d->m_findNode->nextSibling();
2307               }
2308           }
2309         }
2310         else
2311         {
2312           next = d->m_findNode->lastChild();
2313
2314           if (!next ) next = d->m_findNode->previousSibling();
2315           while ( d->m_findNode && !next )
2316           {
2317             d->m_findNode = d->m_findNode->parentNode();
2318             if( d->m_findNode )
2319             {
2320               next = d->m_findNode->previousSibling();
2321             }
2322           }
2323         }
2324
2325         d->m_findNode = next;
2326         if(!d->m_findNode) return false;
2327     }
2328 }
2329
2330 #endif // APPLE_CHANGES
2331
2332 QString KHTMLPart::text(const DOM::Range &r) const
2333 {
2334     return plainText(r);
2335 }
2336
2337 QString KHTMLPart::selectedText() const
2338 {
2339     return text(selection().toRange());
2340 }
2341
2342 bool KHTMLPart::hasSelection() const
2343 {
2344     return d->m_selection.isCaretOrRange();
2345 }
2346
2347 const Selection &KHTMLPart::selection() const
2348 {
2349     return d->m_selection;
2350 }
2351
2352 ETextGranularity KHTMLPart::selectionGranularity() const
2353 {
2354     return d->m_selectionGranularity;
2355 }
2356
2357 const Selection &KHTMLPart::dragCaret() const
2358 {
2359     return d->m_dragCaret;
2360 }
2361
2362 const Selection &KHTMLPart::mark() const
2363 {
2364     return d->m_mark;
2365 }
2366
2367 void KHTMLPart::setMark(const Selection &s)
2368 {
2369     d->m_mark = s;
2370 }
2371
2372 void KHTMLPart::setSelection(const Selection &s, bool closeTyping, bool keepTypingStyle)
2373 {
2374     if (d->m_selection == s) {
2375         return;
2376     }
2377     
2378     clearCaretRectIfNeeded();
2379
2380 #if APPLE_CHANGES
2381     Selection oldSelection = d->m_selection;
2382 #endif
2383
2384     d->m_selection = s;
2385     if (!s.isNone())
2386         setFocusNodeIfNeeded();
2387
2388     selectionLayoutChanged();
2389
2390     // Always clear the x position used for vertical arrow navigation.
2391     // It will be restored by the vertical arrow navigation code if necessary.
2392     d->m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation;
2393
2394     if (closeTyping)
2395         TypingCommand::closeTyping(lastEditCommand());
2396
2397     if (!keepTypingStyle)
2398         clearTypingStyle();
2399     
2400 #if APPLE_CHANGES
2401     KWQ(this)->respondToChangedSelection(oldSelection, closeTyping);
2402 #endif
2403
2404     emitSelectionChanged();
2405 }
2406
2407 void KHTMLPart::setDragCaret(const Selection &dragCaret)
2408 {
2409     if (d->m_dragCaret != dragCaret) {
2410         d->m_dragCaret.needsCaretRepaint();
2411         d->m_dragCaret = dragCaret;
2412         d->m_dragCaret.needsCaretRepaint();
2413     }
2414 }
2415
2416 void KHTMLPart::clearSelection()
2417 {
2418     setSelection(Selection());
2419 }
2420
2421 void KHTMLPart::invalidateSelection()
2422 {
2423     clearCaretRectIfNeeded();
2424     d->m_selection.setNeedsLayout();
2425     selectionLayoutChanged();
2426 }
2427
2428 void KHTMLPart::setCaretVisible(bool flag)
2429 {
2430     if (d->m_caretVisible == flag)
2431         return;
2432     clearCaretRectIfNeeded();
2433     if (flag)
2434         setFocusNodeIfNeeded();
2435     d->m_caretVisible = flag;
2436     selectionLayoutChanged();
2437 }
2438
2439 #if !APPLE_CHANGES
2440 void KHTMLPart::slotClearSelection()
2441 {
2442     clearSelection();
2443 }
2444 #endif
2445
2446 void KHTMLPart::clearCaretRectIfNeeded()
2447 {
2448     if (d->m_caretPaint) {
2449         d->m_caretPaint = false;
2450         d->m_selection.needsCaretRepaint();
2451     }        
2452 }
2453
2454 void KHTMLPart::setFocusNodeIfNeeded()
2455 {
2456     if (!xmlDocImpl() || d->m_selection.isNone() || !d->m_isFocused)
2457         return;
2458
2459     NodeImpl *n = d->m_selection.start().node();
2460     NodeImpl *target = (n && n->isContentEditable()) ? n : 0;
2461     if (!target) {
2462         while (n && n != d->m_selection.end().node()) {
2463             if (n->isContentEditable()) {
2464                 target = n;
2465                 break;
2466             }
2467             n = n->traverseNextNode();
2468         }
2469     }
2470     assert(target == 0 || target->isContentEditable());
2471     
2472     if (target) {
2473         for ( ; target; target = target->parentNode()) {
2474             if (target->isMouseFocusable()) {
2475                 xmlDocImpl()->setFocusNode(target);
2476                 return;
2477             }
2478         }
2479         xmlDocImpl()->setFocusNode(0);
2480     }
2481 }
2482
2483 void KHTMLPart::selectionLayoutChanged()
2484 {
2485     // kill any caret blink timer now running
2486     if (d->m_caretBlinkTimer >= 0) {
2487         killTimer(d->m_caretBlinkTimer);
2488         d->m_caretBlinkTimer = -1;
2489     }
2490
2491     // see if a new caret blink timer needs to be started
2492     if (d->m_caretVisible && d->m_caretBlinks && 
2493         d->m_selection.isCaret() && d->m_selection.start().node()->isContentEditable()) {
2494         d->m_caretBlinkTimer = startTimer(CARET_BLINK_FREQUENCY);
2495         d->m_caretPaint = true;
2496         d->m_selection.needsCaretRepaint();
2497     }
2498
2499     if (d->m_doc)
2500         d->m_doc->updateSelection();
2501 }
2502
2503 void KHTMLPart::setXPosForVerticalArrowNavigation(int x)
2504 {
2505     d->m_xPosForVerticalArrowNavigation = x;
2506 }
2507
2508 int KHTMLPart::xPosForVerticalArrowNavigation() const
2509 {
2510     return d->m_xPosForVerticalArrowNavigation;
2511 }
2512
2513 void KHTMLPart::timerEvent(QTimerEvent *e)
2514 {
2515     if (e->timerId() == d->m_caretBlinkTimer && 
2516         d->m_caretVisible && 
2517         d->m_caretBlinks && 
2518         d->m_selection.isCaret()) {
2519         if (d->m_bMousePressed) {
2520             if (!d->m_caretPaint) {
2521                 d->m_caretPaint = true;
2522                 d->m_selection.needsCaretRepaint();
2523             }
2524         }
2525         else {
2526             d->m_caretPaint = !d->m_caretPaint;
2527             d->m_selection.needsCaretRepaint();
2528         }
2529     }
2530 }
2531
2532 void KHTMLPart::paintCaret(QPainter *p, const QRect &rect) const
2533 {
2534     if (d->m_caretPaint)
2535         d->m_selection.paintCaret(p, rect);
2536 }
2537
2538 void KHTMLPart::paintDragCaret(QPainter *p, const QRect &rect) const
2539 {
2540     d->m_dragCaret.paintCaret(p, rect);
2541 }
2542
2543 #if !APPLE_CHANGES
2544
2545 void KHTMLPart::overURL( const QString &url, const QString &target, bool shiftPressed )
2546 {
2547   if ( !d->m_kjsStatusBarText.isEmpty() && !shiftPressed ) {
2548     emit onURL( url );
2549     emit setStatusBarText( d->m_kjsStatusBarText );
2550     d->m_kjsStatusBarText = QString::null;
2551     return;
2552   }
2553
2554   emit onURL( url );
2555
2556   if ( url.isEmpty() )
2557   {
2558     emit setStatusBarText(completeURL(url).htmlURL());
2559     return;
2560   }
2561
2562   if (url.find( QString::fromLatin1( "javascript:" ),0, false ) != -1 )
2563   {
2564     emit setStatusBarText( KURL::decode_string( url.mid( url.find( "javascript:", 0, false ) ) ) );
2565     return;
2566   }
2567
2568   KURL u = completeURL(url);
2569
2570   // special case for <a href="">
2571   if ( url.isEmpty() )
2572     u.setFileName( url );
2573
2574   QString com;
2575
2576   KMimeType::Ptr typ = KMimeType::findByURL( u );
2577
2578   if ( typ )
2579     com = typ->comment( u, false );
2580
2581   if ( u.isMalformed() )
2582   {
2583     emit setStatusBarText(u.htmlURL());
2584     return;
2585   }
2586
2587   if ( u.isLocalFile() )
2588   {
2589     // TODO : use KIO::stat() and create a KFileItem out of its result,
2590     // to use KFileItem::statusBarText()
2591     QCString path = QFile::encodeName( u.path() );
2592
2593     struct stat buff;
2594     bool ok = !stat( path.data(), &buff );
2595
2596     struct stat lbuff;
2597     if (ok) ok = !lstat( path.data(), &lbuff );
2598
2599     QString text = u.htmlURL();
2600     QString text2 = text;
2601
2602     if (ok && S_ISLNK( lbuff.st_mode ) )
2603     {
2604       QString tmp;
2605       if ( com.isNull() )
2606         tmp = i18n( "Symbolic Link");
2607       else
2608         tmp = i18n("%1 (Link)").arg(com);
2609       char buff_two[1024];
2610       text += " -> ";
2611       int n = readlink ( path.data(), buff_two, 1022);
2612       if (n == -1)
2613       {
2614         text2 += "  ";
2615         text2 += tmp;
2616         emit setStatusBarText(text2);
2617         return;
2618       }
2619       buff_two[n] = 0;
2620
2621       text += buff_two;
2622       text += "  ";
2623       text += tmp;
2624     }
2625     else if ( ok && S_ISREG( buff.st_mode ) )
2626     {
2627       if (buff.st_size < 1024)
2628         text = i18n("%2 (%1 bytes)").arg((long) buff.st_size).arg(text2); // always put the URL last, in case it contains '%'
2629       else
2630       {
2631         float d = (float) buff.st_size/1024.0;
2632         text = i18n("%1 (%2 K)").arg(text2).arg(KGlobal::locale()->formatNumber(d, 2)); // was %.2f
2633       }
2634       text += "  ";
2635       text += com;
2636     }
2637     else if ( ok && S_ISDIR( buff.st_mode ) )
2638     {
2639       text += "  ";
2640       text += com;
2641     }
2642     else
2643     {
2644       text += "  ";
2645       text += com;
2646     }
2647     emit setStatusBarText(text);
2648   }
2649   else
2650   {
2651     QString extra;
2652     if (target == QString::fromLatin1("_blank"))
2653     {
2654       extra = i18n(" (In new window)");
2655     }
2656     else if (!target.isEmpty() &&
2657              (target != QString::fromLatin1("_top")) &&
2658              (target != QString::fromLatin1("_self")) &&
2659              (target != QString::fromLatin1("_parent")))
2660     {
2661       extra = i18n(" (In other frame)");
2662     }
2663
2664     if (u.protocol() == QString::fromLatin1("mailto")) {
2665       QString mailtoMsg/* = QString::fromLatin1("<img src=%1>").arg(locate("icon", QString::fromLatin1("locolor/16x16/actions/mail_send.png")))*/;
2666       mailtoMsg += i18n("Email to: ") + KURL::decode_string(u.path());
2667       QStringList queries = QStringList::split('&', u.query().mid(1));
2668       for (QStringList::Iterator it = queries.begin(); it != queries.end(); ++it)
2669         if ((*it).startsWith(QString::fromLatin1("subject=")))
2670           mailtoMsg += i18n(" - Subject: ") + KURL::decode_string((*it).mid(8));
2671         else if ((*it).startsWith(QString::fromLatin1("cc=")))
2672           mailtoMsg += i18n(" - CC: ") + KURL::decode_string((*it).mid(3));
2673         else if ((*it).startsWith(QString::fromLatin1("bcc=")))
2674           mailtoMsg += i18n(" - BCC: ") + KURL::decode_string((*it).mid(4));
2675       mailtoMsg.replace(QRegExp("&"), QString("&amp;"));
2676       mailtoMsg.replace(QRegExp("<"), QString("&lt;"));
2677       mailtoMsg.replace(QRegExp(">"), QString("&gt;"));
2678       mailtoMsg.replace(QRegExp("([\n\r\t]|[ ]{10})"), "");
2679       emit setStatusBarText(mailtoMsg);
2680       return;
2681     }
2682    // Is this check neccessary at all? (Frerich)
2683 #if 0
2684     else if (u.protocol() == QString::fromLatin1("http")) {
2685         DOM::Node hrefNode = nodeUnderMouse().parentNode();
2686         while (hrefNode.nodeName().string() != QString::fromLatin1("A") && !hrefNode.isNull())
2687           hrefNode = hrefNode.parentNode();
2688
2689         if (!hrefNode.isNull()) {
2690           DOM::Node hreflangNode = hrefNode.attributes().getNamedItem("HREFLANG");
2691           if (!hreflangNode.isNull()) {
2692             QString countryCode = hreflangNode.nodeValue().string().lower();
2693             // Map the language code to an appropriate country code.
2694             if (countryCode == QString::fromLatin1("en"))
2695               countryCode = QString::fromLatin1("gb");
2696             QString flagImg = QString::fromLatin1("<img src=%1>").arg(
2697                 locate("locale", QString::fromLatin1("l10n/")
2698                 + countryCode
2699                 + QString::fromLatin1("/flag.png")));
2700             emit setStatusBarText(flagImg + u.prettyURL() + extra);
2701           }
2702         }
2703       }
2704 #endif
2705     emit setStatusBarText(u.htmlURL() + extra);
2706   }
2707 }
2708
2709 #endif // APPLE_CHANGES
2710
2711 void KHTMLPart::urlSelected( const QString &url, int button, int state, const QString &_target,
2712                              KParts::URLArgs args )
2713 {
2714   bool hasTarget = false;
2715
2716   QString target = _target;
2717   if ( target.isEmpty() && d->m_doc )
2718     target = d->m_doc->baseTarget();
2719   if ( !target.isEmpty() )
2720       hasTarget = true;
2721
2722   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
2723   {
2724     executeScript( KURL::decode_string( url.right( url.length() - 11) ), true );
2725     return;
2726   }
2727
2728   KURL cURL = completeURL(url);
2729 #if !APPLE_CHANGES
2730   // special case for <a href="">
2731   if ( url.isEmpty() )
2732     cURL.setFileName( url );
2733 #endif
2734
2735   if ( !cURL.isValid() )
2736     // ### ERROR HANDLING
2737     return;
2738
2739   //kdDebug( 6000 ) << "urlSelected: complete URL:" << cURL.url() << " target = " << target << endl;
2740
2741 #if !APPLE_CHANGES
2742   if ( button == LeftButton && ( state & ShiftButton ) )
2743   {
2744     KIO::MetaData metaData;
2745     metaData["referrer"] = d->m_referrer;
2746     KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As..." ), cURL, metaData );
2747     return;
2748   }
2749
2750   if (!checkLinkSecurity(cURL,
2751                          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?" ),
2752                          i18n( "Follow" )))
2753     return;
2754 #endif
2755
2756   args.frameName = target;
2757
2758   if ( d->m_bHTTPRefresh )
2759   {
2760     d->m_bHTTPRefresh = false;
2761     args.metaData()["cache"] = "refresh";
2762   }
2763
2764 #if !APPLE_CHANGES
2765   args.metaData().insert("main_frame_request",
2766                          parentPart() == 0 ? "TRUE":"FALSE");
2767   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
2768   args.metaData().insert("ssl_activate_warnings", "TRUE");
2769 #endif
2770
2771 #if APPLE_CHANGES
2772   args.metaData()["referrer"] = d->m_referrer;
2773   KWQ(this)->urlSelected(cURL, button, state, args);
2774 #else
2775   if ( hasTarget )
2776   {
2777     // unknown frame names should open in a new window.
2778     khtml::ChildFrame *frame = recursiveFrameRequest( cURL, args, false );
2779     if ( frame )
2780     {
2781       args.metaData()["referrer"] = d->m_referrer;
2782       requestObject( frame, cURL, args );
2783       return;
2784     }
2785   }
2786
2787   if ( !d->m_bComplete && !hasTarget )
2788     closeURL();
2789
2790   if (!d->m_referrer.isEmpty())
2791     args.metaData()["referrer"] = d->m_referrer;
2792
2793   if ( button == MidButton && (state & ShiftButton) )
2794   {
2795     KParts::WindowArgs winArgs;
2796     winArgs.lowerWindow = true;
2797     KParts::ReadOnlyPart *newPart = 0;
2798     emit d->m_extension->createNewWindow( cURL, args, winArgs, newPart );
2799     return;
2800   }
2801   emit d->m_extension->openURLRequest( cURL, args );
2802 #endif // APPLE_CHANGES
2803 }
2804
2805 #if !APPLE_CHANGES
2806
2807 void KHTMLPart::slotViewDocumentSource()
2808 {
2809   KURL url(m_url);
2810   if (!(url.isLocalFile()) && KHTMLPageCache::self()->isValid(d->m_cacheId))
2811   {
2812      KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
2813      if (sourceFile.status() == 0)
2814      {
2815         KHTMLPageCache::self()->saveData(d->m_cacheId, sourceFile.dataStream());
2816         url = KURL();
2817         url.setPath(sourceFile.name());
2818      }
2819   }
2820
2821   //  emit d->m_extension->openURLRequest( m_url, KParts::URLArgs( false, 0, 0, QString::fromLatin1( "text/plain" ) ) );
2822   (void) KRun::runURL( url, QString::fromLatin1("text/plain") );
2823 }
2824
2825 void KHTMLPart::slotViewFrameSource()
2826 {
2827   KParts::ReadOnlyPart *frame = currentFrame();
2828   if ( !frame )
2829     return;
2830
2831   KURL url = frame->url();
2832   if (!(url.isLocalFile()) && frame->inherits("KHTMLPart"))
2833   {
2834        long cacheId = static_cast<KHTMLPart *>(frame)->d->m_cacheId;
2835
2836        if (KHTMLPageCache::self()->isValid(cacheId))
2837        {
2838            KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
2839            if (sourceFile.status() == 0)
2840            {
2841                KHTMLPageCache::self()->saveData(cacheId, sourceFile.dataStream());
2842                url = KURL();
2843                url.setPath(sourceFile.name());
2844            }
2845      }
2846   }
2847
2848   (void) KRun::runURL( url, QString::fromLatin1("text/plain") );
2849 }
2850
2851 KURL KHTMLPart::backgroundURL() const
2852 {
2853   // ### what about XML documents? get from CSS?
2854   if (!d->m_doc || !d->m_doc->isHTMLDocument())
2855     return KURL();
2856
2857   QString relURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
2858
2859   return KURL( m_url, relURL );
2860 }
2861
2862 void KHTMLPart::slotSaveBackground()
2863 {
2864   KIO::MetaData metaData;
2865   metaData["referrer"] = d->m_referrer;
2866   KHTMLPopupGUIClient::saveURL( d->m_view, i18n("Save background image as"), backgroundURL(), metaData );
2867 }
2868
2869 void KHTMLPart::slotSaveDocument()
2870 {
2871   KURL srcURL( m_url );
2872
2873   if ( srcURL.fileName(false).isEmpty() )
2874     srcURL.setFileName( "index.html" );
2875
2876   KIO::MetaData metaData;
2877   // Referre unknown?
2878   KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, i18n("*.html *.htm|HTML files"), d->m_cacheId );
2879 }
2880
2881 void KHTMLPart::slotSecurity()
2882 {
2883 //   kdDebug( 6050 ) << "Meta Data:" << endl
2884 //                   << d->m_ssl_peer_cert_subject
2885 //                   << endl
2886 //                   << d->m_ssl_peer_cert_issuer
2887 //                   << endl
2888 //                   << d->m_ssl_cipher
2889 //                   << endl
2890 //                   << d->m_ssl_cipher_desc
2891 //                   << endl
2892 //                   << d->m_ssl_cipher_version
2893 //                   << endl
2894 //                   << d->m_ssl_good_from
2895 //                   << endl
2896 //                   << d->m_ssl_good_until
2897 //                   << endl
2898 //                   << d->m_ssl_cert_state
2899 //                   << endl;
2900
2901   KSSLInfoDlg *kid = new KSSLInfoDlg(d->m_ssl_in_use, widget(), "kssl_info_dlg", true );
2902
2903   if (d->m_bSecurityInQuestion)
2904           kid->setSecurityInQuestion(true);
2905
2906   if (d->m_ssl_in_use) {
2907     KSSLCertificate *x = KSSLCertificate::fromString(d->m_ssl_peer_certificate.local8Bit());
2908     if (x) {
2909        // Set the chain back onto the certificate
2910        QStringList cl = QStringList::split(QString("\n"), d->m_ssl_peer_chain);
2911        QPtrList<KSSLCertificate> ncl;
2912
2913        ncl.setAutoDelete(true);
2914        for (QStringList::Iterator it = cl.begin(); it != cl.end(); ++it) {
2915           KSSLCertificate *y = KSSLCertificate::fromString((*it).local8Bit());
2916           if (y) ncl.append(y);
2917        }
2918
2919        if (ncl.count() > 0)
2920           x->chain().setChain(ncl);
2921
2922        kid->setup(x,
2923                   d->m_ssl_peer_ip,
2924                   m_url.url(),
2925                   d->m_ssl_cipher,
2926                   d->m_ssl_cipher_desc,
2927                   d->m_ssl_cipher_version,
2928                   d->m_ssl_cipher_used_bits.toInt(),
2929                   d->m_ssl_cipher_bits.toInt(),
2930                   (KSSLCertificate::KSSLValidation) d->m_ssl_cert_state.toInt()
2931                   );
2932         kid->exec();
2933         delete x;
2934      } else kid->exec();
2935   } else kid->exec();
2936 }
2937
2938 void KHTMLPart::slotSaveFrame()
2939 {
2940     if ( !d->m_activeFrame )
2941         return; // should never be the case, but one never knows :-)
2942
2943     KURL srcURL( static_cast<KParts::ReadOnlyPart *>( d->m_activeFrame )->url() );
2944
2945     if ( srcURL.fileName(false).isEmpty() )
2946         srcURL.setFileName( "index.html" );
2947
2948     KIO::MetaData metaData;
2949     // Referrer unknown?
2950     KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, i18n("*.html *.htm|HTML files") );
2951 }
2952
2953 void KHTMLPart::slotSetEncoding()
2954 {
2955     // first Item is always auto
2956     if(d->m_paSetEncoding->currentItem() == 0)
2957         setEncoding(QString::null, false);
2958     else {
2959         // strip of the language to get the raw encoding again.
2960         QString enc = KGlobal::charsets()->encodingForName(d->m_paSetEncoding->currentText());
2961         setEncoding(enc, true);
2962     }
2963 }
2964
2965 void KHTMLPart::slotUseStylesheet()
2966 {
2967   if (d->m_doc && d->m_paUseStylesheet->currentText() != d->m_sheetUsed) {
2968     d->m_sheetUsed = d->m_paUseStylesheet->currentText();
2969     d->m_doc->updateStyleSelector();
2970   }
2971 }
2972
2973 void KHTMLPart::updateActions()
2974 {
2975   bool frames = false;
2976
2977   QValueList<khtml::ChildFrame>::ConstIterator it = d->m_frames.begin();
2978   QValueList<khtml::ChildFrame>::ConstIterator end = d->m_frames.end();
2979   for (; it != end; ++it )
2980       if ( (*it).m_type == khtml::ChildFrame::Frame )
2981       {
2982           frames = true;
2983           break;
2984       }
2985
2986   d->m_paViewFrame->setEnabled( frames );
2987   d->m_paSaveFrame->setEnabled( frames );
2988
2989   if ( frames )
2990     d->m_paFind->setText( i18n( "&Find in Frame..." ) );
2991   else
2992     d->m_paFind->setText( i18n( "&Find..." ) );
2993
2994   KParts::Part *frame = 0;
2995
2996   if ( frames )
2997     frame = currentFrame();
2998
2999   bool enableFindAndSelectAll = true;
3000
3001   if ( frame )
3002     enableFindAndSelectAll = frame->inherits( "KHTMLPart" );
3003
3004   d->m_paFind->setEnabled( enableFindAndSelectAll );
3005   d->m_paSelectAll->setEnabled( enableFindAndSelectAll );
3006
3007   bool enablePrintFrame = false;
3008
3009   if ( frame )
3010   {
3011     QObject *ext = KParts::BrowserExtension::childObject( frame );
3012     if ( ext )
3013       enablePrintFrame = ext->metaObject()->slotNames().contains( "print()" );
3014   }
3015
3016   d->m_paPrintFrame->setEnabled( enablePrintFrame );
3017
3018   QString bgURL;
3019
3020   // ### frames
3021   if ( d->m_doc && d->m_doc->isHTMLDocument() && static_cast<HTMLDocumentImpl*>(d->m_doc)->body() && !d->m_bClearing )
3022     bgURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
3023
3024   d->m_paSaveBackground->setEnabled( !bgURL.isEmpty() );
3025 }
3026
3027 #endif
3028
3029 bool KHTMLPart::requestFrame( khtml::RenderPart *frame, const QString &url, const QString &frameName,
3030                               const QStringList &paramNames, const QStringList &paramValues, bool isIFrame )
3031 {
3032 //  kdDebug( 6050 ) << "childRequest( ..., " << url << ", " << frameName << " )" << endl;
3033   FrameIt it = d->m_frames.find( frameName );
3034   if ( it == d->m_frames.end() )
3035   {
3036     khtml::ChildFrame child;
3037 //    kdDebug( 6050 ) << "inserting new frame into frame map " << frameName << endl;
3038     child.m_name = frameName;
3039     it = d->m_frames.append( child );
3040   }
3041
3042   (*it).m_type = isIFrame ? khtml::ChildFrame::IFrame : khtml::ChildFrame::Frame;
3043   (*it).m_frame = frame;
3044   (*it).m_paramValues = paramNames;
3045   (*it).m_paramNames = paramValues;
3046
3047   // Support for <frame src="javascript:string">
3048   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
3049   {
3050     if (!processObjectRequest(&(*it), "about:blank", "text/html" ))
3051       return false;
3052
3053     KHTMLPart *newPart = static_cast<KHTMLPart *>(&*(*it).m_part); 
3054     newPart->replaceContentsWithScriptResult( url );
3055
3056     return true;
3057   }
3058
3059   return requestObject( &(*it), completeURL( url ));
3060 }
3061
3062 QString KHTMLPart::requestFrameName()
3063 {
3064 #if APPLE_CHANGES
3065     return KWQ(this)->generateFrameName();
3066 #else
3067     return QString::fromLatin1("<!--frame %1-->").arg(d->m_frameNameId++);
3068 #endif
3069 }
3070
3071 bool KHTMLPart::requestObject( khtml::RenderPart *frame, const QString &url, const QString &serviceType,
3072                                const QStringList &paramNames, const QStringList &paramValues )
3073 {
3074   khtml::ChildFrame child;
3075   QValueList<khtml::ChildFrame>::Iterator it = d->m_objects.append( child );
3076   (*it).m_frame = frame;
3077   (*it).m_type = khtml::ChildFrame::Object;
3078   (*it).m_paramNames = paramNames;
3079   (*it).m_paramValues = paramValues;
3080
3081   KURL completedURL;
3082   if (!url.isEmpty())
3083     completedURL = completeURL(url);
3084
3085   KParts::URLArgs args;
3086   args.serviceType = serviceType;
3087   return requestObject( &(*it), completedURL, args );
3088 }
3089
3090 bool KHTMLPart::requestObject( khtml::ChildFrame *child, const KURL &url, const KParts::URLArgs &_args )
3091 {
3092 #if !APPLE_CHANGES
3093   if (!checkLinkSecurity(url))
3094     return false;
3095 #endif
3096   if ( child->m_bPreloaded )
3097   {
3098     // kdDebug(6005) << "KHTMLPart::requestObject preload" << endl;
3099     if ( child->m_frame && child->m_part && child->m_part->widget() )
3100       child->m_frame->setWidget( child->m_part->widget() );
3101
3102     child->m_bPreloaded = false;
3103     return true;
3104   }
3105
3106   KParts::URLArgs args( _args );
3107
3108 #if !APPLE_CHANGES
3109   if ( child->m_run )
3110     child->m_run->abort();
3111 #endif
3112
3113   if ( child->m_part && !args.reload && urlcmp( child->m_part->url().url(), url.url(), true, true ) )
3114     args.serviceType = child->m_serviceType;
3115
3116   child->m_args = args;
3117   child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload) || (d->m_cachePolicy == KIO::CC_Refresh);
3118   child->m_serviceName = QString::null;
3119   if (!d->m_referrer.isEmpty() && !child->m_args.metaData().contains( "referrer" ))
3120     child->m_args.metaData()["referrer"] = d->m_referrer;
3121
3122 #if !APPLE_CHANGES
3123   child->m_args.metaData().insert("main_frame_request",
3124                                   parentPart() == 0 ? "TRUE":"FALSE");
3125   child->m_args.metaData().insert("ssl_was_in_use",
3126                                   d->m_ssl_in_use ? "TRUE":"FALSE");
3127   child->m_args.metaData().insert("ssl_activate_warnings", "TRUE");
3128 #endif
3129
3130   // We want a KHTMLPart if the HTML says <frame src=""> or <frame src="about:blank">
3131   if ((url.isEmpty() || url.url() == "about:blank") && args.serviceType.isEmpty())
3132     args.serviceType = QString::fromLatin1( "text/html" );
3133
3134 #if APPLE_CHANGES
3135   return processObjectRequest( child, url, args.serviceType );
3136 #else
3137   if ( args.serviceType.isEmpty() ) {
3138     child->m_run = new KHTMLRun( this, child, url, child->m_args,
3139                                  child->m_type != khtml::ChildFrame::Frame );
3140     return false;
3141   } else {
3142     return processObjectRequest( child, url, args.serviceType );
3143   }
3144 #endif
3145 }
3146
3147 bool KHTMLPart::processObjectRequest( khtml::ChildFrame *child, const KURL &_url, const QString &mimetype )
3148 {
3149   //kdDebug( 6050 ) << "KHTMLPart::processObjectRequest trying to create part for " << mimetype << endl;
3150
3151   // IMPORTANT: create a copy of the url here, because it is just a reference, which was likely to be given
3152   // by an emitting frame part (emit openURLRequest( blahurl, ... ) . A few lines below we delete the part
3153   // though -> the reference becomes invalid -> crash is likely
3154   KURL url( _url );
3155
3156   // khtmlrun called us this way to indicate a loading error
3157   if ( d->m_onlyLocalReferences || ( url.isEmpty() && mimetype.isEmpty() ) )
3158   {
3159       checkEmitLoadEvent();
3160       child->m_bCompleted = true;
3161       return true;
3162   }
3163
3164   if (child->m_bNotify)
3165   {
3166       child->m_bNotify = false;
3167       if ( !child->m_args.lockHistory() )
3168           emit d->m_extension->openURLNotify();
3169   }
3170
3171 #if APPLE_CHANGES
3172   if ( child->m_part )
3173   {
3174     KHTMLPart *part = dynamic_cast<KHTMLPart *>(&*child->m_part);
3175     if (part)
3176       part->openURL(url);
3177   }
3178   else
3179   {
3180     KParts::ReadOnlyPart *part = KWQ(this)->createPart(*child, url, mimetype);
3181     KHTMLPart *khtml_part = dynamic_cast<KHTMLPart *>(part);
3182     if (khtml_part)
3183       khtml_part->childBegin();
3184 #else
3185   if ( !child->m_services.contains( mimetype ) )
3186   {
3187     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 );
3188 #endif
3189
3190     if ( !part )
3191     {
3192         if ( child->m_frame )
3193           if (child->m_frame->partLoadingErrorNotify( child, url, mimetype ))
3194             return true; // we succeeded after all (a fallback was used)
3195
3196         checkEmitLoadEvent();
3197         return false;
3198     }
3199
3200     //CRITICAL STUFF
3201     if ( child->m_part )
3202     {
3203       disconnectChild(child);
3204 #if !APPLE_CHANGES
3205       partManager()->removePart( (KParts::ReadOnlyPart *)child->m_part );
3206 #endif
3207       child->m_part->deref();
3208     }
3209
3210     child->m_serviceType = mimetype;
3211     if ( child->m_frame && part->widget() )
3212       child->m_frame->setWidget( part->widget() );
3213
3214 #if !APPLE_CHANGES
3215     if ( child->m_type != khtml::ChildFrame::Object )
3216       partManager()->addPart( part, false );
3217 //  else
3218 //      kdDebug(6005) << "AH! NO FRAME!!!!!" << endl;
3219 #endif
3220
3221     child->m_part = part;
3222     assert( ((void*) child->m_part) != 0);
3223
3224     connectChild(child);
3225
3226 #if APPLE_CHANGES
3227   }
3228 #else
3229     child->m_extension = KParts::BrowserExtension::childObject( part );
3230
3231     if ( child->m_extension )
3232     {
3233       connect( child->m_extension, SIGNAL( openURLNotify() ),
3234                d->m_extension, SIGNAL( openURLNotify() ) );
3235
3236       connect( child->m_extension, SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ),
3237                this, SLOT( slotChildURLRequest( const KURL &, const KParts::URLArgs & ) ) );
3238
3239       connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ),
3240                d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ) );
3241       connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs &, const KParts::WindowArgs &, KParts::ReadOnlyPart *& ) ),
3242                d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & , const KParts::WindowArgs &, KParts::ReadOnlyPart *&) ) );
3243
3244       connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ),
3245                d->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ) );
3246       connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ),
3247                d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ) );
3248       connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ),
3249                d->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ) );
3250       connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ),
3251                d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ) );
3252
3253       connect( child->m_extension, SIGNAL( infoMessage( const QString & ) ),
3254                d->m_extension, SIGNAL( infoMessage( const QString & ) ) );
3255
3256       child->m_extension->setBrowserInterface( d->m_extension->browserInterface() );
3257     }
3258   }
3259 #endif
3260
3261   checkEmitLoadEvent();
3262   // Some JS code in the load event may have destroyed the part
3263   // In that case, abort
3264   if ( !child->m_part )
3265     return false;
3266
3267   if ( child->m_bPreloaded )
3268   {
3269     if ( child->m_frame && child->m_part )
3270       child->m_frame->setWidget( child->m_part->widget() );
3271
3272     child->m_bPreloaded = false;
3273     return true;
3274   }
3275
3276   child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload) || (d->m_cachePolicy == KIO::CC_Refresh);
3277
3278   // make sure the part has a way to find out about the mimetype.
3279   // we actually set it in child->m_args in requestObject already,
3280   // but it's useless if we had to use a KHTMLRun instance, as the
3281   // point the run object is to find out exactly the mimetype.
3282   child->m_args.serviceType = mimetype;
3283
3284   child->m_bCompleted = false;
3285   if ( child->m_extension )
3286     child->m_extension->setURLArgs( child->m_args );
3287
3288 #if APPLE_CHANGES
3289     // In these cases, the synchronous load would have finished
3290     // before we could connect the signals, so make sure to send the
3291     // completed() signal for the child by hand:
3292     if (url.isEmpty() || url.url() == "about:blank") {
3293       ReadOnlyPart *readOnlyPart = child->m_part;
3294       KHTMLPart *part = dynamic_cast<KHTMLPart *>(readOnlyPart);
3295       if (part) {
3296         part->completed();
3297       }
3298     }
3299 #else
3300   if(url.protocol() == "javascript" || url.url() == "about:blank") {
3301       if (!child->m_part->inherits("KHTMLPart"))
3302           return false;
3303
3304       KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>(child->m_part));
3305
3306       p->begin();
3307       if (d->m_doc && p->d->m_doc)
3308         p->d->m_doc->setBaseURL(d->m_doc->baseURL());
3309       if (!url.url().startsWith("about:")) {
3310         p->write(url.path());
3311       } else {
3312         p->m_url = url;
3313       }
3314       p->end();
3315       return true;
3316   }
3317   else if ( !url.isEmpty() )
3318   {
3319       //kdDebug( 6050 ) << "opening " << url.url() << " in frame " << child->m_part << endl;
3320       return child->m_part->openURL( url );
3321   }
3322   else
3323 #endif
3324       return true;
3325 }
3326
3327 #if !APPLE_CHANGES
3328
3329 KParts::ReadOnlyPart *KHTMLPart::createPart( QWidget *parentWidget, const char *widgetName,
3330                                              QObject *parent, const char *name, const QString &mimetype,
3331                                              QString &serviceName, QStringList &serviceTypes,
3332                                              const QStringList &params )
3333 {
3334   QString constr;
3335   if ( !serviceName.isEmpty() )
3336     constr.append( QString::fromLatin1( "Name == '%1'" ).arg( serviceName ) );
3337
3338   KTrader::OfferList offers = KTrader::self()->query( mimetype, "KParts/ReadOnlyPart", constr, QString::null );
3339
3340   if ( offers.isEmpty() )
3341     return 0L;
3342
3343   KService::Ptr service = *offers.begin();
3344
3345   KLibFactory *factory = KLibLoader::self()->factory( QFile::encodeName(service->library()) );
3346
3347   if ( !factory )
3348     return 0L;
3349
3350   KParts::ReadOnlyPart *res = 0L;
3351
3352   const char *className = "KParts::ReadOnlyPart";
3353   if ( service->serviceTypes().contains( "Browser/View" ) )
3354     className = "Browser/View";
3355
3356   if ( factory->inherits( "KParts::Factory" ) )
3357     res = static_cast<KParts::ReadOnlyPart *>(static_cast<KParts::Factory *>( factory )->createPart( parentWidget, widgetName, parent, name, className, params ));
3358   else
3359   res = static_cast<KParts::ReadOnlyPart *>(factory->create( parentWidget, widgetName, className ));
3360
3361   if ( !res )
3362     return res;
3363
3364   serviceTypes = service->serviceTypes();
3365   serviceName = service->name();
3366
3367   return res;
3368 }
3369
3370 KParts::PartManager *KHTMLPart::partManager()
3371 {
3372   if ( !d->m_manager )
3373   {
3374     d->m_manager = new KParts::PartManager( d->m_view->topLevelWidget(), this, "khtml part manager" );
3375     d->m_manager->setAllowNestedParts( true );
3376     connect( d->m_manager, SIGNAL( activePartChanged( KParts::Part * ) ),
3377              this, SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
3378     connect( d->m_manager, SIGNAL( partRemoved( KParts::Part * ) ),
3379              this, SLOT( slotPartRemoved( KParts::Part * ) ) );
3380   }
3381
3382   return d->m_manager;
3383 }
3384
3385 #endif
3386
3387 void KHTMLPart::submitFormAgain()
3388 {
3389   if( d->m_doc && !d->m_doc->parsing() && d->m_submitForm)
3390     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 );
3391
3392   delete d->m_submitForm;
3393   d->m_submitForm = 0;
3394   disconnect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
3395 }
3396
3397 void KHTMLPart::submitForm( const char *action, const QString &url, const FormData &formData, const QString &_target, const QString& contentType, const QString& boundary )
3398 {
3399   kdDebug(6000) << this << ": KHTMLPart::submitForm target=" << _target << " url=" << url << endl;
3400   KURL u = completeURL( url );
3401
3402   if ( !u.isValid() )
3403   {
3404     // ### ERROR HANDLING!
3405     return;
3406   }
3407
3408 #if !APPLE_CHANGES
3409   // Form security checks
3410   //
3411
3412   /* This is separate for a reason.  It has to be _before_ all script, etc,
3413    * AND I don't want to break anything that uses checkLinkSecurity() in
3414    * other places.
3415    */
3416
3417   // This causes crashes... needs to be fixed.
3418   if (!d->m_submitForm && u.protocol() != "https" && u.protocol() != "mailto") {
3419         if (d->m_ssl_in_use) {    // Going from SSL -> nonSSL
3420                 int rc = KMessageBox::warningContinueCancel(NULL, i18n("Warning:  This is a secure form but it is attempting to send your data back unencrypted."
3421                                         "\nA third party may be able to intercept and view this information."
3422                                         "\nAre you sure you wish to continue?"),
3423                                 i18n("SSL"));
3424                 if (rc == KMessageBox::Cancel)
3425                         return;
3426         } else {                  // Going from nonSSL -> nonSSL
3427                 KSSLSettings kss(true);
3428                 if (kss.warnOnUnencrypted()) {
3429                         int rc = KMessageBox::warningContinueCancel(NULL,
3430                                         i18n("Warning: Your data is about to be transmitted across the network unencrypted."
3431                                         "\nAre you sure you wish to continue?"),
3432                                         i18n("KDE"),
3433                                                                     QString::null,
3434                                         "WarnOnUnencryptedForm");
3435                         // Move this setting into KSSL instead
3436                         KConfig *config = kapp->config();
3437                         QString grpNotifMsgs = QString::fromLatin1("Notification Messages");
3438                         KConfigGroupSaver saver( config, grpNotifMsgs );
3439
3440                         if (!config->readBoolEntry("WarnOnUnencryptedForm", true)) {
3441                                 config->deleteEntry("WarnOnUnencryptedForm");
3442                                 config->sync();
3443                                 kss.setWarnOnUnencrypted(false);
3444                                 kss.save();
3445                         }
3446                         if (rc == KMessageBox::Cancel)
3447                           return;
3448         }
3449     }
3450   }
3451
3452   if (!d->m_submitForm && u.protocol() == "mailto") {
3453      int rc = KMessageBox::warningContinueCancel(NULL, 
3454                  i18n("This site is attempting to submit form data via email."),
3455                  i18n("KDE"), 
3456                  QString::null, 
3457                  "WarnTriedEmailSubmit");
3458
3459      if (rc == KMessageBox::Cancel) {
3460          return;
3461      }
3462   }
3463
3464   // End form security checks
3465   //
3466 #endif // APPLE_CHANGES
3467
3468   QString urlstring = u.url();
3469
3470   if ( urlstring.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
3471     urlstring = KURL::decode_string(urlstring);
3472     d->m_executingJavaScriptFormAction = true;
3473     executeScript( urlstring.right( urlstring.length() - 11) );
3474     d->m_executingJavaScriptFormAction = false;
3475     return;
3476   }
3477
3478 #if !APPLE_CHANGES
3479   if (!checkLinkSecurity(u,
3480                          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?" ),
3481                          i18n( "Submit" )))
3482     return;
3483 #endif
3484
3485   KParts::URLArgs args;
3486
3487   if (!d->m_referrer.isEmpty())
3488      args.metaData()["referrer"] = d->m_referrer;
3489
3490 #if !APPLE_CHANGES
3491   args.metaData().insert("main_frame_request",
3492                          parentPart() == 0 ? "TRUE":"FALSE");
3493   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
3494   args.metaData().insert("ssl_activate_warnings", "TRUE");
3495 #endif
3496   args.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;
3497
3498   // Handle mailto: forms
3499   if (u.protocol() == "mailto") {
3500       // 1)  Check for attach= and strip it
3501       QString q = u.query().mid(1);
3502       QStringList nvps = QStringList::split("&", q);
3503       bool triedToAttach = false;
3504
3505       for (QStringList::Iterator nvp = nvps.begin(); nvp != nvps.end(); ++nvp) {
3506          QStringList pair = QStringList::split("=", *nvp);
3507          if (pair.count() >= 2) {
3508             if (pair.first().lower() == "attach") {
3509                nvp = nvps.remove(nvp);
3510                triedToAttach = true;
3511             }
3512          }
3513       }
3514
3515 #if !APPLE_CHANGES
3516       if (triedToAttach)
3517          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");
3518 #endif
3519
3520       // 2)  Append body=
3521       QString bodyEnc;
3522       if (contentType.lower() == "multipart/form-data") {
3523          // FIXME: is this correct?  I suspect not
3524          bodyEnc = KURL::encode_string(formData.flattenToString());
3525       } else if (contentType.lower() == "text/plain") {
3526          // Convention seems to be to decode, and s/&/\n/
3527          QString tmpbody = formData.flattenToString();
3528          tmpbody.replace('&', '\n');
3529          tmpbody.replace('+', ' ');
3530          tmpbody = KURL::decode_string(tmpbody);  // Decode the rest of it
3531          bodyEnc = KURL::encode_string(tmpbody);  // Recode for the URL
3532       } else {
3533          bodyEnc = KURL::encode_string(formData.flattenToString());
3534       }
3535
3536       nvps.append(QString("body=%1").arg(bodyEnc));
3537       q = nvps.join("&");
3538       u.setQuery(q);
3539   } 
3540
3541   if ( strcmp( action, "get" ) == 0 ) {
3542     if (u.protocol() != "mailto")
3543        u.setQuery( formData.flattenToString() );
3544     args.setDoPost( false );
3545   }
3546   else {
3547 #if APPLE_CHANGES
3548     args.postData = formData;
3549 #else
3550     args.postData = formData.flatten();
3551 #endif
3552     args.setDoPost( true );
3553
3554     // construct some user headers if necessary
3555     if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
3556       args.setContentType( "Content-Type: application/x-www-form-urlencoded" );
3557     else // contentType must be "multipart/form-data"
3558       args.setContentType( "Content-Type: " + contentType + "; boundary=" + boundary );
3559   }
3560
3561   if ( d->m_doc->parsing() || d->m_runningScripts > 0 ) {
3562     if( d->m_submitForm ) {
3563       kdDebug(6000) << "KHTMLPart::submitForm ABORTING!" << endl;
3564       return;
3565     }
3566     d->m_submitForm = new KHTMLPartPrivate::SubmitForm;
3567     d->m_submitForm->submitAction = action;
3568     d->m_submitForm->submitUrl = url;
3569     d->m_submitForm->submitFormData = formData;
3570     d->m_submitForm->target = _target;
3571     d->m_submitForm->submitContentType = contentType;
3572     d->m_submitForm->submitBoundary = boundary;
3573     connect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
3574   }
3575   else
3576   {
3577 #if APPLE_CHANGES
3578     KWQ(this)->submitForm( u, args);
3579 #else
3580     emit d->m_extension->openURLRequest( u, args );
3581 #endif
3582   }
3583 }
3584
3585 #if !APPLE_CHANGES
3586
3587 void KHTMLPart::popupMenu( const QString &linkUrl )
3588 {
3589   KURL popupURL;
3590   KURL linkKURL;
3591   if ( linkUrl.isEmpty() ) // click on background
3592     popupURL = this->url();
3593   else {               // click on link
3594     popupURL = completeURL( linkUrl );
3595     linkKURL = popupURL;
3596   }
3597
3598   KXMLGUIClient *client = new KHTMLPopupGUIClient( this, d->m_popupMenuXML, linkKURL );
3599
3600   emit d->m_extension->popupMenu( client, QCursor::pos(), popupURL,
3601                                   QString::fromLatin1( "text/html" ), S_IFREG /*always a file*/ );
3602
3603   delete client;
3604
3605   emit popupMenu(linkUrl, QCursor::pos());
3606 }
3607
3608 #endif
3609
3610 void KHTMLPart::slotParentCompleted()
3611 {
3612   if ( d->m_scheduledRedirection != noRedirectionScheduled && !d->m_redirectionTimer.isActive() )
3613   {
3614     // kdDebug(6050) << this << ": Child redirection -> " << d->m_redirectURL << endl;
3615     d->m_redirectionTimer.start( (int)(1000 * d->m_delayRedirect), true );
3616   }
3617 }
3618
3619 void KHTMLPart::slotChildStarted( KIO::Job *job )
3620 {
3621   khtml::ChildFrame *child = childFrame( sender() );
3622
3623   assert( child );
3624
3625   child->m_bCompleted = false;
3626
3627   if ( d->m_bComplete )
3628   {
3629 #if 0
3630     // WABA: Looks like this belongs somewhere else
3631     if ( !parentPart() ) // "toplevel" html document? if yes, then notify the hosting browser about the document (url) changes
3632     {
3633       emit d->m_extension->openURLNotify();
3634     }
3635 #endif
3636     d->m_bComplete = false;
3637     emit started( job );
3638   }
3639 }
3640
3641 void KHTMLPart::slotChildCompleted()
3642 {
3643   slotChildCompleted( false );
3644 }
3645
3646 void KHTMLPart::slotChildCompleted( bool complete )
3647 {
3648   khtml::ChildFrame *child = childFrame( sender() );
3649
3650   assert( child );
3651
3652   child->m_bCompleted = true;
3653   child->m_args = KParts::URLArgs();
3654
3655   if ( complete && parentPart() == 0 )
3656     d->m_bPendingChildRedirection = true;
3657
3658   checkCompleted();
3659 }
3660
3661 #if !APPLE_CHANGES
3662
3663 void KHTMLPart::slotChildURLRequest( const KURL &url, const KParts::URLArgs &args )
3664 {
3665   khtml::ChildFrame *child = childFrame( sender()->parent() );
3666
3667   QString frameName = args.frameName.lower();
3668   if ( !frameName.isEmpty() )
3669   {
3670     if ( frameName == QString::fromLatin1( "_top" ) )
3671     {
3672       emit d->m_extension->openURLRequest( url, args );
3673       return;
3674     }
3675     else if ( frameName == QString::fromLatin1( "_blank" ) )
3676     {
3677       emit d->m_extension->createNewWindow( url, args );
3678       return;
3679     }
3680     else if ( frameName == QString::fromLatin1( "_parent" ) )
3681     {
3682       KParts::URLArgs newArgs( args );
3683       newArgs.frameName = QString::null;
3684
3685       emit d->m_extension->openURLRequest( url, newArgs );
3686       return;
3687     }
3688     else if ( frameName != QString::fromLatin1( "_self" ) )
3689     {
3690       khtml::ChildFrame *_frame = recursiveFrameRequest( url, args );
3691
3692       if ( !_frame )
3693       {
3694         emit d->m_extension->openURLRequest( url, args );
3695         return;
3696       }
3697
3698       child = _frame;
3699     }
3700   }
3701
3702   // TODO: handle child target correctly! currently the script are always executed fur the parent
3703   QString urlStr = url.url();
3704   if ( urlStr.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
3705       executeScript( KURL::decode_string( urlStr.right( urlStr.length() - 11) ) );
3706       return;
3707   }
3708
3709   if ( child ) {
3710       // Inform someone that we are about to show something else.
3711       child->m_bNotify = true;
3712       requestObject( child, url, args );
3713   }  else if ( frameName==QString::fromLatin1("_self") ) // this is for embedded objects (via <object>) which want to replace the current document
3714   {
3715       KParts::URLArgs newArgs( args );
3716       newArgs.frameName = QString::null;
3717       emit d->m_extension->openURLRequest( url, newArgs );
3718   }
3719 }
3720
3721 #endif // APPLE_CHANGES
3722
3723 khtml::ChildFrame *KHTMLPart::childFrame( const QObject *obj )
3724 {
3725     assert( obj->inherits( "KParts::ReadOnlyPart" ) );
3726     const ReadOnlyPart *part = static_cast<const ReadOnlyPart *>( obj );
3727
3728     FrameIt it = d->m_frames.begin();
3729     FrameIt end = d->m_frames.end();
3730     for (; it != end; ++it )
3731       if ( static_cast<ReadOnlyPart *>((*it).m_part) == part )
3732         return &(*it);
3733
3734     it = d->m_objects.begin();
3735     end = d->m_objects.end();
3736     for (; it != end; ++it )
3737       if ( static_cast<ReadOnlyPart *>((*it).m_part) == part )
3738         return &(*it);
3739
3740     return 0L;
3741 }
3742
3743 KHTMLPart *KHTMLPart::findFrame( const QString &f )
3744 {
3745 #if 0
3746   kdDebug() << "KHTMLPart::findFrame '" << f << "'" << endl;
3747   FrameIt it2 = d->m_frames.begin();
3748   FrameIt end = d->m_frames.end();
3749   for (; it2 != end; ++it2 )
3750       kdDebug() << "  - having frame '" << (*it2).m_name << "'" << endl;
3751 #endif
3752
3753   // ### http://www.w3.org/TR/html4/appendix/notes.html#notes-frames
3754   ConstFrameIt it = d->m_frames.find( f );
3755   if ( it == d->m_frames.end() )
3756   {
3757     //kdDebug() << "KHTMLPart::findFrame frame " << f << " not found" << endl;
3758     return 0L;
3759   }
3760   else {
3761     KParts::ReadOnlyPart *p = (*it).m_part;
3762     if ( p && p->inherits( "KHTMLPart" ))
3763     {
3764       //kdDebug() << "KHTMLPart::findFrame frame " << f << " is a KHTMLPart, ok" << endl;
3765       return (KHTMLPart*)p;
3766     }
3767     else
3768     {
3769 #if 0
3770       if (p)
3771         kdWarning() << "KHTMLPart::findFrame frame " << f << " found but isn't a KHTMLPart ! " << p->className() << endl;
3772       else
3773         kdWarning() << "KHTMLPart::findFrame frame " << f << " found but m_part=0L" << endl;
3774 #endif
3775       return 0L;
3776     }
3777   }
3778 }
3779
3780 #if !APPLE_CHANGES
3781
3782 KParts::ReadOnlyPart *KHTMLPart::currentFrame() const
3783 {
3784   KParts::ReadOnlyPart* part = (KParts::ReadOnlyPart*)(this);
3785   // Find active part in our frame manager, in case we are a frameset
3786   // and keep doing that (in case of nested framesets).
3787   // Just realized we could also do this recursively, calling part->currentFrame()...
3788   while ( part && part->inherits("KHTMLPart") &&
3789           static_cast<KHTMLPart *>(part)->d->m_frames.count() > 0 ) {
3790     KHTMLPart* frameset = static_cast<KHTMLPart *>(part);
3791     part = static_cast<KParts::ReadOnlyPart *>(frameset->partManager()->activePart());
3792     if ( !part ) return frameset;
3793   }
3794   return part;
3795 }
3796
3797 #endif // APPLE_CHANGES
3798
3799 bool KHTMLPart::frameExists( const QString &frameName )
3800 {
3801   ConstFrameIt it = d->m_frames.find( frameName );
3802   if ( it == d->m_frames.end() )
3803     return false;
3804
3805   // WABA: We only return true if the child actually has a frame
3806   // set. Otherwise we might find our preloaded-selve.
3807   // This happens when we restore the frameset.
3808   return (!(*it).m_frame.isNull());
3809 }
3810
3811 KHTMLPart *KHTMLPart::parentPart() const
3812 {
3813   if ( !parent() || !parent()->inherits( "KHTMLPart" ) )
3814     return 0L;
3815
3816   return (KHTMLPart *)parent();
3817 }
3818
3819 #if !APPLE_CHANGES
3820
3821 khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( const KURL &url, const KParts::URLArgs &args,
3822                                                      bool callParent )
3823 {
3824   FrameIt it = d->m_frames.find( args.frameName );
3825
3826   if ( it != d->m_frames.end() )
3827     return &(*it);
3828
3829   it = d->m_frames.begin();
3830   FrameIt end = d->m_frames.end();
3831   for (; it != end; ++it )
3832     if ( (*it).m_part && (*it).m_part->inherits( "KHTMLPart" ) )
3833     {
3834       KHTMLPart *childPart = (KHTMLPart *)(KParts::ReadOnlyPart *)(*it).m_part;
3835
3836       khtml::ChildFrame *res = childPart->recursiveFrameRequest( url, args, false );
3837       if ( !res )
3838         continue;
3839
3840       childPart->requestObject( res, url, args );
3841       return 0L;
3842     }
3843
3844   if ( parentPart() && callParent )
3845   {
3846     khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( url, args );
3847
3848     if ( res )
3849       parentPart()->requestObject( res, url, args );
3850
3851     return 0L;
3852   }
3853
3854   return 0L;
3855 }
3856
3857 void KHTMLPart::saveState( QDataStream &stream )
3858 {
3859   kdDebug( 6050 ) << "KHTMLPart::saveState saving URL " << m_url.url() << endl;
3860
3861   stream << m_url << (Q_INT32)d->m_view->contentsX() << (Q_INT32)d->m_view->contentsY()
3862          << (Q_INT32) d->m_view->contentsWidth() << (Q_INT32) d->m_view->contentsHeight() << (Q_INT32) d->m_view->marginWidth() << (Q_INT32) d->m_view->marginHeight();
3863
3864   // save link cursor position
3865   int focusNodeNumber;
3866   if (!d->m_focusNodeRestored)
3867       focusNodeNumber = d->m_focusNodeNumber;
3868   else if (d->m_doc->focusNode())
3869       focusNodeNumber = d->m_doc->nodeAbsIndex(d->m_doc->focusNode());
3870   else
3871       focusNodeNumber = -1;
3872   stream << focusNodeNumber;
3873
3874   // Save the doc's cache id.
3875   stream << d->m_cacheId;
3876
3877   // Save the state of the document (Most notably the state of any forms)
3878   QStringList docState;
3879   if (d->m_doc)
3880   {
3881      docState = d->m_doc->docState();
3882   }
3883   stream << d->m_encoding << d->m_sheetUsed << docState;
3884
3885   stream << d->m_zoomFactor;
3886
3887   // Save ssl data
3888   stream << d->m_ssl_in_use
3889          << d->m_ssl_peer_certificate
3890          << d->m_ssl_peer_chain
3891          << d->m_ssl_peer_ip
3892          << d->m_ssl_cipher
3893          << d->m_ssl_cipher_desc
3894          << d->m_ssl_cipher_version
3895          << d->m_ssl_cipher_used_bits
3896          << d->m_ssl_cipher_bits
3897          << d->m_ssl_cert_state;
3898
3899
3900   QStringList frameNameLst, frameServiceTypeLst, frameServiceNameLst;
3901   KURL::List frameURLLst;
3902   QValueList<QByteArray> frameStateBufferLst;
3903
3904   ConstFrameIt it = d->m_frames.begin();
3905   ConstFrameIt end = d->m_frames.end();
3906   for (; it != end; ++it )
3907   {
3908     if ( !(*it).m_part )
3909        continue;
3910
3911     frameNameLst << (*it).m_name;
3912     frameServiceTypeLst << (*it).m_serviceType;
3913     frameServiceNameLst << (*it).m_serviceName;
3914     frameURLLst << (*it).m_part->url();
3915
3916     QByteArray state;
3917     QDataStream frameStream( state, IO_WriteOnly );
3918
3919     if ( (*it).m_extension )
3920       (*it).m_extension->saveState( frameStream );
3921
3922     frameStateBufferLst << state;
3923   }
3924
3925   // Save frame data
3926   stream << (Q_UINT32) frameNameLst.count();
3927   stream << frameNameLst << frameServiceTypeLst << frameServiceNameLst << frameURLLst << frameStateBufferLst;
3928 }
3929
3930 void KHTMLPart::restoreState( QDataStream &stream )
3931 {
3932   KURL u;
3933   Q_INT32 xOffset, yOffset, wContents, hContents, mWidth, mHeight;
3934   Q_UINT32 frameCount;
3935   QStringList frameNames, frameServiceTypes, docState, frameServiceNames;
3936   KURL::List frameURLs;
3937   QValueList<QByteArray> frameStateBuffers;
3938   QValueList<int> fSizes;
3939   QString encoding, sheetUsed;
3940   long old_cacheId = d->m_cacheId;
3941
3942   stream >> u >> xOffset >> yOffset >> wContents >> hContents >> mWidth >> mHeight;
3943
3944   d->m_view->setMarginWidth( mWidth );
3945   d->m_view->setMarginHeight( mHeight );
3946
3947   // restore link cursor position
3948   // nth node is active. value is set in checkCompleted()
3949   stream >> d->m_focusNodeNumber;
3950   d->m_focusNodeRestored = false;
3951   kdDebug(6050)<<"new focus Node number is:"<<d->m_focusNodeNumber<<endl;
3952
3953   stream >> d->m_cacheId;
3954
3955   stream >> encoding >> sheetUsed >> docState;
3956   d->m_encoding = encoding;
3957   d->m_sheetUsed = sheetUsed;
3958
3959   int zoomFactor;
3960   stream >> zoomFactor;
3961   setZoomFactor(zoomFactor);
3962
3963   // Restore ssl data
3964   stream >> d->m_ssl_in_use
3965          >> d->m_ssl_peer_certificate
3966          >> d->m_ssl_peer_chain
3967          >> d->m_ssl_peer_ip
3968          >> d->m_ssl_cipher
3969          >> d->m_ssl_cipher_desc
3970          >> d->m_ssl_cipher_version
3971          >> d->m_ssl_cipher_used_bits
3972          >> d->m_ssl_cipher_bits
3973          >> d->m_ssl_cert_state;
3974
3975   d->m_paSecurity->setIcon( d->m_ssl_in_use ? "encrypted" : "decrypted" );
3976
3977   stream >> frameCount >> frameNames >> frameServiceTypes >> frameServiceNames
3978          >> frameURLs >> frameStateBuffers;
3979
3980   d->m_bComplete = false;
3981   d->m_bLoadEventEmitted = false;
3982
3983 //   kdDebug( 6050 ) << "restoreStakte() docState.count() = " << docState.count() << endl;
3984 //   kdDebug( 6050 ) << "m_url " << m_url.url() << " <-> " << u.url() << endl;
3985 //   kdDebug( 6050 ) << "m_frames.count() " << d->m_frames.count() << " <-> " << frameCount << endl;
3986
3987   if (d->m_cacheId == old_cacheId)
3988   {
3989     // Partial restore
3990     cancelRedirection();
3991
3992     FrameIt fIt = d->m_frames.begin();
3993     FrameIt fEnd = d->m_frames.end();
3994
3995     for (; fIt != fEnd; ++fIt )
3996         (*fIt).m_bCompleted = false;
3997
3998     fIt = d->m_frames.begin();
3999
4000     QStringList::ConstIterator fNameIt = frameNames.begin();
4001     QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
4002     QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
4003     KURL::List::ConstIterator fURLIt = frameURLs.begin();
4004     QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
4005
4006     for (; fIt != fEnd; ++fIt, ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
4007     {
4008       khtml::ChildFrame *child = &(*fIt);
4009
4010 //      kdDebug( 6050 ) <<  *fNameIt  << " ---- " <<  *fServiceTypeIt << endl;
4011
4012       if ( child->m_name != *fNameIt || child->m_serviceType != *fServiceTypeIt )
4013       {
4014         child->m_bPreloaded = true;
4015         child->m_name = *fNameIt;
4016         child->m_serviceName = *fServiceNameIt;
4017         processObjectRequest( child, *fURLIt, *fServiceTypeIt );
4018       }
4019
4020       if ( child->m_part )
4021       {
4022         child->m_bCompleted = false;
4023         if ( child->m_extension && !(*fBufferIt).isEmpty() )
4024         {
4025           QDataStream frameStream( *fBufferIt, IO_ReadOnly );
4026           child->m_extension->restoreState( frameStream );
4027         }
4028         else
4029           child->m_part->openURL( *fURLIt );
4030       }
4031     }
4032
4033     KParts::URLArgs args( d->m_extension->urlArgs() );
4034     args.xOffset = xOffset;
4035     args.yOffset = yOffset;
4036     args.docState = docState; // WABA: How are we going to restore this??
4037     d->m_extension->setURLArgs( args );
4038
4039     d->m_view->resizeContents( wContents,  hContents);
4040     d->m_view->setContentsPos( xOffset, yOffset );
4041   }
4042   else
4043   {
4044     // Full restore.
4045     closeURL();
4046     // We must force a clear because we want to be sure to delete all
4047     // frames.
4048     d->m_bCleared = false;
4049     clear();
4050     d->m_encoding = encoding;
4051     d->m_sheetUsed = sheetUsed;
4052
4053     QStringList::ConstIterator fNameIt = frameNames.begin();
4054     QStringList::ConstIterator fNameEnd = frameNames.end();
4055
4056     QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
4057     QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
4058     KURL::List::ConstIterator fURLIt = frameURLs.begin();
4059     QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
4060
4061     for (; fNameIt != fNameEnd; ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
4062     {
4063       khtml::ChildFrame newChild;
4064       newChild.m_bPreloaded = true;
4065       newChild.m_name = *fNameIt;
4066       newChild.m_serviceName = *fServiceNameIt;
4067
4068 //      kdDebug( 6050 ) << *fNameIt << " ---- " << *fServiceTypeIt << endl;
4069
4070       FrameIt childFrame = d->m_frames.append( newChild );
4071
4072       processObjectRequest( &(*childFrame), *fURLIt, *fServiceTypeIt );
4073
4074       (*childFrame).m_bPreloaded = true;
4075
4076       if ( (*childFrame).m_part )
4077       {
4078         if ( (*childFrame).m_extension )
4079         if ( (*childFrame).m_extension && !(*fBufferIt).isEmpty() )
4080         {
4081           QDataStream frameStream( *fBufferIt, IO_ReadOnly );
4082           (*childFrame).m_extension->restoreState( frameStream );
4083         }
4084         else
4085           (*childFrame).m_part->openURL( *fURLIt );
4086       }
4087     }
4088
4089     KParts::URLArgs args( d->m_extension->urlArgs() );
4090     args.xOffset = xOffset;
4091     args.yOffset = yOffset;
4092     args.docState = docState;
4093     d->m_extension->setURLArgs( args );
4094     if (!KHTMLPageCache::self()->isValid(d->m_cacheId))
4095     {
4096        d->m_restored = true;
4097        openURL( u );
4098        d->m_restored = false;
4099     }
4100     else
4101     {
4102        restoreURL( u );
4103     }
4104   }
4105
4106 }
4107
4108 void KHTMLPart::show()
4109 {
4110   if ( d->m_view )
4111     d->m_view->show();
4112 }
4113
4114 void KHTMLPart::hide()
4115 {
4116   if ( d->m_view )
4117     d->m_view->hide();
4118 }
4119
4120 #endif // APPLE_CHANGES
4121
4122 DOM::Node KHTMLPart::nodeUnderMouse() const
4123 {
4124     return d->m_view->nodeUnderMouse();
4125 }
4126
4127 void KHTMLPart::emitSelectionChanged()
4128 {
4129 #if !APPLE_CHANGES
4130   emit d->m_extension->enableAction( "copy", hasSelection() );
4131   emit d->m_extension->selectionInfo( selectedText() );
4132   emit selectionChanged();
4133 #endif
4134 }
4135
4136 int KHTMLPart::zoomFactor() const
4137 {
4138   return d->m_zoomFactor;
4139 }
4140
4141 // ### make the list configurable ?
4142 static const int zoomSizes[] = { 20, 40, 60, 80, 90, 95, 100, 105, 110, 120, 140, 160, 180, 200, 250, 300 };
4143 static const int zoomSizeCount = (sizeof(zoomSizes) / sizeof(int));
4144 static const int minZoom = 20;
4145 static const int maxZoom = 300;
4146
4147 void KHTMLPart::slotIncZoom()
4148 {
4149   int zoomFactor = d->m_zoomFactor;
4150
4151   if (zoomFactor < maxZoom) {
4152     // find the entry nearest to the given zoomsizes
4153     for (int i = 0; i < zoomSizeCount; ++i)
4154       if (zoomSizes[i] > zoomFactor) {
4155         zoomFactor = zoomSizes[i];
4156         break;
4157       }
4158     setZoomFactor(zoomFactor);
4159   }
4160 }
4161
4162 void KHTMLPart::slotDecZoom()
4163 {
4164     int zoomFactor = d->m_zoomFactor;
4165     if (zoomFactor > minZoom) {
4166       // find the entry nearest to the given zoomsizes
4167       for (int i = zoomSizeCount-1; i >= 0; --i)
4168         if (zoomSizes[i] < zoomFactor) {
4169           zoomFactor = zoomSizes[i];
4170           break;
4171         }
4172       setZoomFactor(zoomFactor);
4173     }
4174 }
4175
4176 void KHTMLPart::setZoomFactor (int percent)
4177 {
4178 #if !APPLE_CHANGES // limits are client's responsibility
4179   if (percent < minZoom) percent = minZoom;
4180   if (percent > maxZoom) percent = maxZoom;
4181 #endif
4182   
4183   if (d->m_zoomFactor == percent) return;
4184   d->m_zoomFactor = percent;
4185
4186   if(d->m_doc) {
4187 #if !APPLE_CHANGES
4188       QApplication::setOverrideCursor( waitCursor );
4189 #endif
4190     d->m_doc->recalcStyle( NodeImpl::Force );
4191 #if !APPLE_CHANGES
4192     QApplication::restoreOverrideCursor();
4193 #endif
4194   }
4195
4196   ConstFrameIt it = d->m_frames.begin();
4197   ConstFrameIt end = d->m_frames.end();
4198   for (; it != end; ++it )
4199     if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
4200       KParts::ReadOnlyPart* p = ( *it ).m_part;
4201       static_cast<KHTMLPart*>( p )->setZoomFactor(d->m_zoomFactor);
4202     }
4203
4204 #if !APPLE_CHANGES
4205   d->m_paDecZoomFactor->setEnabled( d->m_zoomFactor > minZoom );
4206   d->m_paIncZoomFactor->setEnabled( d->m_zoomFactor < maxZoom );
4207 #endif
4208
4209   if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout())
4210     view()->layout();
4211 }
4212
4213 void KHTMLPart::setJSStatusBarText( const QString &text )
4214 {
4215    d->m_kjsStatusBarText = text;
4216    emit setStatusBarText( d->m_kjsStatusBarText );
4217 }
4218
4219 void KHTMLPart::setJSDefaultStatusBarText( const QString &text )
4220 {
4221    d->m_kjsDefaultStatusBarText = text;
4222    emit setStatusBarText( d->m_kjsDefaultStatusBarText );
4223 }
4224
4225 QString KHTMLPart::jsStatusBarText() const
4226 {
4227     return d->m_kjsStatusBarText;
4228 }
4229
4230 QString KHTMLPart::jsDefaultStatusBarText() const
4231 {
4232    return d->m_kjsDefaultStatusBarText;
4233 }
4234
4235 QString KHTMLPart::referrer() const
4236 {
4237    return d->m_referrer;
4238 }
4239
4240 QString KHTMLPart::lastModified() const
4241 {
4242   return d->m_lastModified;
4243 }
4244
4245 #if !APPLE_CHANGES
4246
4247 void KHTMLPart::slotLoadImages()
4248 {
4249   if (d->m_doc )
4250     d->m_doc->docLoader()->setAutoloadImages( !d->m_doc->docLoader()->autoloadImages() );
4251
4252   ConstFrameIt it = d->m_frames.begin();
4253   ConstFrameIt end = d->m_frames.end();
4254   for (; it != end; ++it )
4255     if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
4256       KParts::ReadOnlyPart* p = ( *it ).m_part;
4257       static_cast<KHTMLPart*>( p )->slotLoadImages();
4258     }
4259 }
4260
4261 #endif
4262
4263 void KHTMLPart::reparseConfiguration()
4264 {
4265 #if !APPLE_CHANGES
4266   setAutoloadImages( settings->autoLoadImages() );
4267   if (d->m_doc)
4268      d->m_doc->docLoader()->setShowAnimations( settings->showAnimations() );
4269
4270   d->m_bJScriptEnabled = settings->isJavaScriptEnabled(m_url.host());
4271   d->m_bJScriptDebugEnabled = settings->isJavaScriptDebugEnabled();
4272   d->m_bJavaEnabled = settings->isJavaEnabled(m_url.host());
4273   d->m_bPluginsEnabled = settings->isPluginsEnabled(m_url.host());
4274   delete d->m_settings;
4275   d->m_settings = new KHTMLSettings(*KHTMLFactory::defaultHTMLSettings());
4276
4277   QString userStyleSheet = KHTMLFactory::defaultHTMLSettings()->userStyleSheet();
4278 #else
4279   setAutoloadImages( d->m_settings->autoLoadImages() );
4280   if (d->m_doc)
4281      d->m_doc->docLoader()->setShowAnimations( d->m_settings->showAnimations() );
4282
4283   d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled(m_url.host());
4284   d->m_bJScriptDebugEnabled = d->m_settings->isJavaScriptDebugEnabled();
4285   d->m_bJavaEnabled = d->m_settings->isJavaEnabled(m_url.host());
4286   d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled(m_url.host());
4287
4288   QString userStyleSheet = d->m_settings->userStyleSheet();
4289 #endif
4290   if ( !userStyleSheet.isEmpty() )
4291     setUserStyleSheet( KURL( userStyleSheet ) );
4292   else
4293     setUserStyleSheet( QString() );
4294
4295 #if !APPLE_CHANGES
4296   QApplication::setOverrideCursor( waitCursor );
4297 #endif
4298   if(d->m_doc) d->m_doc->updateStyleSelector();
4299 #if !APPLE_CHANGES
4300   QApplication::restoreOverrideCursor();
4301 #endif
4302 }
4303
4304 QStringList KHTMLPart::frameNames() const
4305 {
4306   QStringList res;
4307
4308   ConstFrameIt it = d->m_frames.begin();
4309   ConstFrameIt end = d->m_frames.end();
4310   for (; it != end; ++it )
4311     if (!(*it).m_bPreloaded)
4312       res += (*it).m_name;
4313
4314   return res;
4315 }
4316
4317 QPtrList<KParts::ReadOnlyPart> KHTMLPart::frames() const
4318 {
4319   QPtrList<KParts::ReadOnlyPart> res;
4320
4321   ConstFrameIt it = d->m_frames.begin();
4322   ConstFrameIt end = d->m_frames.end();
4323   for (; it != end; ++it )
4324     if (!(*it).m_bPreloaded)
4325       res.append( (*it).m_part );
4326
4327   return res;
4328 }
4329
4330 #if !APPLE_CHANGES
4331
4332 bool KHTMLPart::openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs )
4333 {
4334   FrameIt it = d->m_frames.find( urlArgs.frameName );
4335
4336   if ( it == d->m_frames.end() )
4337     return false;
4338
4339   // Inform someone that we are about to show something else.
4340   if ( !urlArgs.lockHistory() )
4341       emit d->m_extension->openURLNotify();
4342
4343   requestObject( &(*it), url, urlArgs );
4344
4345   return true;
4346 }
4347
4348 #endif
4349
4350 void KHTMLPart::setDNDEnabled( bool b )
4351 {
4352   d->m_bDnd = b;
4353 }
4354
4355 bool KHTMLPart::dndEnabled() const
4356 {
4357   return d->m_bDnd;
4358 }
4359
4360 bool KHTMLPart::shouldDragAutoNode(DOM::NodeImpl *node, int x, int y) const
4361 {
4362     // No KDE impl yet
4363     return false;
4364 }
4365
4366 void KHTMLPart::customEvent( QCustomEvent *event )
4367 {
4368   if ( khtml::MousePressEvent::test( event ) )
4369   {
4370     khtmlMousePressEvent( static_cast<khtml::MousePressEvent *>( event ) );
4371     return;
4372   }
4373
4374   if ( khtml::MouseDoubleClickEvent::test( event ) )
4375   {
4376     khtmlMouseDoubleClickEvent( static_cast<khtml::MouseDoubleClickEvent *>( event ) );
4377     return;
4378   }
4379
4380   if ( khtml::MouseMoveEvent::test( event ) )
4381   {
4382     khtmlMouseMoveEvent( static_cast<khtml::MouseMoveEvent *>( event ) );
4383     return;
4384   }
4385
4386   if ( khtml::MouseReleaseEvent::test( event ) )
4387   {
4388     khtmlMouseReleaseEvent( static_cast<khtml::MouseReleaseEvent *>( event ) );
4389     return;
4390   }
4391
4392   if ( khtml::DrawContentsEvent::test( event ) )
4393   {
4394     khtmlDrawContentsEvent( static_cast<khtml::DrawContentsEvent *>( event ) );
4395     return;
4396   }
4397
4398   KParts::ReadOnlyPart::customEvent( event );
4399 }
4400
4401 bool KHTMLPart::isPointInsideSelection(int x, int y)
4402 {
4403     // Treat a collapsed selection like no selection.
4404     if (!d->m_selection.isRange())
4405         return false;
4406     if (!xmlDocImpl()->renderer()) 
4407         return false;
4408     
4409     RenderObject::NodeInfo nodeInfo(true, true);
4410     xmlDocImpl()->renderer()->layer()->hitTest(nodeInfo, x, y);
4411     NodeImpl *innerNode = nodeInfo.innerNode();
4412     if (!innerNode || !innerNode->renderer())
4413         return false;
4414     
4415     Position pos(innerNode->renderer()->positionForCoordinates(x, y));
4416     if (pos.isNull())
4417         return false;
4418
4419     NodeImpl *n = d->m_selection.start().node();
4420     while (n) {