WebCore:
[WebKit-https.git] / WebCore / page / Frame.cpp
1 /* This file is part of the KDE project
2  *
3  * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
4  *                     1999 Lars Knoll <knoll@kde.org>
5  *                     1999 Antti Koivisto <koivisto@kde.org>
6  *                     2000 Simon Hausmann <hausmann@kde.org>
7  *                     2000 Stefan Schimanski <1Stein@gmx.de>
8  *                     2001 George Staikos <staikos@kde.org>
9  * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
10  * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Library General Public
14  * License as published by the Free Software Foundation; either
15  * version 2 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public License
23  * along with this library; see the file COPYING.LIB.  If not, write to
24  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25  * Boston, MA 02111-1307, USA.
26  */
27
28 #include "config.h"
29 #include "Frame.h"
30 #include "FramePrivate.h"
31
32 #include "ApplyStyleCommand.h"
33 #include "CSSComputedStyleDeclaration.h"
34 #include "CSSProperty.h"
35 #include "CSSPropertyNames.h"
36 #include "Cache.h"
37 #include "CachedCSSStyleSheet.h"
38 #include "DOMImplementation.h"
39 #include "DOMWindow.h"
40 #include "Decoder.h"
41 #include "DocLoader.h"
42 #include "DocumentType.h"
43 #include "EditingText.h"
44 #include "Event.h"
45 #include "EventNames.h"
46 #include "FloatRect.h"
47 #include "Frame.h"
48 #include "GraphicsContext.h"
49 #include "HTMLFormElement.h"
50 #include "HTMLFrameElement.h"
51 #include "HTMLGenericFormElement.h"
52 #include "HTMLInputElement.h"
53 #include "HTMLNames.h"
54 #include "HTMLObjectElement.h"
55 #include "HTMLViewSourceDocument.h"
56 #include "ImageDocument.h"
57 #include "loader/icon/IconDatabase.h"
58 #include "loader/icon/IconLoader.h"
59 #include "MediaFeatureNames.h"
60 #include "MouseEventWithHitTestResults.h"
61 #include "NodeList.h"
62 #include "Page.h"
63 #include "PlatformScrollBar.h"
64 #include "PlugInInfoStore.h"
65 #include "Plugin.h"
66 #include "PluginDocument.h"
67 #include "RenderListBox.h"
68 #include "RenderPart.h"
69 #include "RenderTextControl.h"
70 #include "RenderTheme.h"
71 #include "RenderView.h"
72 #include "SegmentedString.h"
73 #include "TextDocument.h"
74 #include "TextIterator.h"
75 #include "TypingCommand.h"
76 #include "XMLTokenizer.h"
77 #include "cssstyleselector.h"
78 #include "htmlediting.h"
79 #include "kjs_window.h"
80 #include "markup.h"
81 #include "visible_units.h"
82 #include "xmlhttprequest.h"
83 #include <math.h>
84 #include <sys/types.h>
85 #include <wtf/Platform.h>
86
87 #if PLATFORM(MAC)
88 #include "FrameMac.h"
89 #endif
90
91 #if !PLATFORM(WIN_OS)
92 #include <unistd.h>
93 #endif
94
95 #ifdef SVG_SUPPORT
96 #include "SVGNames.h"
97 #include "XLinkNames.h"
98 #include "XMLNames.h"
99 #include "SVGDocument.h"
100 #include "SVGDocumentExtensions.h"
101 #endif
102
103 using namespace std;
104
105 using KJS::JSLock;
106 using KJS::JSValue;
107 using KJS::Location;
108 using KJS::PausedTimeouts;
109 using KJS::SavedProperties;
110 using KJS::SavedBuiltins;
111 using KJS::UString;
112 using KJS::Window;
113
114 namespace WebCore {
115
116 using namespace EventNames;
117 using namespace HTMLNames;
118
119 const double caretBlinkFrequency = 0.5;
120 const double autoscrollInterval = 0.1;
121
122 class UserStyleSheetLoader : public CachedResourceClient {
123 public:
124     UserStyleSheetLoader(Frame* frame, const String& url, DocLoader* dl)
125         : m_frame(frame)
126         , m_cachedSheet(Cache::requestCSSStyleSheet(dl, url, false, 0, ""))
127     {
128         m_cachedSheet->ref(this);
129     }
130     ~UserStyleSheetLoader()
131     {
132         m_cachedSheet->deref(this);
133     }
134 private:
135     virtual void setCSSStyleSheet(const String& /*URL*/, const String& /*charset*/, const String& sheet)
136     {
137         m_frame->setUserStyleSheet(sheet);
138     }
139     Frame* m_frame;
140     CachedCSSStyleSheet* m_cachedSheet;
141 };
142
143 #ifndef NDEBUG
144 struct FrameCounter { 
145     static int count; 
146     ~FrameCounter() { if (count != 0) fprintf(stderr, "LEAK: %d Frame\n", count); }
147 };
148 int FrameCounter::count = 0;
149 static FrameCounter frameCounter;
150 #endif
151
152 static inline Frame* parentFromOwnerElement(Element* ownerElement)
153 {
154     if (!ownerElement)
155         return 0;
156     return ownerElement->document()->frame();
157 }
158
159 Frame::Frame(Page* page, Element* ownerElement) 
160     : d(new FramePrivate(page, parentFromOwnerElement(ownerElement), this, ownerElement))
161 {
162     AtomicString::init();
163     Cache::init();
164     EventNames::init();
165     HTMLNames::init();
166     QualifiedName::init();
167     MediaFeatureNames::init();
168
169 #ifdef SVG_SUPPORT
170     SVGNames::init();
171     XLinkNames::init();
172     XMLNames::init();
173 #endif
174
175     if (d->m_ownerElement)
176         d->m_page->incrementFrameCount();
177
178     // FIXME: Frames were originally created with a refcount of 1, leave this
179     // ref call here until we can straighten that out.
180     ref();
181 #ifndef NDEBUG
182     ++FrameCounter::count;
183 #endif
184 }
185
186 Frame::~Frame()
187 {
188     // FIXME: We should not be doing all this work inside the destructor
189
190     ASSERT(!d->m_lifeSupportTimer.isActive());
191
192 #ifndef NDEBUG
193     --FrameCounter::count;
194 #endif
195
196     if (d->m_jscript && d->m_jscript->haveInterpreter())
197         if (Window* w = Window::retrieveWindow(this)) {
198             w->disconnectFrame();
199             // Must clear the window pointer, otherwise we will not
200             // garbage-collect collect the window (inside the call to
201             // delete d below).
202             w = 0;
203         }
204
205     disconnectOwnerElement();
206     
207     if (d->m_domWindow)
208         d->m_domWindow->disconnectFrame();
209             
210     setOpener(0);
211     HashSet<Frame*> openedBy = d->m_openedFrames;
212     HashSet<Frame*>::iterator end = openedBy.end();
213     for (HashSet<Frame*>::iterator it = openedBy.begin(); it != end; ++it)
214         (*it)->setOpener(0);
215     
216     if (d->m_view) {
217         d->m_view->hide();
218         d->m_view->m_frame = 0;
219     }
220   
221     ASSERT(!d->m_lifeSupportTimer.isActive());
222
223     delete d->m_userStyleSheetLoader;
224     delete d;
225     d = 0;
226 }
227
228 KURL Frame::iconURL()
229 {
230     // If this isn't a top level frame, return nothing
231     if (tree() && tree()->parent())
232         return "";
233         
234     // If we have an iconURL from a Link element, return that
235     if (document() && !document()->iconURL().isEmpty())
236         return KURL(document()->iconURL().deprecatedString());
237         
238     // Don't return a favicon iconURL unless we're http or https
239     if (d->m_url.protocol() != "http" && d->m_url.protocol() != "https")
240         return "";
241         
242     KURL url;
243     url.setProtocol(d->m_url.protocol());
244     url.setHost(d->m_url.host());
245     url.setPath("/favicon.ico");
246     return url;
247 }
248
249 bool Frame::didOpenURL(const KURL& url)
250 {
251   if (d->m_scheduledRedirection == locationChangeScheduledDuringLoad) {
252     // A redirect was shceduled before the document was created. This can happen
253     // when one frame changes another frame's location.
254     return false;
255   }
256   
257   cancelRedirection();
258   
259   // clear last edit command
260   d->m_lastEditCommand = 0;
261   
262   closeURL();
263
264   d->m_bComplete = false;
265   d->m_bLoadingMainResource = true;
266   d->m_bLoadEventEmitted = false;
267
268   d->m_kjsStatusBarText = String();
269   d->m_kjsDefaultStatusBarText = String();
270
271   d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled();
272   d->m_bJavaEnabled = d->m_settings->isJavaEnabled();
273   d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled();
274
275   // initializing d->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
276   // data arrives) (Simon)
277   d->m_url = url;
278   if (d->m_url.protocol().startsWith("http") && !d->m_url.host().isEmpty() && d->m_url.path().isEmpty())
279     d->m_url.setPath("/");
280   d->m_workingURL = d->m_url;
281
282   started();
283
284   return true;
285 }
286
287 void Frame::didExplicitOpen()
288 {
289   d->m_bComplete = false;
290   d->m_bLoadEventEmitted = false;
291     
292   // Prevent window.open(url) -- eg window.open("about:blank") -- from blowing away results
293   // from a subsequent window.document.open / window.document.write call. 
294   // Cancelling redirection here works for all cases because document.open 
295   // implicitly precedes document.write.
296   cancelRedirection(); 
297   d->m_url = d->m_doc->URL();
298 }
299
300 void Frame::stopLoading(bool sendUnload)
301 {
302   if (d->m_doc && d->m_doc->tokenizer())
303     d->m_doc->tokenizer()->stopParsing();
304   
305   d->m_metaData.clear();
306
307   if (sendUnload) {
308     if (d->m_doc) {
309       if (d->m_bLoadEventEmitted && !d->m_bUnloadEventEmitted) {
310         Node* currentFocusNode = d->m_doc->focusNode();
311         if (currentFocusNode)
312             currentFocusNode->aboutToUnload();
313         d->m_doc->dispatchWindowEvent(unloadEvent, false, false);
314         if (d->m_doc)
315           d->m_doc->updateRendering();
316         d->m_bUnloadEventEmitted = true;
317       }
318     }
319     
320     if (d->m_doc && !d->m_doc->inPageCache())
321       d->m_doc->removeAllEventListenersFromAllNodes();
322   }
323
324   d->m_bComplete = true; // to avoid calling completed() in finishedParsing() (David)
325   d->m_bLoadingMainResource = false;
326   d->m_bLoadEventEmitted = true; // don't want that one either
327   d->m_cachePolicy = CachePolicyVerify; // Why here?
328
329   if (d->m_doc && d->m_doc->parsing()) {
330     finishedParsing();
331     d->m_doc->setParsing(false);
332   }
333   
334   d->m_workingURL = KURL();
335
336   if (Document *doc = d->m_doc.get()) {
337     if (DocLoader *docLoader = doc->docLoader())
338       Cache::loader()->cancelRequests(docLoader);
339       XMLHttpRequest::cancelRequests(doc);
340   }
341
342   // tell all subframes to stop as well
343   for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
344       child->stopLoading(sendUnload);
345
346   d->m_bPendingChildRedirection = false;
347
348   cancelRedirection();
349 }
350
351 BrowserExtension *Frame::browserExtension() const
352 {
353   return d->m_extension;
354 }
355
356 FrameView* Frame::view() const
357 {
358     return d->m_view.get();
359 }
360
361 void Frame::setView(FrameView* view)
362 {
363     // Detach the document now, so any onUnload handlers get run - if
364     // we wait until the view is destroyed, then things won't be
365     // hooked up enough for some JavaScript calls to work.
366     if (d->m_doc && view == 0)
367         d->m_doc->detach();
368
369     d->m_view = view;
370 }
371
372 bool Frame::jScriptEnabled() const
373 {
374     return d->m_bJScriptEnabled;
375 }
376
377 KJSProxy *Frame::jScript()
378 {
379     if (!d->m_bJScriptEnabled)
380         return 0;
381
382     if (!d->m_jscript)
383         d->m_jscript = new KJSProxy(this);
384
385     return d->m_jscript;
386 }
387
388 static bool getString(JSValue* result, String& string)
389 {
390     if (!result)
391         return false;
392     JSLock lock;
393     UString ustring;
394     if (!result->getString(ustring))
395         return false;
396     string = ustring;
397     return true;
398 }
399
400 void Frame::replaceContentsWithScriptResult(const KURL& url)
401 {
402     JSValue* ret = executeScript(0, KURL::decode_string(url.url().mid(strlen("javascript:"))));
403     String scriptResult;
404     if (getString(ret, scriptResult)) {
405         begin();
406         write(scriptResult);
407         end();
408     }
409 }
410
411 JSValue* Frame::executeScript(Node* n, const String& script, bool forceUserGesture)
412 {
413   KJSProxy *proxy = jScript();
414
415   if (!proxy)
416     return 0;
417
418   d->m_runningScripts++;
419   // If forceUserGesture is true, then make the script interpreter
420   // treat it as if triggered by a user gesture even if there is no
421   // current DOM event being processed.
422   JSValue* ret = proxy->evaluate(forceUserGesture ? DeprecatedString::null : d->m_url.url(), 0, script, n);
423   d->m_runningScripts--;
424
425   if (!d->m_runningScripts)
426       submitFormAgain();
427
428   Document::updateDocumentsRendering();
429
430   return ret;
431 }
432
433 bool Frame::javaEnabled() const
434 {
435     return d->m_settings->isJavaEnabled();
436 }
437
438 bool Frame::pluginsEnabled() const
439 {
440     return d->m_bPluginsEnabled;
441 }
442
443 void Frame::setAutoloadImages(bool enable)
444 {
445   if (d->m_doc && d->m_doc->docLoader()->autoloadImages() == enable)
446     return;
447
448   if (d->m_doc)
449     d->m_doc->docLoader()->setAutoloadImages(enable);
450 }
451
452 bool Frame::autoloadImages() const
453 {
454   if (d->m_doc)
455     return d->m_doc->docLoader()->autoloadImages();
456
457   return true;
458 }
459
460 void Frame::cancelAndClear()
461 {
462     cancelRedirection();
463
464     if (!d->m_bComplete)
465         closeURL();
466
467     clear(false);
468 }
469
470 void Frame::clear(bool clearWindowProperties)
471 {
472   if (d->m_bCleared)
473     return;
474   d->m_bCleared = true;
475   d->m_mousePressNode = 0;
476
477 #if !PLATFORM(MAC)
478   // FIXME: This is a temporary hack to work around a mismatch between WebCore and WebKit
479   // regarding frame lifetime. The proper solution is to move all frame management
480   // into WebCore, so frames can work the same way on all platforms.
481   detachChildren();
482 #endif
483
484   if (d->m_doc) {
485     d->m_doc->cancelParsing();
486     d->m_doc->detach();
487   }
488
489   // Moving past doc so that onUnload works.
490   if (clearWindowProperties && d->m_jscript)
491     d->m_jscript->clear();
492
493   if (d->m_view)
494     d->m_view->clear();
495
496   // do not drop the document before the jscript and view are cleared, as some destructors
497   // might still try to access the document.
498   d->m_doc = 0;
499   d->m_decoder = 0;
500
501   d->m_plugins.clear();
502   cleanupPluginObjects();
503   
504   d->m_scheduledRedirection = noRedirectionScheduled;
505   d->m_delayRedirect = 0;
506   d->m_redirectURL = DeprecatedString::null;
507   d->m_redirectReferrer = String();
508   d->m_redirectLockHistory = true;
509   d->m_redirectUserGesture = false;
510   d->m_bHTTPRefresh = false;
511   d->m_bFirstData = true;
512
513   d->m_bMousePressed = false;
514
515   if (!d->m_haveEncoding)
516     d->m_encoding = String();
517 }
518
519 Document *Frame::document() const
520 {
521     if (d)
522         return d->m_doc.get();
523     return 0;
524 }
525
526 void Frame::setDocument(Document* newDoc)
527 {
528     if (d) {
529         if (d->m_doc)
530             d->m_doc->detach();
531         d->m_doc = newDoc;
532         if (newDoc)
533             newDoc->attach();
534     }
535 }
536
537 void Frame::receivedFirstData()
538 {
539     begin(d->m_workingURL);
540
541     d->m_doc->docLoader()->setCachePolicy(d->m_cachePolicy);
542     d->m_workingURL = KURL();
543
544     // When the first data arrives, the metadata has just been made available
545     DeprecatedString qData;
546
547     // Support for http-refresh
548     qData = d->m_metaData.get("http-refresh").deprecatedString();
549     if (!qData.isEmpty()) {
550       double delay;
551       int pos = qData.find(';');
552       if (pos == -1)
553         pos = qData.find(',');
554
555       if (pos == -1) {
556         delay = qData.stripWhiteSpace().toDouble();
557         // We want a new history item if the refresh timeout > 1 second
558         scheduleRedirection(delay, d->m_url.url(), delay <= 1);
559       } else {
560         int end_pos = qData.length();
561         delay = qData.left(pos).stripWhiteSpace().toDouble();
562         while (qData[++pos] == ' ');
563         if (qData.find("url", pos, false) == pos) {
564           pos += 3;
565           while (qData[pos] == ' ' || qData[pos] == '=')
566               pos++;
567           if (qData[pos] == '"') {
568               pos++;
569               int index = end_pos-1;
570               while (index > pos) {
571                 if (qData[index] == '"')
572                     break;
573                 index--;
574               }
575               if (index > pos)
576                 end_pos = index;
577           }
578         }
579         // We want a new history item if the refresh timeout > 1 second
580         scheduleRedirection(delay, d->m_doc->completeURL(qData.mid(pos, end_pos)), delay <= 1);
581       }
582       d->m_bHTTPRefresh = true;
583     }
584
585     // Support for http last-modified
586     d->m_lastModified = d->m_metaData.get("modified");
587 }
588
589 void Frame::childBegin()
590 {
591     // We need to do this when the child is created so as to avoid the parent thining the child
592     // is complete before it has even started loading.
593     // FIXME: do we really still need this?
594     d->m_bComplete = false;
595 }
596
597 void Frame::setResourceRequest(const ResourceRequest& request)
598 {
599     d->m_request = request;
600 }
601
602 const ResourceRequest& Frame::resourceRequest() const
603 {
604     return d->m_request;
605 }
606
607 void Frame::begin(const KURL& url)
608 {
609   if (d->m_workingURL.isEmpty())
610     createEmptyDocument(); // Creates an empty document if we don't have one already
611
612   clear();
613   partClearedInBegin();
614
615   d->m_bCleared = false;
616   d->m_bComplete = false;
617   d->m_bLoadEventEmitted = false;
618   d->m_bLoadingMainResource = true;
619
620   KURL ref(url);
621   ref.setUser(DeprecatedString());
622   ref.setPass(DeprecatedString());
623   ref.setRef(DeprecatedString());
624   d->m_referrer = ref.url();
625   d->m_url = url;
626   KURL baseurl;
627
628   // We don't need KDE chained URI handling or window caption setting
629   if (!d->m_url.isEmpty())
630     baseurl = d->m_url;
631
632 #ifdef SVG_SUPPORT
633   if (d->m_request.m_responseMIMEType == "image/svg+xml")
634     d->m_doc = DOMImplementation::instance()->createSVGDocument(d->m_view.get());
635   else
636 #endif
637   if (DOMImplementation::isXMLMIMEType(d->m_request.m_responseMIMEType))
638     d->m_doc = DOMImplementation::instance()->createDocument(d->m_view.get());
639   else if (DOMImplementation::isTextMIMEType(d->m_request.m_responseMIMEType))
640     d->m_doc = new TextDocument(DOMImplementation::instance(), d->m_view.get());
641   else if ((d->m_request.m_responseMIMEType == "application/pdf" || d->m_request.m_responseMIMEType == "text/pdf") && PlugInInfoStore::supportsMIMEType(d->m_request.m_responseMIMEType))
642     d->m_doc = new PluginDocument(DOMImplementation::instance(), d->m_view.get());
643   else if (Image::supportsType(d->m_request.m_responseMIMEType))
644     d->m_doc = new ImageDocument(DOMImplementation::instance(), d->m_view.get());
645   else if (PlugInInfoStore::supportsMIMEType(d->m_request.m_responseMIMEType))
646     d->m_doc = new PluginDocument(DOMImplementation::instance(), d->m_view.get());
647   else if (inViewSourceMode())
648     d->m_doc = new HTMLViewSourceDocument(DOMImplementation::instance(), d->m_view.get());
649   else
650     d->m_doc = DOMImplementation::instance()->createHTMLDocument(d->m_view.get());
651
652   if (!d->m_doc->attached())
653     d->m_doc->attach();
654   d->m_doc->setURL(d->m_url.url());
655   // We prefer m_baseURL over d->m_url because d->m_url changes when we are
656   // about to load a new page.
657   d->m_doc->setBaseURL(baseurl.url());
658   if (d->m_decoder)
659     d->m_doc->setDecoder(d->m_decoder.get());
660
661   updatePolicyBaseURL();
662
663   setAutoloadImages(d->m_settings->autoLoadImages());
664   const KURL& userStyleSheet = d->m_settings->userStyleSheetLocation();
665
666   if (!userStyleSheet.isEmpty())
667     setUserStyleSheetLocation(KURL(userStyleSheet));
668
669   restoreDocumentState();
670
671   d->m_doc->implicitOpen();
672   // clear widget
673   if (d->m_view)
674     d->m_view->resizeContents(0, 0);
675 }
676
677 void Frame::write(const char* str, int len)
678 {
679     if (len == 0)
680         return;
681     
682     if (len == -1)
683         len = strlen(str);
684
685     if (Tokenizer* t = d->m_doc->tokenizer()) {
686         if (t->wantsRawData()) {
687             t->writeRawData(str, len);
688             return;
689         }
690     }
691     
692     if (!d->m_decoder) {
693         d->m_decoder = new Decoder(d->m_request.m_responseMIMEType, settings()->encoding());
694         if (!d->m_encoding.isNull())
695             d->m_decoder->setEncoding(d->m_encoding,
696                 d->m_haveEncoding ? Decoder::UserChosenEncoding : Decoder::EncodingFromHTTPHeader);
697         if (d->m_doc)
698             d->m_doc->setDecoder(d->m_decoder.get());
699     }
700
701     String decoded = d->m_decoder->decode(str, len);
702
703     if (decoded.isEmpty())
704         return;
705
706     if (d->m_bFirstData) {
707         d->m_bFirstData = false;
708         d->m_doc->determineParseMode(decoded);
709         if (d->m_decoder->encoding().usesVisualOrdering())
710             d->m_doc->setVisuallyOrdered();
711         d->m_doc->recalcStyle(Node::Force);
712     }
713
714     if (Tokenizer* t = d->m_doc->tokenizer()) {
715         ASSERT(!t->wantsRawData());
716         t->write(decoded, true);
717     }
718 }
719
720 void Frame::write(const String& str)
721 {
722     if (str.isNull())
723         return;
724
725     if (d->m_bFirstData) {
726         // determine the parse mode
727         d->m_doc->setParseMode(Document::Strict);
728         d->m_bFirstData = false;
729     }
730     Tokenizer* t = d->m_doc->tokenizer();
731     if (t)
732         t->write(str, true);
733 }
734
735 void Frame::end()
736 {
737     d->m_bLoadingMainResource = false;
738     endIfNotLoading();
739 }
740
741 void Frame::endIfNotLoading()
742 {
743     // http://bugzilla.opendarwin.org/show_bug.cgi?id=10854
744     // The frame's last ref may be remove and it be deleted by checkCompleted(), 
745     // so we'll add a protective refcount
746     RefPtr<Frame> protector(this);
747     
748     if (d->m_bLoadingMainResource)
749         return;
750
751     // make sure nothing's left in there...
752     if (d->m_doc) {
753         if (d->m_decoder) {
754             String decoded = d->m_decoder->flush();
755             if (d->m_bFirstData) {
756                 d->m_bFirstData = false;
757                 d->m_doc->determineParseMode(decoded);
758             }
759             write(decoded);
760         }
761         d->m_doc->finishParsing();
762     } else
763         // WebKit partially uses WebCore when loading non-HTML docs.  In these cases doc==nil, but
764         // WebCore is enough involved that we need to checkCompleted() in order for m_bComplete to
765         // become true.  An example is when a subframe is a pure text doc, and that subframe is the
766         // last one to complete.
767         checkCompleted();
768     
769     // FIXME - Right now, we kick off the icon loader when the frame is done receiving all its main resource.
770     // We could kick off the icon loader after we're done parsing the HEAD element, if that becomes convinient to find
771     // at a future date
772     
773     // Don't load an icon if -
774     // 1) This is not the main frame 
775     // 2) The database is disabled
776     // 3) We have no valid icon URL
777     // 4) We already have an unexpired icon
778     
779     if (tree()->parent())
780         return;
781         
782     
783     if (IconDatabase* sharedIconDatabase = IconDatabase::sharedIconDatabase()) {
784         if (!sharedIconDatabase->enabled())
785             return;
786         
787         String url(iconURL().url());
788         if (url.isEmpty())
789             return;
790         
791         // If we already have an unexpired icon, we won't kick off a load but we *will* map the appropriate URLs to it
792         if (sharedIconDatabase->hasEntryForIconURL(url) && !isLoadTypeReload() && !sharedIconDatabase->isIconExpiredForIconURL(url)) {
793             commitIconURLToIconDatabase();
794             return;
795         }
796         
797         if (!d->m_iconLoader)
798             d->m_iconLoader = IconLoader::createForFrame(this);
799         d->m_iconLoader->startLoading();
800     }
801 }
802
803 void Frame::commitIconURLToIconDatabase()
804 {
805     KURL icon = iconURL();
806     
807     IconDatabase* iconDatabase = IconDatabase::sharedIconDatabase();
808     ASSERT(iconDatabase);
809     iconDatabase->setIconURLForPageURL(icon.url(), this->url().url());
810     iconDatabase->setIconURLForPageURL(icon.url(), originalRequestURL().url());
811 }
812
813 void Frame::stop()
814 {
815     // http://bugzilla.opendarwin.org/show_bug.cgi?id=10854
816     // The frame's last ref may be remove and it be deleted by checkCompleted(), 
817     // so we'll add a protective refcount
818     RefPtr<Frame> protector(this);
819     
820     if (d->m_doc) {
821         if (d->m_doc->tokenizer())
822             d->m_doc->tokenizer()->stopParsing();
823         d->m_doc->finishParsing();
824     } else
825         // WebKit partially uses WebCore when loading non-HTML docs.  In these cases doc==nil, but
826         // WebCore is enough involved that we need to checkCompleted() in order for m_bComplete to
827         // become true.  An example is when a subframe is a pure text doc, and that subframe is the
828         // last one to complete.
829         checkCompleted();
830     if (d->m_iconLoader)
831         d->m_iconLoader->stopLoading();
832 }
833
834 void Frame::gotoAnchor()
835 {
836     // If our URL has no ref, then we have no place we need to jump to.
837     if (!d->m_url.hasRef())
838         return;
839
840     DeprecatedString ref = d->m_url.encodedHtmlRef();
841     if (!gotoAnchor(ref)) {
842         // Can't use htmlRef() here because it doesn't know which encoding to use to decode.
843         // Decoding here has to match encoding in completeURL, which means it has to use the
844         // page's encoding rather than UTF-8.
845         if (d->m_decoder)
846             gotoAnchor(KURL::decode_string(ref, d->m_decoder->encoding()));
847     }
848 }
849
850 void Frame::finishedParsing()
851 {
852   // This method can be called from our destructor, in which case we shouldn't protect ourselves
853   // because doing so will cause us to re-enter our destructor when protector goes out of scope.
854   RefPtr<Frame> protector = refCount() > 0 ? this : 0;
855   checkCompleted();
856
857   if (!d->m_view)
858     return; // We are being destroyed by something checkCompleted called.
859
860   // check if the scrollbars are really needed for the content
861   // if not, remove them, relayout, and repaint
862
863   d->m_view->restoreScrollbar();
864   gotoAnchor();
865 }
866
867 void Frame::loadDone()
868 {
869     if (d->m_doc)
870         checkCompleted();
871 }
872
873 void Frame::checkCompleted()
874 {
875   // Any frame that hasn't completed yet ?
876   for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
877       if (!child->d->m_bComplete)
878           return;
879
880   // Have we completed before?
881   if (d->m_bComplete)
882       return;
883
884   // Are we still parsing?
885   if (d->m_doc && d->m_doc->parsing())
886       return;
887
888   // Still waiting for images/scripts from the loader ?
889   int requests = 0;
890   if (d->m_doc && d->m_doc->docLoader())
891       requests = Cache::loader()->numRequests(d->m_doc->docLoader());
892
893   if (requests > 0)
894       return;
895
896   // OK, completed.
897   // Now do what should be done when we are really completed.
898   d->m_bComplete = true;
899
900   checkEmitLoadEvent(); // if we didn't do it before
901
902   if (d->m_scheduledRedirection != noRedirectionScheduled) {
903       // Do not start redirection for frames here! That action is
904       // deferred until the parent emits a completed signal.
905       if (!tree()->parent())
906           startRedirectionTimer();
907
908       completed(true);
909   } else {
910       completed(d->m_bPendingChildRedirection);
911   }
912 }
913
914 void Frame::checkEmitLoadEvent()
915 {
916     if (d->m_bLoadEventEmitted || !d->m_doc || d->m_doc->parsing())
917         return;
918
919     for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
920         if (!child->d->m_bComplete) // still got a frame running -> too early
921             return;
922
923     // All frames completed -> set their domain to the frameset's domain
924     // This must only be done when loading the frameset initially (#22039),
925     // not when following a link in a frame (#44162).
926     if (d->m_doc) {
927         String domain = d->m_doc->domain();
928         for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
929             if (child->d->m_doc)
930                 child->d->m_doc->setDomain(domain);
931     }
932
933     d->m_bLoadEventEmitted = true;
934     d->m_bUnloadEventEmitted = false;
935     if (d->m_doc)
936         d->m_doc->implicitClose();
937 }
938
939 const Settings *Frame::settings() const
940 {
941   return d->m_settings;
942 }
943
944 KURL Frame::baseURL() const
945 {
946     if (!d->m_doc)
947         return KURL();
948     return d->m_doc->baseURL();
949 }
950
951 String Frame::baseTarget() const
952 {
953     if (!d->m_doc)
954         return String();
955     return d->m_doc->baseTarget();
956 }
957
958 KURL Frame::completeURL(const DeprecatedString& url)
959 {
960     if (!d->m_doc)
961         return url;
962
963     return KURL(d->m_doc->completeURL(url));
964 }
965
966 void Frame::scheduleRedirection(double delay, const DeprecatedString& url, bool doLockHistory)
967 {
968     if (delay < 0 || delay > INT_MAX / 1000)
969       return;
970     if (d->m_scheduledRedirection == noRedirectionScheduled || delay <= d->m_delayRedirect)
971     {
972        d->m_scheduledRedirection = redirectionScheduled;
973        d->m_delayRedirect = delay;
974        d->m_redirectURL = url;
975        d->m_redirectReferrer = String();
976        d->m_redirectLockHistory = doLockHistory;
977        d->m_redirectUserGesture = false;
978
979        stopRedirectionTimer();
980        if (d->m_bComplete)
981          startRedirectionTimer();
982     }
983 }
984
985 void Frame::scheduleLocationChange(const DeprecatedString& url, const String& referrer, bool lockHistory, bool userGesture)
986 {
987     KURL u(url);
988     
989     // If the URL we're going to navigate to is the same as the current one, except for the
990     // fragment part, we don't need to schedule the location change.
991     if (u.hasRef() && equalIgnoringRef(d->m_url, u)) {
992         changeLocation(url, referrer, lockHistory, userGesture);
993         return;
994     }
995         
996     // Handle a location change of a page with no document as a special case.
997     // This may happen when a frame changes the location of another frame.
998     d->m_scheduledRedirection = d->m_doc ? locationChangeScheduled : locationChangeScheduledDuringLoad;
999     
1000     // If a redirect was scheduled during a load, then stop the current load.
1001     // Otherwise when the current load transitions from a provisional to a 
1002     // committed state, pending redirects may be cancelled. 
1003     if (d->m_scheduledRedirection == locationChangeScheduledDuringLoad) {
1004         stopLoading(true);   
1005     }
1006
1007     d->m_delayRedirect = 0;
1008     d->m_redirectURL = url;
1009     d->m_redirectReferrer = referrer;
1010     d->m_redirectLockHistory = lockHistory;
1011     d->m_redirectUserGesture = userGesture;
1012     stopRedirectionTimer();
1013     if (d->m_bComplete)
1014         startRedirectionTimer();
1015 }
1016
1017 void Frame::scheduleRefresh(bool userGesture)
1018 {
1019     // Handle a location change of a page with no document as a special case.
1020     // This may happen when a frame requests a refresh of another frame.
1021     d->m_scheduledRedirection = d->m_doc ? locationChangeScheduled : locationChangeScheduledDuringLoad;
1022     
1023     // If a refresh was scheduled during a load, then stop the current load.
1024     // Otherwise when the current load transitions from a provisional to a 
1025     // committed state, pending redirects may be cancelled. 
1026     if (d->m_scheduledRedirection == locationChangeScheduledDuringLoad)
1027         stopLoading(true);   
1028
1029     d->m_delayRedirect = 0;
1030     d->m_redirectURL = url().url();
1031     d->m_redirectReferrer = referrer();
1032     d->m_redirectLockHistory = true;
1033     d->m_redirectUserGesture = userGesture;
1034     d->m_cachePolicy = CachePolicyRefresh;
1035     stopRedirectionTimer();
1036     if (d->m_bComplete)
1037         startRedirectionTimer();
1038 }
1039
1040 bool Frame::isScheduledLocationChangePending() const
1041 {
1042     switch (d->m_scheduledRedirection) {
1043         case noRedirectionScheduled:
1044         case redirectionScheduled:
1045             return false;
1046         case historyNavigationScheduled:
1047         case locationChangeScheduled:
1048         case locationChangeScheduledDuringLoad:
1049             return true;
1050     }
1051     return false;
1052 }
1053
1054 void Frame::scheduleHistoryNavigation(int steps)
1055 {
1056     // navigation will always be allowed in the 0 steps case, which is OK because
1057     // that's supposed to force a reload.
1058     if (!canGoBackOrForward(steps)) {
1059         cancelRedirection();
1060         return;
1061     }
1062
1063     // If the URL we're going to navigate to is the same as the current one, except for the
1064     // fragment part, we don't need to schedule the navigation.
1065     if (d->m_extension) {
1066         KURL u = d->m_extension->historyURL(steps);
1067         
1068         if (equalIgnoringRef(d->m_url, u)) {
1069             d->m_extension->goBackOrForward(steps);
1070             return;
1071         }
1072     }
1073     
1074     d->m_scheduledRedirection = historyNavigationScheduled;
1075     d->m_delayRedirect = 0;
1076     d->m_redirectURL = DeprecatedString::null;
1077     d->m_redirectReferrer = String();
1078     d->m_scheduledHistoryNavigationSteps = steps;
1079     stopRedirectionTimer();
1080     if (d->m_bComplete)
1081         startRedirectionTimer();
1082 }
1083
1084 void Frame::cancelRedirection(bool cancelWithLoadInProgress)
1085 {
1086     if (d) {
1087         d->m_cancelWithLoadInProgress = cancelWithLoadInProgress;
1088         d->m_scheduledRedirection = noRedirectionScheduled;
1089         stopRedirectionTimer();
1090     }
1091 }
1092
1093 void Frame::changeLocation(const DeprecatedString& URL, const String& referrer, bool lockHistory, bool userGesture)
1094 {
1095     if (URL.find("javascript:", 0, false) == 0) {
1096         String script = KURL::decode_string(URL.mid(11));
1097         JSValue* result = executeScript(0, script, userGesture);
1098         String scriptResult;
1099         if (getString(result, scriptResult)) {
1100             begin(url());
1101             write(scriptResult);
1102             end();
1103         }
1104         return;
1105     }
1106
1107     ResourceRequest request(completeURL(URL));
1108     request.setLockHistory(lockHistory);
1109     if (!referrer.isEmpty())
1110         request.setReferrer(referrer);
1111
1112     request.reload = (d->m_cachePolicy == CachePolicyReload) || (d->m_cachePolicy == CachePolicyRefresh);
1113     
1114     urlSelected(request, "_self");
1115 }
1116
1117 void Frame::redirectionTimerFired(Timer<Frame>*)
1118 {
1119     if (d->m_scheduledRedirection == historyNavigationScheduled) {
1120         d->m_scheduledRedirection = noRedirectionScheduled;
1121
1122         // Special case for go(0) from a frame -> reload only the frame
1123         // go(i!=0) from a frame navigates into the history of the frame only,
1124         // in both IE and NS (but not in Mozilla).... we can't easily do that
1125         // in Konqueror...
1126         if (d->m_scheduledHistoryNavigationSteps == 0) // add && parent() to get only frames, but doesn't matter
1127             openURL(url()); /// ## need args.reload=true?
1128         else {
1129             if (d->m_extension) {
1130                 d->m_extension->goBackOrForward(d->m_scheduledHistoryNavigationSteps);
1131             }
1132         }
1133         return;
1134     }
1135
1136     DeprecatedString URL = d->m_redirectURL;
1137     String referrer = d->m_redirectReferrer;
1138     bool lockHistory = d->m_redirectLockHistory;
1139     bool userGesture = d->m_redirectUserGesture;
1140
1141     d->m_scheduledRedirection = noRedirectionScheduled;
1142     d->m_delayRedirect = 0;
1143     d->m_redirectURL = DeprecatedString::null;
1144     d->m_redirectReferrer = String();
1145
1146     changeLocation(URL, referrer, lockHistory, userGesture);
1147 }
1148
1149 String Frame::encoding() const
1150 {
1151     if (d->m_haveEncoding && !d->m_encoding.isEmpty())
1152         return d->m_encoding;
1153     if (d->m_decoder && d->m_decoder->encoding().isValid())
1154         return d->m_decoder->encoding().name();
1155     return settings()->encoding();
1156 }
1157
1158 void Frame::setUserStyleSheetLocation(const KURL& url)
1159 {
1160     delete d->m_userStyleSheetLoader;
1161     d->m_userStyleSheetLoader = 0;
1162     if (d->m_doc && d->m_doc->docLoader())
1163         d->m_userStyleSheetLoader = new UserStyleSheetLoader(this, url.url(), d->m_doc->docLoader());
1164 }
1165
1166 void Frame::setUserStyleSheet(const String& styleSheet)
1167 {
1168     delete d->m_userStyleSheetLoader;
1169     d->m_userStyleSheetLoader = 0;
1170     if (d->m_doc)
1171         d->m_doc->setUserStyleSheet(styleSheet);
1172 }
1173
1174 bool Frame::gotoAnchor(const String& name)
1175 {
1176   if (!d->m_doc)
1177     return false;
1178
1179   Node *n = d->m_doc->getElementById(AtomicString(name));
1180   if (!n)
1181       n = d->m_doc->anchors()->namedItem(name, !d->m_doc->inCompatMode());
1182
1183   d->m_doc->setCSSTarget(n); // Setting to null will clear the current target.
1184   
1185   // Implement the rule that "" and "top" both mean top of page as in other browsers.
1186   if (!n && !(name.isEmpty() || name.lower() == "top"))
1187       return false;
1188
1189   // We need to update the layout before scrolling, otherwise we could
1190   // really mess things up if an anchor scroll comes at a bad moment.
1191   if (d->m_doc) {
1192     d->m_doc->updateRendering();
1193     // Only do a layout if changes have occurred that make it necessary.      
1194     if (d->m_view && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout()) {
1195       d->m_view->layout();
1196     }
1197   }
1198   
1199   // Scroll nested layers and frames to reveal the anchor.
1200   RenderObject *renderer;
1201   IntRect rect;
1202   if (n) {
1203       renderer = n->renderer();
1204       rect = n->getRect();
1205   } else {
1206     // If there's no node, we should scroll to the top of the document.
1207       renderer = d->m_doc->renderer();
1208       rect = IntRect();
1209   }
1210
1211   if (renderer) {
1212     // Align to the top and to the closest side (this matches other browsers).
1213     renderer->enclosingLayer()->scrollRectToVisible(rect, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignTopAlways);
1214   }
1215   
1216   return true;
1217 }
1218
1219 void Frame::setStandardFont(const String& name)
1220 {
1221     d->m_settings->setStdFontName(AtomicString(name));
1222 }
1223
1224 void Frame::setFixedFont(const String& name)
1225 {
1226     d->m_settings->setFixedFontName(AtomicString(name));
1227 }
1228
1229 String Frame::selectedText() const
1230 {
1231     return plainText(selectionController()->toRange().get());
1232 }
1233
1234 bool Frame::hasSelection() const
1235 {
1236     return selectionController()->isCaretOrRange();
1237 }
1238
1239 SelectionController* Frame::selectionController() const
1240 {
1241     return &(d->m_selectionController);
1242 }
1243
1244 CommandByName* Frame::command() const
1245 {
1246     return &(d->m_command);
1247 }
1248
1249 TextGranularity Frame::selectionGranularity() const
1250 {
1251     return d->m_selectionGranularity;
1252 }
1253
1254 void Frame::setSelectionGranularity(TextGranularity granularity) const
1255 {
1256     d->m_selectionGranularity = granularity;
1257 }
1258
1259 SelectionController* Frame::dragCaretController() const
1260 {
1261     return d->m_page->dragCaretController();
1262 }
1263
1264 const Selection& Frame::mark() const
1265 {
1266     return d->m_mark;
1267 }
1268
1269 void Frame::setMark(const Selection& s)
1270 {
1271     ASSERT(!s.base().node() || s.base().node()->document() == document());
1272     ASSERT(!s.extent().node() || s.extent().node()->document() == document());
1273     ASSERT(!s.start().node() || s.start().node()->document() == document());
1274     ASSERT(!s.end().node() || s.end().node()->document() == document());
1275
1276     d->m_mark = s;
1277 }
1278
1279 void Frame::notifyRendererOfSelectionChange(bool userTriggered)
1280 {
1281     RenderObject* renderer = 0;
1282     if (selectionController()->rootEditableElement())
1283         renderer = selectionController()->rootEditableElement()->shadowAncestorNode()->renderer();
1284
1285     // If the current selection is in a textfield or textarea, notify the renderer that the selection has changed
1286     if (renderer && (renderer->isTextArea() || renderer->isTextField()))
1287         static_cast<RenderTextControl*>(renderer)->selectionChanged(userTriggered);
1288 }
1289
1290 void Frame::invalidateSelection()
1291 {
1292     selectionController()->setNeedsLayout();
1293     selectionLayoutChanged();
1294 }
1295
1296 void Frame::setCaretVisible(bool flag)
1297 {
1298     if (d->m_caretVisible == flag)
1299         return;
1300     clearCaretRectIfNeeded();
1301     if (flag)
1302         setFocusNodeIfNeeded();
1303     d->m_caretVisible = flag;
1304     selectionLayoutChanged();
1305 }
1306
1307
1308 void Frame::clearCaretRectIfNeeded()
1309 {
1310     if (d->m_caretPaint) {
1311         d->m_caretPaint = false;
1312         selectionController()->invalidateCaretRect();
1313     }        
1314 }
1315
1316 // Helper function that tells whether a particular node is an element that has an entire
1317 // Frame and FrameView, a <frame>, <iframe>, or <object>.
1318 static bool isFrameElement(const Node *n)
1319 {
1320     if (!n)
1321         return false;
1322     RenderObject *renderer = n->renderer();
1323     if (!renderer || !renderer->isWidget())
1324         return false;
1325     Widget* widget = static_cast<RenderWidget*>(renderer)->widget();
1326     return widget && widget->isFrameView();
1327 }
1328
1329 void Frame::setFocusNodeIfNeeded()
1330 {
1331     if (!document() || selectionController()->isNone() || !d->m_isActive)
1332         return;
1333
1334     Node* target = selectionController()->rootEditableElement();
1335     if (target) {
1336         RenderObject* renderer = target->renderer();
1337
1338         // Walk up the render tree to search for a node to focus.
1339         // Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields.
1340         while (renderer) {
1341             // We don't want to set focus on a subframe when selecting in a parent frame,
1342             // so add the !isFrameElement check here. There's probably a better way to make this
1343             // work in the long term, but this is the safest fix at this time.
1344             if (target && target->isMouseFocusable() && !isFrameElement(target)) {
1345                 document()->setFocusNode(target);
1346                 return;
1347             }
1348             renderer = renderer->parent();
1349             if (renderer)
1350                 target = renderer->element();
1351         }
1352         document()->setFocusNode(0);
1353     }
1354 }
1355
1356 void Frame::selectionLayoutChanged()
1357 {
1358     bool caretRectChanged = selectionController()->recomputeCaretRect();
1359
1360     bool shouldBlink = d->m_caretVisible
1361         && selectionController()->isCaret() && selectionController()->isContentEditable();
1362
1363     // If the caret moved, stop the blink timer so we can restart with a
1364     // black caret in the new location.
1365     if (caretRectChanged || !shouldBlink)
1366         d->m_caretBlinkTimer.stop();
1367
1368     // Start blinking with a black caret. Be sure not to restart if we're
1369     // already blinking in the right location.
1370     if (shouldBlink && !d->m_caretBlinkTimer.isActive()) {
1371         d->m_caretBlinkTimer.startRepeating(caretBlinkFrequency);
1372         d->m_caretPaint = true;
1373     }
1374
1375     if (d->m_doc)
1376         d->m_doc->updateSelection();
1377 }
1378
1379 void Frame::setXPosForVerticalArrowNavigation(int x)
1380 {
1381     d->m_xPosForVerticalArrowNavigation = x;
1382 }
1383
1384 int Frame::xPosForVerticalArrowNavigation() const
1385 {
1386     return d->m_xPosForVerticalArrowNavigation;
1387 }
1388
1389 void Frame::caretBlinkTimerFired(Timer<Frame>*)
1390 {
1391     ASSERT(d->m_caretVisible);
1392     ASSERT(selectionController()->isCaret());
1393     bool caretPaint = d->m_caretPaint;
1394     if (d->m_bMousePressed && caretPaint)
1395         return;
1396     d->m_caretPaint = !caretPaint;
1397     selectionController()->invalidateCaretRect();
1398 }
1399
1400 void Frame::paintCaret(GraphicsContext* p, const IntRect& rect) const
1401 {
1402     if (d->m_caretPaint)
1403         selectionController()->paintCaret(p, rect);
1404 }
1405
1406 void Frame::paintDragCaret(GraphicsContext* p, const IntRect& rect) const
1407 {
1408     SelectionController* dragCaretController = d->m_page->dragCaretController();
1409     assert(dragCaretController->selection().isCaret());
1410     if (dragCaretController->selection().start().node()->document()->frame() == this)
1411         dragCaretController->paintCaret(p, rect);
1412 }
1413
1414 void Frame::urlSelected(const DeprecatedString& url, const String& target)
1415 {
1416     urlSelected(ResourceRequest(completeURL(url)), target);
1417 }
1418
1419 void Frame::urlSelected(const ResourceRequest& request, const String& _target)
1420 {
1421   String target = _target;
1422   if (target.isEmpty() && d->m_doc)
1423     target = d->m_doc->baseTarget();
1424
1425   const KURL& url = request.url();
1426
1427   if (url.url().startsWith("javascript:", false)) {
1428     executeScript(0, KURL::decode_string(url.url().mid(11)), true);
1429     return;
1430   }
1431
1432   if (!url.isValid())
1433     // ### ERROR HANDLING
1434     return;
1435
1436   ResourceRequest requestCopy = request;
1437   requestCopy.frameName = target;
1438
1439   if (d->m_bHTTPRefresh)
1440     d->m_bHTTPRefresh = false;
1441
1442   if (!d->m_referrer.isEmpty())
1443     requestCopy.setReferrer(d->m_referrer);
1444
1445   urlSelected(requestCopy);
1446 }
1447
1448 bool Frame::requestFrame(Element* ownerElement, const String& urlParam, const AtomicString& frameName)
1449 {
1450     DeprecatedString _url = urlParam.deprecatedString();
1451     // Support for <frame src="javascript:string">
1452     KURL scriptURL;
1453     KURL url;
1454     if (_url.startsWith("javascript:", false)) {
1455         scriptURL = _url;
1456         url = "about:blank";
1457     } else
1458         url = completeURL(_url);
1459
1460     Frame* frame = tree()->child(frameName);
1461     if (frame) {
1462         ResourceRequest request(url);
1463         request.setReferrer(d->m_referrer);
1464         request.reload = (d->m_cachePolicy == CachePolicyReload) || (d->m_cachePolicy == CachePolicyRefresh);
1465         frame->openURLRequest(request);
1466     } else
1467         frame = loadSubframe(ownerElement, url, frameName, d->m_referrer);
1468     
1469     if (!frame)
1470         return false;
1471
1472     if (!scriptURL.isEmpty())
1473         frame->replaceContentsWithScriptResult(scriptURL);
1474
1475     return true;
1476 }
1477
1478 bool Frame::requestObject(RenderPart* renderer, const String& url, const AtomicString& frameName,
1479                           const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues)
1480 {
1481     KURL completedURL;
1482     if (!url.isEmpty())
1483         completedURL = completeURL(url.deprecatedString());
1484     
1485     if (url.isEmpty() && mimeType.isEmpty())
1486         return true;
1487     
1488     bool useFallback;
1489     if (shouldUsePlugin(renderer->element(), completedURL, mimeType, renderer->hasFallbackContent(), useFallback))
1490         return loadPlugin(renderer, completedURL, mimeType, paramNames, paramValues, useFallback);
1491
1492     ASSERT(renderer->node()->hasTagName(objectTag) || renderer->node()->hasTagName(embedTag));
1493     AtomicString uniqueFrameName = tree()->uniqueChildName(frameName);
1494     static_cast<HTMLPlugInElement*>(renderer->node())->setFrameName(uniqueFrameName);
1495     
1496     // FIXME: ok to always make a new one? when does the old frame get removed?
1497     return loadSubframe(static_cast<Element*>(renderer->node()), completedURL, uniqueFrameName, d->m_referrer);
1498 }
1499
1500 bool Frame::shouldUsePlugin(Node* element, const KURL& url, const String& mimeType, bool hasFallback, bool& useFallback)
1501 {
1502     useFallback = false;
1503     ObjectContentType objectType = objectContentType(url, mimeType);
1504
1505     // if an object's content can't be handled and it has no fallback, let
1506     // it be handled as a plugin to show the broken plugin icon
1507     if (objectType == ObjectContentNone && hasFallback)
1508         useFallback = true;
1509
1510     return objectType == ObjectContentNone || objectType == ObjectContentPlugin;
1511 }
1512
1513
1514 bool Frame::loadPlugin(RenderPart *renderer, const KURL& url, const String& mimeType, 
1515                        const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback)
1516 {
1517     if (useFallback) {
1518         checkEmitLoadEvent();
1519         return false;
1520     }
1521
1522     Element *pluginElement;
1523     if (renderer && renderer->node() && renderer->node()->isElementNode())
1524         pluginElement = static_cast<Element*>(renderer->node());
1525     else
1526         pluginElement = 0;
1527         
1528     Plugin* plugin = createPlugin(pluginElement, url, paramNames, paramValues, mimeType);
1529     if (!plugin) {
1530         checkEmitLoadEvent();
1531         return false;
1532     }
1533     d->m_plugins.append(plugin);
1534     
1535     if (renderer && plugin->view())
1536         renderer->setWidget(plugin->view());
1537     
1538     checkEmitLoadEvent();
1539     
1540     return true;
1541 }
1542
1543 Frame* Frame::loadSubframe(Element* ownerElement, const KURL& url, const String& name, const String& referrer)
1544 {
1545     Frame* frame = createFrame(url, name, ownerElement, referrer);
1546     if (!frame)  {
1547         checkEmitLoadEvent();
1548         return 0;
1549     }
1550     
1551     frame->childBegin();
1552     
1553     if (ownerElement->renderer() && frame->view())
1554         static_cast<RenderWidget*>(ownerElement->renderer())->setWidget(frame->view());
1555     
1556     checkEmitLoadEvent();
1557     
1558     // In these cases, the synchronous load would have finished
1559     // before we could connect the signals, so make sure to send the 
1560     // completed() signal for the child by hand
1561     // FIXME: In this case the Frame will have finished loading before 
1562     // it's being added to the child list. It would be a good idea to
1563     // create the child first, then invoke the loader separately.
1564     if (url.isEmpty() || url == "about:blank") {
1565         frame->completed(false);
1566         frame->checkCompleted();
1567     }
1568
1569     return frame;
1570 }
1571
1572 void Frame::clearRecordedFormValues()
1573 {
1574     d->m_formAboutToBeSubmitted = 0;
1575     d->m_formValuesAboutToBeSubmitted.clear();
1576 }
1577
1578 void Frame::recordFormValue(const String& name, const String& value, PassRefPtr<HTMLFormElement> element)
1579 {
1580     d->m_formAboutToBeSubmitted = element;
1581     d->m_formValuesAboutToBeSubmitted.set(name, value);
1582 }
1583
1584 void Frame::submitFormAgain()
1585 {
1586     FramePrivate::SubmitForm* form = d->m_submitForm;
1587     d->m_submitForm = 0;
1588     if (d->m_doc && !d->m_doc->parsing() && form)
1589         submitForm(form->submitAction, form->submitUrl, form->submitFormData,
1590             form->target, form->submitContentType, form->submitBoundary);
1591     delete form;
1592 }
1593
1594 void Frame::submitForm(const char *action, const String& url, const FormData& formData, const String& _target, const String& contentType, const String& boundary)
1595 {
1596   KURL u = completeURL(url.deprecatedString());
1597
1598   if (!u.isValid())
1599     // ### ERROR HANDLING!
1600     return;
1601
1602   DeprecatedString urlstring = u.url();
1603   if (urlstring.startsWith("javascript:", false)) {
1604     urlstring = KURL::decode_string(urlstring);
1605     d->m_executingJavaScriptFormAction = true;
1606     executeScript(0, urlstring.mid(11));
1607     d->m_executingJavaScriptFormAction = false;
1608     return;
1609   }
1610
1611   ResourceRequest request;
1612
1613   if (!d->m_referrer.isEmpty())
1614      request.setReferrer(d->m_referrer);
1615
1616   request.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;
1617
1618   // Handle mailto: forms
1619   if (u.protocol() == "mailto") {
1620       // 2)  Append body=
1621       DeprecatedString bodyEnc;
1622       if (contentType.lower() == "multipart/form-data")
1623          // FIXME: is this correct?  I suspect not
1624          bodyEnc = KURL::encode_string(formData.flattenToString().deprecatedString());
1625       else if (contentType.lower() == "text/plain") {
1626          // Convention seems to be to decode, and s/&/\n/
1627          DeprecatedString tmpbody = formData.flattenToString().deprecatedString();
1628          tmpbody.replace('&', '\n');
1629          tmpbody.replace('+', ' ');
1630          tmpbody = KURL::decode_string(tmpbody);  // Decode the rest of it
1631          bodyEnc = KURL::encode_string(tmpbody);  // Recode for the URL
1632       } else
1633          bodyEnc = KURL::encode_string(formData.flattenToString().deprecatedString());
1634
1635       DeprecatedString query = u.query();
1636       if (!query.isEmpty())
1637           query += '&';
1638       query += "body=" + bodyEnc;
1639       
1640       u.setQuery(query);
1641   } 
1642
1643   if (strcmp(action, "get") == 0) {
1644     if (u.protocol() != "mailto")
1645        u.setQuery(formData.flattenToString().deprecatedString());
1646     request.setDoPost(false);
1647   } else {
1648     request.postData = formData;
1649     request.setDoPost(true);
1650
1651     // construct some user headers if necessary
1652     if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
1653       request.setContentType("Content-Type: application/x-www-form-urlencoded");
1654     else // contentType must be "multipart/form-data"
1655       request.setContentType("Content-Type: " + contentType + "; boundary=" + boundary);
1656   }
1657
1658   if (d->m_runningScripts > 0) {
1659     if (d->m_submitForm)
1660         return;
1661     d->m_submitForm = new FramePrivate::SubmitForm;
1662     d->m_submitForm->submitAction = action;
1663     d->m_submitForm->submitUrl = url;
1664     d->m_submitForm->submitFormData = formData;
1665     d->m_submitForm->target = _target;
1666     d->m_submitForm->submitContentType = contentType;
1667     d->m_submitForm->submitBoundary = boundary;
1668   } else {
1669       request.setURL(u);
1670       submitForm(request);
1671   }
1672 }
1673
1674 void Frame::parentCompleted()
1675 {
1676     if (d->m_scheduledRedirection != noRedirectionScheduled && !d->m_redirectionTimer.isActive())
1677         startRedirectionTimer();
1678 }
1679
1680 void Frame::childCompleted(bool complete)
1681 {
1682     if (complete && !tree()->parent())
1683         d->m_bPendingChildRedirection = true;
1684     checkCompleted();
1685 }
1686
1687 int Frame::zoomFactor() const
1688 {
1689   return d->m_zoomFactor;
1690 }
1691
1692 void Frame::setZoomFactor(int percent)
1693 {  
1694   if (d->m_zoomFactor == percent)
1695       return;
1696
1697   d->m_zoomFactor = percent;
1698
1699   if (d->m_doc)
1700       d->m_doc->recalcStyle(Node::Force);
1701
1702   for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
1703       child->setZoomFactor(d->m_zoomFactor);
1704
1705   if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout())
1706       view()->layout();
1707 }
1708
1709 void Frame::setJSStatusBarText(const String& text)
1710 {
1711     d->m_kjsStatusBarText = text;
1712     setStatusBarText(d->m_kjsStatusBarText);
1713 }
1714
1715 void Frame::setJSDefaultStatusBarText(const String& text)
1716 {
1717     d->m_kjsDefaultStatusBarText = text;
1718     setStatusBarText(d->m_kjsDefaultStatusBarText);
1719 }
1720
1721 String Frame::jsStatusBarText() const
1722 {
1723     return d->m_kjsStatusBarText;
1724 }
1725
1726 String Frame::jsDefaultStatusBarText() const
1727 {
1728    return d->m_kjsDefaultStatusBarText;
1729 }
1730
1731 String Frame::referrer() const
1732 {
1733     return d->m_referrer;
1734 }
1735
1736 String Frame::lastModified() const
1737 {
1738     return d->m_lastModified;
1739 }
1740
1741 void Frame::reparseConfiguration()
1742 {
1743     setAutoloadImages(d->m_settings->autoLoadImages());
1744         
1745     d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled();
1746     d->m_bJavaEnabled = d->m_settings->isJavaEnabled();
1747     d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled();
1748
1749     const KURL& userStyleSheetLocation = d->m_settings->userStyleSheetLocation();
1750     if (!userStyleSheetLocation.isEmpty())
1751         setUserStyleSheetLocation(userStyleSheetLocation);
1752     else
1753         setUserStyleSheet(String());
1754
1755     // FIXME: It's not entirely clear why the following is needed.
1756     // The document automatically does this as required when you set the style sheet.
1757     // But we had problems when this code was removed. Details are in
1758     // <http://bugzilla.opendarwin.org/show_bug.cgi?id=8079>.
1759     if (d->m_doc)
1760         d->m_doc->updateStyleSelector();
1761 }
1762
1763 bool Frame::shouldDragAutoNode(Node *node, const IntPoint& point) const
1764 {
1765     // No KDE impl yet
1766     return false;
1767 }
1768
1769 bool Frame::isPointInsideSelection(const IntPoint& point)
1770 {
1771     // Treat a collapsed selection like no selection.
1772     if (!selectionController()->isRange())
1773         return false;
1774     if (!document()->renderer()) 
1775         return false;
1776     
1777     RenderObject::NodeInfo nodeInfo(true, true);
1778     document()->renderer()->layer()->hitTest(nodeInfo, point);
1779     Node *innerNode = nodeInfo.innerNode();
1780     if (!innerNode || !innerNode->renderer())
1781         return false;
1782     
1783     Position pos(innerNode->renderer()->positionForPoint(point).deepEquivalent());
1784     if (pos.isNull())
1785         return false;
1786
1787     Node *n = selectionController()->start().node();
1788     while (n) {
1789         if (n == pos.node()) {
1790             if ((n == selectionController()->start().node() && pos.offset() < selectionController()->start().offset()) ||
1791                 (n == selectionController()->end().node() && pos.offset() > selectionController()->end().offset())) {
1792                 return false;
1793             }
1794             return true;
1795         }
1796         if (n == selectionController()->end().node())
1797             break;
1798         n = n->traverseNextNode();
1799     }
1800
1801    return false;
1802 }
1803
1804 void Frame::selectClosestWordFromMouseEvent(const PlatformMouseEvent& mouse, Node *innerNode)
1805 {
1806     Selection newSelection;
1807
1808     if (innerNode && innerNode->renderer() && mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
1809         IntPoint vPoint = view()->windowToContents(mouse.pos());
1810         VisiblePosition pos(innerNode->renderer()->positionForPoint(vPoint));
1811         if (pos.isNotNull()) {
1812             newSelection = Selection(pos);
1813             newSelection.expandUsingGranularity(WordGranularity);
1814         }
1815     }
1816     
1817     if (newSelection.isRange()) {
1818         d->m_selectionGranularity = WordGranularity;
1819         d->m_beganSelectingText = true;
1820     }
1821     
1822     if (shouldChangeSelection(newSelection))
1823         selectionController()->setSelection(newSelection);
1824 }
1825
1826 void Frame::handleMousePressEventDoubleClick(const MouseEventWithHitTestResults& event)
1827 {
1828     if (event.event().button() == LeftButton) {
1829         if (selectionController()->isRange())
1830             // A double-click when range is already selected
1831             // should not change the selection.  So, do not call
1832             // selectClosestWordFromMouseEvent, but do set
1833             // m_beganSelectingText to prevent handleMouseReleaseEvent
1834             // from setting caret selection.
1835             d->m_beganSelectingText = true;
1836         else
1837             selectClosestWordFromMouseEvent(event.event(), event.targetNode());
1838     }
1839 }
1840
1841 void Frame::handleMousePressEventTripleClick(const MouseEventWithHitTestResults& event)
1842 {
1843     Node *innerNode = event.targetNode();
1844     
1845     if (event.event().button() == LeftButton && innerNode && innerNode->renderer() &&
1846         mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
1847         Selection newSelection;
1848         IntPoint vPoint = view()->windowToContents(event.event().pos());
1849         VisiblePosition pos(innerNode->renderer()->positionForPoint(vPoint));
1850         if (pos.isNotNull()) {
1851             newSelection = Selection(pos);
1852             newSelection.expandUsingGranularity(ParagraphGranularity);
1853         }
1854         if (newSelection.isRange()) {
1855             d->m_selectionGranularity = ParagraphGranularity;
1856             d->m_beganSelectingText = true;
1857         }
1858         
1859         if (shouldChangeSelection(newSelection))
1860             selectionController()->setSelection(newSelection);
1861     }
1862 }
1863
1864 void Frame::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event)
1865 {
1866     Node *innerNode = event.targetNode();
1867     
1868     if (event.event().button() == LeftButton) {
1869         if (innerNode && innerNode->renderer() &&
1870             mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
1871             
1872             // Extend the selection if the Shift key is down, unless the click is in a link.
1873             bool extendSelection = event.event().shiftKey() && !event.isOverLink();
1874
1875             // Don't restart the selection when the mouse is pressed on an
1876             // existing selection so we can allow for text dragging.
1877             IntPoint vPoint = view()->windowToContents(event.event().pos());
1878             if (!extendSelection && isPointInsideSelection(vPoint))
1879                 return;
1880
1881             VisiblePosition visiblePos(innerNode->renderer()->positionForPoint(vPoint));
1882             if (visiblePos.isNull())
1883                 visiblePos = VisiblePosition(innerNode, innerNode->caretMinOffset(), DOWNSTREAM);
1884             Position pos = visiblePos.deepEquivalent();
1885             
1886             Selection newSelection = selectionController()->selection();
1887             if (extendSelection && newSelection.isCaretOrRange()) {
1888                 selectionController()->clearModifyBias();
1889                 
1890                 // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection 
1891                 // was created right-to-left
1892                 Position start = newSelection.start();
1893                 Position end = newSelection.end();
1894                 short before = Range::compareBoundaryPoints(pos.node(), pos.offset(), start.node(), start.offset());
1895                 if (before <= 0)
1896                     newSelection = Selection(pos, end);
1897                 else
1898                     newSelection = Selection(start, pos);
1899
1900                 if (d->m_selectionGranularity != CharacterGranularity)
1901                     newSelection.expandUsingGranularity(d->m_selectionGranularity);
1902                 d->m_beganSelectingText = true;
1903             } else {
1904                 newSelection = Selection(visiblePos);
1905                 d->m_selectionGranularity = CharacterGranularity;
1906             }
1907             
1908             if (shouldChangeSelection(newSelection))
1909                 selectionController()->setSelection(newSelection);
1910         }
1911     }
1912 }
1913
1914 void Frame::handleMousePressEvent(const MouseEventWithHitTestResults& event)
1915 {
1916     Node *innerNode = event.targetNode();
1917
1918     d->m_mousePressNode = innerNode;
1919     d->m_dragStartPos = event.event().pos();
1920
1921     if (event.event().button() == LeftButton || event.event().button() == MiddleButton) {
1922         d->m_bMousePressed = true;
1923         d->m_beganSelectingText = false;
1924
1925         if (event.event().clickCount() == 2) {
1926             handleMousePressEventDoubleClick(event);
1927             return;
1928         }
1929         if (event.event().clickCount() >= 3) {
1930             handleMousePressEventTripleClick(event);
1931             return;
1932         }
1933         handleMousePressEventSingleClick(event);
1934     }
1935     
1936    setMouseDownMayStartAutoscroll(mouseDownMayStartSelect() || 
1937         (d->m_mousePressNode && d->m_mousePressNode->renderer() && d->m_mousePressNode->renderer()->shouldAutoscroll()));
1938 }
1939
1940 void Frame::handleMouseMoveEvent(const MouseEventWithHitTestResults& event)
1941 {
1942     // Mouse not pressed. Do nothing.
1943     if (!d->m_bMousePressed)
1944         return;
1945
1946     Node *innerNode = event.targetNode();
1947
1948     if (event.event().button() != 0 || !innerNode || !innerNode->renderer())
1949         return;
1950
1951      if (mouseDownMayStartAutoscroll()) {            
1952         // If the selection is contained in a layer that can scroll, that layer should handle the autoscroll
1953         // Otherwise, let the bridge handle it so the view can scroll itself.
1954         RenderObject* renderer = innerNode->renderer();
1955         while (renderer && !renderer->shouldAutoscroll())
1956             renderer = renderer->parent();
1957         if (renderer)
1958             handleAutoscroll(renderer);
1959                 
1960         setMouseDownMayStartDrag(false);
1961         view()->invalidateClick();
1962     }
1963     
1964     if (mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
1965         // handle making selection
1966         IntPoint vPoint = view()->windowToContents(event.event().pos());        
1967         VisiblePosition pos(innerNode->renderer()->positionForPoint(vPoint));
1968
1969         updateSelectionForMouseDragOverPosition(pos);
1970     }
1971
1972 }
1973
1974 void Frame::updateSelectionForMouseDragOverPosition(const VisiblePosition& pos)
1975 {
1976     // Don't modify the selection if we're not on a node.
1977     if (pos.isNull())
1978         return;
1979
1980     // Restart the selection if this is the first mouse move. This work is usually
1981     // done in handleMousePressEvent, but not if the mouse press was on an existing selection.
1982     Selection newSelection = selectionController()->selection();
1983     selectionController()->clearModifyBias();
1984     
1985     if (!d->m_beganSelectingText) {
1986         d->m_beganSelectingText = true;
1987         newSelection = Selection(pos);
1988     }
1989
1990     newSelection.setExtent(pos);
1991     if (d->m_selectionGranularity != CharacterGranularity)
1992         newSelection.expandUsingGranularity(d->m_selectionGranularity);
1993
1994     if (shouldChangeSelection(newSelection))
1995         selectionController()->setSelection(newSelection);
1996 }
1997
1998 void Frame::handleMouseReleaseEvent(const MouseEventWithHitTestResults& event)
1999 {
2000     stopAutoscrollTimer();
2001     
2002     // Used to prevent mouseMoveEvent from initiating a drag before
2003     // the mouse is pressed again.
2004     d->m_bMousePressed = false;
2005   
2006     // Clear the selection if the mouse didn't move after the last mouse press.
2007     // We do this so when clicking on the selection, the selection goes away.
2008     // However, if we are editing, place the caret.
2009     if (mouseDownMayStartSelect() && !d->m_beganSelectingText
2010             && d->m_dragStartPos == event.event().pos()
2011             && selectionController()->isRange()) {
2012         Selection newSelection;
2013         Node *node = event.targetNode();
2014         if (node && node->isContentEditable() && node->renderer()) {
2015             IntPoint vPoint = view()->windowToContents(event.event().pos());
2016             VisiblePosition pos = node->renderer()->positionForPoint(vPoint);
2017             newSelection = Selection(pos);
2018         }
2019         if (shouldChangeSelection(newSelection))
2020             selectionController()->setSelection(newSelection);
2021     }
2022
2023     notifyRendererOfSelectionChange(true);
2024
2025     selectFrameElementInParentIfFullySelected();
2026 }
2027
2028 void Frame::selectAll()
2029 {
2030     if (!d->m_doc)
2031         return;
2032     
2033     Node* root = selectionController()->isContentEditable() ? selectionController()->rootEditableElement() : d->m_doc->documentElement();
2034     selectContentsOfNode(root);
2035     selectFrameElementInParentIfFullySelected();
2036     notifyRendererOfSelectionChange(true);
2037 }
2038
2039 bool Frame::selectContentsOfNode(Node* node)
2040 {
2041     Selection newSelection(Selection::selectionFromContentsOfNode(node));
2042     if (shouldChangeSelection(newSelection)) {
2043         selectionController()->setSelection(newSelection);
2044         return true;
2045     }
2046     return false;
2047 }
2048
2049 bool Frame::shouldChangeSelection(const Selection& newSelection) const
2050 {
2051     return shouldChangeSelection(selectionController()->selection(), newSelection, newSelection.affinity(), false);
2052 }
2053
2054 bool Frame::shouldDeleteSelection(const Selection& newSelection) const
2055 {
2056     return true;
2057 }
2058
2059 bool Frame::shouldBeginEditing(const Range *range) const
2060 {
2061     return true;
2062 }
2063
2064 bool Frame::shouldEndEditing(const Range *range) const
2065 {
2066     return true;
2067 }
2068
2069 bool Frame::isContentEditable() const 
2070 {
2071     if (!d->m_doc)
2072         return false;
2073     return d->m_doc->inDesignMode();
2074 }
2075
2076 void Frame::textFieldDidBeginEditing(Element* input)
2077 {
2078 }
2079
2080 void Frame::textFieldDidEndEditing(Element* input)
2081 {
2082 }
2083
2084 void Frame::textDidChangeInTextField(Element* input)
2085 {
2086 }
2087
2088 bool Frame::doTextFieldCommandFromEvent(Element* input, const PlatformKeyboardEvent* evt)
2089 {
2090     return false;
2091 }
2092
2093 void Frame::textWillBeDeletedInTextField(Element* input)
2094 {
2095 }
2096
2097 void Frame::textDidChangeInTextArea(Element* input)
2098 {
2099 }
2100
2101 bool Frame::isSelectionInPasswordField()
2102 {
2103     Node* startNode = selectionController()->start().node();
2104     if (startNode)
2105         startNode = startNode->shadowAncestorNode();
2106     return startNode && startNode->hasTagName(inputTag) && static_cast<HTMLInputElement*>(startNode)->inputType() == HTMLInputElement::PASSWORD;
2107 }
2108   
2109 EditCommand* Frame::lastEditCommand()
2110 {
2111     return d->m_lastEditCommand.get();
2112 }
2113
2114 static void dispatchEditableContentChangedEvents(const EditCommand& command)
2115 {
2116      Element* startRoot = command.startingRootEditableElement();
2117      Element* endRoot = command.endingRootEditableElement();
2118      ExceptionCode ec;
2119      if (startRoot)
2120          startRoot->dispatchEvent(new Event(khtmlEditableContentChangedEvent, false, false), ec, true);
2121      if (endRoot && endRoot != startRoot)
2122          endRoot->dispatchEvent(new Event(khtmlEditableContentChangedEvent, false, false), ec, true);
2123 }
2124
2125 void Frame::appliedEditing(PassRefPtr<EditCommand> cmd)
2126 {
2127     dispatchEditableContentChangedEvents(*cmd);
2128  
2129     Selection newSelection(cmd->endingSelection());
2130     if (shouldChangeSelection(newSelection))
2131         selectionController()->setSelection(newSelection, false);
2132     
2133     // Now set the typing style from the command. Clear it when done.
2134     // This helps make the case work where you completely delete a piece
2135     // of styled text and then type a character immediately after.
2136     // That new character needs to take on the style of the just-deleted text.
2137     // FIXME: Improve typing style.
2138     // See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
2139     if (cmd->typingStyle()) {
2140         setTypingStyle(cmd->typingStyle());
2141         cmd->setTypingStyle(0);
2142     }
2143
2144     // Command will be equal to last edit command only in the case of typing
2145     if (d->m_lastEditCommand == cmd)
2146         assert(cmd->isTypingCommand());
2147     else {
2148         // Only register a new undo command if the command passed in is
2149         // different from the last command
2150         d->m_lastEditCommand = cmd.get();
2151         registerCommandForUndo(cmd);
2152     }
2153     respondToChangedContents(newSelection);
2154 }
2155
2156 void Frame::unappliedEditing(PassRefPtr<EditCommand> cmd)
2157 {
2158     dispatchEditableContentChangedEvents(*cmd);
2159
2160     Selection newSelection(cmd->startingSelection());
2161     if (shouldChangeSelection(newSelection))
2162         selectionController()->setSelection(newSelection, true);
2163         
2164     d->m_lastEditCommand = 0;
2165     registerCommandForRedo(cmd);
2166     respondToChangedContents(newSelection);
2167 }
2168
2169 void Frame::reappliedEditing(PassRefPtr<EditCommand> cmd)
2170 {
2171     dispatchEditableContentChangedEvents(*cmd);
2172
2173     Selection newSelection(cmd->endingSelection());
2174     if (shouldChangeSelection(newSelection))
2175         selectionController()->setSelection(newSelection, true);
2176         
2177     d->m_lastEditCommand = 0;
2178     registerCommandForUndo(cmd);
2179     respondToChangedContents(newSelection);
2180 }
2181
2182 CSSMutableStyleDeclaration *Frame::typingStyle() const
2183 {
2184     return d->m_typingStyle.get();
2185 }
2186
2187 void Frame::setTypingStyle(CSSMutableStyleDeclaration *style)
2188 {
2189     d->m_typingStyle = style;
2190 }
2191
2192 void Frame::clearTypingStyle()
2193 {
2194     d->m_typingStyle = 0;
2195 }
2196
2197 JSValue* Frame::executeScript(const String& filename, int baseLine, Node* n, const String& script)
2198 {
2199     // FIXME: This is missing stuff that the other executeScript has.
2200     // --> d->m_runningScripts and submitFormAgain.
2201     // Why is that OK?
2202     KJSProxy* proxy = jScript();
2203     if (!proxy)
2204         return 0;
2205     JSValue* ret = proxy->evaluate(filename, baseLine, script, n);
2206     Document::updateDocumentsRendering();
2207     return ret;
2208 }
2209
2210 Frame *Frame::opener()
2211 {
2212     return d->m_opener;
2213 }
2214
2215 void Frame::setOpener(Frame* opener)
2216 {
2217     if (d->m_opener)
2218         d->m_opener->d->m_openedFrames.remove(this);
2219     if (opener)
2220         opener->d->m_openedFrames.add(this);
2221     d->m_opener = opener;
2222 }
2223
2224 bool Frame::openedByJS()
2225 {
2226     return d->m_openedByJS;
2227 }
2228
2229 void Frame::setOpenedByJS(bool _openedByJS)
2230 {
2231     d->m_openedByJS = _openedByJS;
2232 }
2233
2234 bool Frame::tabsToLinks() const
2235 {
2236     return true;
2237 }
2238
2239 bool Frame::tabsToAllControls() const
2240 {
2241     return true;
2242 }
2243
2244 void Frame::copyToPasteboard()
2245 {
2246     issueCopyCommand();
2247 }
2248
2249 void Frame::cutToPasteboard()
2250 {
2251     issueCutCommand();
2252 }
2253
2254 void Frame::pasteFromPasteboard()
2255 {
2256     issuePasteCommand();
2257 }
2258
2259 void Frame::pasteAndMatchStyle()
2260 {
2261     issuePasteAndMatchStyleCommand();
2262 }
2263
2264 bool Frame::mayCopy()
2265 {
2266     return !isSelectionInPasswordField();
2267 }
2268
2269 void Frame::transpose()
2270 {
2271     issueTransposeCommand();
2272 }
2273
2274 void Frame::redo()
2275 {
2276     issueRedoCommand();
2277 }
2278
2279 void Frame::undo()
2280 {
2281     issueUndoCommand();
2282 }
2283
2284
2285 void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction editingAction)
2286 {
2287     if (!style || style->length() == 0) {
2288         clearTypingStyle();
2289         return;
2290     }
2291
2292     // Calculate the current typing style.
2293     RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
2294     if (typingStyle()) {
2295         typingStyle()->merge(mutableStyle.get());
2296         mutableStyle = typingStyle();
2297     }
2298
2299     Node *node = selectionController()->selection().visibleStart().deepEquivalent().node();
2300     CSSComputedStyleDeclaration computedStyle(node);
2301     computedStyle.diff(mutableStyle.get());
2302     
2303     // Handle block styles, substracting these from the typing style.
2304     RefPtr<CSSMutableStyleDeclaration> blockStyle = mutableStyle->copyBlockProperties();
2305     blockStyle->diff(mutableStyle.get());
2306     if (document() && blockStyle->length() > 0)
2307         applyCommand(new ApplyStyleCommand(document(), blockStyle.get(), editingAction));
2308     
2309     // Set the remaining style as the typing style.
2310     d->m_typingStyle = mutableStyle.release();
2311 }
2312
2313 void Frame::applyStyle(CSSStyleDeclaration *style, EditAction editingAction)
2314 {
2315     switch (selectionController()->state()) {
2316         case Selection::NONE:
2317             // do nothing
2318             break;
2319         case Selection::CARET: {
2320             computeAndSetTypingStyle(style, editingAction);
2321             break;
2322         }
2323         case Selection::RANGE:
2324             if (document() && style)
2325                 applyCommand(new ApplyStyleCommand(document(), style, editingAction));
2326             break;
2327     }
2328 }
2329
2330 void Frame::applyParagraphStyle(CSSStyleDeclaration *style, EditAction editingAction)
2331 {
2332     switch (selectionController()->state()) {
2333         case Selection::NONE:
2334             // do nothing
2335             break;
2336         case Selection::CARET:
2337         case Selection::RANGE:
2338             if (document() && style)
2339                 applyCommand(new ApplyStyleCommand(document(), style, editingAction, ApplyStyleCommand::ForceBlockProperties));
2340             break;
2341     }
2342 }
2343
2344 static void updateState(CSSMutableStyleDeclaration *desiredStyle, CSSComputedStyleDeclaration *computedStyle, bool& atStart, Frame::TriState& state)
2345 {
2346     DeprecatedValueListConstIterator<CSSProperty> end;
2347     for (DeprecatedValueListConstIterator<CSSProperty> it = desiredStyle->valuesIterator(); it != end; ++it) {
2348         int propertyID = (*it).id();
2349         String desiredProperty = desiredStyle->getPropertyValue(propertyID);
2350         String computedProperty = computedStyle->getPropertyValue(propertyID);
2351         Frame::TriState propertyState = equalIgnoringCase(desiredProperty, computedProperty)
2352             ? Frame::trueTriState : Frame::falseTriState;
2353         if (atStart) {
2354             state = propertyState;
2355             atStart = false;
2356         } else if (state != propertyState) {
2357             state = Frame::mixedTriState;
2358             break;
2359         }
2360     }
2361 }
2362
2363 Frame::TriState Frame::selectionListState() const
2364 {
2365     TriState state = falseTriState;
2366
2367     if (!selectionController()->isRange()) {
2368         Node* selectionNode = selectionController()->selection().start().node();
2369         if (enclosingList(selectionNode))
2370             return trueTriState;
2371     } else {
2372         //FIXME: Support ranges
2373     }
2374
2375     return state;
2376 }
2377
2378 Frame::TriState Frame::selectionHasStyle(CSSStyleDeclaration *style) const
2379 {
2380     bool atStart = true;
2381     TriState state = falseTriState;
2382
2383     RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
2384
2385     if (!selectionController()->isRange()) {
2386         Node* nodeToRemove;
2387         RefPtr<CSSComputedStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
2388         if (!selectionStyle)
2389             return falseTriState;
2390         updateState(mutableStyle.get(), selectionStyle.get(), atStart, state);
2391         if (nodeToRemove) {
2392             ExceptionCode ec = 0;
2393             nodeToRemove->remove(ec);
2394             assert(ec == 0);
2395         }
2396     } else {
2397         for (Node* node = selectionController()->start().node(); node; node = node->traverseNextNode()) {
2398             RefPtr<CSSComputedStyleDeclaration> computedStyle = new CSSComputedStyleDeclaration(node);
2399             if (computedStyle)
2400                 updateState(mutableStyle.get(), computedStyle.get(), atStart, state);
2401             if (state == mixedTriState)
2402                 break;
2403             if (node == selectionController()->end().node())
2404                 break;
2405         }
2406     }
2407
2408     return state;
2409 }
2410
2411 bool Frame::selectionStartHasStyle(CSSStyleDeclaration *style) const
2412 {
2413     Node* nodeToRemove;
2414     RefPtr<CSSStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
2415     if (!selectionStyle)
2416         return false;
2417
2418     RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
2419
2420     bool match = true;
2421     DeprecatedValueListConstIterator<CSSProperty> end;
2422     for (DeprecatedValueListConstIterator<CSSProperty> it = mutableStyle->valuesIterator(); it != end; ++it) {
2423         int propertyID = (*it).id();
2424         if (!equalIgnoringCase(mutableStyle->getPropertyValue(propertyID), selectionStyle->getPropertyValue(propertyID))) {
2425             match = false;
2426             break;
2427         }
2428     }
2429
2430     if (nodeToRemove) {
2431         ExceptionCode ec = 0;
2432         nodeToRemove->remove(ec);
2433         assert(ec == 0);
2434     }
2435
2436     return match;
2437 }
2438
2439 String Frame::selectionStartStylePropertyValue(int stylePropertyID) const
2440 {
2441     Node *nodeToRemove;
2442     RefPtr<CSSStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
2443     if (!selectionStyle)
2444         return String();
2445
2446     String value = selectionStyle->getPropertyValue(stylePropertyID);
2447
2448     if (nodeToRemove) {
2449         ExceptionCode ec = 0;
2450         nodeToRemove->remove(ec);
2451         assert(ec == 0);
2452     }
2453
2454     return value;
2455 }
2456
2457 CSSComputedStyleDeclaration *Frame::selectionComputedStyle(Node *&nodeToRemove) const
2458 {
2459     nodeToRemove = 0;
2460
2461     if (!document())
2462         return 0;
2463
2464     if (selectionController()->isNone())
2465         return 0;
2466
2467     RefPtr<Range> range(selectionController()->toRange());
2468     Position pos = range->editingStartPosition();
2469
2470     Element *elem = pos.element();
2471     if (!elem)
2472         return 0;
2473     
2474     RefPtr<Element> styleElement = elem;
2475     ExceptionCode ec = 0;
2476
2477     if (d->m_typingStyle) {
2478         styleElement = document()->createElementNS(xhtmlNamespaceURI, "span", ec);
2479         assert(ec == 0);
2480
2481         styleElement->setAttribute(styleAttr, d->m_typingStyle->cssText().impl(), ec);
2482         assert(ec == 0);
2483         
2484         styleElement->appendChild(document()->createEditingTextNode(""), ec);
2485         assert(ec == 0);
2486
2487         if (elem->renderer() && elem->renderer()->canHaveChildren()) {
2488             elem->appendChild(styleElement, ec);
2489         } else {
2490             Node *parent = elem->parent();
2491             Node *next = elem->nextSibling();
2492
2493             if (next) {
2494                 parent->insertBefore(styleElement, next, ec);
2495             } else {
2496                 parent->appendChild(styleElement, ec);
2497             }
2498         }
2499         assert(ec == 0);
2500
2501         nodeToRemove = styleElement.get();
2502     }
2503
2504     return new CSSComputedStyleDeclaration(styleElement);
2505 }
2506
2507 void Frame::applyEditingStyleToBodyElement() const
2508 {
2509     if (!d->m_doc)
2510         return;
2511         
2512     RefPtr<NodeList> list = d->m_doc->getElementsByTagName("body");
2513     unsigned len = list->length();
2514     for (unsigned i = 0; i < len; i++) {
2515         applyEditingStyleToElement(static_cast<Element*>(list->item(i)));    
2516     }
2517 }
2518
2519 void Frame::removeEditingStyleFromBodyElement() const
2520 {
2521     if (!d->m_doc)
2522         return;
2523         
2524     RefPtr<NodeList> list = d->m_doc->getElementsByTagName("body");
2525     unsigned len = list->length();
2526     for (unsigned i = 0; i < len; i++) {
2527         removeEditingStyleFromElement(static_cast<Element*>(list->item(i)));    
2528     }
2529 }
2530
2531 void Frame::applyEditingStyleToElement(Element* element) const
2532 {
2533     if (!element)
2534         return;
2535
2536     CSSStyleDeclaration* style = element->style();
2537     ASSERT(style);
2538
2539     ExceptionCode ec = 0;
2540     style->setProperty(CSS_PROP_WORD_WRAP, "break-word", false, ec);
2541     ASSERT(ec == 0);
2542     style->setProperty(CSS_PROP__WEBKIT_NBSP_MODE, "space", false, ec);
2543     ASSERT(ec == 0);
2544     style->setProperty(CSS_PROP__WEBKIT_LINE_BREAK, "after-white-space", false, ec);
2545     ASSERT(ec == 0);
2546 }
2547
2548 void Frame::removeEditingStyleFromElement(Element*) const
2549 {
2550 }
2551
2552 bool Frame::isCharacterSmartReplaceExempt(UChar, bool)
2553 {
2554     // no smart replace
2555     return true;
2556 }
2557
2558 #ifndef NDEBUG
2559 static HashSet<Frame*> lifeSupportSet;
2560 #endif
2561
2562 void Frame::endAllLifeSupport()
2563 {
2564 #ifndef NDEBUG
2565     HashSet<Frame*> lifeSupportCopy = lifeSupportSet;
2566     HashSet<Frame*>::iterator end = lifeSupportCopy.end();
2567     for (HashSet<Frame*>::iterator it = lifeSupportCopy.begin(); it != end; ++it)
2568         (*it)->endLifeSupport();
2569 #endif
2570 }
2571
2572 void Frame::keepAlive()
2573 {
2574     if (d->m_lifeSupportTimer.isActive())
2575         return;
2576     ref();
2577 #ifndef NDEBUG
2578     lifeSupportSet.add(this);
2579 #endif
2580     d->m_lifeSupportTimer.startOneShot(0);
2581 }
2582
2583 void Frame::endLifeSupport()
2584 {
2585     if (!d->m_lifeSupportTimer.isActive())
2586         return;
2587     d->m_lifeSupportTimer.stop();
2588 #ifndef NDEBUG
2589     lifeSupportSet.remove(this);
2590 #endif
2591     deref();
2592 }
2593
2594 void Frame::lifeSupportTimerFired(Timer<Frame>*)
2595 {
2596 #ifndef NDEBUG
2597     lifeSupportSet.remove(this);
2598 #endif
2599     deref();
2600 }
2601
2602 // Workaround for the fact that it's hard to delete a frame.
2603 // Call this after doing user-triggered selections to make it easy to delete the frame you entirely selected.
2604 // Can't do this implicitly as part of every setSelection call because in some contexts it might not be good
2605 // for the focus to move to another frame. So instead we call it from places where we are selecting with the
2606 // mouse or the keyboard after setting the selection.
2607 void Frame::selectFrameElementInParentIfFullySelected()
2608 {
2609     // Find the parent frame; if there is none, then we have nothing to do.
2610     Frame *parent = tree()->parent();
2611     if (!parent)
2612         return;
2613     FrameView *parentView = parent->view();
2614     if (!parentView)
2615         return;
2616
2617     // Check if the selection contains the entire frame contents; if not, then there is nothing to do.
2618     if (!selectionController()->isRange())
2619         return;
2620     if (!isStartOfDocument(selectionController()->selection().visibleStart()))
2621         return;
2622     if (!isEndOfDocument(selectionController()->selection().visibleEnd()))
2623         return;
2624
2625     // Get to the <iframe> or <frame> (or even <object>) element in the parent frame.
2626     Document *doc = document();
2627     if (!doc)
2628         return;
2629     Element *ownerElement = doc->ownerElement();
2630     if (!ownerElement)
2631         return;
2632     Node *ownerElementParent = ownerElement->parentNode();
2633     if (!ownerElementParent)
2634         return;
2635         
2636     // This method's purpose is it to make it easier to select iframes (in order to delete them).  Don't do anything if the iframe isn't deletable.
2637     if (!ownerElementParent->isContentEditable())
2638         return;
2639
2640     // Create compute positions before and after the element.
2641     unsigned ownerElementNodeIndex = ownerElement->nodeIndex();
2642     VisiblePosition beforeOwnerElement(VisiblePosition(ownerElementParent, ownerElementNodeIndex, SEL_DEFAULT_AFFINITY));
2643     VisiblePosition afterOwnerElement(VisiblePosition(ownerElementParent, ownerElementNodeIndex + 1, VP_UPSTREAM_IF_POSSIBLE));
2644
2645     // Focus on the parent frame, and then select from before this element to after.
2646     Selection newSelection(beforeOwnerElement, afterOwnerElement);
2647     if (parent->shouldChangeSelection(newSelection)) {
2648         parentView->setFocus();
2649         parent->selectionController()->setSelection(newSelection);
2650     }
2651 }
2652
2653 bool Frame::mouseDownMayStartAutoscroll() const
2654 {
2655     return d->m_mouseDownMayStartAutoscroll;
2656 }
2657
2658 void Frame::setMouseDownMayStartAutoscroll(bool b)
2659 {
2660     d->m_mouseDownMayStartAutoscroll = b;
2661 }
2662
2663 bool Frame::mouseDownMayStartDrag() const
2664 {
2665     return d->m_mouseDownMayStartDrag;
2666 }
2667
2668 void Frame::setMouseDownMayStartDrag(bool b)
2669 {
2670     d->m_mouseDownMayStartDrag = b;
2671 }
2672
2673 void Frame::handleFallbackContent()
2674 {
2675     Element* owner = ownerElement();
2676     if (!owner || !owner->hasTagName(objectTag))
2677         return;
2678     static_cast<HTMLObjectElement*>(owner)->renderFallbackContent();
2679 }
2680
2681 void Frame::setSettings(Settings *settings)
2682 {
2683     d->m_settings = settings;
2684 }
2685
2686 void Frame::provisionalLoadStarted()
2687 {
2688     // we don't want to wait until we get an actual http response back
2689     // to cancel pending redirects, otherwise they might fire before
2690     // that happens.
2691     cancelRedirection(true);
2692 }
2693
2694 bool Frame::userGestureHint()
2695 {
2696     Frame *rootFrame = this;
2697     while (rootFrame->tree()->parent())
2698         rootFrame = rootFrame->tree()->parent();
2699
2700     if (rootFrame->jScript())
2701         return rootFrame->jScript()->interpreter()->wasRunByUserGesture();
2702
2703     return true; // If JavaScript is disabled, a user gesture must have initiated the navigation
2704 }
2705
2706 RenderObject *Frame::renderer() const
2707 {
2708     Document *doc = document();
2709     return doc ? doc->renderer() : 0;
2710 }
2711
2712 Element* Frame::ownerElement()
2713 {
2714     return d->m_ownerElement;
2715 }
2716
2717 RenderPart* Frame::ownerRenderer()
2718 {
2719     Element* ownerElement = d->m_ownerElement;
2720     if (!ownerElement)
2721         return 0;
2722     return static_cast<RenderPart*>(ownerElement->renderer());
2723 }
2724
2725 IntRect Frame::selectionRect() const
2726 {
2727     RenderView *root = static_cast<RenderView*>(renderer());
2728     if (!root)
2729         return IntRect();
2730
2731     return root->selectionRect();
2732 }
2733
2734 // returns FloatRect because going through IntRect would truncate any floats
2735 FloatRect Frame::visibleSelectionRect() const
2736 {
2737     if (!d->m_view)
2738         return FloatRect();
2739     
2740     return intersection(selectionRect(), d->m_view->visibleContentRect());
2741 }
2742
2743 bool Frame::isFrameSet() const
2744 {
2745     Document* document = d->m_doc.get();
2746     if (!document || !document->isHTMLDocument())
2747         return false;
2748     Node *body = static_cast<HTMLDocument*>(document)->body();
2749     return body && body->renderer() && body->hasTagName(framesetTag);
2750 }
2751
2752 bool Frame::openURL(const KURL& URL)
2753 {
2754     ASSERT_NOT_REACHED();
2755     return true;
2756 }
2757
2758 void Frame::didNotOpenURL(const KURL& URL)
2759 {
2760     if (d->m_submittedFormURL == URL)
2761         d->m_submittedFormURL = KURL();
2762 }
2763
2764 // Scans logically forward from "start", including any child frames
2765 static HTMLFormElement *scanForForm(Node *start)
2766 {
2767     Node *n;
2768     for (n = start; n; n = n->traverseNextNode()) {
2769         if (n->hasTagName(formTag))
2770             return static_cast<HTMLFormElement*>(n);
2771         else if (n->isHTMLElement() && static_cast<HTMLElement*>(n)->isGenericFormElement())
2772             return static_cast<HTMLGenericFormElement*>(n)->form();
2773         else if (n->hasTagName(frameTag) || n->hasTagName(iframeTag)) {
2774             Node *childDoc = static_cast<HTMLFrameElement*>(n)->contentDocument();
2775             if (HTMLFormElement *frameResult = scanForForm(childDoc))
2776                 return frameResult;
2777         }
2778     }
2779     return 0;
2780 }
2781
2782 // We look for either the form containing the current focus, or for one immediately after it
2783 HTMLFormElement *Frame::currentForm() const
2784 {
2785     // start looking either at the active (first responder) node, or where the selection is
2786     Node *start = d->m_doc ? d->m_doc->focusNode() : 0;
2787     if (!start)
2788         start = selectionController()->start().node();
2789     
2790     // try walking up the node tree to find a form element
2791     Node *n;
2792     for (n = start; n; n = n->parentNode()) {
2793         if (n->hasTagName(formTag))
2794             return static_cast<HTMLFormElement*>(n);
2795         else if (n->isHTMLElement()
2796                    && static_cast<HTMLElement*>(n)->isGenericFormElement())
2797             return static_cast<HTMLGenericFormElement*>(n)->form();
2798     }
2799     
2800     // try walking forward in the node tree to find a form element
2801     return start ? scanForForm(start) : 0;
2802 }
2803
2804 void Frame::setEncoding(const String& name, bool userChosen)
2805 {
2806     if (!d->m_workingURL.isEmpty())
2807         receivedFirstData();
2808     d->m_encoding = name;
2809     d->m_haveEncoding = userChosen;
2810 }
2811
2812 void Frame::addData(const char *bytes, int length)
2813 {
2814     ASSERT(d->m_workingURL.isEmpty());
2815     ASSERT(d->m_doc);
2816     ASSERT(d->m_doc->parsing());
2817     write(bytes, length);
2818 }
2819
2820 // FIXME: should this go in SelectionController?
2821 void Frame::revealSelection(const RenderLayer::ScrollAlignment& alignment) const
2822 {
2823     IntRect rect;
2824     
2825     switch (selectionController()->state()) {
2826         case Selection::NONE:
2827             return;
2828             
2829         case Selection::CARET:
2830             rect = selectionController()->caretRect();
2831             break;
2832             
2833         case Selection::RANGE:
2834             rect = selectionRect();
2835             break;
2836     }
2837
2838     Position start = selectionController()->start();
2839     Position end = selectionController()->end();
2840
2841     ASSERT(start.node());
2842     if (start.node() && start.node()->renderer()) {
2843         RenderLayer *layer = start.node()->renderer()->enclosingLayer();
2844         if (layer) {
2845             ASSERT(!end.node() || !end.node()->renderer() 
2846                    || (end.node()->renderer()->enclosingLayer() == layer));
2847             layer->scrollRectToVisible(rect, alignment, alignment);
2848         }
2849     }
2850 }
2851
2852 void Frame::revealCaret(const RenderLayer::ScrollAlignment& alignment) const
2853 {
2854     if (!hasSelection())
2855         return;
2856
2857     Position extent = selectionController()->extent();
2858     if (extent.node() && extent.node()->renderer()) {
2859         IntRect extentRect = VisiblePosition(extent).caretRect();
2860         RenderLayer* layer = extent.node()->renderer()->enclosingLayer();
2861         if (layer)
2862             layer->scrollRectToVisible(extentRect, alignment, alignment);
2863     }
2864 }
2865
2866 // FIXME: should this be here?
2867 bool Frame::scrollOverflow(ScrollDirection direction, ScrollGranularity granularity)
2868 {
2869     if (!document()) {
2870         return false;
2871     }
2872     
2873     Node *node = document()->focusNode();
2874     if (node == 0) {
2875         node = d->m_mousePressNode.get();
2876     }
2877     
2878     if (node != 0) {
2879         RenderObject *r = node->renderer();
2880         if (r != 0 && !r->isListBox()) {
2881             return r->scroll(direction, granularity);
2882         }
2883     }
2884     
2885     return false;
2886 }
2887
2888 void Frame::handleAutoscroll(RenderObject* renderer)
2889 {
2890     if (d->m_autoscrollTimer.isActive())
2891         return;
2892     setAutoscrollRenderer(renderer);
2893     startAutoscrollTimer();
2894 }
2895
2896 void Frame::autoscrollTimerFired(Timer<Frame>*)
2897 {
2898     if (!d->m_bMousePressed){
2899         stopAutoscrollTimer();
2900         return;
2901     }
2902     if (RenderObject* r = autoscrollRenderer())
2903         r->autoscroll();
2904 }
2905
2906 RenderObject* Frame::autoscrollRenderer() const
2907 {
2908     return d->m_autoscrollRenderer;
2909 }
2910
2911 void Frame::setAutoscrollRenderer(RenderObject* renderer)
2912 {
2913     d->m_autoscrollRenderer = renderer;
2914 }
2915
2916 RenderObject::NodeInfo Frame::nodeInfoAtPoint(const IntPoint& point, bool allowShadowContent)
2917 {
2918     RenderObject::NodeInfo nodeInfo(true, true);
2919     renderer()->layer()->hitTest(nodeInfo, point);
2920
2921     Node *n;
2922     Widget *widget = 0;
2923     IntPoint widgetPoint(point);
2924     
2925     while (true) {
2926         n = nodeInfo.innerNode();
2927         if (!n || !n->renderer() || !n->renderer()->isWidget())
2928             break;
2929         widget = static_cast<RenderWidget*>(n->renderer())->widget();
2930         if (!widget || !widget->isFrameView())
2931             break;
2932         Frame* frame = static_cast<HTMLFrameElement*>(n)->contentFrame();
2933         if (!frame || !frame->renderer())
2934             break;
2935         int absX, absY;
2936         n->renderer()->absolutePosition(absX, absY, true);
2937         FrameView *view = static_cast<FrameView*>(widget);
2938         widgetPoint.setX(widgetPoint.x() - absX + view->contentsX());
2939         widgetPoint.setY(widgetPoint.y() - absY + view->contentsY());
2940
2941         RenderObject::NodeInfo widgetNodeInfo(true, true);
2942         frame->renderer()->layer()->hitTest(widgetNodeInfo, widgetPoint);
2943         nodeInfo = widgetNodeInfo;
2944     }
2945     
2946     if (!allowShadowContent) {
2947         Node* node = nodeInfo.innerNode();
2948         if (node)
2949             node = node->shadowAncestorNode();
2950         nodeInfo.setInnerNode(node);
2951         node = nodeInfo.innerNonSharedNode();
2952         if (node)
2953             node = node->shadowAncestorNode();
2954         nodeInfo.setInnerNonSharedNode(node); 
2955     }
2956     return nodeInfo;
2957 }
2958
2959 bool Frame::hasSelection()
2960 {
2961     if (selectionController()->isNone())
2962         return false;
2963
2964     // If a part has a selection, it should also have a document.        
2965     ASSERT(document());
2966
2967     return true;
2968 }
2969
2970 void Frame::startAutoscrollTimer()
2971 {
2972     d->m_autoscrollTimer.startRepeating(autoscrollInterval);
2973 }
2974
2975 void Frame::stopAutoscrollTimer()
2976 {
2977     setAutoscrollRenderer(0);
2978     d->m_autoscrollTimer.stop();
2979 }
2980
2981 // FIXME: why is this here instead of on the FrameView?
2982 void Frame::paint(GraphicsContext* p, const IntRect& rect)
2983 {
2984 #ifndef NDEBUG
2985     bool fillWithRed;
2986     if (!document() || document()->printing())
2987         fillWithRed = false; // Printing, don't fill with red (can't remember why).
2988     else if (document()->ownerElement())
2989         fillWithRed = false; // Subframe, don't fill with red.
2990     else if (view() && view()->isTransparent())
2991         fillWithRed = false; // Transparent, don't fill with red.
2992     else if (d->m_paintRestriction == PaintRestrictionSelectionOnly || d->m_paintRestriction == PaintRestrictionSelectionOnlyWhiteText)
2993         fillWithRed = false; // Selections are transparent, don't fill with red.
2994     else if (d->m_elementToDraw)
2995         fillWithRed = false; // Element images are transparent, don't fill with red.
2996     else
2997         fillWithRed = true;
2998     
2999     if (fillWithRed)
3000         p->fillRect(rect, Color(0xFF, 0, 0));
3001 #endif
3002     
3003     if (renderer()) {
3004         // d->m_elementToDraw is used to draw only one element
3005         RenderObject *eltRenderer = d->m_elementToDraw ? d->m_elementToDraw->renderer() : 0;
3006         if (d->m_paintRestriction == PaintRestrictionNone)
3007             renderer()->document()->invalidateRenderedRectsForMarkersInRect(rect);
3008         renderer()->layer()->paint(p, rect, d->m_paintRestriction, eltRenderer);
3009
3010 #if __APPLE__
3011         // Regions may have changed as a result of the visibility/z-index of element changing.
3012         if (renderer()->document()->dashboardRegionsDirty())
3013             renderer()->view()->frameView()->updateDashboardRegions();
3014 #endif
3015     } else
3016         LOG_ERROR("called Frame::paint with nil renderer");
3017 }
3018
3019 #if __APPLE__
3020
3021 void Frame::adjustPageHeight(float *newBottom, float oldTop, float oldBottom, float bottomLimit)
3022 {
3023     RenderView *root = static_cast<RenderView*>(document()->renderer());
3024     if (root) {
3025         // Use a context with painting disabled.
3026         GraphicsContext context(0);
3027         root->setTruncatedAt((int)floorf(oldBottom));
3028         IntRect dirtyRect(0, (int)floorf(oldTop), root->docWidth(), (int)ceilf(oldBottom - oldTop));
3029         root->layer()->paint(&context, dirtyRect);
3030         *newBottom = root->bestTruncatedAt();
3031         if (*newBottom == 0)
3032             *newBottom = oldBottom;
3033     } else
3034         *newBottom = oldBottom;
3035 }
3036
3037 #endif
3038
3039 PausedTimeouts *Frame::pauseTimeouts()
3040 {
3041 #ifdef SVG_SUPPORT
3042     if (d->m_doc && d->m_doc->svgExtensions())
3043         d->m_doc->accessSVGExtensions()->pauseAnimations();
3044 #endif
3045
3046     if (d->m_doc && d->m_jscript) {
3047         if (Window* w = Window::retrieveWindow(this))
3048             return w->pauseTimeouts();
3049     }
3050     return 0;
3051 }
3052
3053 void Frame::resumeTimeouts(PausedTimeouts* t)
3054 {
3055 #ifdef SVG_SUPPORT
3056     if (d->m_doc && d->m_doc->svgExtensions())
3057         d->m_doc->accessSVGExtensions()->unpauseAnimations();
3058 #endif
3059
3060     if (d->m_doc && d->m_jscript && d->m_bJScriptEnabled) {
3061         if (Window* w = Window::retrieveWindow(this))
3062             w->resumeTimeouts(t);
3063     }
3064 }
3065
3066 bool Frame::canCachePage()
3067 {
3068     // Only save page state if:
3069     // 1.  We're not a frame or frameset.
3070     // 2.  The page has no unload handler.
3071     // 3.  The page has no password fields.
3072     // 4.  The URL for the page is not https.
3073     // 5.  The page has no applets.
3074     if (tree()->childCount() || d->m_plugins.size() ||
3075         tree()->parent() ||
3076         d->m_url.protocol().startsWith("https") || 
3077         (d->m_doc && (d->m_doc->applets()->length() != 0 ||
3078                       d->m_doc->hasWindowEventListener(unloadEvent) ||
3079                       d->m_doc->hasPasswordField()))) {
3080         return false;
3081     }
3082     return true;
3083 }
3084
3085 void Frame::saveWindowProperties(KJS::SavedProperties *windowProperties)
3086 {
3087     Window *window = Window::retrieveWindow(this);
3088     if (window)
3089         window->saveProperties(*windowProperties);
3090 }
3091
3092 void Frame::saveLocationProperties(SavedProperties *locationProperties)
3093 {
3094     Window *window = Window::retrieveWindow(this);
3095     if (window) {
3096         JSLock lock;
3097         Location *location = window->location();
3098         location->saveProperties(*locationProperties);
3099     }
3100 }
3101
3102 void Frame::restoreWindowProperties(SavedProperties *windowProperties)
3103 {
3104     Window *window = Window::retrieveWindow(this);
3105     if (window)
3106         window->restoreProperties(*windowProperties);
3107 }
3108
3109 void Frame::restoreLocationProperties(SavedProperties *locationProperties)
3110 {
3111     Window *window = Window::retrieveWindow(this);
3112     if (window) {
3113         JSLock lock;
3114         Location *location = window->location();
3115         location->restoreProperties(*locationProperties);
3116     }
3117 }
3118
3119 void Frame::saveInterpreterBuiltins(SavedBuiltins& interpreterBuiltins)
3120 {
3121     if (jScript())
3122         jScript()->interpreter()->saveBuiltins(interpreterBuiltins);
3123 }
3124
3125 void Frame::restoreInterpreterBuiltins(const SavedBuiltins& interpreterBuiltins)
3126 {
3127     if (jScript())
3128         jScript()->interpreter()->restoreBuiltins(interpreterBuiltins);
3129 }
3130
3131 Frame *Frame::frameForWidget(const Widget *widget)
3132 {
3133     ASSERT_ARG(widget, widget);
3134     
3135     Node *node = nodeForWidget(widget);
3136     if (node)
3137         return frameForNode(node);
3138     
3139     // Assume all widgets are either form controls, or FrameViews.
3140     ASSERT(widget->isFrameView());
3141     return static_cast<const FrameView*>(widget)->frame();
3142 }
3143
3144 Frame *Frame::frameForNode(Node *node)
3145 {
3146     ASSERT_ARG(node, node);
3147     return node->document()->frame();
3148 }
3149
3150 Node* Frame::nodeForWidget(const Widget* widget)
3151 {
3152     ASSERT_ARG(widget, widget);
3153     WidgetClient* client = widget->client();
3154     if (!client)
3155         return 0;
3156     return client->element(const_cast<Widget*>(widget));
3157 }
3158
3159 void Frame::clearDocumentFocus(Widget *widget)
3160 {
3161     Node *node = nodeForWidget(widget);
3162     ASSERT(node);
3163     node->document()->setFocusNode(0);
3164 }
3165
3166 void Frame::updatePolicyBaseURL()
3167 {
3168     if (tree()->parent() && tree()->parent()->document())
3169         setPolicyBaseURL(tree()->parent()->document()->policyBaseURL());
3170     else
3171         setPolicyBaseURL(d->m_url.url());
3172 }
3173
3174 void Frame::setPolicyBaseURL(const String& s)
3175 {
3176     if (document())
3177         document()->setPolicyBaseURL(s);
3178     for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
3179         child->setPolicyBaseURL(s);
3180 }
3181
3182 void Frame::forceLayout()
3183 {
3184     FrameView *v = d->m_view.get();
3185     if (v) {
3186         v->layout(false);
3187         // We cannot unschedule a pending relayout, since the force can be called with
3188         // a tiny rectangle from a drawRect update.  By unscheduling we in effect
3189         // "validate" and stop the necessary full repaint from occurring.  Basically any basic
3190         // append/remove DHTML is broken by this call.  For now, I have removed the optimization
3191         // until we have a better invalidation stategy. -dwh
3192         //v->unscheduleRelayout();
3193     }
3194 }
3195
3196 void Frame::forceLayoutWithPageWidthRange(float minPageWidth, float maxPageWidth)
3197 {
3198     // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
3199     // the state of things before and after the layout
3200     RenderView *root = static_cast<RenderView*>(document()->renderer());
3201     if (root) {
3202         // This magic is basically copied from khtmlview::print
3203         int pageW = (int)ceilf(minPageWidth);
3204         root->setWidth(pageW);
3205         root->setNeedsLayoutAndMinMaxRecalc();
3206         forceLayout();
3207         
3208         // If we don't fit in the minimum page width, we'll lay out again. If we don't fit in the
3209         // maximum page width, we will lay out to the maximum page width and clip extra content.
3210         // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
3211         // implementation should not do this!
3212         int rightmostPos = root->rightmostPosition();
3213         if (rightmostPos > minPageWidth) {
3214             pageW = min(rightmostPos, (int)ceilf(maxPageWidth));
3215             root->setWidth(pageW);
3216             root->setNeedsLayoutAndMinMaxRecalc();
3217             forceLayout();
3218         }
3219     }
3220 }
3221
3222 void Frame::sendResizeEvent()
3223 {
3224     if (Document* doc = document())
3225         doc->dispatchWindowEvent(EventNames::resizeEvent, false, false);
3226 }
3227
3228 void Frame::sendScrollEvent()
3229 {
3230     FrameView *v = d->m_view.get();
3231     if (v) {
3232         Document *doc = document();
3233         if (!doc)
3234             return;
3235         doc->dispatchHTMLEvent(scrollEvent, true, false);
3236     }
3237 }
3238
3239 bool Frame::scrollbarsVisible()
3240 {
3241     if (!view())
3242         return false;
3243     
3244     if (view()->hScrollbarMode() == ScrollbarAlwaysOff || view()->vScrollbarMode() == ScrollbarAlwaysOff)
3245         return false;
3246     
3247     return true;
3248 }
3249
3250 void Frame::addMetaData(const String& key, const String& value)
3251 {
3252     d->m_metaData.set(key, value);
3253 }
3254
3255 // This does the same kind of work that Frame::openURL does, except it relies on the fact
3256 // that a higher level already checked that the URLs match and the scrolling is the right thing to do.
3257 void Frame::scrollToAnchor(const KURL& URL)
3258 {
3259     d->m_url = URL;
3260     started();
3261     
3262     gotoAnchor();
3263     
3264     // It's important to model this as a load that starts and immediately finishes.
3265     // Otherwise, the parent frame may think we never finished loading.
3266     d->m_bComplete = false;
3267     checkCompleted();
3268 }
3269
3270 bool Frame::closeURL()
3271 {
3272     saveDocumentState();
3273     stopLoading(true);
3274     clearUndoRedoOperations();
3275     return true;
3276 }
3277
3278 bool Frame::canMouseDownStartSelect(Node* node)
3279 {
3280     if (!node || !node->renderer())
3281         return true;
3282     
3283     // Check to see if -webkit-user-select has been set to none
3284     if (!node->renderer()->canSelect())
3285         return false;
3286     
3287     // Some controls and images can't start a select on a mouse down.
3288     for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) {
3289         if (curr->style()->userSelect() == SELECT_IGNORE)
3290             return false;
3291     }
3292     
3293     return true;
3294 }
3295
3296 void Frame::clearTimers(FrameView *view)
3297 {
3298     if (view) {
3299         view->unscheduleRelayout();
3300         if (view->frame()) {
3301             Document* document = view->frame()->document();
3302             if (document && document->renderer() && document->renderer()->layer())
3303                 document->renderer()->layer()->suspendMarquees();
3304         }
3305     }
3306 }
3307
3308 void Frame::clearTimers()
3309 {
3310     clearTimers(d->m_view.get());
3311 }
3312
3313 RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const
3314 {
3315     nodeToRemove = 0;
3316     
3317     if (!document())
3318         return 0;
3319     if (selectionController()->isNone())
3320         return 0;
3321     
3322     Position pos = selectionController()->selection().visibleStart().deepEquivalent();
3323     if (!pos.inRenderedContent())
3324         return 0;
3325     Node *node = pos.node();
3326     if (!node)
3327         return 0;
3328     
3329     if (!d->m_typingStyle)
3330         return node->renderer()->style();
3331     
3332     ExceptionCode ec = 0;
3333     RefPtr<Element> styleElement = document()->createElementNS(xhtmlNamespaceURI, "span", ec);
3334     ASSERT(ec == 0);
3335     
3336     styleElement->setAttribute(styleAttr, d->m_typingStyle->cssText().impl(), ec);
3337     ASSERT(ec == 0);
3338     
3339     styleElement->appendChild(document()->createEditingTextNode(""), ec);
3340     ASSERT(ec == 0);
3341     
3342     node->parentNode()->appendChild(styleElement, ec);
3343     ASSERT(ec == 0);
3344     
3345     nodeToRemove = styleElement.get();    
3346     return styleElement->renderer()->style();
3347 }
3348
3349 void Frame::setMediaType(const String& type)
3350 {
3351     if (d->m_view)
3352         d->m_view->setMediaType(type);
3353 }
3354
3355 void Frame::setSelectionFromNone()
3356 {
3357     // Put a caret inside the body if the entire frame is editable (either the 
3358     // entire WebView is editable or designMode is on for this document).
3359     Document *doc = document();
3360     if (!doc || !selectionController()->isNone() || !isContentEditable())
3361         return;
3362         
3363     Node* node = doc->documentElement();
3364     while (node && !node->hasTagName(bodyTag))
3365         node = node->traverseNextNode();
3366     if (node)
3367         selectionController()->setSelection(Selection(Position(node, 0), DOWNSTREAM));
3368 }
3369
3370 bool Frame::isActive() const
3371 {
3372     return d->m_isActive;
3373 }
3374
3375 void Frame::setIsActive(bool flag)
3376 {
3377     if (d->m_isActive == flag)
3378         return;
3379     
3380     d->m_isActive = flag;
3381
3382     // This method does the job of updating the view based on whether the view is "active".
3383     // This involves three kinds of drawing updates:
3384
3385     // 1. The background color used to draw behind selected content (active | inactive color)
3386     if (d->m_view)
3387         d->m_view->updateContents(enclosingIntRect(visibleSelectionRect()));
3388
3389     // 2. Caret blinking (blinks | does not blink)
3390     if (flag)
3391         setSelectionFromNone();
3392     setCaretVisible(flag);
3393     
3394     // 3. The drawing of a focus ring around links in web pages.
3395     Document *doc = document();
3396     if (doc) {
3397         Node *node = doc->focusNode();
3398         if (node) {
3399             node->setChanged();
3400             if (node->renderer() && node->renderer()->style()->hasAppearance())
3401                 theme()->stateChanged(node->renderer(), FocusState);
3402         }
3403     }
3404     
3405     // 4. Changing the tint of controls from clear to aqua/graphite and vice versa.  We
3406     // do a "fake" paint.  When the theme gets a paint call, it can then do an invalidate.  This is only
3407     // done if the theme supports control tinting.
3408     if (doc && d->m_view && theme()->supportsControlTints() && renderer()) {
3409         doc->updateLayout(); // Ensure layout is up to date.
3410         IntRect visibleRect(enclosingIntRect(d->m_view->visibleContentRect()));
3411         GraphicsContext context((PlatformGraphicsContext*)0);
3412         context.setUpdatingControlTints(true);
3413         paint(&context, visibleRect);
3414     }
3415    
3416     // 5. Enable or disable secure keyboard entry
3417     if ((flag && !isSecureKeyboardEntry() && doc && doc->focusNode() && doc->focusNode()->hasTagName(inputTag) && 
3418             static_cast<HTMLInputElement*>(doc->focusNode())->inputType() == HTMLInputElement::PASSWORD) ||
3419         (!flag && isSecureKeyboardEntry()))
3420             setSecureKeyboardEntry(flag);
3421 }
3422
3423 void Frame::setWindowHasFocus(bool flag)
3424 {
3425     if (d->m_windowHasFocus == flag)
3426         return;
3427     d->m_windowHasFocus = flag;
3428     
3429     if (Document *doc = document())
3430         doc->dispatchWindowEvent(flag ? focusEvent : blurEvent, false, false);
3431 }
3432
3433 bool Frame::inViewSourceMode() const
3434 {
3435     return d->m_inViewSourceMode;
3436 }
3437
3438 void Frame::setInViewSourceMode(bool mode) const
3439 {
3440     d->m_inViewSourceMode = mode;
3441 }
3442   
3443 UChar Frame::backslashAsCurrencySymbol() const
3444 {
3445     Document *doc = document();
3446     if (!doc)
3447         return '\\';
3448     Decoder *decoder = doc->decoder();
3449     if (!decoder)
3450         return '\\';
3451
3452     return decoder->encoding().backslashAsCurrencySymbol();
3453 }
3454
3455 bool Frame::markedTextUsesUnderlines() const
3456 {
3457     return d->m_markedTextUsesUnderlines;
3458 }
3459
3460 const Vector<MarkedTextUnderline>& Frame::markedTextUnderlines() const
3461 {
3462     return d->m_markedTextUnderlines;
3463 }
3464
3465 // Searches from the beginning of the document if nothing is selected.
3466 bool Frame::findString(const String& target, bool forward, bool caseFlag, bool wrapFlag)
3467 {
3468     if (target.isEmpty())
3469         return false;
3470     
3471     // Initially search from the start (if forward) or end (if backward) of the selection, and search to edge of document.
3472     RefPtr<Range> searchRange(rangeOfContents(document()));
3473     Selection selection(selectionController()->selection());
3474     if (!selection.isNone()) {
3475         if (forward)
3476             setStart(searchRange.get(), selection.visibleStart());
3477         else
3478             setEnd(searchRange.get(), selection.visibleEnd());
3479     }
3480     RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, forward, caseFlag));
3481     // If the found range is already selected, find again.
3482     // Build a selection with the found range to remove collapsed whitespace.
3483     // Compare ranges instead of selection objects to ignore the way that the current selection was made.
3484     if (!selection.isNone() && *Selection(resultRange.get()).toRange() == *selection.toRange()) {
3485         searchRange = rangeOfContents(document());
3486         if (forward)
3487             setStart(searchRange.get(), selection.visibleEnd());
3488         else
3489             setEnd(searchRange.get(), selection.visibleStart());
3490         resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
3491     }
3492     
3493     int exception = 0;
3494     
3495     // If we didn't find anything and we're wrapping, search again in the entire document (this will
3496     // redundantly re-search the area already searched in some cases).
3497     if (resultRange->collapsed(exception) && wrapFlag) {
3498         searchRange = rangeOfContents(document());
3499         resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
3500         // We used to return false here if we ended up with the same range that we started with
3501         // (e.g., the selection was already the only instance of this text). But we decided that
3502         // this should be a success case instead, so we'll just fall through in that case.
3503     }
3504
3505     if (resultRange->collapsed(exception))
3506         return false;
3507
3508     selectionController()->setSelection(Selection(resultRange.get(), DOWNSTREAM));
3509     revealSelection();
3510     return true;
3511 }
3512
3513 unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsigned limit)
3514 {
3515     if (target.isEmpty())
3516         return 0;
3517     
3518     RefPtr<Range> searchRange(rangeOfContents(document()));
3519     
3520     int exception = 0;
3521     unsigned matchCount = 0;
3522     do {
3523         RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, caseFlag));
3524         if (resultRange->collapsed(exception))
3525             break;
3526         
3527         // A non-collapsed result range can in some funky whitespace cases still not
3528         // advance the range's start position (4509328). Break to avoid infinite loop.
3529         VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
3530         if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
3531             break;
3532
3533         ++matchCount;
3534         
3535         document()->addMarker(resultRange.get(), DocumentMarker::TextMatch);        
3536         
3537         // Stop looking if we hit the specified limit. A limit of 0 means no limit.
3538         if (limit > 0 && matchCount >= limit)
3539             break;
3540         
3541         setStart(searchRange.get(), newStart);
3542     } while (true);
3543     
3544     // Do a "fake" paint in order to execute the code that computes the rendered rect for 
3545     // each text match.
3546     Document* doc = document();
3547     if (doc && d->m_view && renderer()) {
3548         doc->updateLayout(); // Ensure layout is up to date.
3549         IntRect visibleRect(enclosingIntRect(d->m_view->visibleContentRect()));
3550         GraphicsContext context((PlatformGraphicsContext*)0);
3551         context.setPaintingDisabled(true);
3552         paint(&context, visibleRect);
3553     }
3554     
3555     return matchCount;
3556 }
3557
3558 bool Frame::markedTextMatchesAreHighlighted() const
3559 {
3560     return d->m_highlightTextMatches;
3561 }
3562
3563 void Frame::setMarkedTextMatchesAreHighlighted(bool flag)
3564 {
3565     if (flag == d->m_highlightTextMatches)
3566         return;
3567     
3568     d->m_highlightTextMatches = flag;
3569     document()->repaintMarkers(DocumentMarker::TextMatch);
3570 }
3571
3572 void Frame::prepareForUserAction()
3573 {
3574     // Reset the multiple form submission protection code.
3575     // We'll let you submit the same form twice if you do two separate user actions.
3576     d->m_submittedFormURL = KURL();
3577 }
3578
3579 Node *Frame::mousePressNode()
3580 {
3581     return d->m_mousePressNode.get();
3582 }
3583
3584 bool Frame::isComplete() const
3585 {
3586     return d->m_bComplete;
3587 }
3588
3589 bool Frame::isLoadingMainResource() const
3590 {
3591     return d->m_bLoadingMainResource;
3592 }
3593
3594 FrameTree* Frame::tree() const
3595 {
3596     return &d->m_treeNode;
3597 }
3598
3599 DOMWindow* Frame::domWindow() const
3600 {
3601     if (!d->m_domWindow)
3602         d->m_domWindow = new DOMWindow(const_cast<Frame*>(this));
3603
3604     return d->m_domWindow.get();
3605 }
3606
3607 KURL Frame::url() const
3608 {
3609     return d->m_url;
3610 }
3611
3612 void Frame::startRedirectionTimer()
3613 {
3614     d->m_redirectionTimer.startOneShot(d->m_delayRedirect);
3615 }
3616
3617 void Frame::stopRedirectionTimer()
3618 {
3619     d->m_redirectionTimer.stop();
3620 }
3621
3622 void Frame::frameDetached()
3623 {
3624 }
3625
3626 void Frame::detachChildren()
3627 {
3628     // FIXME: is it really necessary to do this in reverse order any more?
3629     while (Frame* child = tree()->lastChild())
3630         tree()->removeChild(child);
3631 }
3632
3633 void Frame::updateBaseURLForEmptyDocument()
3634 {
3635     Element* owner = ownerElement();
3636     // FIXME: Should embed be included?
3637     if (owner && (owner->hasTagName(iframeTag) || owner->hasTagName(objectTag) || owner->hasTagName(embedTag)))
3638         d->m_doc->setBaseURL(tree()->parent()->d->m_doc->baseURL());
3639 }
3640
3641 Page* Frame::page() const
3642 {
3643     return d->m_page;
3644 }
3645
3646 void Frame::pageDestroyed()
3647 {
3648     d->m_page = 0;
3649
3650     // This will stop any JS timers
3651     if (d->m_jscript && d->m_jscript->haveInterpreter())
3652         if (Window* w = Window::retrieveWindow(this))
3653             w->disconnectFrame();
3654 }
3655
3656 void Frame::completed(bool complete)
3657 {
3658     ref();
3659     for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
3660         child->parentCompleted();
3661     if (Frame* parent = tree()->parent())
3662         parent->childCompleted(complete);
3663     submitFormAgain();
3664     deref();
3665 }
3666
3667 void Frame::setStatusBarText(const String&)
3668 {
3669 }
3670
3671 void Frame::started()
3672 {
3673     for (Frame* frame = this; frame; frame = frame->tree()->parent())
3674         frame->d->m_bComplete = false;
3675 }
3676
3677 void Frame::disconnectOwnerElement()
3678 {
3679     if (d->m_ownerElement && d->m_page)
3680         d->m_page->decrementFrameCount();
3681         
3682     d->m_ownerElement = 0;
3683 }
3684
3685 String Frame::documentTypeString() const
3686 {
3687     if (Document *doc = document())
3688         if (DocumentType *doctype = doc->realDocType())
3689             return doctype->toString();
3690
3691     return String();
3692 }
3693
3694 bool Frame::containsPlugins() const 
3695
3696     return d->m_plugins.size() != 0;
3697 }
3698
3699 bool Frame::prohibitsScrolling() const
3700 {
3701     return d->m_prohibitsScrolling;
3702 }
3703
3704 void Frame::setProhibitsScrolling(const bool prohibit)
3705 {
3706     d->m_prohibitsScrolling = prohibit;
3707 }
3708
3709 } // namespace WebCore