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