13cfc825f0245519d85d440a0a010b9fbf39597f
[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->isFocusable(); target = target->parentNode()); // loop
2474         if (target && target->isMouseFocusable())
2475             xmlDocImpl()->setFocusNode(target);
2476         else if (!target || !target->focused())
2477             xmlDocImpl()->setFocusNode(0);
2478     }
2479 }
2480
2481 void KHTMLPart::selectionLayoutChanged()
2482 {
2483     // kill any caret blink timer now running
2484     if (d->m_caretBlinkTimer >= 0) {
2485         killTimer(d->m_caretBlinkTimer);
2486         d->m_caretBlinkTimer = -1;
2487     }
2488
2489     // see if a new caret blink timer needs to be started
2490     if (d->m_caretVisible && d->m_caretBlinks && 
2491         d->m_selection.isCaret() && d->m_selection.start().node()->isContentEditable()) {
2492         d->m_caretBlinkTimer = startTimer(CARET_BLINK_FREQUENCY);
2493         d->m_caretPaint = true;
2494         d->m_selection.needsCaretRepaint();
2495     }
2496
2497     if (d->m_doc)
2498         d->m_doc->updateSelection();
2499 }
2500
2501 void KHTMLPart::setXPosForVerticalArrowNavigation(int x)
2502 {
2503     d->m_xPosForVerticalArrowNavigation = x;
2504 }
2505
2506 int KHTMLPart::xPosForVerticalArrowNavigation() const
2507 {
2508     return d->m_xPosForVerticalArrowNavigation;
2509 }
2510
2511 void KHTMLPart::timerEvent(QTimerEvent *e)
2512 {
2513     if (e->timerId() == d->m_caretBlinkTimer && 
2514         d->m_caretVisible && 
2515         d->m_caretBlinks && 
2516         d->m_selection.isCaret()) {
2517         d->m_caretPaint = !d->m_caretPaint;
2518         d->m_selection.needsCaretRepaint();
2519     }
2520 }
2521
2522 void KHTMLPart::paintCaret(QPainter *p, const QRect &rect) const
2523 {
2524     if (d->m_caretPaint)
2525         d->m_selection.paintCaret(p, rect);
2526 }
2527
2528 void KHTMLPart::paintDragCaret(QPainter *p, const QRect &rect) const
2529 {
2530     d->m_dragCaret.paintCaret(p, rect);
2531 }
2532
2533 #if !APPLE_CHANGES
2534
2535 void KHTMLPart::overURL( const QString &url, const QString &target, bool shiftPressed )
2536 {
2537   if ( !d->m_kjsStatusBarText.isEmpty() && !shiftPressed ) {
2538     emit onURL( url );
2539     emit setStatusBarText( d->m_kjsStatusBarText );
2540     d->m_kjsStatusBarText = QString::null;
2541     return;
2542   }
2543
2544   emit onURL( url );
2545
2546   if ( url.isEmpty() )
2547   {
2548     emit setStatusBarText(completeURL(url).htmlURL());
2549     return;
2550   }
2551
2552   if (url.find( QString::fromLatin1( "javascript:" ),0, false ) != -1 )
2553   {
2554     emit setStatusBarText( KURL::decode_string( url.mid( url.find( "javascript:", 0, false ) ) ) );
2555     return;
2556   }
2557
2558   KURL u = completeURL(url);
2559
2560   // special case for <a href="">
2561   if ( url.isEmpty() )
2562     u.setFileName( url );
2563
2564   QString com;
2565
2566   KMimeType::Ptr typ = KMimeType::findByURL( u );
2567
2568   if ( typ )
2569     com = typ->comment( u, false );
2570
2571   if ( u.isMalformed() )
2572   {
2573     emit setStatusBarText(u.htmlURL());
2574     return;
2575   }
2576
2577   if ( u.isLocalFile() )
2578   {
2579     // TODO : use KIO::stat() and create a KFileItem out of its result,
2580     // to use KFileItem::statusBarText()
2581     QCString path = QFile::encodeName( u.path() );
2582
2583     struct stat buff;
2584     bool ok = !stat( path.data(), &buff );
2585
2586     struct stat lbuff;
2587     if (ok) ok = !lstat( path.data(), &lbuff );
2588
2589     QString text = u.htmlURL();
2590     QString text2 = text;
2591
2592     if (ok && S_ISLNK( lbuff.st_mode ) )
2593     {
2594       QString tmp;
2595       if ( com.isNull() )
2596         tmp = i18n( "Symbolic Link");
2597       else
2598         tmp = i18n("%1 (Link)").arg(com);
2599       char buff_two[1024];
2600       text += " -> ";
2601       int n = readlink ( path.data(), buff_two, 1022);
2602       if (n == -1)
2603       {
2604         text2 += "  ";
2605         text2 += tmp;
2606         emit setStatusBarText(text2);
2607         return;
2608       }
2609       buff_two[n] = 0;
2610
2611       text += buff_two;
2612       text += "  ";
2613       text += tmp;
2614     }
2615     else if ( ok && S_ISREG( buff.st_mode ) )
2616     {
2617       if (buff.st_size < 1024)
2618         text = i18n("%2 (%1 bytes)").arg((long) buff.st_size).arg(text2); // always put the URL last, in case it contains '%'
2619       else
2620       {
2621         float d = (float) buff.st_size/1024.0;
2622         text = i18n("%1 (%2 K)").arg(text2).arg(KGlobal::locale()->formatNumber(d, 2)); // was %.2f
2623       }
2624       text += "  ";
2625       text += com;
2626     }
2627     else if ( ok && S_ISDIR( buff.st_mode ) )
2628     {
2629       text += "  ";
2630       text += com;
2631     }
2632     else
2633     {
2634       text += "  ";
2635       text += com;
2636     }
2637     emit setStatusBarText(text);
2638   }
2639   else
2640   {
2641     QString extra;
2642     if (target == QString::fromLatin1("_blank"))
2643     {
2644       extra = i18n(" (In new window)");
2645     }
2646     else if (!target.isEmpty() &&
2647              (target != QString::fromLatin1("_top")) &&
2648              (target != QString::fromLatin1("_self")) &&
2649              (target != QString::fromLatin1("_parent")))
2650     {
2651       extra = i18n(" (In other frame)");
2652     }
2653
2654     if (u.protocol() == QString::fromLatin1("mailto")) {
2655       QString mailtoMsg/* = QString::fromLatin1("<img src=%1>").arg(locate("icon", QString::fromLatin1("locolor/16x16/actions/mail_send.png")))*/;
2656       mailtoMsg += i18n("Email to: ") + KURL::decode_string(u.path());
2657       QStringList queries = QStringList::split('&', u.query().mid(1));
2658       for (QStringList::Iterator it = queries.begin(); it != queries.end(); ++it)
2659         if ((*it).startsWith(QString::fromLatin1("subject=")))
2660           mailtoMsg += i18n(" - Subject: ") + KURL::decode_string((*it).mid(8));
2661         else if ((*it).startsWith(QString::fromLatin1("cc=")))
2662           mailtoMsg += i18n(" - CC: ") + KURL::decode_string((*it).mid(3));
2663         else if ((*it).startsWith(QString::fromLatin1("bcc=")))
2664           mailtoMsg += i18n(" - BCC: ") + KURL::decode_string((*it).mid(4));
2665       mailtoMsg.replace(QRegExp("&"), QString("&amp;"));
2666       mailtoMsg.replace(QRegExp("<"), QString("&lt;"));
2667       mailtoMsg.replace(QRegExp(">"), QString("&gt;"));
2668       mailtoMsg.replace(QRegExp("([\n\r\t]|[ ]{10})"), "");
2669       emit setStatusBarText(mailtoMsg);
2670       return;
2671     }
2672    // Is this check neccessary at all? (Frerich)
2673 #if 0
2674     else if (u.protocol() == QString::fromLatin1("http")) {
2675         DOM::Node hrefNode = nodeUnderMouse().parentNode();
2676         while (hrefNode.nodeName().string() != QString::fromLatin1("A") && !hrefNode.isNull())
2677           hrefNode = hrefNode.parentNode();
2678
2679         if (!hrefNode.isNull()) {
2680           DOM::Node hreflangNode = hrefNode.attributes().getNamedItem("HREFLANG");
2681           if (!hreflangNode.isNull()) {
2682             QString countryCode = hreflangNode.nodeValue().string().lower();
2683             // Map the language code to an appropriate country code.
2684             if (countryCode == QString::fromLatin1("en"))
2685               countryCode = QString::fromLatin1("gb");
2686             QString flagImg = QString::fromLatin1("<img src=%1>").arg(
2687                 locate("locale", QString::fromLatin1("l10n/")
2688                 + countryCode
2689                 + QString::fromLatin1("/flag.png")));
2690             emit setStatusBarText(flagImg + u.prettyURL() + extra);
2691           }
2692         }
2693       }
2694 #endif
2695     emit setStatusBarText(u.htmlURL() + extra);
2696   }
2697 }
2698
2699 #endif // APPLE_CHANGES
2700
2701 void KHTMLPart::urlSelected( const QString &url, int button, int state, const QString &_target,
2702                              KParts::URLArgs args )
2703 {
2704   bool hasTarget = false;
2705
2706   QString target = _target;
2707   if ( target.isEmpty() && d->m_doc )
2708     target = d->m_doc->baseTarget();
2709   if ( !target.isEmpty() )
2710       hasTarget = true;
2711
2712   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
2713   {
2714     executeScript( KURL::decode_string( url.right( url.length() - 11) ), true );
2715     return;
2716   }
2717
2718   KURL cURL = completeURL(url);
2719 #if !APPLE_CHANGES
2720   // special case for <a href="">
2721   if ( url.isEmpty() )
2722     cURL.setFileName( url );
2723 #endif
2724
2725   if ( !cURL.isValid() )
2726     // ### ERROR HANDLING
2727     return;
2728
2729   //kdDebug( 6000 ) << "urlSelected: complete URL:" << cURL.url() << " target = " << target << endl;
2730
2731 #if !APPLE_CHANGES
2732   if ( button == LeftButton && ( state & ShiftButton ) )
2733   {
2734     KIO::MetaData metaData;
2735     metaData["referrer"] = d->m_referrer;
2736     KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As..." ), cURL, metaData );
2737     return;
2738   }
2739
2740   if (!checkLinkSecurity(cURL,
2741                          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?" ),
2742                          i18n( "Follow" )))
2743     return;
2744 #endif
2745
2746   args.frameName = target;
2747
2748   if ( d->m_bHTTPRefresh )
2749   {
2750     d->m_bHTTPRefresh = false;
2751     args.metaData()["cache"] = "refresh";
2752   }
2753
2754 #if !APPLE_CHANGES
2755   args.metaData().insert("main_frame_request",
2756                          parentPart() == 0 ? "TRUE":"FALSE");
2757   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
2758   args.metaData().insert("ssl_activate_warnings", "TRUE");
2759 #endif
2760
2761 #if APPLE_CHANGES
2762   args.metaData()["referrer"] = d->m_referrer;
2763   KWQ(this)->urlSelected(cURL, button, state, args);
2764 #else
2765   if ( hasTarget )
2766   {
2767     // unknown frame names should open in a new window.
2768     khtml::ChildFrame *frame = recursiveFrameRequest( cURL, args, false );
2769     if ( frame )
2770     {
2771       args.metaData()["referrer"] = d->m_referrer;
2772       requestObject( frame, cURL, args );
2773       return;
2774     }
2775   }
2776
2777   if ( !d->m_bComplete && !hasTarget )
2778     closeURL();
2779
2780   if (!d->m_referrer.isEmpty())
2781     args.metaData()["referrer"] = d->m_referrer;
2782
2783   if ( button == MidButton && (state & ShiftButton) )
2784   {
2785     KParts::WindowArgs winArgs;
2786     winArgs.lowerWindow = true;
2787     KParts::ReadOnlyPart *newPart = 0;
2788     emit d->m_extension->createNewWindow( cURL, args, winArgs, newPart );
2789     return;
2790   }
2791   emit d->m_extension->openURLRequest( cURL, args );
2792 #endif // APPLE_CHANGES
2793 }
2794
2795 #if !APPLE_CHANGES
2796
2797 void KHTMLPart::slotViewDocumentSource()
2798 {
2799   KURL url(m_url);
2800   if (!(url.isLocalFile()) && KHTMLPageCache::self()->isValid(d->m_cacheId))
2801   {
2802      KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
2803      if (sourceFile.status() == 0)
2804      {
2805         KHTMLPageCache::self()->saveData(d->m_cacheId, sourceFile.dataStream());
2806         url = KURL();
2807         url.setPath(sourceFile.name());
2808      }
2809   }
2810
2811   //  emit d->m_extension->openURLRequest( m_url, KParts::URLArgs( false, 0, 0, QString::fromLatin1( "text/plain" ) ) );
2812   (void) KRun::runURL( url, QString::fromLatin1("text/plain") );
2813 }
2814
2815 void KHTMLPart::slotViewFrameSource()
2816 {
2817   KParts::ReadOnlyPart *frame = currentFrame();
2818   if ( !frame )
2819     return;
2820
2821   KURL url = frame->url();
2822   if (!(url.isLocalFile()) && frame->inherits("KHTMLPart"))
2823   {
2824        long cacheId = static_cast<KHTMLPart *>(frame)->d->m_cacheId;
2825
2826        if (KHTMLPageCache::self()->isValid(cacheId))
2827        {
2828            KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
2829            if (sourceFile.status() == 0)
2830            {
2831                KHTMLPageCache::self()->saveData(cacheId, sourceFile.dataStream());
2832                url = KURL();
2833                url.setPath(sourceFile.name());
2834            }
2835      }
2836   }
2837
2838   (void) KRun::runURL( url, QString::fromLatin1("text/plain") );
2839 }
2840
2841 KURL KHTMLPart::backgroundURL() const
2842 {
2843   // ### what about XML documents? get from CSS?
2844   if (!d->m_doc || !d->m_doc->isHTMLDocument())
2845     return KURL();
2846
2847   QString relURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
2848
2849   return KURL( m_url, relURL );
2850 }
2851
2852 void KHTMLPart::slotSaveBackground()
2853 {
2854   KIO::MetaData metaData;
2855   metaData["referrer"] = d->m_referrer;
2856   KHTMLPopupGUIClient::saveURL( d->m_view, i18n("Save background image as"), backgroundURL(), metaData );
2857 }
2858
2859 void KHTMLPart::slotSaveDocument()
2860 {
2861   KURL srcURL( m_url );
2862
2863   if ( srcURL.fileName(false).isEmpty() )
2864     srcURL.setFileName( "index.html" );
2865
2866   KIO::MetaData metaData;
2867   // Referre unknown?
2868   KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, i18n("*.html *.htm|HTML files"), d->m_cacheId );
2869 }
2870
2871 void KHTMLPart::slotSecurity()
2872 {
2873 //   kdDebug( 6050 ) << "Meta Data:" << endl
2874 //                   << d->m_ssl_peer_cert_subject
2875 //                   << endl
2876 //                   << d->m_ssl_peer_cert_issuer
2877 //                   << endl
2878 //                   << d->m_ssl_cipher
2879 //                   << endl
2880 //                   << d->m_ssl_cipher_desc
2881 //                   << endl
2882 //                   << d->m_ssl_cipher_version
2883 //                   << endl
2884 //                   << d->m_ssl_good_from
2885 //                   << endl
2886 //                   << d->m_ssl_good_until
2887 //                   << endl
2888 //                   << d->m_ssl_cert_state
2889 //                   << endl;
2890
2891   KSSLInfoDlg *kid = new KSSLInfoDlg(d->m_ssl_in_use, widget(), "kssl_info_dlg", true );
2892
2893   if (d->m_bSecurityInQuestion)
2894           kid->setSecurityInQuestion(true);
2895
2896   if (d->m_ssl_in_use) {
2897     KSSLCertificate *x = KSSLCertificate::fromString(d->m_ssl_peer_certificate.local8Bit());
2898     if (x) {
2899        // Set the chain back onto the certificate
2900        QStringList cl = QStringList::split(QString("\n"), d->m_ssl_peer_chain);
2901        QPtrList<KSSLCertificate> ncl;
2902
2903        ncl.setAutoDelete(true);
2904        for (QStringList::Iterator it = cl.begin(); it != cl.end(); ++it) {
2905           KSSLCertificate *y = KSSLCertificate::fromString((*it).local8Bit());
2906           if (y) ncl.append(y);
2907        }
2908
2909        if (ncl.count() > 0)
2910           x->chain().setChain(ncl);
2911
2912        kid->setup(x,
2913                   d->m_ssl_peer_ip,
2914                   m_url.url(),
2915                   d->m_ssl_cipher,
2916                   d->m_ssl_cipher_desc,
2917                   d->m_ssl_cipher_version,
2918                   d->m_ssl_cipher_used_bits.toInt(),
2919                   d->m_ssl_cipher_bits.toInt(),
2920                   (KSSLCertificate::KSSLValidation) d->m_ssl_cert_state.toInt()
2921                   );
2922         kid->exec();
2923         delete x;
2924      } else kid->exec();
2925   } else kid->exec();
2926 }
2927
2928 void KHTMLPart::slotSaveFrame()
2929 {
2930     if ( !d->m_activeFrame )
2931         return; // should never be the case, but one never knows :-)
2932
2933     KURL srcURL( static_cast<KParts::ReadOnlyPart *>( d->m_activeFrame )->url() );
2934
2935     if ( srcURL.fileName(false).isEmpty() )
2936         srcURL.setFileName( "index.html" );
2937
2938     KIO::MetaData metaData;
2939     // Referrer unknown?
2940     KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, i18n("*.html *.htm|HTML files") );
2941 }
2942
2943 void KHTMLPart::slotSetEncoding()
2944 {
2945     // first Item is always auto
2946     if(d->m_paSetEncoding->currentItem() == 0)
2947         setEncoding(QString::null, false);
2948     else {
2949         // strip of the language to get the raw encoding again.
2950         QString enc = KGlobal::charsets()->encodingForName(d->m_paSetEncoding->currentText());
2951         setEncoding(enc, true);
2952     }
2953 }
2954
2955 void KHTMLPart::slotUseStylesheet()
2956 {
2957   if (d->m_doc && d->m_paUseStylesheet->currentText() != d->m_sheetUsed) {
2958     d->m_sheetUsed = d->m_paUseStylesheet->currentText();
2959     d->m_doc->updateStyleSelector();
2960   }
2961 }
2962
2963 void KHTMLPart::updateActions()
2964 {
2965   bool frames = false;
2966
2967   QValueList<khtml::ChildFrame>::ConstIterator it = d->m_frames.begin();
2968   QValueList<khtml::ChildFrame>::ConstIterator end = d->m_frames.end();
2969   for (; it != end; ++it )
2970       if ( (*it).m_type == khtml::ChildFrame::Frame )
2971       {
2972           frames = true;
2973           break;
2974       }
2975
2976   d->m_paViewFrame->setEnabled( frames );
2977   d->m_paSaveFrame->setEnabled( frames );
2978
2979   if ( frames )
2980     d->m_paFind->setText( i18n( "&Find in Frame..." ) );
2981   else
2982     d->m_paFind->setText( i18n( "&Find..." ) );
2983
2984   KParts::Part *frame = 0;
2985
2986   if ( frames )
2987     frame = currentFrame();
2988
2989   bool enableFindAndSelectAll = true;
2990
2991   if ( frame )
2992     enableFindAndSelectAll = frame->inherits( "KHTMLPart" );
2993
2994   d->m_paFind->setEnabled( enableFindAndSelectAll );
2995   d->m_paSelectAll->setEnabled( enableFindAndSelectAll );
2996
2997   bool enablePrintFrame = false;
2998
2999   if ( frame )
3000   {
3001     QObject *ext = KParts::BrowserExtension::childObject( frame );
3002     if ( ext )
3003       enablePrintFrame = ext->metaObject()->slotNames().contains( "print()" );
3004   }
3005
3006   d->m_paPrintFrame->setEnabled( enablePrintFrame );
3007
3008   QString bgURL;
3009
3010   // ### frames
3011   if ( d->m_doc && d->m_doc->isHTMLDocument() && static_cast<HTMLDocumentImpl*>(d->m_doc)->body() && !d->m_bClearing )
3012     bgURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
3013
3014   d->m_paSaveBackground->setEnabled( !bgURL.isEmpty() );
3015 }
3016
3017 #endif
3018
3019 bool KHTMLPart::requestFrame( khtml::RenderPart *frame, const QString &url, const QString &frameName,
3020                               const QStringList &paramNames, const QStringList &paramValues, bool isIFrame )
3021 {
3022 //  kdDebug( 6050 ) << "childRequest( ..., " << url << ", " << frameName << " )" << endl;
3023   FrameIt it = d->m_frames.find( frameName );
3024   if ( it == d->m_frames.end() )
3025   {
3026     khtml::ChildFrame child;
3027 //    kdDebug( 6050 ) << "inserting new frame into frame map " << frameName << endl;
3028     child.m_name = frameName;
3029     it = d->m_frames.append( child );
3030   }
3031
3032   (*it).m_type = isIFrame ? khtml::ChildFrame::IFrame : khtml::ChildFrame::Frame;
3033   (*it).m_frame = frame;
3034   (*it).m_paramValues = paramNames;
3035   (*it).m_paramNames = paramValues;
3036
3037   // Support for <frame src="javascript:string">
3038   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
3039   {
3040     if (!processObjectRequest(&(*it), "about:blank", "text/html" ))
3041       return false;
3042
3043     KHTMLPart *newPart = static_cast<KHTMLPart *>(&*(*it).m_part); 
3044     newPart->replaceContentsWithScriptResult( url );
3045
3046     return true;
3047   }
3048
3049   return requestObject( &(*it), completeURL( url ));
3050 }
3051
3052 QString KHTMLPart::requestFrameName()
3053 {
3054 #if APPLE_CHANGES
3055     return KWQ(this)->generateFrameName();
3056 #else
3057     return QString::fromLatin1("<!--frame %1-->").arg(d->m_frameNameId++);
3058 #endif
3059 }
3060
3061 bool KHTMLPart::requestObject( khtml::RenderPart *frame, const QString &url, const QString &serviceType,
3062                                const QStringList &paramNames, const QStringList &paramValues )
3063 {
3064   khtml::ChildFrame child;
3065   QValueList<khtml::ChildFrame>::Iterator it = d->m_objects.append( child );
3066   (*it).m_frame = frame;
3067   (*it).m_type = khtml::ChildFrame::Object;
3068   (*it).m_paramNames = paramNames;
3069   (*it).m_paramValues = paramValues;
3070
3071   KURL completedURL;
3072   if (!url.isEmpty())
3073     completedURL = completeURL(url);
3074
3075   KParts::URLArgs args;
3076   args.serviceType = serviceType;
3077   return requestObject( &(*it), completedURL, args );
3078 }
3079
3080 bool KHTMLPart::requestObject( khtml::ChildFrame *child, const KURL &url, const KParts::URLArgs &_args )
3081 {
3082 #if !APPLE_CHANGES
3083   if (!checkLinkSecurity(url))
3084     return false;
3085 #endif
3086   if ( child->m_bPreloaded )
3087   {
3088     // kdDebug(6005) << "KHTMLPart::requestObject preload" << endl;
3089     if ( child->m_frame && child->m_part && child->m_part->widget() )
3090       child->m_frame->setWidget( child->m_part->widget() );
3091
3092     child->m_bPreloaded = false;
3093     return true;
3094   }
3095
3096   KParts::URLArgs args( _args );
3097
3098 #if !APPLE_CHANGES
3099   if ( child->m_run )
3100     child->m_run->abort();
3101 #endif
3102
3103   if ( child->m_part && !args.reload && urlcmp( child->m_part->url().url(), url.url(), true, true ) )
3104     args.serviceType = child->m_serviceType;
3105
3106   child->m_args = args;
3107   child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload) || (d->m_cachePolicy == KIO::CC_Refresh);
3108   child->m_serviceName = QString::null;
3109   if (!d->m_referrer.isEmpty() && !child->m_args.metaData().contains( "referrer" ))
3110     child->m_args.metaData()["referrer"] = d->m_referrer;
3111
3112 #if !APPLE_CHANGES
3113   child->m_args.metaData().insert("main_frame_request",
3114                                   parentPart() == 0 ? "TRUE":"FALSE");
3115   child->m_args.metaData().insert("ssl_was_in_use",
3116                                   d->m_ssl_in_use ? "TRUE":"FALSE");
3117   child->m_args.metaData().insert("ssl_activate_warnings", "TRUE");
3118 #endif
3119
3120   // We want a KHTMLPart if the HTML says <frame src=""> or <frame src="about:blank">
3121   if ((url.isEmpty() || url.url() == "about:blank") && args.serviceType.isEmpty())
3122     args.serviceType = QString::fromLatin1( "text/html" );
3123
3124 #if APPLE_CHANGES
3125   return processObjectRequest( child, url, args.serviceType );
3126 #else
3127   if ( args.serviceType.isEmpty() ) {
3128     child->m_run = new KHTMLRun( this, child, url, child->m_args,
3129                                  child->m_type != khtml::ChildFrame::Frame );
3130     return false;
3131   } else {
3132     return processObjectRequest( child, url, args.serviceType );
3133   }
3134 #endif
3135 }
3136
3137 bool KHTMLPart::processObjectRequest( khtml::ChildFrame *child, const KURL &_url, const QString &mimetype )
3138 {
3139   //kdDebug( 6050 ) << "KHTMLPart::processObjectRequest trying to create part for " << mimetype << endl;
3140
3141   // IMPORTANT: create a copy of the url here, because it is just a reference, which was likely to be given
3142   // by an emitting frame part (emit openURLRequest( blahurl, ... ) . A few lines below we delete the part
3143   // though -> the reference becomes invalid -> crash is likely
3144   KURL url( _url );
3145
3146   // khtmlrun called us this way to indicate a loading error
3147   if ( d->m_onlyLocalReferences || ( url.isEmpty() && mimetype.isEmpty() ) )
3148   {
3149       checkEmitLoadEvent();
3150       child->m_bCompleted = true;
3151       return true;
3152   }
3153
3154   if (child->m_bNotify)
3155   {
3156       child->m_bNotify = false;
3157       if ( !child->m_args.lockHistory() )
3158           emit d->m_extension->openURLNotify();
3159   }
3160
3161 #if APPLE_CHANGES
3162   if ( child->m_part )
3163   {
3164     KHTMLPart *part = dynamic_cast<KHTMLPart *>(&*child->m_part);
3165     if (part)
3166       part->openURL(url);
3167   }
3168   else
3169   {
3170     KParts::ReadOnlyPart *part = KWQ(this)->createPart(*child, url, mimetype);
3171     KHTMLPart *khtml_part = dynamic_cast<KHTMLPart *>(part);
3172     if (khtml_part)
3173       khtml_part->childBegin();
3174 #else
3175   if ( !child->m_services.contains( mimetype ) )
3176   {
3177     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 );
3178 #endif
3179
3180     if ( !part )
3181     {
3182         if ( child->m_frame )
3183           if (child->m_frame->partLoadingErrorNotify( child, url, mimetype ))
3184             return true; // we succeeded after all (a fallback was used)
3185
3186         checkEmitLoadEvent();
3187         return false;
3188     }
3189
3190     //CRITICAL STUFF
3191     if ( child->m_part )
3192     {
3193       disconnectChild(child);
3194 #if !APPLE_CHANGES
3195       partManager()->removePart( (KParts::ReadOnlyPart *)child->m_part );
3196 #endif
3197       child->m_part->deref();
3198     }
3199
3200     child->m_serviceType = mimetype;
3201     if ( child->m_frame && part->widget() )
3202       child->m_frame->setWidget( part->widget() );
3203
3204 #if !APPLE_CHANGES
3205     if ( child->m_type != khtml::ChildFrame::Object )
3206       partManager()->addPart( part, false );
3207 //  else
3208 //      kdDebug(6005) << "AH! NO FRAME!!!!!" << endl;
3209 #endif
3210
3211     child->m_part = part;
3212     assert( ((void*) child->m_part) != 0);
3213
3214     connectChild(child);
3215
3216 #if APPLE_CHANGES
3217   }
3218 #else
3219     child->m_extension = KParts::BrowserExtension::childObject( part );
3220
3221     if ( child->m_extension )
3222     {
3223       connect( child->m_extension, SIGNAL( openURLNotify() ),
3224                d->m_extension, SIGNAL( openURLNotify() ) );
3225
3226       connect( child->m_extension, SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ),
3227                this, SLOT( slotChildURLRequest( const KURL &, const KParts::URLArgs & ) ) );
3228
3229       connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ),
3230                d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ) );
3231       connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs &, const KParts::WindowArgs &, KParts::ReadOnlyPart *& ) ),
3232                d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & , const KParts::WindowArgs &, KParts::ReadOnlyPart *&) ) );
3233
3234       connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ),
3235                d->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ) );
3236       connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ),
3237                d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ) );
3238       connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ),
3239                d->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ) );
3240       connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ),
3241                d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ) );
3242
3243       connect( child->m_extension, SIGNAL( infoMessage( const QString & ) ),
3244                d->m_extension, SIGNAL( infoMessage( const QString & ) ) );
3245
3246       child->m_extension->setBrowserInterface( d->m_extension->browserInterface() );
3247     }
3248   }
3249 #endif
3250
3251   checkEmitLoadEvent();
3252   // Some JS code in the load event may have destroyed the part
3253   // In that case, abort
3254   if ( !child->m_part )
3255     return false;
3256
3257   if ( child->m_bPreloaded )
3258   {
3259     if ( child->m_frame && child->m_part )
3260       child->m_frame->setWidget( child->m_part->widget() );
3261
3262     child->m_bPreloaded = false;
3263     return true;
3264   }
3265
3266   child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload) || (d->m_cachePolicy == KIO::CC_Refresh);
3267
3268   // make sure the part has a way to find out about the mimetype.
3269   // we actually set it in child->m_args in requestObject already,
3270   // but it's useless if we had to use a KHTMLRun instance, as the
3271   // point the run object is to find out exactly the mimetype.
3272   child->m_args.serviceType = mimetype;
3273
3274   child->m_bCompleted = false;
3275   if ( child->m_extension )
3276     child->m_extension->setURLArgs( child->m_args );
3277
3278 #if APPLE_CHANGES
3279     // In these cases, the synchronous load would have finished
3280     // before we could connect the signals, so make sure to send the
3281     // completed() signal for the child by hand:
3282     if (url.isEmpty() || url.url() == "about:blank") {
3283       ReadOnlyPart *readOnlyPart = child->m_part;
3284       KHTMLPart *part = dynamic_cast<KHTMLPart *>(readOnlyPart);
3285       if (part) {
3286         part->completed();
3287       }
3288     }
3289 #else
3290   if(url.protocol() == "javascript" || url.url() == "about:blank") {
3291       if (!child->m_part->inherits("KHTMLPart"))
3292           return false;
3293
3294       KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>(child->m_part));
3295
3296       p->begin();
3297       if (d->m_doc && p->d->m_doc)
3298         p->d->m_doc->setBaseURL(d->m_doc->baseURL());
3299       if (!url.url().startsWith("about:")) {
3300         p->write(url.path());
3301       } else {
3302         p->m_url = url;
3303       }
3304       p->end();
3305       return true;
3306   }
3307   else if ( !url.isEmpty() )
3308   {
3309       //kdDebug( 6050 ) << "opening " << url.url() << " in frame " << child->m_part << endl;
3310       return child->m_part->openURL( url );
3311   }
3312   else
3313 #endif
3314       return true;
3315 }
3316
3317 #if !APPLE_CHANGES
3318
3319 KParts::ReadOnlyPart *KHTMLPart::createPart( QWidget *parentWidget, const char *widgetName,
3320                                              QObject *parent, const char *name, const QString &mimetype,
3321                                              QString &serviceName, QStringList &serviceTypes,
3322                                              const QStringList &params )
3323 {
3324   QString constr;
3325   if ( !serviceName.isEmpty() )
3326     constr.append( QString::fromLatin1( "Name == '%1'" ).arg( serviceName ) );
3327
3328   KTrader::OfferList offers = KTrader::self()->query( mimetype, "KParts/ReadOnlyPart", constr, QString::null );
3329
3330   if ( offers.isEmpty() )
3331     return 0L;
3332
3333   KService::Ptr service = *offers.begin();
3334
3335   KLibFactory *factory = KLibLoader::self()->factory( QFile::encodeName(service->library()) );
3336
3337   if ( !factory )
3338     return 0L;
3339
3340   KParts::ReadOnlyPart *res = 0L;
3341
3342   const char *className = "KParts::ReadOnlyPart";
3343   if ( service->serviceTypes().contains( "Browser/View" ) )
3344     className = "Browser/View";
3345
3346   if ( factory->inherits( "KParts::Factory" ) )
3347     res = static_cast<KParts::ReadOnlyPart *>(static_cast<KParts::Factory *>( factory )->createPart( parentWidget, widgetName, parent, name, className, params ));
3348   else
3349   res = static_cast<KParts::ReadOnlyPart *>(factory->create( parentWidget, widgetName, className ));
3350
3351   if ( !res )
3352     return res;
3353
3354   serviceTypes = service->serviceTypes();
3355   serviceName = service->name();
3356
3357   return res;
3358 }
3359
3360 KParts::PartManager *KHTMLPart::partManager()
3361 {
3362   if ( !d->m_manager )
3363   {
3364     d->m_manager = new KParts::PartManager( d->m_view->topLevelWidget(), this, "khtml part manager" );
3365     d->m_manager->setAllowNestedParts( true );
3366     connect( d->m_manager, SIGNAL( activePartChanged( KParts::Part * ) ),
3367              this, SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
3368     connect( d->m_manager, SIGNAL( partRemoved( KParts::Part * ) ),
3369              this, SLOT( slotPartRemoved( KParts::Part * ) ) );
3370   }
3371
3372   return d->m_manager;
3373 }
3374
3375 #endif
3376
3377 void KHTMLPart::submitFormAgain()
3378 {
3379   if( d->m_doc && !d->m_doc->parsing() && d->m_submitForm)
3380     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 );
3381
3382   delete d->m_submitForm;
3383   d->m_submitForm = 0;
3384   disconnect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
3385 }
3386
3387 void KHTMLPart::submitForm( const char *action, const QString &url, const FormData &formData, const QString &_target, const QString& contentType, const QString& boundary )
3388 {
3389   kdDebug(6000) << this << ": KHTMLPart::submitForm target=" << _target << " url=" << url << endl;
3390   KURL u = completeURL( url );
3391
3392   if ( !u.isValid() )
3393   {
3394     // ### ERROR HANDLING!
3395     return;
3396   }
3397
3398 #if !APPLE_CHANGES
3399   // Form security checks
3400   //
3401
3402   /* This is separate for a reason.  It has to be _before_ all script, etc,
3403    * AND I don't want to break anything that uses checkLinkSecurity() in
3404    * other places.
3405    */
3406
3407   // This causes crashes... needs to be fixed.
3408   if (!d->m_submitForm && u.protocol() != "https" && u.protocol() != "mailto") {
3409         if (d->m_ssl_in_use) {    // Going from SSL -> nonSSL
3410                 int rc = KMessageBox::warningContinueCancel(NULL, i18n("Warning:  This is a secure form but it is attempting to send your data back unencrypted."
3411                                         "\nA third party may be able to intercept and view this information."
3412                                         "\nAre you sure you wish to continue?"),
3413                                 i18n("SSL"));
3414                 if (rc == KMessageBox::Cancel)
3415                         return;
3416         } else {                  // Going from nonSSL -> nonSSL
3417                 KSSLSettings kss(true);
3418                 if (kss.warnOnUnencrypted()) {
3419                         int rc = KMessageBox::warningContinueCancel(NULL,
3420                                         i18n("Warning: Your data is about to be transmitted across the network unencrypted."
3421                                         "\nAre you sure you wish to continue?"),
3422                                         i18n("KDE"),
3423                                                                     QString::null,
3424                                         "WarnOnUnencryptedForm");
3425                         // Move this setting into KSSL instead
3426                         KConfig *config = kapp->config();
3427                         QString grpNotifMsgs = QString::fromLatin1("Notification Messages");
3428                         KConfigGroupSaver saver( config, grpNotifMsgs );
3429
3430                         if (!config->readBoolEntry("WarnOnUnencryptedForm", true)) {
3431                                 config->deleteEntry("WarnOnUnencryptedForm");
3432                                 config->sync();
3433                                 kss.setWarnOnUnencrypted(false);
3434                                 kss.save();
3435                         }
3436                         if (rc == KMessageBox::Cancel)
3437                           return;
3438         }
3439     }
3440   }
3441
3442   if (!d->m_submitForm && u.protocol() == "mailto") {
3443      int rc = KMessageBox::warningContinueCancel(NULL, 
3444                  i18n("This site is attempting to submit form data via email."),
3445                  i18n("KDE"), 
3446                  QString::null, 
3447                  "WarnTriedEmailSubmit");
3448
3449      if (rc == KMessageBox::Cancel) {
3450          return;
3451      }
3452   }
3453
3454   // End form security checks
3455   //
3456 #endif // APPLE_CHANGES
3457
3458   QString urlstring = u.url();
3459
3460   if ( urlstring.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
3461     urlstring = KURL::decode_string(urlstring);
3462     d->m_executingJavaScriptFormAction = true;
3463     executeScript( urlstring.right( urlstring.length() - 11) );
3464     d->m_executingJavaScriptFormAction = false;
3465     return;
3466   }
3467
3468 #if !APPLE_CHANGES
3469   if (!checkLinkSecurity(u,
3470                          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?" ),
3471                          i18n( "Submit" )))
3472     return;
3473 #endif
3474
3475   KParts::URLArgs args;
3476
3477   if (!d->m_referrer.isEmpty())
3478      args.metaData()["referrer"] = d->m_referrer;
3479
3480 #if !APPLE_CHANGES
3481   args.metaData().insert("main_frame_request",
3482                          parentPart() == 0 ? "TRUE":"FALSE");
3483   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
3484   args.metaData().insert("ssl_activate_warnings", "TRUE");
3485 #endif
3486   args.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;
3487
3488   // Handle mailto: forms
3489   if (u.protocol() == "mailto") {
3490       // 1)  Check for attach= and strip it
3491       QString q = u.query().mid(1);
3492       QStringList nvps = QStringList::split("&", q);
3493       bool triedToAttach = false;
3494
3495       for (QStringList::Iterator nvp = nvps.begin(); nvp != nvps.end(); ++nvp) {
3496          QStringList pair = QStringList::split("=", *nvp);
3497          if (pair.count() >= 2) {
3498             if (pair.first().lower() == "attach") {
3499                nvp = nvps.remove(nvp);
3500                triedToAttach = true;
3501             }
3502          }
3503       }
3504
3505 #if !APPLE_CHANGES
3506       if (triedToAttach)
3507          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");
3508 #endif
3509
3510       // 2)  Append body=
3511       QString bodyEnc;
3512       if (contentType.lower() == "multipart/form-data") {
3513          // FIXME: is this correct?  I suspect not
3514          bodyEnc = KURL::encode_string(formData.flattenToString());
3515       } else if (contentType.lower() == "text/plain") {
3516          // Convention seems to be to decode, and s/&/\n/
3517          QString tmpbody = formData.flattenToString();
3518          tmpbody.replace('&', '\n');
3519          tmpbody.replace('+', ' ');
3520          tmpbody = KURL::decode_string(tmpbody);  // Decode the rest of it
3521          bodyEnc = KURL::encode_string(tmpbody);  // Recode for the URL
3522       } else {
3523          bodyEnc = KURL::encode_string(formData.flattenToString());
3524       }
3525
3526       nvps.append(QString("body=%1").arg(bodyEnc));
3527       q = nvps.join("&");
3528       u.setQuery(q);
3529   } 
3530
3531   if ( strcmp( action, "get" ) == 0 ) {
3532     if (u.protocol() != "mailto")
3533        u.setQuery( formData.flattenToString() );
3534     args.setDoPost( false );
3535   }
3536   else {
3537 #if APPLE_CHANGES
3538     args.postData = formData;
3539 #else
3540     args.postData = formData.flatten();
3541 #endif
3542     args.setDoPost( true );
3543
3544     // construct some user headers if necessary
3545     if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
3546       args.setContentType( "Content-Type: application/x-www-form-urlencoded" );
3547     else // contentType must be "multipart/form-data"
3548       args.setContentType( "Content-Type: " + contentType + "; boundary=" + boundary );
3549   }
3550
3551   if ( d->m_doc->parsing() || d->m_runningScripts > 0 ) {
3552     if( d->m_submitForm ) {
3553       kdDebug(6000) << "KHTMLPart::submitForm ABORTING!" << endl;
3554       return;
3555     }
3556     d->m_submitForm = new KHTMLPartPrivate::SubmitForm;
3557     d->m_submitForm->submitAction = action;
3558     d->m_submitForm->submitUrl = url;
3559     d->m_submitForm->submitFormData = formData;
3560     d->m_submitForm->target = _target;
3561     d->m_submitForm->submitContentType = contentType;
3562     d->m_submitForm->submitBoundary = boundary;
3563     connect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
3564   }
3565   else
3566   {
3567 #if APPLE_CHANGES
3568     KWQ(this)->submitForm( u, args);
3569 #else
3570     emit d->m_extension->openURLRequest( u, args );
3571 #endif
3572   }
3573 }
3574
3575 #if !APPLE_CHANGES
3576
3577 void KHTMLPart::popupMenu( const QString &linkUrl )
3578 {
3579   KURL popupURL;
3580   KURL linkKURL;
3581   if ( linkUrl.isEmpty() ) // click on background
3582     popupURL = this->url();
3583   else {               // click on link
3584     popupURL = completeURL( linkUrl );
3585     linkKURL = popupURL;
3586   }
3587
3588   KXMLGUIClient *client = new KHTMLPopupGUIClient( this, d->m_popupMenuXML, linkKURL );
3589
3590   emit d->m_extension->popupMenu( client, QCursor::pos(), popupURL,
3591                                   QString::fromLatin1( "text/html" ), S_IFREG /*always a file*/ );
3592
3593   delete client;
3594
3595   emit popupMenu(linkUrl, QCursor::pos());
3596 }
3597
3598 #endif
3599
3600 void KHTMLPart::slotParentCompleted()
3601 {
3602   if ( d->m_scheduledRedirection != noRedirectionScheduled && !d->m_redirectionTimer.isActive() )
3603   {
3604     // kdDebug(6050) << this << ": Child redirection -> " << d->m_redirectURL << endl;
3605     d->m_redirectionTimer.start( (int)(1000 * d->m_delayRedirect), true );
3606   }
3607 }
3608
3609 void KHTMLPart::slotChildStarted( KIO::Job *job )
3610 {
3611   khtml::ChildFrame *child = childFrame( sender() );
3612
3613   assert( child );
3614
3615   child->m_bCompleted = false;
3616
3617   if ( d->m_bComplete )
3618   {
3619 #if 0
3620     // WABA: Looks like this belongs somewhere else
3621     if ( !parentPart() ) // "toplevel" html document? if yes, then notify the hosting browser about the document (url) changes
3622     {
3623       emit d->m_extension->openURLNotify();
3624     }
3625 #endif
3626     d->m_bComplete = false;
3627     emit started( job );
3628   }
3629 }
3630
3631 void KHTMLPart::slotChildCompleted()
3632 {
3633   slotChildCompleted( false );
3634 }
3635
3636 void KHTMLPart::slotChildCompleted( bool complete )
3637 {
3638   khtml::ChildFrame *child = childFrame( sender() );
3639
3640   assert( child );
3641
3642   child->m_bCompleted = true;
3643   child->m_args = KParts::URLArgs();
3644
3645   if ( complete && parentPart() == 0 )
3646     d->m_bPendingChildRedirection = true;
3647
3648   checkCompleted();
3649 }
3650
3651 #if !APPLE_CHANGES
3652
3653 void KHTMLPart::slotChildURLRequest( const KURL &url, const KParts::URLArgs &args )
3654 {
3655   khtml::ChildFrame *child = childFrame( sender()->parent() );
3656
3657   QString frameName = args.frameName.lower();
3658   if ( !frameName.isEmpty() )
3659   {
3660     if ( frameName == QString::fromLatin1( "_top" ) )
3661     {
3662       emit d->m_extension->openURLRequest( url, args );
3663       return;
3664     }
3665     else if ( frameName == QString::fromLatin1( "_blank" ) )
3666     {
3667       emit d->m_extension->createNewWindow( url, args );
3668       return;
3669     }
3670     else if ( frameName == QString::fromLatin1( "_parent" ) )
3671     {
3672       KParts::URLArgs newArgs( args );
3673       newArgs.frameName = QString::null;
3674
3675       emit d->m_extension->openURLRequest( url, newArgs );
3676       return;
3677     }
3678     else if ( frameName != QString::fromLatin1( "_self" ) )
3679     {
3680       khtml::ChildFrame *_frame = recursiveFrameRequest( url, args );
3681
3682       if ( !_frame )
3683       {
3684         emit d->m_extension->openURLRequest( url, args );
3685         return;
3686       }
3687
3688       child = _frame;
3689     }
3690   }
3691
3692   // TODO: handle child target correctly! currently the script are always executed fur the parent
3693   QString urlStr = url.url();
3694   if ( urlStr.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
3695       executeScript( KURL::decode_string( urlStr.right( urlStr.length() - 11) ) );
3696       return;
3697   }
3698
3699   if ( child ) {
3700       // Inform someone that we are about to show something else.
3701       child->m_bNotify = true;
3702       requestObject( child, url, args );
3703   }  else if ( frameName==QString::fromLatin1("_self") ) // this is for embedded objects (via <object>) which want to replace the current document
3704   {
3705       KParts::URLArgs newArgs( args );
3706       newArgs.frameName = QString::null;
3707       emit d->m_extension->openURLRequest( url, newArgs );
3708   }
3709 }
3710
3711 #endif // APPLE_CHANGES
3712
3713 khtml::ChildFrame *KHTMLPart::childFrame( const QObject *obj )
3714 {
3715     assert( obj->inherits( "KParts::ReadOnlyPart" ) );
3716     const ReadOnlyPart *part = static_cast<const ReadOnlyPart *>( obj );
3717
3718     FrameIt it = d->m_frames.begin();
3719     FrameIt end = d->m_frames.end();
3720     for (; it != end; ++it )
3721       if ( static_cast<ReadOnlyPart *>((*it).m_part) == part )
3722         return &(*it);
3723
3724     it = d->m_objects.begin();
3725     end = d->m_objects.end();
3726     for (; it != end; ++it )
3727       if ( static_cast<ReadOnlyPart *>((*it).m_part) == part )
3728         return &(*it);
3729
3730     return 0L;
3731 }
3732
3733 KHTMLPart *KHTMLPart::findFrame( const QString &f )
3734 {
3735 #if 0
3736   kdDebug() << "KHTMLPart::findFrame '" << f << "'" << endl;
3737   FrameIt it2 = d->m_frames.begin();
3738   FrameIt end = d->m_frames.end();
3739   for (; it2 != end; ++it2 )
3740       kdDebug() << "  - having frame '" << (*it2).m_name << "'" << endl;
3741 #endif
3742
3743   // ### http://www.w3.org/TR/html4/appendix/notes.html#notes-frames
3744   ConstFrameIt it = d->m_frames.find( f );
3745   if ( it == d->m_frames.end() )
3746   {
3747     //kdDebug() << "KHTMLPart::findFrame frame " << f << " not found" << endl;
3748     return 0L;
3749   }
3750   else {
3751     KParts::ReadOnlyPart *p = (*it).m_part;
3752     if ( p && p->inherits( "KHTMLPart" ))
3753     {
3754       //kdDebug() << "KHTMLPart::findFrame frame " << f << " is a KHTMLPart, ok" << endl;
3755       return (KHTMLPart*)p;
3756     }
3757     else
3758     {
3759 #if 0
3760       if (p)
3761         kdWarning() << "KHTMLPart::findFrame frame " << f << " found but isn't a KHTMLPart ! " << p->className() << endl;
3762       else
3763         kdWarning() << "KHTMLPart::findFrame frame " << f << " found but m_part=0L" << endl;
3764 #endif
3765       return 0L;
3766     }
3767   }
3768 }
3769
3770 #if !APPLE_CHANGES
3771
3772 KParts::ReadOnlyPart *KHTMLPart::currentFrame() const
3773 {
3774   KParts::ReadOnlyPart* part = (KParts::ReadOnlyPart*)(this);
3775   // Find active part in our frame manager, in case we are a frameset
3776   // and keep doing that (in case of nested framesets).
3777   // Just realized we could also do this recursively, calling part->currentFrame()...
3778   while ( part && part->inherits("KHTMLPart") &&
3779           static_cast<KHTMLPart *>(part)->d->m_frames.count() > 0 ) {
3780     KHTMLPart* frameset = static_cast<KHTMLPart *>(part);
3781     part = static_cast<KParts::ReadOnlyPart *>(frameset->partManager()->activePart());
3782     if ( !part ) return frameset;
3783   }
3784   return part;
3785 }
3786
3787 #endif // APPLE_CHANGES
3788
3789 bool KHTMLPart::frameExists( const QString &frameName )
3790 {
3791   ConstFrameIt it = d->m_frames.find( frameName );
3792   if ( it == d->m_frames.end() )
3793     return false;
3794
3795   // WABA: We only return true if the child actually has a frame
3796   // set. Otherwise we might find our preloaded-selve.
3797   // This happens when we restore the frameset.
3798   return (!(*it).m_frame.isNull());
3799 }
3800
3801 KHTMLPart *KHTMLPart::parentPart() const
3802 {
3803   if ( !parent() || !parent()->inherits( "KHTMLPart" ) )
3804     return 0L;
3805
3806   return (KHTMLPart *)parent();
3807 }
3808
3809 #if !APPLE_CHANGES
3810
3811 khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( const KURL &url, const KParts::URLArgs &args,
3812                                                      bool callParent )
3813 {
3814   FrameIt it = d->m_frames.find( args.frameName );
3815
3816   if ( it != d->m_frames.end() )
3817     return &(*it);
3818
3819   it = d->m_frames.begin();
3820   FrameIt end = d->m_frames.end();
3821   for (; it != end; ++it )
3822     if ( (*it).m_part && (*it).m_part->inherits( "KHTMLPart" ) )
3823     {
3824       KHTMLPart *childPart = (KHTMLPart *)(KParts::ReadOnlyPart *)(*it).m_part;
3825
3826       khtml::ChildFrame *res = childPart->recursiveFrameRequest( url, args, false );
3827       if ( !res )
3828         continue;
3829
3830       childPart->requestObject( res, url, args );
3831       return 0L;
3832     }
3833
3834   if ( parentPart() && callParent )
3835   {
3836     khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( url, args );
3837
3838     if ( res )
3839       parentPart()->requestObject( res, url, args );
3840
3841     return 0L;
3842   }
3843
3844   return 0L;
3845 }
3846
3847 void KHTMLPart::saveState( QDataStream &stream )
3848 {
3849   kdDebug( 6050 ) << "KHTMLPart::saveState saving URL " << m_url.url() << endl;
3850
3851   stream << m_url << (Q_INT32)d->m_view->contentsX() << (Q_INT32)d->m_view->contentsY()
3852          << (Q_INT32) d->m_view->contentsWidth() << (Q_INT32) d->m_view->contentsHeight() << (Q_INT32) d->m_view->marginWidth() << (Q_INT32) d->m_view->marginHeight();
3853
3854   // save link cursor position
3855   int focusNodeNumber;
3856   if (!d->m_focusNodeRestored)
3857       focusNodeNumber = d->m_focusNodeNumber;
3858   else if (d->m_doc->focusNode())
3859       focusNodeNumber = d->m_doc->nodeAbsIndex(d->m_doc->focusNode());
3860   else
3861       focusNodeNumber = -1;
3862   stream << focusNodeNumber;
3863
3864   // Save the doc's cache id.
3865   stream << d->m_cacheId;
3866
3867   // Save the state of the document (Most notably the state of any forms)
3868   QStringList docState;
3869   if (d->m_doc)
3870   {
3871      docState = d->m_doc->docState();
3872   }
3873   stream << d->m_encoding << d->m_sheetUsed << docState;
3874
3875   stream << d->m_zoomFactor;
3876
3877   // Save ssl data
3878   stream << d->m_ssl_in_use
3879          << d->m_ssl_peer_certificate
3880          << d->m_ssl_peer_chain
3881          << d->m_ssl_peer_ip
3882          << d->m_ssl_cipher
3883          << d->m_ssl_cipher_desc
3884          << d->m_ssl_cipher_version
3885          << d->m_ssl_cipher_used_bits
3886          << d->m_ssl_cipher_bits
3887          << d->m_ssl_cert_state;
3888
3889
3890   QStringList frameNameLst, frameServiceTypeLst, frameServiceNameLst;
3891   KURL::List frameURLLst;
3892   QValueList<QByteArray> frameStateBufferLst;
3893
3894   ConstFrameIt it = d->m_frames.begin();
3895   ConstFrameIt end = d->m_frames.end();
3896   for (; it != end; ++it )
3897   {
3898     if ( !(*it).m_part )
3899        continue;
3900
3901     frameNameLst << (*it).m_name;
3902     frameServiceTypeLst << (*it).m_serviceType;
3903     frameServiceNameLst << (*it).m_serviceName;
3904     frameURLLst << (*it).m_part->url();
3905
3906     QByteArray state;
3907     QDataStream frameStream( state, IO_WriteOnly );
3908
3909     if ( (*it).m_extension )
3910       (*it).m_extension->saveState( frameStream );
3911
3912     frameStateBufferLst << state;
3913   }
3914
3915   // Save frame data
3916   stream << (Q_UINT32) frameNameLst.count();
3917   stream << frameNameLst << frameServiceTypeLst << frameServiceNameLst << frameURLLst << frameStateBufferLst;
3918 }
3919
3920 void KHTMLPart::restoreState( QDataStream &stream )
3921 {
3922   KURL u;
3923   Q_INT32 xOffset, yOffset, wContents, hContents, mWidth, mHeight;
3924   Q_UINT32 frameCount;
3925   QStringList frameNames, frameServiceTypes, docState, frameServiceNames;
3926   KURL::List frameURLs;
3927   QValueList<QByteArray> frameStateBuffers;
3928   QValueList<int> fSizes;
3929   QString encoding, sheetUsed;
3930   long old_cacheId = d->m_cacheId;
3931
3932   stream >> u >> xOffset >> yOffset >> wContents >> hContents >> mWidth >> mHeight;
3933
3934   d->m_view->setMarginWidth( mWidth );
3935   d->m_view->setMarginHeight( mHeight );
3936
3937   // restore link cursor position
3938   // nth node is active. value is set in checkCompleted()
3939   stream >> d->m_focusNodeNumber;
3940   d->m_focusNodeRestored = false;
3941   kdDebug(6050)<<"new focus Node number is:"<<d->m_focusNodeNumber<<endl;
3942
3943   stream >> d->m_cacheId;
3944
3945   stream >> encoding >> sheetUsed >> docState;
3946   d->m_encoding = encoding;
3947   d->m_sheetUsed = sheetUsed;
3948
3949   int zoomFactor;
3950   stream >> zoomFactor;
3951   setZoomFactor(zoomFactor);
3952
3953   // Restore ssl data
3954   stream >> d->m_ssl_in_use
3955          >> d->m_ssl_peer_certificate
3956          >> d->m_ssl_peer_chain
3957          >> d->m_ssl_peer_ip
3958          >> d->m_ssl_cipher
3959          >> d->m_ssl_cipher_desc
3960          >> d->m_ssl_cipher_version
3961          >> d->m_ssl_cipher_used_bits
3962          >> d->m_ssl_cipher_bits
3963          >> d->m_ssl_cert_state;
3964
3965   d->m_paSecurity->setIcon( d->m_ssl_in_use ? "encrypted" : "decrypted" );
3966
3967   stream >> frameCount >> frameNames >> frameServiceTypes >> frameServiceNames
3968          >> frameURLs >> frameStateBuffers;
3969
3970   d->m_bComplete = false;
3971   d->m_bLoadEventEmitted = false;
3972
3973 //   kdDebug( 6050 ) << "restoreStakte() docState.count() = " << docState.count() << endl;
3974 //   kdDebug( 6050 ) << "m_url " << m_url.url() << " <-> " << u.url() << endl;
3975 //   kdDebug( 6050 ) << "m_frames.count() " << d->m_frames.count() << " <-> " << frameCount << endl;
3976
3977   if (d->m_cacheId == old_cacheId)
3978   {
3979     // Partial restore
3980     cancelRedirection();
3981
3982     FrameIt fIt = d->m_frames.begin();
3983     FrameIt fEnd = d->m_frames.end();
3984
3985     for (; fIt != fEnd; ++fIt )
3986         (*fIt).m_bCompleted = false;
3987
3988     fIt = d->m_frames.begin();
3989
3990     QStringList::ConstIterator fNameIt = frameNames.begin();
3991     QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
3992     QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
3993     KURL::List::ConstIterator fURLIt = frameURLs.begin();
3994     QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
3995
3996     for (; fIt != fEnd; ++fIt, ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
3997     {
3998       khtml::ChildFrame *child = &(*fIt);
3999
4000 //      kdDebug( 6050 ) <<  *fNameIt  << " ---- " <<  *fServiceTypeIt << endl;
4001
4002       if ( child->m_name != *fNameIt || child->m_serviceType != *fServiceTypeIt )
4003       {
4004         child->m_bPreloaded = true;
4005         child->m_name = *fNameIt;
4006         child->m_serviceName = *fServiceNameIt;
4007         processObjectRequest( child, *fURLIt, *fServiceTypeIt );
4008       }
4009
4010       if ( child->m_part )
4011       {
4012         child->m_bCompleted = false;
4013         if ( child->m_extension && !(*fBufferIt).isEmpty() )
4014         {
4015           QDataStream frameStream( *fBufferIt, IO_ReadOnly );
4016           child->m_extension->restoreState( frameStream );
4017         }
4018         else
4019           child->m_part->openURL( *fURLIt );
4020       }
4021     }
4022
4023     KParts::URLArgs args( d->m_extension->urlArgs() );
4024     args.xOffset = xOffset;
4025     args.yOffset = yOffset;
4026     args.docState = docState; // WABA: How are we going to restore this??
4027     d->m_extension->setURLArgs( args );
4028
4029     d->m_view->resizeContents( wContents,  hContents);
4030     d->m_view->setContentsPos( xOffset, yOffset );
4031   }
4032   else
4033   {
4034     // Full restore.
4035     closeURL();
4036     // We must force a clear because we want to be sure to delete all
4037     // frames.
4038     d->m_bCleared = false;
4039     clear();
4040     d->m_encoding = encoding;
4041     d->m_sheetUsed = sheetUsed;
4042
4043     QStringList::ConstIterator fNameIt = frameNames.begin();
4044     QStringList::ConstIterator fNameEnd = frameNames.end();
4045
4046     QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
4047     QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
4048     KURL::List::ConstIterator fURLIt = frameURLs.begin();
4049     QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
4050
4051     for (; fNameIt != fNameEnd; ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
4052     {
4053       khtml::ChildFrame newChild;
4054       newChild.m_bPreloaded = true;
4055       newChild.m_name = *fNameIt;
4056       newChild.m_serviceName = *fServiceNameIt;
4057
4058 //      kdDebug( 6050 ) << *fNameIt << " ---- " << *fServiceTypeIt << endl;
4059
4060       FrameIt childFrame = d->m_frames.append( newChild );
4061
4062       processObjectRequest( &(*childFrame), *fURLIt, *fServiceTypeIt );
4063
4064       (*childFrame).m_bPreloaded = true;
4065
4066       if ( (*childFrame).m_part )
4067       {
4068         if ( (*childFrame).m_extension )
4069         if ( (*childFrame).m_extension && !(*fBufferIt).isEmpty() )
4070         {
4071           QDataStream frameStream( *fBufferIt, IO_ReadOnly );
4072           (*childFrame).m_extension->restoreState( frameStream );
4073         }
4074         else
4075           (*childFrame).m_part->openURL( *fURLIt );
4076       }
4077     }
4078
4079     KParts::URLArgs args( d->m_extension->urlArgs() );
4080     args.xOffset = xOffset;
4081     args.yOffset = yOffset;
4082     args.docState = docState;
4083     d->m_extension->setURLArgs( args );
4084     if (!KHTMLPageCache::self()->isValid(d->m_cacheId))
4085     {
4086        d->m_restored = true;
4087        openURL( u );
4088        d->m_restored = false;
4089     }
4090     else
4091     {
4092        restoreURL( u );
4093     }
4094   }
4095
4096 }
4097
4098 void KHTMLPart::show()
4099 {
4100   if ( d->m_view )
4101     d->m_view->show();
4102 }
4103
4104 void KHTMLPart::hide()
4105 {
4106   if ( d->m_view )
4107     d->m_view->hide();
4108 }
4109
4110 #endif // APPLE_CHANGES
4111
4112 DOM::Node KHTMLPart::nodeUnderMouse() const
4113 {
4114     return d->m_view->nodeUnderMouse();
4115 }
4116
4117 void KHTMLPart::emitSelectionChanged()
4118 {
4119 #if !APPLE_CHANGES
4120   emit d->m_extension->enableAction( "copy", hasSelection() );
4121   emit d->m_extension->selectionInfo( selectedText() );
4122   emit selectionChanged();
4123 #endif
4124 }
4125
4126 int KHTMLPart::zoomFactor() const
4127 {
4128   return d->m_zoomFactor;
4129 }
4130
4131 // ### make the list configurable ?
4132 static const int zoomSizes[] = { 20, 40, 60, 80, 90, 95, 100, 105, 110, 120, 140, 160, 180, 200, 250, 300 };
4133 static const int zoomSizeCount = (sizeof(zoomSizes) / sizeof(int));
4134 static const int minZoom = 20;
4135 static const int maxZoom = 300;
4136
4137 void KHTMLPart::slotIncZoom()
4138 {
4139   int zoomFactor = d->m_zoomFactor;
4140
4141   if (zoomFactor < maxZoom) {
4142     // find the entry nearest to the given zoomsizes
4143     for (int i = 0; i < zoomSizeCount; ++i)
4144       if (zoomSizes[i] > zoomFactor) {
4145         zoomFactor = zoomSizes[i];
4146         break;
4147       }
4148     setZoomFactor(zoomFactor);
4149   }
4150 }
4151
4152 void KHTMLPart::slotDecZoom()
4153 {
4154     int zoomFactor = d->m_zoomFactor;
4155     if (zoomFactor > minZoom) {
4156       // find the entry nearest to the given zoomsizes
4157       for (int i = zoomSizeCount-1; i >= 0; --i)
4158         if (zoomSizes[i] < zoomFactor) {
4159           zoomFactor = zoomSizes[i];
4160           break;
4161         }
4162       setZoomFactor(zoomFactor);
4163     }
4164 }
4165
4166 void KHTMLPart::setZoomFactor (int percent)
4167 {
4168 #if !APPLE_CHANGES // limits are client's responsibility
4169   if (percent < minZoom) percent = minZoom;
4170   if (percent > maxZoom) percent = maxZoom;
4171 #endif
4172   
4173   if (d->m_zoomFactor == percent) return;
4174   d->m_zoomFactor = percent;
4175
4176   if(d->m_doc) {
4177 #if !APPLE_CHANGES
4178       QApplication::setOverrideCursor( waitCursor );
4179 #endif
4180     d->m_doc->recalcStyle( NodeImpl::Force );
4181 #if !APPLE_CHANGES
4182     QApplication::restoreOverrideCursor();
4183 #endif
4184   }
4185
4186   ConstFrameIt it = d->m_frames.begin();
4187   ConstFrameIt end = d->m_frames.end();
4188   for (; it != end; ++it )
4189     if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
4190       KParts::ReadOnlyPart* p = ( *it ).m_part;
4191       static_cast<KHTMLPart*>( p )->setZoomFactor(d->m_zoomFactor);
4192     }
4193
4194 #if !APPLE_CHANGES
4195   d->m_paDecZoomFactor->setEnabled( d->m_zoomFactor > minZoom );
4196   d->m_paIncZoomFactor->setEnabled( d->m_zoomFactor < maxZoom );
4197 #endif
4198
4199   if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout())
4200     view()->layout();
4201 }
4202
4203 void KHTMLPart::setJSStatusBarText( const QString &text )
4204 {
4205    d->m_kjsStatusBarText = text;
4206    emit setStatusBarText( d->m_kjsStatusBarText );
4207 }
4208
4209 void KHTMLPart::setJSDefaultStatusBarText( const QString &text )
4210 {
4211    d->m_kjsDefaultStatusBarText = text;
4212    emit setStatusBarText( d->m_kjsDefaultStatusBarText );
4213 }
4214
4215 QString KHTMLPart::jsStatusBarText() const
4216 {
4217     return d->m_kjsStatusBarText;
4218 }
4219
4220 QString KHTMLPart::jsDefaultStatusBarText() const
4221 {
4222    return d->m_kjsDefaultStatusBarText;
4223 }
4224
4225 QString KHTMLPart::referrer() const
4226 {
4227    return d->m_referrer;
4228 }
4229
4230 QString KHTMLPart::lastModified() const
4231 {
4232   return d->m_lastModified;
4233 }
4234
4235 #if !APPLE_CHANGES
4236
4237 void KHTMLPart::slotLoadImages()
4238 {
4239   if (d->m_doc )
4240     d->m_doc->docLoader()->setAutoloadImages( !d->m_doc->docLoader()->autoloadImages() );
4241
4242   ConstFrameIt it = d->m_frames.begin();
4243   ConstFrameIt end = d->m_frames.end();
4244   for (; it != end; ++it )
4245     if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
4246       KParts::ReadOnlyPart* p = ( *it ).m_part;
4247       static_cast<KHTMLPart*>( p )->slotLoadImages();
4248     }
4249 }
4250
4251 #endif
4252
4253 void KHTMLPart::reparseConfiguration()
4254 {
4255 #if !APPLE_CHANGES
4256   setAutoloadImages( settings->autoLoadImages() );
4257   if (d->m_doc)
4258      d->m_doc->docLoader()->setShowAnimations( settings->showAnimations() );
4259
4260   d->m_bJScriptEnabled = settings->isJavaScriptEnabled(m_url.host());
4261   d->m_bJScriptDebugEnabled = settings->isJavaScriptDebugEnabled();
4262   d->m_bJavaEnabled = settings->isJavaEnabled(m_url.host());
4263   d->m_bPluginsEnabled = settings->isPluginsEnabled(m_url.host());
4264   delete d->m_settings;
4265   d->m_settings = new KHTMLSettings(*KHTMLFactory::defaultHTMLSettings());
4266
4267   QString userStyleSheet = KHTMLFactory::defaultHTMLSettings()->userStyleSheet();
4268 #else
4269   setAutoloadImages( d->m_settings->autoLoadImages() );
4270   if (d->m_doc)
4271      d->m_doc->docLoader()->setShowAnimations( d->m_settings->showAnimations() );
4272
4273   d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled(m_url.host());
4274   d->m_bJScriptDebugEnabled = d->m_settings->isJavaScriptDebugEnabled();
4275   d->m_bJavaEnabled = d->m_settings->isJavaEnabled(m_url.host());
4276   d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled(m_url.host());
4277
4278   QString userStyleSheet = d->m_settings->userStyleSheet();
4279 #endif
4280   if ( !userStyleSheet.isEmpty() )
4281     setUserStyleSheet( KURL( userStyleSheet ) );
4282   else
4283     setUserStyleSheet( QString() );
4284
4285 #if !APPLE_CHANGES
4286   QApplication::setOverrideCursor( waitCursor );
4287 #endif
4288   if(d->m_doc) d->m_doc->updateStyleSelector();
4289 #if !APPLE_CHANGES
4290   QApplication::restoreOverrideCursor();
4291 #endif
4292 }
4293
4294 QStringList KHTMLPart::frameNames() const
4295 {
4296   QStringList res;
4297
4298   ConstFrameIt it = d->m_frames.begin();
4299   ConstFrameIt end = d->m_frames.end();
4300   for (; it != end; ++it )
4301     if (!(*it).m_bPreloaded)
4302       res += (*it).m_name;
4303
4304   return res;
4305 }
4306
4307 QPtrList<KParts::ReadOnlyPart> KHTMLPart::frames() const
4308 {
4309   QPtrList<KParts::ReadOnlyPart> res;
4310
4311   ConstFrameIt it = d->m_frames.begin();
4312   ConstFrameIt end = d->m_frames.end();
4313   for (; it != end; ++it )
4314     if (!(*it).m_bPreloaded)
4315       res.append( (*it).m_part );
4316
4317   return res;
4318 }
4319
4320 #if !APPLE_CHANGES
4321
4322 bool KHTMLPart::openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs )
4323 {
4324   FrameIt it = d->m_frames.find( urlArgs.frameName );
4325
4326   if ( it == d->m_frames.end() )
4327     return false;
4328
4329   // Inform someone that we are about to show something else.
4330   if ( !urlArgs.lockHistory() )
4331       emit d->m_extension->openURLNotify();
4332
4333   requestObject( &(*it), url, urlArgs );
4334
4335   return true;
4336 }
4337
4338 #endif
4339
4340 void KHTMLPart::setDNDEnabled( bool b )
4341 {
4342   d->m_bDnd = b;
4343 }
4344
4345 bool KHTMLPart::dndEnabled() const
4346 {
4347   return d->m_bDnd;
4348 }
4349
4350 bool KHTMLPart::shouldDragAutoNode(DOM::NodeImpl *node, int x, int y) const
4351 {
4352     // No KDE impl yet
4353     return false;
4354 }
4355
4356 void KHTMLPart::customEvent( QCustomEvent *event )
4357 {
4358   if ( khtml::MousePressEvent::test( event ) )
4359   {
4360     khtmlMousePressEvent( static_cast<khtml::MousePressEvent *>( event ) );
4361     return;
4362   }
4363
4364   if ( khtml::MouseDoubleClickEvent::test( event ) )
4365   {
4366     khtmlMouseDoubleClickEvent( static_cast<khtml::MouseDoubleClickEvent *>( event ) );
4367     return;
4368   }
4369
4370   if ( khtml::MouseMoveEvent::test( event ) )
4371   {
4372     khtmlMouseMoveEvent( static_cast<khtml::MouseMoveEvent *>( event ) );
4373     return;
4374   }
4375
4376   if ( khtml::MouseReleaseEvent::test( event ) )
4377   {
4378     khtmlMouseReleaseEvent( static_cast<khtml::MouseReleaseEvent *>( event ) );
4379     return;
4380   }
4381
4382   if ( khtml::DrawContentsEvent::test( event ) )
4383   {
4384     khtmlDrawContentsEvent( static_cast<khtml::DrawContentsEvent *>( event ) );
4385     return;
4386   }
4387
4388   KParts::ReadOnlyPart::customEvent( event );
4389 }
4390
4391 bool KHTMLPart::isPointInsideSelection(int x, int y)
4392 {
4393     // Treat a collapsed selection like no selection.
4394     if (!d->m_selection.isRange())
4395         return false;
4396     if (!xmlDocImpl()->renderer()) 
4397         return false;
4398     
4399     RenderObject::NodeInfo nodeInfo(true, true);
4400     xmlDocImpl()->renderer()->layer()->nodeAtPoint(nodeInfo, x, y);
4401     NodeImpl *innerNode = nodeInfo.innerNode();
4402     if (!innerNode || !innerNode->renderer())
4403         return false;
4404     
4405     Position pos(innerNode->renderer()->positionForCoordinates(x, y));
4406     if (pos.isNull())
4407         return false;
4408
4409     NodeImpl *n = d->m_selection.start().node();
4410     while (n) {
4411         if (n == pos.node()) {
4412             if ((n == d->m_selection.start().node() && pos.offset() < d->m_selection.start().offset()) ||
4413                 (n == d->m_selection.end().node() && pos.offset() > d->m_selection.end().offset())) {
4414                 return false;
4415             }
4416             return true;
4417         }
4418         if (n == d->m_selection.end().node())
4419             break;