833a0860af8091ae5de2d813197c70429ba6acac
[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 "DOMWindow.h"
39 #include "DocLoader.h"
40 #include "DocumentType.h"
41 #include "EditingText.h"
42 #include "EditorClient.h"
43 #include "Event.h"
44 #include "EventNames.h"
45 #include "FloatRect.h"
46 #include "Frame.h"
47 #include "FrameLoader.h"
48 #include "FrameLoadRequest.h"
49 #include "FrameView.h"
50 #include "GraphicsContext.h"
51 #include "HTMLFormElement.h"
52 #include "HTMLFrameElement.h"
53 #include "HTMLGenericFormElement.h"
54 #include "HTMLInputElement.h"
55 #include "HTMLNames.h"
56 #include "HTMLObjectElement.h"
57 #include "HTMLViewSourceDocument.h"
58 #include "HitTestRequest.h"
59 #include "HitTestResult.h"
60 #include "IconDatabase.h"
61 #include "IconLoader.h"
62 #include "ImageDocument.h"
63 #include "IndentOutdentCommand.h"
64 #include "MediaFeatureNames.h"
65 #include "MouseEventWithHitTestResults.h"
66 #include "NodeList.h"
67 #include "Page.h"
68 #include "PlatformScrollBar.h"
69 #include "PlugInInfoStore.h"
70 #include "Plugin.h"
71 #include "PluginDocument.h"
72 #include "RenderListBox.h"
73 #include "RenderObject.h"
74 #include "RenderPart.h"
75 #include "RenderTextControl.h"
76 #include "RenderTheme.h"
77 #include "RenderView.h"
78 #include "SegmentedString.h"
79 #include "TextDocument.h"
80 #include "TextIterator.h"
81 #include "TextResourceDecoder.h"
82 #include "TypingCommand.h"
83 #include "XMLTokenizer.h"
84 #include "cssstyleselector.h"
85 #include "htmlediting.h"
86 #include "kjs_proxy.h"
87 #include "kjs_window.h"
88 #include "markup.h"
89 #include "visible_units.h"
90 #include "xmlhttprequest.h"
91 #include <math.h>
92 #include <sys/types.h>
93 #include <wtf/Platform.h>
94
95 #if PLATFORM(MAC)
96 #include "FrameMac.h"
97 #endif
98
99 #if !PLATFORM(WIN_OS)
100 #include <unistd.h>
101 #endif
102
103 #ifdef SVG_SUPPORT
104 #include "SVGNames.h"
105 #include "XLinkNames.h"
106 #include "XMLNames.h"
107 #include "SVGDocument.h"
108 #include "SVGDocumentExtensions.h"
109 #endif
110
111 using namespace std;
112
113 using KJS::JSLock;
114 using KJS::JSValue;
115 using KJS::Location;
116 using KJS::PausedTimeouts;
117 using KJS::SavedProperties;
118 using KJS::SavedBuiltins;
119 using KJS::UString;
120 using KJS::Window;
121
122 namespace WebCore {
123
124 using namespace EventNames;
125 using namespace HTMLNames;
126
127 const double caretBlinkFrequency = 0.5;
128 const double autoscrollInterval = 0.1;
129
130 class UserStyleSheetLoader : public CachedResourceClient {
131 public:
132     UserStyleSheetLoader(Frame* frame, const String& url, DocLoader* docLoader)
133         : m_frame(frame)
134         , m_cachedSheet(docLoader->requestCSSStyleSheet(url, ""))
135     {
136         m_cachedSheet->ref(this);
137     }
138     ~UserStyleSheetLoader()
139     {
140         m_cachedSheet->deref(this);
141     }
142 private:
143     virtual void setCSSStyleSheet(const String& /*URL*/, const String& /*charset*/, const String& sheet)
144     {
145         m_frame->setUserStyleSheet(sheet);
146     }
147     Frame* m_frame;
148     CachedCSSStyleSheet* m_cachedSheet;
149 };
150
151 #ifndef NDEBUG
152 struct FrameCounter { 
153     static int count; 
154     ~FrameCounter() { if (count != 0) fprintf(stderr, "LEAK: %d Frame\n", count); }
155 };
156 int FrameCounter::count = 0;
157 static FrameCounter frameCounter;
158 #endif
159
160 static inline Frame* parentFromOwnerElement(Element* ownerElement)
161 {
162     if (!ownerElement)
163         return 0;
164     return ownerElement->document()->frame();
165 }
166
167 Frame::Frame(Page* page, Element* ownerElement, PassRefPtr<EditorClient> client) 
168     : d(new FramePrivate(page, parentFromOwnerElement(ownerElement), this, ownerElement, client))
169 {
170     AtomicString::init();
171     EventNames::init();
172     HTMLNames::init();
173     QualifiedName::init();
174     MediaFeatureNames::init();
175
176 #ifdef SVG_SUPPORT
177     SVGNames::init();
178     XLinkNames::init();
179     XMLNames::init();
180 #endif
181
182     if (!ownerElement)
183         page->setMainFrame(this);
184     else {
185         // FIXME: Frames were originally created with a refcount of 1.
186         // Leave this ref call here until we can straighten that out.
187         ref();
188         page->incrementFrameCount();
189     }
190
191 #ifndef NDEBUG
192     ++FrameCounter::count;
193 #endif
194 }
195
196 Frame::~Frame()
197 {
198     // FIXME: We should not be doing all this work inside the destructor
199
200     ASSERT(!d->m_lifeSupportTimer.isActive());
201
202 #ifndef NDEBUG
203     --FrameCounter::count;
204 #endif
205
206     if (d->m_jscript && d->m_jscript->haveInterpreter())
207         if (Window* w = Window::retrieveWindow(this)) {
208             w->disconnectFrame();
209             // Must clear the window pointer, otherwise we will not
210             // garbage-collect collect the window (inside the call to
211             // delete d below).
212             w = 0;
213         }
214
215     disconnectOwnerElement();
216     
217     if (d->m_domWindow)
218         d->m_domWindow->disconnectFrame();
219             
220     if (d->m_view) {
221         d->m_view->hide();
222         d->m_view->m_frame = 0;
223     }
224   
225     ASSERT(!d->m_lifeSupportTimer.isActive());
226
227     delete d->m_userStyleSheetLoader;
228     delete d;
229     d = 0;
230 }
231
232 FrameLoader* Frame::loader() const
233 {
234     return d->m_loader;
235 }
236
237 FrameView* Frame::view() const
238 {
239     return d->m_view.get();
240 }
241
242 void Frame::setView(FrameView* view)
243 {
244     // Detach the document now, so any onUnload handlers get run - if
245     // we wait until the view is destroyed, then things won't be
246     // hooked up enough for some JavaScript calls to work.
247     if (d->m_doc && view == 0)
248         d->m_doc->detach();
249
250     d->m_view = view;
251 }
252
253 bool Frame::javaScriptEnabled() const
254 {
255     return d->m_bJScriptEnabled;
256 }
257
258 KJSProxy *Frame::scriptProxy()
259 {
260     if (!d->m_bJScriptEnabled)
261         return 0;
262
263     if (!d->m_jscript)
264         d->m_jscript = new KJSProxy(this);
265
266     return d->m_jscript;
267 }
268
269 bool Frame::javaEnabled() const
270 {
271     return d->m_settings->isJavaEnabled();
272 }
273
274 bool Frame::pluginsEnabled() const
275 {
276     return d->m_bPluginsEnabled;
277 }
278
279 Document *Frame::document() const
280 {
281     if (d)
282         return d->m_doc.get();
283     return 0;
284 }
285
286 void Frame::setDocument(Document* newDoc)
287 {
288     if (d) {
289         if (d->m_doc)
290             d->m_doc->detach();
291         d->m_doc = newDoc;
292         if (newDoc)
293             newDoc->attach();
294     }
295 }
296
297 const Settings *Frame::settings() const
298 {
299   return d->m_settings;
300 }
301
302 void Frame::setUserStyleSheetLocation(const KURL& url)
303 {
304     delete d->m_userStyleSheetLoader;
305     d->m_userStyleSheetLoader = 0;
306     if (d->m_doc && d->m_doc->docLoader())
307         d->m_userStyleSheetLoader = new UserStyleSheetLoader(this, url.url(), d->m_doc->docLoader());
308 }
309
310 void Frame::setUserStyleSheet(const String& styleSheet)
311 {
312     delete d->m_userStyleSheetLoader;
313     d->m_userStyleSheetLoader = 0;
314     if (d->m_doc)
315         d->m_doc->setUserStyleSheet(styleSheet);
316 }
317
318 void Frame::setStandardFont(const String& name)
319 {
320     d->m_settings->setStdFontName(AtomicString(name));
321 }
322
323 void Frame::setFixedFont(const String& name)
324 {
325     d->m_settings->setFixedFontName(AtomicString(name));
326 }
327
328 String Frame::selectedText() const
329 {
330     return plainText(selectionController()->toRange().get());
331 }
332
333 SelectionController* Frame::selectionController() const
334 {
335     return &d->m_selectionController;
336 }
337
338 Editor* Frame::editor() const
339 {
340     return &d->m_editor;
341 }
342
343 CommandByName* Frame::command() const
344 {
345     return &d->m_command;
346 }
347
348 TextGranularity Frame::selectionGranularity() const
349 {
350     return d->m_selectionGranularity;
351 }
352
353 void Frame::setSelectionGranularity(TextGranularity granularity) const
354 {
355     d->m_selectionGranularity = granularity;
356 }
357
358 SelectionController* Frame::dragCaretController() const
359 {
360     return d->m_page->dragCaretController();
361 }
362
363 const Selection& Frame::mark() const
364 {
365     return d->m_mark;
366 }
367
368 void Frame::setMark(const Selection& s)
369 {
370     ASSERT(!s.base().node() || s.base().node()->document() == document());
371     ASSERT(!s.extent().node() || s.extent().node()->document() == document());
372     ASSERT(!s.start().node() || s.start().node()->document() == document());
373     ASSERT(!s.end().node() || s.end().node()->document() == document());
374
375     d->m_mark = s;
376 }
377
378 void Frame::notifyRendererOfSelectionChange(bool userTriggered)
379 {
380     RenderObject* renderer = 0;
381     if (selectionController()->rootEditableElement())
382         renderer = selectionController()->rootEditableElement()->shadowAncestorNode()->renderer();
383
384     // If the current selection is in a textfield or textarea, notify the renderer that the selection has changed
385     if (renderer && (renderer->isTextArea() || renderer->isTextField()))
386         static_cast<RenderTextControl*>(renderer)->selectionChanged(userTriggered);
387 }
388
389 void Frame::invalidateSelection()
390 {
391     selectionController()->setNeedsLayout();
392     selectionLayoutChanged();
393 }
394
395 void Frame::setCaretVisible(bool flag)
396 {
397     if (d->m_caretVisible == flag)
398         return;
399     clearCaretRectIfNeeded();
400     if (flag)
401         setFocusNodeIfNeeded();
402     d->m_caretVisible = flag;
403     selectionLayoutChanged();
404 }
405
406
407 void Frame::clearCaretRectIfNeeded()
408 {
409     if (d->m_caretPaint) {
410         d->m_caretPaint = false;
411         selectionController()->invalidateCaretRect();
412     }        
413 }
414
415 // Helper function that tells whether a particular node is an element that has an entire
416 // Frame and FrameView, a <frame>, <iframe>, or <object>.
417 static bool isFrameElement(const Node *n)
418 {
419     if (!n)
420         return false;
421     RenderObject *renderer = n->renderer();
422     if (!renderer || !renderer->isWidget())
423         return false;
424     Widget* widget = static_cast<RenderWidget*>(renderer)->widget();
425     return widget && widget->isFrameView();
426 }
427
428 void Frame::setFocusNodeIfNeeded()
429 {
430     if (!document() || selectionController()->isNone() || !d->m_isActive)
431         return;
432
433     Node* target = selectionController()->rootEditableElement();
434     if (target) {
435         RenderObject* renderer = target->renderer();
436
437         // Walk up the render tree to search for a node to focus.
438         // Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields.
439         while (renderer) {
440             // We don't want to set focus on a subframe when selecting in a parent frame,
441             // so add the !isFrameElement check here. There's probably a better way to make this
442             // work in the long term, but this is the safest fix at this time.
443             if (target && target->isMouseFocusable() && !isFrameElement(target)) {
444                 document()->setFocusNode(target);
445                 return;
446             }
447             renderer = renderer->parent();
448             if (renderer)
449                 target = renderer->element();
450         }
451         document()->setFocusNode(0);
452     }
453 }
454
455 void Frame::selectionLayoutChanged()
456 {
457     bool caretRectChanged = selectionController()->recomputeCaretRect();
458
459     bool shouldBlink = d->m_caretVisible
460         && selectionController()->isCaret() && selectionController()->isContentEditable();
461
462     // If the caret moved, stop the blink timer so we can restart with a
463     // black caret in the new location.
464     if (caretRectChanged || !shouldBlink)
465         d->m_caretBlinkTimer.stop();
466
467     // Start blinking with a black caret. Be sure not to restart if we're
468     // already blinking in the right location.
469     if (shouldBlink && !d->m_caretBlinkTimer.isActive()) {
470         d->m_caretBlinkTimer.startRepeating(caretBlinkFrequency);
471         d->m_caretPaint = true;
472     }
473
474     if (d->m_doc)
475         d->m_doc->updateSelection();
476 }
477
478 void Frame::setXPosForVerticalArrowNavigation(int x)
479 {
480     d->m_xPosForVerticalArrowNavigation = x;
481 }
482
483 int Frame::xPosForVerticalArrowNavigation() const
484 {
485     return d->m_xPosForVerticalArrowNavigation;
486 }
487
488 void Frame::caretBlinkTimerFired(Timer<Frame>*)
489 {
490     ASSERT(d->m_caretVisible);
491     ASSERT(selectionController()->isCaret());
492     bool caretPaint = d->m_caretPaint;
493     if (d->m_bMousePressed && caretPaint)
494         return;
495     d->m_caretPaint = !caretPaint;
496     selectionController()->invalidateCaretRect();
497 }
498
499 void Frame::paintCaret(GraphicsContext* p, const IntRect& rect) const
500 {
501     if (d->m_caretPaint && d->m_caretVisible)
502         selectionController()->paintCaret(p, rect);
503 }
504
505 void Frame::paintDragCaret(GraphicsContext* p, const IntRect& rect) const
506 {
507     SelectionController* dragCaretController = d->m_page->dragCaretController();
508     assert(dragCaretController->selection().isCaret());
509     if (dragCaretController->selection().start().node()->document()->frame() == this)
510         dragCaretController->paintCaret(p, rect);
511 }
512
513 int Frame::zoomFactor() const
514 {
515   return d->m_zoomFactor;
516 }
517
518 void Frame::setZoomFactor(int percent)
519 {  
520   if (d->m_zoomFactor == percent)
521       return;
522
523   d->m_zoomFactor = percent;
524
525   if (d->m_doc)
526       d->m_doc->recalcStyle(Node::Force);
527
528   for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
529       child->setZoomFactor(d->m_zoomFactor);
530
531   if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout())
532       view()->layout();
533 }
534
535 void Frame::setJSStatusBarText(const String& text)
536 {
537     d->m_kjsStatusBarText = text;
538     setStatusBarText(d->m_kjsStatusBarText);
539 }
540
541 void Frame::setJSDefaultStatusBarText(const String& text)
542 {
543     d->m_kjsDefaultStatusBarText = text;
544     setStatusBarText(d->m_kjsDefaultStatusBarText);
545 }
546
547 String Frame::jsStatusBarText() const
548 {
549     return d->m_kjsStatusBarText;
550 }
551
552 String Frame::jsDefaultStatusBarText() const
553 {
554    return d->m_kjsDefaultStatusBarText;
555 }
556
557 void Frame::reparseConfiguration()
558 {
559     if (d->m_doc)
560         d->m_doc->docLoader()->setAutoLoadImages(d->m_settings->autoLoadImages());
561         
562     d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled();
563     d->m_bJavaEnabled = d->m_settings->isJavaEnabled();
564     d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled();
565
566     const KURL& userStyleSheetLocation = d->m_settings->userStyleSheetLocation();
567     if (!userStyleSheetLocation.isEmpty())
568         setUserStyleSheetLocation(userStyleSheetLocation);
569     else
570         setUserStyleSheet(String());
571
572     // FIXME: It's not entirely clear why the following is needed.
573     // The document automatically does this as required when you set the style sheet.
574     // But we had problems when this code was removed. Details are in
575     // <http://bugs.webkit.org/show_bug.cgi?id=8079>.
576     if (d->m_doc)
577         d->m_doc->updateStyleSelector();
578 }
579
580 bool Frame::shouldDragAutoNode(Node *node, const IntPoint& point) const
581 {
582     return false;
583 }
584
585 void Frame::selectClosestWordFromMouseEvent(const PlatformMouseEvent& mouse, Node *innerNode)
586 {
587     Selection newSelection;
588
589     if (innerNode && innerNode->renderer() && mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
590         IntPoint vPoint = view()->windowToContents(mouse.pos());
591         VisiblePosition pos(innerNode->renderer()->positionForPoint(vPoint));
592         if (pos.isNotNull()) {
593             newSelection = Selection(pos);
594             newSelection.expandUsingGranularity(WordGranularity);
595         }
596     }
597     
598     if (newSelection.isRange()) {
599         d->m_selectionGranularity = WordGranularity;
600         d->m_beganSelectingText = true;
601     }
602     
603     if (shouldChangeSelection(newSelection))
604         selectionController()->setSelection(newSelection);
605 }
606
607 void Frame::handleMousePressEventDoubleClick(const MouseEventWithHitTestResults& event)
608 {
609     if (event.event().button() == LeftButton) {
610         if (selectionController()->isRange())
611             // A double-click when range is already selected
612             // should not change the selection.  So, do not call
613             // selectClosestWordFromMouseEvent, but do set
614             // m_beganSelectingText to prevent handleMouseReleaseEvent
615             // from setting caret selection.
616             d->m_beganSelectingText = true;
617         else
618             selectClosestWordFromMouseEvent(event.event(), event.targetNode());
619     }
620 }
621
622 void Frame::handleMousePressEventTripleClick(const MouseEventWithHitTestResults& event)
623 {
624     Node *innerNode = event.targetNode();
625     
626     if (event.event().button() == LeftButton && innerNode && innerNode->renderer() &&
627         mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
628         Selection newSelection;
629         IntPoint vPoint = view()->windowToContents(event.event().pos());
630         VisiblePosition pos(innerNode->renderer()->positionForPoint(vPoint));
631         if (pos.isNotNull()) {
632             newSelection = Selection(pos);
633             newSelection.expandUsingGranularity(ParagraphGranularity);
634         }
635         if (newSelection.isRange()) {
636             d->m_selectionGranularity = ParagraphGranularity;
637             d->m_beganSelectingText = true;
638         }
639         
640         if (shouldChangeSelection(newSelection))
641             selectionController()->setSelection(newSelection);
642     }
643 }
644
645 void Frame::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event)
646 {
647     Node *innerNode = event.targetNode();
648     
649     if (event.event().button() == LeftButton) {
650         if (innerNode && innerNode->renderer() &&
651             mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
652             
653             // Extend the selection if the Shift key is down, unless the click is in a link.
654             bool extendSelection = event.event().shiftKey() && !event.isOverLink();
655
656             // Don't restart the selection when the mouse is pressed on an
657             // existing selection so we can allow for text dragging.
658             IntPoint vPoint = view()->windowToContents(event.event().pos());
659             if (!extendSelection && selectionController()->contains(vPoint))
660                 return;
661
662             VisiblePosition visiblePos(innerNode->renderer()->positionForPoint(vPoint));
663             if (visiblePos.isNull())
664                 visiblePos = VisiblePosition(innerNode, innerNode->caretMinOffset(), DOWNSTREAM);
665             Position pos = visiblePos.deepEquivalent();
666             
667             Selection newSelection = selectionController()->selection();
668             if (extendSelection && newSelection.isCaretOrRange()) {
669                 selectionController()->clearModifyBias();
670                 
671                 // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection 
672                 // was created right-to-left
673                 Position start = newSelection.start();
674                 Position end = newSelection.end();
675                 short before = Range::compareBoundaryPoints(pos.node(), pos.offset(), start.node(), start.offset());
676                 if (before <= 0)
677                     newSelection = Selection(pos, end);
678                 else
679                     newSelection = Selection(start, pos);
680
681                 if (d->m_selectionGranularity != CharacterGranularity)
682                     newSelection.expandUsingGranularity(d->m_selectionGranularity);
683                 d->m_beganSelectingText = true;
684             } else {
685                 newSelection = Selection(visiblePos);
686                 d->m_selectionGranularity = CharacterGranularity;
687             }
688             
689             if (shouldChangeSelection(newSelection))
690                 selectionController()->setSelection(newSelection);
691         }
692     }
693 }
694
695 void Frame::handleMousePressEvent(const MouseEventWithHitTestResults& event)
696 {
697     Node *innerNode = event.targetNode();
698
699     d->m_mousePressNode = innerNode;
700     d->m_dragStartPos = event.event().pos();
701
702     if (event.event().button() == LeftButton || event.event().button() == MiddleButton) {
703         d->m_bMousePressed = true;
704         d->m_beganSelectingText = false;
705
706         if (event.event().clickCount() == 2) {
707             handleMousePressEventDoubleClick(event);
708             return;
709         }
710         if (event.event().clickCount() >= 3) {
711             handleMousePressEventTripleClick(event);
712             return;
713         }
714         handleMousePressEventSingleClick(event);
715     }
716     
717    setMouseDownMayStartAutoscroll(mouseDownMayStartSelect() || 
718         (d->m_mousePressNode && d->m_mousePressNode->renderer() && d->m_mousePressNode->renderer()->shouldAutoscroll()));
719 }
720
721 void Frame::handleMouseMoveEvent(const MouseEventWithHitTestResults& event)
722 {
723     // Mouse not pressed. Do nothing.
724     if (!d->m_bMousePressed)
725         return;
726
727     Node *innerNode = event.targetNode();
728
729     if (event.event().button() != 0 || !innerNode || !innerNode->renderer())
730         return;
731
732     ASSERT(mouseDownMayStartSelect() || mouseDownMayStartAutoscroll());
733
734     setMouseDownMayStartDrag(false);
735     view()->invalidateClick();
736
737      if (mouseDownMayStartAutoscroll()) {            
738         // If the selection is contained in a layer that can scroll, that layer should handle the autoscroll
739         // Otherwise, let the bridge handle it so the view can scroll itself.
740         RenderObject* renderer = innerNode->renderer();
741         while (renderer && !renderer->shouldAutoscroll())
742             renderer = renderer->parent();
743         if (renderer)
744             handleAutoscroll(renderer);
745     }
746     
747     if (mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
748         // handle making selection
749         IntPoint vPoint = view()->windowToContents(event.event().pos());        
750         VisiblePosition pos(innerNode->renderer()->positionForPoint(vPoint));
751
752         updateSelectionForMouseDragOverPosition(pos);
753     }
754
755 }
756
757 void Frame::updateSelectionForMouseDragOverPosition(const VisiblePosition& pos)
758 {
759     // Don't modify the selection if we're not on a node.
760     if (pos.isNull())
761         return;
762
763     // Restart the selection if this is the first mouse move. This work is usually
764     // done in handleMousePressEvent, but not if the mouse press was on an existing selection.
765     Selection newSelection = selectionController()->selection();
766     selectionController()->clearModifyBias();
767     
768     if (!d->m_beganSelectingText) {
769         d->m_beganSelectingText = true;
770         newSelection = Selection(pos);
771     }
772
773     newSelection.setExtent(pos);
774     if (d->m_selectionGranularity != CharacterGranularity)
775         newSelection.expandUsingGranularity(d->m_selectionGranularity);
776
777     if (shouldChangeSelection(newSelection))
778         selectionController()->setSelection(newSelection);
779 }
780
781 void Frame::handleMouseReleaseEvent(const MouseEventWithHitTestResults& event)
782 {
783     stopAutoscrollTimer();
784     
785     // Used to prevent mouseMoveEvent from initiating a drag before
786     // the mouse is pressed again.
787     d->m_bMousePressed = false;
788   
789     // Clear the selection if the mouse didn't move after the last mouse press.
790     // We do this so when clicking on the selection, the selection goes away.
791     // However, if we are editing, place the caret.
792     if (mouseDownMayStartSelect() && !d->m_beganSelectingText
793             && d->m_dragStartPos == event.event().pos()
794             && selectionController()->isRange()) {
795         Selection newSelection;
796         Node *node = event.targetNode();
797         if (node && node->isContentEditable() && node->renderer()) {
798             IntPoint vPoint = view()->windowToContents(event.event().pos());
799             VisiblePosition pos = node->renderer()->positionForPoint(vPoint);
800             newSelection = Selection(pos);
801         }
802         if (shouldChangeSelection(newSelection))
803             selectionController()->setSelection(newSelection);
804     }
805
806     notifyRendererOfSelectionChange(true);
807
808     selectionController()->selectFrameElementInParentIfFullySelected();
809 }
810
811 bool Frame::shouldChangeSelection(const Selection& newSelection) const
812 {
813     return shouldChangeSelection(selectionController()->selection(), newSelection, newSelection.affinity(), false);
814 }
815
816 bool Frame::shouldDeleteSelection(const Selection& newSelection) const
817 {
818     return true;
819 }
820
821 bool Frame::isContentEditable() const 
822 {
823     if (!d->m_doc)
824         return false;
825     return d->m_doc->inDesignMode();
826 }
827
828 void Frame::textFieldDidBeginEditing(Element* input)
829 {
830 }
831
832 void Frame::textFieldDidEndEditing(Element* input)
833 {
834 }
835
836 void Frame::textDidChangeInTextField(Element* input)
837 {
838 }
839
840 bool Frame::doTextFieldCommandFromEvent(Element* input, const PlatformKeyboardEvent* evt)
841 {
842     return false;
843 }
844
845 void Frame::textWillBeDeletedInTextField(Element* input)
846 {
847 }
848
849 void Frame::textDidChangeInTextArea(Element* input)
850 {
851 }
852
853 static void dispatchEditableContentChangedEvents(const EditCommand& command)
854 {
855      Element* startRoot = command.startingRootEditableElement();
856      Element* endRoot = command.endingRootEditableElement();
857      ExceptionCode ec;
858      if (startRoot)
859          startRoot->dispatchEvent(new Event(khtmlEditableContentChangedEvent, false, false), ec, true);
860      if (endRoot && endRoot != startRoot)
861          endRoot->dispatchEvent(new Event(khtmlEditableContentChangedEvent, false, false), ec, true);
862 }
863
864 void Frame::appliedEditing(PassRefPtr<EditCommand> cmd)
865 {
866     dispatchEditableContentChangedEvents(*cmd);
867  
868     Selection newSelection(cmd->endingSelection());
869     if (shouldChangeSelection(newSelection))
870         selectionController()->setSelection(newSelection, false);
871     
872     // Now set the typing style from the command. Clear it when done.
873     // This helps make the case work where you completely delete a piece
874     // of styled text and then type a character immediately after.
875     // That new character needs to take on the style of the just-deleted text.
876     // FIXME: Improve typing style.
877     // See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
878     if (cmd->typingStyle()) {
879         setTypingStyle(cmd->typingStyle());
880         cmd->setTypingStyle(0);
881     }
882
883     // Command will be equal to last edit command only in the case of typing
884     if (editor()->lastEditCommand() == cmd)
885         assert(cmd->isTypingCommand());
886     else {
887         // Only register a new undo command if the command passed in is
888         // different from the last command
889         editor()->setLastEditCommand(cmd.get());
890         registerCommandForUndo(cmd);
891     }
892     respondToChangedContents(newSelection);
893     editor()->respondToChangedContents();
894 }
895
896 void Frame::unappliedEditing(PassRefPtr<EditCommand> cmd)
897 {
898     dispatchEditableContentChangedEvents(*cmd);
899
900     Selection newSelection(cmd->startingSelection());
901     if (shouldChangeSelection(newSelection))
902         selectionController()->setSelection(newSelection, true);
903         
904     editor()->setLastEditCommand(0);
905     registerCommandForRedo(cmd);
906     respondToChangedContents(newSelection);
907     editor()->respondToChangedContents();
908 }
909
910 void Frame::reappliedEditing(PassRefPtr<EditCommand> cmd)
911 {
912     dispatchEditableContentChangedEvents(*cmd);
913
914     Selection newSelection(cmd->endingSelection());
915     if (shouldChangeSelection(newSelection))
916         selectionController()->setSelection(newSelection, true);
917         
918     editor()->setLastEditCommand(0);
919     registerCommandForUndo(cmd);
920     respondToChangedContents(newSelection);
921     editor()->respondToChangedContents();
922 }
923
924 CSSMutableStyleDeclaration *Frame::typingStyle() const
925 {
926     return d->m_typingStyle.get();
927 }
928
929 void Frame::setTypingStyle(CSSMutableStyleDeclaration *style)
930 {
931     d->m_typingStyle = style;
932 }
933
934 void Frame::clearTypingStyle()
935 {
936     d->m_typingStyle = 0;
937 }
938
939 bool Frame::tabsToLinks() const
940 {
941     return true;
942 }
943
944 bool Frame::tabsToAllControls() const
945 {
946     return true;
947 }
948
949 void Frame::copyToPasteboard()
950 {
951     issueCopyCommand();
952 }
953
954 void Frame::cutToPasteboard()
955 {
956     issueCutCommand();
957 }
958
959 void Frame::pasteFromPasteboard()
960 {
961     issuePasteCommand();
962 }
963
964 void Frame::pasteAndMatchStyle()
965 {
966     issuePasteAndMatchStyleCommand();
967 }
968
969 void Frame::transpose()
970 {
971     issueTransposeCommand();
972 }
973
974 void Frame::redo()
975 {
976     issueRedoCommand();
977 }
978
979 void Frame::undo()
980 {
981     issueUndoCommand();
982 }
983
984
985 void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction editingAction)
986 {
987     if (!style || style->length() == 0) {
988         clearTypingStyle();
989         return;
990     }
991
992     // Calculate the current typing style.
993     RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
994     if (typingStyle()) {
995         typingStyle()->merge(mutableStyle.get());
996         mutableStyle = typingStyle();
997     }
998
999     Node *node = selectionController()->selection().visibleStart().deepEquivalent().node();
1000     CSSComputedStyleDeclaration computedStyle(node);
1001     computedStyle.diff(mutableStyle.get());
1002     
1003     // Handle block styles, substracting these from the typing style.
1004     RefPtr<CSSMutableStyleDeclaration> blockStyle = mutableStyle->copyBlockProperties();
1005     blockStyle->diff(mutableStyle.get());
1006     if (document() && blockStyle->length() > 0)
1007         applyCommand(new ApplyStyleCommand(document(), blockStyle.get(), editingAction));
1008     
1009     // Set the remaining style as the typing style.
1010     d->m_typingStyle = mutableStyle.release();
1011 }
1012
1013 static void updateState(CSSMutableStyleDeclaration *desiredStyle, CSSComputedStyleDeclaration *computedStyle, bool& atStart, Frame::TriState& state)
1014 {
1015     DeprecatedValueListConstIterator<CSSProperty> end;
1016     for (DeprecatedValueListConstIterator<CSSProperty> it = desiredStyle->valuesIterator(); it != end; ++it) {
1017         int propertyID = (*it).id();
1018         String desiredProperty = desiredStyle->getPropertyValue(propertyID);
1019         String computedProperty = computedStyle->getPropertyValue(propertyID);
1020         Frame::TriState propertyState = equalIgnoringCase(desiredProperty, computedProperty)
1021             ? Frame::trueTriState : Frame::falseTriState;
1022         if (atStart) {
1023             state = propertyState;
1024             atStart = false;
1025         } else if (state != propertyState) {
1026             state = Frame::mixedTriState;
1027             break;
1028         }
1029     }
1030 }
1031
1032 Frame::TriState Frame::selectionHasStyle(CSSStyleDeclaration *style) const
1033 {
1034     bool atStart = true;
1035     TriState state = falseTriState;
1036
1037     RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
1038
1039     if (!selectionController()->isRange()) {
1040         Node* nodeToRemove;
1041         RefPtr<CSSComputedStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
1042         if (!selectionStyle)
1043             return falseTriState;
1044         updateState(mutableStyle.get(), selectionStyle.get(), atStart, state);
1045         if (nodeToRemove) {
1046             ExceptionCode ec = 0;
1047             nodeToRemove->remove(ec);
1048             assert(ec == 0);
1049         }
1050     } else {
1051         for (Node* node = selectionController()->start().node(); node; node = node->traverseNextNode()) {
1052             RefPtr<CSSComputedStyleDeclaration> computedStyle = new CSSComputedStyleDeclaration(node);
1053             if (computedStyle)
1054                 updateState(mutableStyle.get(), computedStyle.get(), atStart, state);
1055             if (state == mixedTriState)
1056                 break;
1057             if (node == selectionController()->end().node())
1058                 break;
1059         }
1060     }
1061
1062     return state;
1063 }
1064
1065 String Frame::selectionStartStylePropertyValue(int stylePropertyID) const
1066 {
1067     Node *nodeToRemove;
1068     RefPtr<CSSStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
1069     if (!selectionStyle)
1070         return String();
1071
1072     String value = selectionStyle->getPropertyValue(stylePropertyID);
1073
1074     if (nodeToRemove) {
1075         ExceptionCode ec = 0;
1076         nodeToRemove->remove(ec);
1077         assert(ec == 0);
1078     }
1079
1080     return value;
1081 }
1082
1083 CSSComputedStyleDeclaration *Frame::selectionComputedStyle(Node *&nodeToRemove) const
1084 {
1085     nodeToRemove = 0;
1086
1087     if (!document())
1088         return 0;
1089
1090     if (selectionController()->isNone())
1091         return 0;
1092
1093     RefPtr<Range> range(selectionController()->toRange());
1094     Position pos = range->editingStartPosition();
1095
1096     Element *elem = pos.element();
1097     if (!elem)
1098         return 0;
1099     
1100     RefPtr<Element> styleElement = elem;
1101     ExceptionCode ec = 0;
1102
1103     if (d->m_typingStyle) {
1104         styleElement = document()->createElementNS(xhtmlNamespaceURI, "span", ec);
1105         assert(ec == 0);
1106
1107         styleElement->setAttribute(styleAttr, d->m_typingStyle->cssText().impl(), ec);
1108         assert(ec == 0);
1109         
1110         styleElement->appendChild(document()->createEditingTextNode(""), ec);
1111         assert(ec == 0);
1112
1113         if (elem->renderer() && elem->renderer()->canHaveChildren()) {
1114             elem->appendChild(styleElement, ec);
1115         } else {
1116             Node *parent = elem->parent();
1117             Node *next = elem->nextSibling();
1118
1119             if (next) {
1120                 parent->insertBefore(styleElement, next, ec);
1121             } else {
1122                 parent->appendChild(styleElement, ec);
1123             }
1124         }
1125         assert(ec == 0);
1126
1127         nodeToRemove = styleElement.get();
1128     }
1129
1130     return new CSSComputedStyleDeclaration(styleElement);
1131 }
1132
1133 void Frame::applyEditingStyleToBodyElement() const
1134 {
1135     if (!d->m_doc)
1136         return;
1137         
1138     RefPtr<NodeList> list = d->m_doc->getElementsByTagName("body");
1139     unsigned len = list->length();
1140     for (unsigned i = 0; i < len; i++) {
1141         applyEditingStyleToElement(static_cast<Element*>(list->item(i)));    
1142     }
1143 }
1144
1145 void Frame::removeEditingStyleFromBodyElement() const
1146 {
1147     if (!d->m_doc)
1148         return;
1149         
1150     RefPtr<NodeList> list = d->m_doc->getElementsByTagName("body");
1151     unsigned len = list->length();
1152     for (unsigned i = 0; i < len; i++) {
1153         removeEditingStyleFromElement(static_cast<Element*>(list->item(i)));    
1154     }
1155 }
1156
1157 void Frame::applyEditingStyleToElement(Element* element) const
1158 {
1159     if (!element)
1160         return;
1161
1162     CSSStyleDeclaration* style = element->style();
1163     ASSERT(style);
1164
1165     ExceptionCode ec = 0;
1166     style->setProperty(CSS_PROP_WORD_WRAP, "break-word", false, ec);
1167     ASSERT(ec == 0);
1168     style->setProperty(CSS_PROP__WEBKIT_NBSP_MODE, "space", false, ec);
1169     ASSERT(ec == 0);
1170     style->setProperty(CSS_PROP__WEBKIT_LINE_BREAK, "after-white-space", false, ec);
1171     ASSERT(ec == 0);
1172 }
1173
1174 void Frame::removeEditingStyleFromElement(Element*) const
1175 {
1176 }
1177
1178 bool Frame::isCharacterSmartReplaceExempt(UChar, bool)
1179 {
1180     // no smart replace
1181     return true;
1182 }
1183
1184 #ifndef NDEBUG
1185 static HashSet<Frame*> lifeSupportSet;
1186 #endif
1187
1188 void Frame::endAllLifeSupport()
1189 {
1190 #ifndef NDEBUG
1191     HashSet<Frame*> lifeSupportCopy = lifeSupportSet;
1192     HashSet<Frame*>::iterator end = lifeSupportCopy.end();
1193     for (HashSet<Frame*>::iterator it = lifeSupportCopy.begin(); it != end; ++it)
1194         (*it)->endLifeSupport();
1195 #endif
1196 }
1197
1198 void Frame::keepAlive()
1199 {
1200     if (d->m_lifeSupportTimer.isActive())
1201         return;
1202     ref();
1203 #ifndef NDEBUG
1204     lifeSupportSet.add(this);
1205 #endif
1206     d->m_lifeSupportTimer.startOneShot(0);
1207 }
1208
1209 void Frame::endLifeSupport()
1210 {
1211     if (!d->m_lifeSupportTimer.isActive())
1212         return;
1213     d->m_lifeSupportTimer.stop();
1214 #ifndef NDEBUG
1215     lifeSupportSet.remove(this);
1216 #endif
1217     deref();
1218 }
1219
1220 void Frame::lifeSupportTimerFired(Timer<Frame>*)
1221 {
1222 #ifndef NDEBUG
1223     lifeSupportSet.remove(this);
1224 #endif
1225     deref();
1226 }
1227
1228 bool Frame::mouseDownMayStartAutoscroll() const
1229 {
1230     return d->m_mouseDownMayStartAutoscroll;
1231 }
1232
1233 void Frame::setMouseDownMayStartAutoscroll(bool b)
1234 {
1235     d->m_mouseDownMayStartAutoscroll = b;
1236 }
1237
1238 bool Frame::mouseDownMayStartDrag() const
1239 {
1240     return d->m_mouseDownMayStartDrag;
1241 }
1242
1243 void Frame::setMouseDownMayStartDrag(bool b)
1244 {
1245     d->m_mouseDownMayStartDrag = b;
1246 }
1247
1248 void Frame::setSettings(Settings *settings)
1249 {
1250     d->m_settings = settings;
1251 }
1252
1253 RenderObject *Frame::renderer() const
1254 {
1255     Document *doc = document();
1256     return doc ? doc->renderer() : 0;
1257 }
1258
1259 Element* Frame::ownerElement()
1260 {
1261     return d->m_ownerElement;
1262 }
1263
1264 RenderPart* Frame::ownerRenderer()
1265 {
1266     Element* ownerElement = d->m_ownerElement;
1267     if (!ownerElement)
1268         return 0;
1269     return static_cast<RenderPart*>(ownerElement->renderer());
1270 }
1271
1272 IntRect Frame::selectionRect() const
1273 {
1274     RenderView *root = static_cast<RenderView*>(renderer());
1275     if (!root)
1276         return IntRect();
1277
1278     return root->selectionRect();
1279 }
1280
1281 // returns FloatRect because going through IntRect would truncate any floats
1282 FloatRect Frame::visibleSelectionRect() const
1283 {
1284     if (!d->m_view)
1285         return FloatRect();
1286     
1287     return intersection(selectionRect(), d->m_view->visibleContentRect());
1288 }
1289
1290 bool Frame::isFrameSet() const
1291 {
1292     Document* document = d->m_doc.get();
1293     if (!document || !document->isHTMLDocument())
1294         return false;
1295     Node *body = static_cast<HTMLDocument*>(document)->body();
1296     return body && body->renderer() && body->hasTagName(framesetTag);
1297 }
1298
1299 // Scans logically forward from "start", including any child frames
1300 static HTMLFormElement *scanForForm(Node *start)
1301 {
1302     Node *n;
1303     for (n = start; n; n = n->traverseNextNode()) {
1304         if (n->hasTagName(formTag))
1305             return static_cast<HTMLFormElement*>(n);
1306         else if (n->isHTMLElement() && static_cast<HTMLElement*>(n)->isGenericFormElement())
1307             return static_cast<HTMLGenericFormElement*>(n)->form();
1308         else if (n->hasTagName(frameTag) || n->hasTagName(iframeTag)) {
1309             Node *childDoc = static_cast<HTMLFrameElement*>(n)->contentDocument();
1310             if (HTMLFormElement *frameResult = scanForForm(childDoc))
1311                 return frameResult;
1312         }
1313     }
1314     return 0;
1315 }
1316
1317 // We look for either the form containing the current focus, or for one immediately after it
1318 HTMLFormElement *Frame::currentForm() const
1319 {
1320     // start looking either at the active (first responder) node, or where the selection is
1321     Node *start = d->m_doc ? d->m_doc->focusNode() : 0;
1322     if (!start)
1323         start = selectionController()->start().node();
1324     
1325     // try walking up the node tree to find a form element
1326     Node *n;
1327     for (n = start; n; n = n->parentNode()) {
1328         if (n->hasTagName(formTag))
1329             return static_cast<HTMLFormElement*>(n);
1330         else if (n->isHTMLElement()
1331                    && static_cast<HTMLElement*>(n)->isGenericFormElement())
1332             return static_cast<HTMLGenericFormElement*>(n)->form();
1333     }
1334     
1335     // try walking forward in the node tree to find a form element
1336     return start ? scanForForm(start) : 0;
1337 }
1338
1339 // FIXME: should this go in SelectionController?
1340 void Frame::revealSelection(const RenderLayer::ScrollAlignment& alignment) const
1341 {
1342     IntRect rect;
1343     
1344     switch (selectionController()->state()) {
1345         case Selection::NONE:
1346             return;
1347             
1348         case Selection::CARET:
1349             rect = selectionController()->caretRect();
1350             break;
1351             
1352         case Selection::RANGE:
1353             rect = selectionRect();
1354             break;
1355     }
1356
1357     Position start = selectionController()->start();
1358     Position end = selectionController()->end();
1359
1360     ASSERT(start.node());
1361     if (start.node() && start.node()->renderer()) {
1362         RenderLayer *layer = start.node()->renderer()->enclosingLayer();
1363         if (layer) {
1364             ASSERT(!end.node() || !end.node()->renderer() 
1365                    || (end.node()->renderer()->enclosingLayer() == layer));
1366             layer->scrollRectToVisible(rect, alignment, alignment);
1367         }
1368     }
1369 }
1370
1371 void Frame::revealCaret(const RenderLayer::ScrollAlignment& alignment) const
1372 {
1373     if (selectionController()->isNone())
1374         return;
1375
1376     Position extent = selectionController()->extent();
1377     if (extent.node() && extent.node()->renderer()) {
1378         IntRect extentRect = VisiblePosition(extent).caretRect();
1379         RenderLayer* layer = extent.node()->renderer()->enclosingLayer();
1380         if (layer)
1381             layer->scrollRectToVisible(extentRect, alignment, alignment);
1382     }
1383 }
1384
1385 // FIXME: should this be here?
1386 bool Frame::scrollOverflow(ScrollDirection direction, ScrollGranularity granularity)
1387 {
1388     if (!document()) {
1389         return false;
1390     }
1391     
1392     Node *node = document()->focusNode();
1393     if (node == 0) {
1394         node = d->m_mousePressNode.get();
1395     }
1396     
1397     if (node != 0) {
1398         RenderObject *r = node->renderer();
1399         if (r != 0 && !r->isListBox()) {
1400             return r->scroll(direction, granularity);
1401         }
1402     }
1403     
1404     return false;
1405 }
1406
1407 void Frame::handleAutoscroll(RenderObject* renderer)
1408 {
1409     if (d->m_autoscrollTimer.isActive())
1410         return;
1411     setAutoscrollRenderer(renderer);
1412     startAutoscrollTimer();
1413 }
1414
1415 void Frame::autoscrollTimerFired(Timer<Frame>*)
1416 {
1417     if (!d->m_bMousePressed){
1418         stopAutoscrollTimer();
1419         return;
1420     }
1421     if (RenderObject* r = autoscrollRenderer())
1422         r->autoscroll();
1423 }
1424
1425 RenderObject* Frame::autoscrollRenderer() const
1426 {
1427     return d->m_autoscrollRenderer;
1428 }
1429
1430 void Frame::setAutoscrollRenderer(RenderObject* renderer)
1431 {
1432     d->m_autoscrollRenderer = renderer;
1433 }
1434
1435 HitTestResult Frame::hitTestResultAtPoint(const IntPoint& point, bool allowShadowContent)
1436 {
1437     HitTestResult result(point);
1438     if (!renderer())
1439         return result;
1440     renderer()->layer()->hitTest(HitTestRequest(true, true), result);
1441
1442     IntPoint widgetPoint(point);
1443     while (true) {
1444         Node* n = result.innerNode();
1445         if (!n || !n->renderer() || !n->renderer()->isWidget())
1446             break;
1447         Widget* widget = static_cast<RenderWidget*>(n->renderer())->widget();
1448         if (!widget || !widget->isFrameView())
1449             break;
1450         Frame* frame = static_cast<HTMLFrameElement*>(n)->contentFrame();
1451         if (!frame || !frame->renderer())
1452             break;
1453         int absX, absY;
1454         n->renderer()->absolutePosition(absX, absY, true);
1455         FrameView* view = static_cast<FrameView*>(widget);
1456         widgetPoint.move(view->contentsX() - absX, view->contentsY() - absY);
1457         HitTestResult widgetHitTestResult(widgetPoint);
1458         frame->renderer()->layer()->hitTest(HitTestRequest(true, true), widgetHitTestResult);
1459         result = widgetHitTestResult;
1460     }
1461
1462     if (!allowShadowContent) {
1463         Node* node = result.innerNode();
1464         if (node)
1465             node = node->shadowAncestorNode();
1466         result.setInnerNode(node);
1467         node = result.innerNonSharedNode();
1468         if (node)
1469             node = node->shadowAncestorNode();
1470         result.setInnerNonSharedNode(node); 
1471     }
1472
1473     return result;
1474 }
1475
1476
1477 void Frame::startAutoscrollTimer()
1478 {
1479     d->m_autoscrollTimer.startRepeating(autoscrollInterval);
1480 }
1481
1482 void Frame::stopAutoscrollTimer(bool rendererIsBeingDestroyed)
1483 {
1484     if (!rendererIsBeingDestroyed && autoscrollRenderer())
1485         autoscrollRenderer()->stopAutoscroll();
1486     setAutoscrollRenderer(0);
1487     d->m_autoscrollTimer.stop();
1488 }
1489
1490 // FIXME: why is this here instead of on the FrameView?
1491 void Frame::paint(GraphicsContext* p, const IntRect& rect)
1492 {
1493 #ifndef NDEBUG
1494     bool fillWithRed;
1495     if (!document() || document()->printing())
1496         fillWithRed = false; // Printing, don't fill with red (can't remember why).
1497     else if (document()->ownerElement())
1498         fillWithRed = false; // Subframe, don't fill with red.
1499     else if (view() && view()->isTransparent())
1500         fillWithRed = false; // Transparent, don't fill with red.
1501     else if (d->m_paintRestriction == PaintRestrictionSelectionOnly || d->m_paintRestriction == PaintRestrictionSelectionOnlyWhiteText)
1502         fillWithRed = false; // Selections are transparent, don't fill with red.
1503     else if (d->m_elementToDraw)
1504         fillWithRed = false; // Element images are transparent, don't fill with red.
1505     else
1506         fillWithRed = true;
1507     
1508     if (fillWithRed)
1509         p->fillRect(rect, Color(0xFF, 0, 0));
1510 #endif
1511     
1512     if (renderer()) {
1513         // d->m_elementToDraw is used to draw only one element
1514         RenderObject *eltRenderer = d->m_elementToDraw ? d->m_elementToDraw->renderer() : 0;
1515         if (d->m_paintRestriction == PaintRestrictionNone)
1516             renderer()->document()->invalidateRenderedRectsForMarkersInRect(rect);
1517         renderer()->layer()->paint(p, rect, d->m_paintRestriction, eltRenderer);
1518
1519 #if PLATFORM(MAC)
1520         // Regions may have changed as a result of the visibility/z-index of element changing.
1521         if (renderer()->document()->dashboardRegionsDirty())
1522             renderer()->view()->frameView()->updateDashboardRegions();
1523 #endif
1524     } else
1525         LOG_ERROR("called Frame::paint with nil renderer");
1526 }
1527
1528 #if PLATFORM(CG)
1529
1530 void Frame::adjustPageHeight(float *newBottom, float oldTop, float oldBottom, float bottomLimit)
1531 {
1532     RenderView *root = static_cast<RenderView*>(document()->renderer());
1533     if (root) {
1534         // Use a context with painting disabled.
1535         GraphicsContext context((PlatformGraphicsContext*)0);
1536         root->setTruncatedAt((int)floorf(oldBottom));
1537         IntRect dirtyRect(0, (int)floorf(oldTop), root->docWidth(), (int)ceilf(oldBottom - oldTop));
1538         root->layer()->paint(&context, dirtyRect);
1539         *newBottom = root->bestTruncatedAt();
1540         if (*newBottom == 0)
1541             *newBottom = oldBottom;
1542     } else
1543         *newBottom = oldBottom;
1544 }
1545
1546 #endif
1547
1548 Frame *Frame::frameForWidget(const Widget *widget)
1549 {
1550     ASSERT_ARG(widget, widget);
1551     
1552     Node *node = nodeForWidget(widget);
1553     if (node)
1554         return frameForNode(node);
1555     
1556     // Assume all widgets are either form controls, or FrameViews.
1557     ASSERT(widget->isFrameView());
1558     return static_cast<const FrameView*>(widget)->frame();
1559 }
1560
1561 Frame *Frame::frameForNode(Node *node)
1562 {
1563     ASSERT_ARG(node, node);
1564     return node->document()->frame();
1565 }
1566
1567 Node* Frame::nodeForWidget(const Widget* widget)
1568 {
1569     ASSERT_ARG(widget, widget);
1570     WidgetClient* client = widget->client();
1571     if (!client)
1572         return 0;
1573     return client->element(const_cast<Widget*>(widget));
1574 }
1575
1576 void Frame::clearDocumentFocus(Widget *widget)
1577 {
1578     Node *node = nodeForWidget(widget);
1579     ASSERT(node);
1580     node->document()->setFocusNode(0);
1581 }
1582
1583 void Frame::forceLayout()
1584 {
1585     FrameView *v = d->m_view.get();
1586     if (v) {
1587         v->layout(false);
1588         // We cannot unschedule a pending relayout, since the force can be called with
1589         // a tiny rectangle from a drawRect update.  By unscheduling we in effect
1590         // "validate" and stop the necessary full repaint from occurring.  Basically any basic
1591         // append/remove DHTML is broken by this call.  For now, I have removed the optimization
1592         // until we have a better invalidation stategy. -dwh
1593         //v->unscheduleRelayout();
1594     }
1595 }
1596
1597 void Frame::forceLayoutWithPageWidthRange(float minPageWidth, float maxPageWidth)
1598 {
1599     // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
1600     // the state of things before and after the layout
1601     RenderView *root = static_cast<RenderView*>(document()->renderer());
1602     if (root) {
1603         // This magic is basically copied from khtmlview::print
1604         int pageW = (int)ceilf(minPageWidth);
1605         root->setWidth(pageW);
1606         root->setNeedsLayoutAndMinMaxRecalc();
1607         forceLayout();
1608         
1609         // If we don't fit in the minimum page width, we'll lay out again. If we don't fit in the
1610         // maximum page width, we will lay out to the maximum page width and clip extra content.
1611         // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
1612         // implementation should not do this!
1613         int rightmostPos = root->rightmostPosition();
1614         if (rightmostPos > minPageWidth) {
1615             pageW = min(rightmostPos, (int)ceilf(maxPageWidth));
1616             root->setWidth(pageW);
1617             root->setNeedsLayoutAndMinMaxRecalc();
1618             forceLayout();
1619         }
1620     }
1621 }
1622
1623 void Frame::sendResizeEvent()
1624 {
1625     if (Document* doc = document())
1626         doc->dispatchWindowEvent(EventNames::resizeEvent, false, false);
1627 }
1628
1629 void Frame::sendScrollEvent()
1630 {
1631     FrameView *v = d->m_view.get();
1632     if (v) {
1633         Document *doc = document();
1634         if (!doc)
1635             return;
1636         doc->dispatchHTMLEvent(scrollEvent, true, false);
1637     }
1638 }
1639
1640 bool Frame::canMouseDownStartSelect(Node* node)
1641 {
1642     if (!node || !node->renderer())
1643         return true;
1644     
1645     // Check to see if -webkit-user-select has been set to none
1646     if (!node->renderer()->canSelect())
1647         return false;
1648     
1649     // Some controls and images can't start a select on a mouse down.
1650     for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) {
1651         if (curr->style()->userSelect() == SELECT_IGNORE)
1652             return false;
1653     }
1654     
1655     return true;
1656 }
1657
1658 void Frame::clearTimers(FrameView *view)
1659 {
1660     if (view) {
1661         view->unscheduleRelayout();
1662         if (view->frame()) {
1663             Document* document = view->frame()->document();
1664             if (document && document->renderer() && document->renderer()->layer())
1665                 document->renderer()->layer()->suspendMarquees();
1666         }
1667     }
1668 }
1669
1670 void Frame::clearTimers()
1671 {
1672     clearTimers(d->m_view.get());
1673 }
1674
1675 RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const
1676 {
1677     nodeToRemove = 0;
1678     
1679     if (!document())
1680         return 0;
1681     if (selectionController()->isNone())
1682         return 0;
1683     
1684     Position pos = selectionController()->selection().visibleStart().deepEquivalent();
1685     if (!pos.inRenderedContent())
1686         return 0;
1687     Node *node = pos.node();
1688     if (!node)
1689         return 0;
1690     
1691     if (!d->m_typingStyle)
1692         return node->renderer()->style();
1693     
1694     ExceptionCode ec = 0;
1695     RefPtr<Element> styleElement = document()->createElementNS(xhtmlNamespaceURI, "span", ec);
1696     ASSERT(ec == 0);
1697     
1698     styleElement->setAttribute(styleAttr, d->m_typingStyle->cssText().impl(), ec);
1699     ASSERT(ec == 0);
1700     
1701     styleElement->appendChild(document()->createEditingTextNode(""), ec);
1702     ASSERT(ec == 0);
1703     
1704     node->parentNode()->appendChild(styleElement, ec);
1705     ASSERT(ec == 0);
1706     
1707     nodeToRemove = styleElement.get();    
1708     return styleElement->renderer()->style();
1709 }
1710
1711 void Frame::setSelectionFromNone()
1712 {
1713     // Put a caret inside the body if the entire frame is editable (either the 
1714     // entire WebView is editable or designMode is on for this document).
1715     Document *doc = document();
1716     if (!doc || !selectionController()->isNone() || !isContentEditable())
1717         return;
1718         
1719     Node* node = doc->documentElement();
1720     while (node && !node->hasTagName(bodyTag))
1721         node = node->traverseNextNode();
1722     if (node)
1723         selectionController()->setSelection(Selection(Position(node, 0), DOWNSTREAM));
1724 }
1725
1726 bool Frame::isActive() const
1727 {
1728     return d->m_isActive;
1729 }
1730
1731 void Frame::setIsActive(bool flag)
1732 {
1733     if (d->m_isActive == flag)
1734         return;
1735     
1736     d->m_isActive = flag;
1737
1738     // This method does the job of updating the view based on whether the view is "active".
1739     // This involves three kinds of drawing updates:
1740
1741     // 1. The background color used to draw behind selected content (active | inactive color)
1742     if (d->m_view)
1743         d->m_view->updateContents(enclosingIntRect(visibleSelectionRect()));
1744
1745     // 2. Caret blinking (blinks | does not blink)
1746     if (flag)
1747         setSelectionFromNone();
1748     setCaretVisible(flag);
1749     
1750     // 3. The drawing of a focus ring around links in web pages.
1751     Document *doc = document();
1752     if (doc) {
1753         Node *node = doc->focusNode();
1754         if (node) {
1755             node->setChanged();
1756             if (node->renderer() && node->renderer()->style()->hasAppearance())
1757                 theme()->stateChanged(node->renderer(), FocusState);
1758         }
1759     }
1760     
1761     // 4. Changing the tint of controls from clear to aqua/graphite and vice versa.  We
1762     // do a "fake" paint.  When the theme gets a paint call, it can then do an invalidate.  This is only
1763     // done if the theme supports control tinting.
1764     if (doc && d->m_view && theme()->supportsControlTints() && renderer()) {
1765         doc->updateLayout(); // Ensure layout is up to date.
1766         IntRect visibleRect(enclosingIntRect(d->m_view->visibleContentRect()));
1767         GraphicsContext context((PlatformGraphicsContext*)0);
1768         context.setUpdatingControlTints(true);
1769         paint(&context, visibleRect);
1770     }
1771    
1772     // 5. Enable or disable secure keyboard entry
1773     if ((flag && !isSecureKeyboardEntry() && doc && doc->focusNode() && doc->focusNode()->hasTagName(inputTag) && 
1774             static_cast<HTMLInputElement*>(doc->focusNode())->inputType() == HTMLInputElement::PASSWORD) ||
1775         (!flag && isSecureKeyboardEntry()))
1776             setSecureKeyboardEntry(flag);
1777 }
1778
1779 void Frame::setWindowHasFocus(bool flag)
1780 {
1781     if (d->m_windowHasFocus == flag)
1782         return;
1783     d->m_windowHasFocus = flag;
1784     
1785     if (Document *doc = document())
1786         doc->dispatchWindowEvent(flag ? focusEvent : blurEvent, false, false);
1787 }
1788
1789 bool Frame::inViewSourceMode() const
1790 {
1791     return d->m_inViewSourceMode;
1792 }
1793
1794 void Frame::setInViewSourceMode(bool mode) const
1795 {
1796     d->m_inViewSourceMode = mode;
1797 }
1798   
1799 UChar Frame::backslashAsCurrencySymbol() const
1800 {
1801     Document *doc = document();
1802     if (!doc)
1803         return '\\';
1804     TextResourceDecoder *decoder = doc->decoder();
1805     if (!decoder)
1806         return '\\';
1807
1808     return decoder->encoding().backslashAsCurrencySymbol();
1809 }
1810
1811 bool Frame::markedTextUsesUnderlines() const
1812 {
1813     return d->m_markedTextUsesUnderlines;
1814 }
1815
1816 const Vector<MarkedTextUnderline>& Frame::markedTextUnderlines() const
1817 {
1818     return d->m_markedTextUnderlines;
1819 }
1820
1821 // Searches from the beginning of the document if nothing is selected.
1822 bool Frame::findString(const String& target, bool forward, bool caseFlag, bool wrapFlag)
1823 {
1824     if (target.isEmpty())
1825         return false;
1826     
1827     // Initially search from the start (if forward) or end (if backward) of the selection, and search to edge of document.
1828     RefPtr<Range> searchRange(rangeOfContents(document()));
1829     Selection selection(selectionController()->selection());
1830     if (!selection.isNone()) {
1831         if (forward)
1832             setStart(searchRange.get(), selection.visibleStart());
1833         else
1834             setEnd(searchRange.get(), selection.visibleEnd());
1835     }
1836     RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, forward, caseFlag));
1837     // If the found range is already selected, find again.
1838     // Build a selection with the found range to remove collapsed whitespace.
1839     // Compare ranges instead of selection objects to ignore the way that the current selection was made.
1840     if (!selection.isNone() && *Selection(resultRange.get()).toRange() == *selection.toRange()) {
1841         searchRange = rangeOfContents(document());
1842         if (forward)
1843             setStart(searchRange.get(), selection.visibleEnd());
1844         else
1845             setEnd(searchRange.get(), selection.visibleStart());
1846         resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
1847     }
1848     
1849     int exception = 0;
1850     
1851     // If we didn't find anything and we're wrapping, search again in the entire document (this will
1852     // redundantly re-search the area already searched in some cases).
1853     if (resultRange->collapsed(exception) && wrapFlag) {
1854         searchRange = rangeOfContents(document());
1855         resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
1856         // We used to return false here if we ended up with the same range that we started with
1857         // (e.g., the selection was already the only instance of this text). But we decided that
1858         // this should be a success case instead, so we'll just fall through in that case.
1859     }
1860
1861     if (resultRange->collapsed(exception))
1862         return false;
1863
1864     selectionController()->setSelection(Selection(resultRange.get(), DOWNSTREAM));
1865     revealSelection();
1866     return true;
1867 }
1868
1869 unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsigned limit)
1870 {
1871     if (target.isEmpty())
1872         return 0;
1873     
1874     RefPtr<Range> searchRange(rangeOfContents(document()));
1875     
1876     int exception = 0;
1877     unsigned matchCount = 0;
1878     do {
1879         RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, caseFlag));
1880         if (resultRange->collapsed(exception))
1881             break;
1882         
1883         // A non-collapsed result range can in some funky whitespace cases still not
1884         // advance the range's start position (4509328). Break to avoid infinite loop.
1885         VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
1886         if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
1887             break;
1888
1889         ++matchCount;
1890         
1891         document()->addMarker(resultRange.get(), DocumentMarker::TextMatch);        
1892         
1893         // Stop looking if we hit the specified limit. A limit of 0 means no limit.
1894         if (limit > 0 && matchCount >= limit)
1895             break;
1896         
1897         setStart(searchRange.get(), newStart);
1898     } while (true);
1899     
1900     // Do a "fake" paint in order to execute the code that computes the rendered rect for 
1901     // each text match.
1902     Document* doc = document();
1903     if (doc && d->m_view && renderer()) {
1904         doc->updateLayout(); // Ensure layout is up to date.
1905         IntRect visibleRect(enclosingIntRect(d->m_view->visibleContentRect()));
1906         GraphicsContext context((PlatformGraphicsContext*)0);
1907         context.setPaintingDisabled(true);
1908         paint(&context, visibleRect);
1909     }
1910     
1911     return matchCount;
1912 }
1913
1914 bool Frame::markedTextMatchesAreHighlighted() const
1915 {
1916     return d->m_highlightTextMatches;
1917 }
1918
1919 void Frame::setMarkedTextMatchesAreHighlighted(bool flag)
1920 {
1921     if (flag == d->m_highlightTextMatches)
1922         return;
1923     
1924     d->m_highlightTextMatches = flag;
1925     document()->repaintMarkers(DocumentMarker::TextMatch);
1926 }
1927
1928 void Frame::prepareForUserAction()
1929 {
1930     // Reset the multiple form submission protection code.
1931     // We'll let you submit the same form twice if you do two separate user actions.
1932     loader()->resetMultipleFormSubmissionProtection();
1933 }
1934
1935 Node *Frame::mousePressNode()
1936 {
1937     return d->m_mousePressNode.get();
1938 }
1939
1940 FrameTree* Frame::tree() const
1941 {
1942     return &d->m_treeNode;
1943 }
1944
1945 DOMWindow* Frame::domWindow() const
1946 {
1947     if (!d->m_domWindow)
1948         d->m_domWindow = new DOMWindow(const_cast<Frame*>(this));
1949
1950     return d->m_domWindow.get();
1951 }
1952
1953 Page* Frame::page() const
1954 {
1955     return d->m_page;
1956 }
1957
1958 void Frame::pageDestroyed()
1959 {
1960     d->m_page = 0;
1961
1962     // This will stop any JS timers
1963     if (d->m_jscript && d->m_jscript->haveInterpreter())
1964         if (Window* w = Window::retrieveWindow(this))
1965             w->disconnectFrame();
1966 }
1967
1968 void Frame::setStatusBarText(const String&)
1969 {
1970 }
1971
1972 void Frame::disconnectOwnerElement()
1973 {
1974     if (d->m_ownerElement && d->m_page)
1975         d->m_page->decrementFrameCount();
1976         
1977     d->m_ownerElement = 0;
1978 }
1979
1980 String Frame::documentTypeString() const
1981 {
1982     if (Document *doc = document())
1983         if (DocumentType *doctype = doc->realDocType())
1984             return doctype->toString();
1985
1986     return String();
1987 }
1988
1989 bool Frame::prohibitsScrolling() const
1990 {
1991     return d->m_prohibitsScrolling;
1992 }
1993
1994 void Frame::setProhibitsScrolling(const bool prohibit)
1995 {
1996     d->m_prohibitsScrolling = prohibit;
1997 }
1998
1999 FramePrivate::FramePrivate(Page* page, Frame* parent, Frame* thisFrame, Element* ownerElement, PassRefPtr<EditorClient> client)
2000     : m_page(page)
2001     , m_treeNode(thisFrame, parent)
2002     , m_ownerElement(ownerElement)
2003     , m_jscript(0)
2004     , m_bJScriptEnabled(true)
2005     , m_bJavaEnabled(true)
2006     , m_bPluginsEnabled(true)
2007     , m_settings(0)
2008     , m_zoomFactor(parent ? parent->d->m_zoomFactor : 100)
2009     , m_bMousePressed(false)
2010     , m_beganSelectingText(false)
2011     , m_selectionController(thisFrame)
2012     , m_caretBlinkTimer(thisFrame, &Frame::caretBlinkTimerFired)
2013     , m_editor(thisFrame, client)
2014     , m_command(thisFrame)
2015     , m_caretVisible(false)
2016     , m_caretPaint(true)
2017     , m_isActive(false)
2018     , m_lifeSupportTimer(thisFrame, &Frame::lifeSupportTimerFired)
2019     , m_loader(new FrameLoader(thisFrame))
2020     , m_userStyleSheetLoader(0)
2021     , m_autoscrollTimer(thisFrame, &Frame::autoscrollTimerFired)
2022     , m_autoscrollRenderer(0)
2023     , m_mouseDownMayStartAutoscroll(false)
2024     , m_mouseDownMayStartDrag(false)
2025     , m_paintRestriction(PaintRestrictionNone)
2026     , m_markedTextUsesUnderlines(false)
2027     , m_highlightTextMatches(false)
2028     , m_windowHasFocus(false)
2029     , m_inViewSourceMode(false)
2030     , frameCount(0)
2031     , m_prohibitsScrolling(false)
2032 {
2033 }
2034
2035 FramePrivate::~FramePrivate()
2036 {
2037     delete m_jscript;
2038     delete m_loader;
2039 }
2040
2041 } // namespace WebCore