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