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