diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2009-06-15 09:06:43 (GMT) |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-06-15 09:31:31 (GMT) |
commit | c411f16870f112c3407c28c22b617f613a82cff4 (patch) | |
tree | 29a1bcd590c8b31af2aab445bfe8a978dc5bf582 /src/3rdparty/webkit/WebCore/page/Frame.cpp | |
parent | 3d77b56b32a0c53ec0bbfaa07236fedb900ff336 (diff) | |
download | Qt-c411f16870f112c3407c28c22b617f613a82cff4.zip Qt-c411f16870f112c3407c28c22b617f613a82cff4.tar.gz Qt-c411f16870f112c3407c28c22b617f613a82cff4.tar.bz2 |
Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit-4.6-snapshot-15062009 ( 65232bf00dc494ebfd978f998c88f58d18ecce1e )
Diffstat (limited to 'src/3rdparty/webkit/WebCore/page/Frame.cpp')
-rw-r--r-- | src/3rdparty/webkit/WebCore/page/Frame.cpp | 778 |
1 files changed, 339 insertions, 439 deletions
diff --git a/src/3rdparty/webkit/WebCore/page/Frame.cpp b/src/3rdparty/webkit/WebCore/page/Frame.cpp index a4c0b57..328f321 100644 --- a/src/3rdparty/webkit/WebCore/page/Frame.cpp +++ b/src/3rdparty/webkit/WebCore/page/Frame.cpp @@ -5,7 +5,7 @@ * 2000 Simon Hausmann <hausmann@kde.org> * 2000 Stefan Schimanski <1Stein@gmx.de> * 2001 George Staikos <staikos@kde.org> - * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com> * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * Copyright (C) 2008 Eric Seidel <eric@webkit.org> @@ -28,11 +28,11 @@ #include "config.h" #include "Frame.h" -#include "FramePrivate.h" #include "ApplyStyleCommand.h" #include "BeforeUnloadEvent.h" #include "CSSComputedStyleDeclaration.h" +#include "CSSMutableStyleDeclaration.h" #include "CSSProperty.h" #include "CSSPropertyNames.h" #include "CachedCSSStyleSheet.h" @@ -43,7 +43,9 @@ #include "EditorClient.h" #include "EventNames.h" #include "FocusController.h" +#include "FloatQuad.h" #include "FrameLoader.h" +#include "FrameLoaderClient.h" #include "FrameView.h" #include "GraphicsContext.h" #include "HTMLDocument.h" @@ -53,7 +55,6 @@ #include "HTMLNames.h" #include "HTMLTableCellElement.h" #include "HitTestResult.h" -#include "JSDOMWindowShell.h" #include "Logging.h" #include "markup.h" #include "MediaFeatureNames.h" @@ -67,17 +68,21 @@ #include "RenderTheme.h" #include "RenderView.h" #include "Settings.h" -#include "SystemTime.h" #include "TextIterator.h" #include "TextResourceDecoder.h" #include "XMLNames.h" #include "ScriptController.h" +#include "htmlediting.h" #include "npruntime_impl.h" -#include "runtime_root.h" #include "visible_units.h" #include <wtf/RefCountedLeakCounter.h> #include <wtf/StdLibExtras.h> +#if USE(JSC) +#include "JSDOMWindowShell.h" +#include "runtime_root.h" +#endif + #if FRAME_LOADS_USER_STYLESHEET #include "UserStyleSheetLoader.h" #endif @@ -111,8 +116,32 @@ static inline Frame* parentFromOwnerElement(HTMLFrameOwnerElement* ownerElement) } Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* frameLoaderClient) - : d(new FramePrivate(page, parentFromOwnerElement(ownerElement), this, ownerElement, frameLoaderClient)) + : m_page(page) + , m_treeNode(this, parentFromOwnerElement(ownerElement)) + , m_loader(this, frameLoaderClient) + , m_ownerElement(ownerElement) + , m_script(this) + , m_selectionGranularity(CharacterGranularity) + , m_selectionController(this) + , m_caretBlinkTimer(this, &Frame::caretBlinkTimerFired) + , m_editor(this) + , m_eventHandler(this) + , m_animationController(this) + , m_lifeSupportTimer(this, &Frame::lifeSupportTimerFired) + , m_caretVisible(false) + , m_caretPaint(true) + , m_highlightTextMatches(false) + , m_inViewSourceMode(false) + , m_needsReapplyStyles(false) + , m_isDisconnected(false) + , m_excludeFromTextSearch(false) +#if FRAME_LOADS_USER_STYLESHEET + , m_userStyleSheetLoader(0) +#endif { + Frame* parent = parentFromOwnerElement(ownerElement); + m_zoomFactor = parent ? parent->m_zoomFactor : 1.0f; + AtomicString::init(); HTMLNames::init(); QualifiedName::init(); @@ -146,73 +175,66 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* Frame::~Frame() { setView(0); - loader()->clearRecordedFormValues(); loader()->cancelAndClear(); // FIXME: We should not be doing all this work inside the destructor - ASSERT(!d->m_lifeSupportTimer.isActive()); + ASSERT(!m_lifeSupportTimer.isActive()); #ifndef NDEBUG frameCounter.decrement(); #endif - if (d->m_script.haveWindowShell()) - d->m_script.windowShell()->disconnectFrame(); - disconnectOwnerElement(); - if (d->m_domWindow) - d->m_domWindow->disconnectFrame(); + if (m_domWindow) + m_domWindow->disconnectFrame(); - HashSet<DOMWindow*>::iterator end = d->m_liveFormerWindows.end(); - for (HashSet<DOMWindow*>::iterator it = d->m_liveFormerWindows.begin(); it != end; ++it) + HashSet<DOMWindow*>::iterator end = m_liveFormerWindows.end(); + for (HashSet<DOMWindow*>::iterator it = m_liveFormerWindows.begin(); it != end; ++it) (*it)->disconnectFrame(); - if (d->m_view) { - d->m_view->hide(); - d->m_view->clearFrame(); + if (m_view) { + m_view->hide(); + m_view->clearFrame(); } - ASSERT(!d->m_lifeSupportTimer.isActive()); + ASSERT(!m_lifeSupportTimer.isActive()); #if FRAME_LOADS_USER_STYLESHEET - delete d->m_userStyleSheetLoader; + delete m_userStyleSheetLoader; #endif - - delete d; - d = 0; } void Frame::init() { - d->m_loader.init(); + m_loader.init(); } FrameLoader* Frame::loader() const { - return &d->m_loader; + return &m_loader; } FrameView* Frame::view() const { - return d->m_view.get(); + return m_view.get(); } -void Frame::setView(FrameView* view) +void Frame::setView(PassRefPtr<FrameView> view) { // Detach the document now, so any onUnload handlers get run - if // we wait until the view is destroyed, then things won't be // hooked up enough for some JavaScript calls to work. - if (!view && d->m_doc && d->m_doc->attached() && !d->m_doc->inPageCache()) { + if (!view && m_doc && m_doc->attached() && !m_doc->inPageCache()) { // FIXME: We don't call willRemove here. Why is that OK? - d->m_doc->detach(); - if (d->m_view) - d->m_view->unscheduleRelayout(); + m_doc->detach(); + if (m_view) + m_view->unscheduleRelayout(); } eventHandler()->clear(); - d->m_view = view; + m_view = view; // Only one form submission is allowed per view of a part. // Since this part may be getting reused as a result of being @@ -222,40 +244,40 @@ void Frame::setView(FrameView* view) ScriptController* Frame::script() { - return &d->m_script; + return &m_script; } Document* Frame::document() const { - return d->m_doc.get(); + return m_doc.get(); } void Frame::setDocument(PassRefPtr<Document> newDoc) { - if (d->m_doc && d->m_doc->attached() && !d->m_doc->inPageCache()) { + if (m_doc && m_doc->attached() && !m_doc->inPageCache()) { // FIXME: We don't call willRemove here. Why is that OK? - d->m_doc->detach(); + m_doc->detach(); } - d->m_doc = newDoc; - if (d->m_doc && selection()->isFocusedAndActive()) - setUseSecureKeyboardEntry(d->m_doc->useSecureKeyboardEntryWhenActive()); + m_doc = newDoc; + if (m_doc && selection()->isFocusedAndActive()) + setUseSecureKeyboardEntry(m_doc->useSecureKeyboardEntryWhenActive()); - if (d->m_doc && !d->m_doc->attached()) - d->m_doc->attach(); + if (m_doc && !m_doc->attached()) + m_doc->attach(); // Update the cached 'document' property, which is now stale. - d->m_script.updateDocument(); + m_script.updateDocument(); } Settings* Frame::settings() const { - return d->m_page ? d->m_page->settings() : 0; + return m_page ? m_page->settings() : 0; } String Frame::selectedText() const { - return plainText(selection()->toRange().get()); + return plainText(selection()->toNormalizedRange().get()); } IntRect Frame::firstRectForRange(Range* range) const @@ -300,33 +322,33 @@ IntRect Frame::firstRectForRange(Range* range) const SelectionController* Frame::selection() const { - return &d->m_selectionController; + return &m_selectionController; } Editor* Frame::editor() const { - return &d->m_editor; + return &m_editor; } TextGranularity Frame::selectionGranularity() const { - return d->m_selectionGranularity; + return m_selectionGranularity; } -void Frame::setSelectionGranularity(TextGranularity granularity) const +void Frame::setSelectionGranularity(TextGranularity granularity) { - d->m_selectionGranularity = granularity; + m_selectionGranularity = granularity; } SelectionController* Frame::dragCaretController() const { - return d->m_page->dragCaretController(); + return m_page->dragCaretController(); } AnimationController* Frame::animation() const { - return &d->m_animationController; + return &m_animationController; } static RegularExpression* createRegExpForLabels(const Vector<String>& labels) @@ -334,7 +356,7 @@ static RegularExpression* createRegExpForLabels(const Vector<String>& labels) // REVIEW- version of this call in FrameMac.mm caches based on the NSArray ptrs being // the same across calls. We can't do that. - DEFINE_STATIC_LOCAL(RegularExpression, wordRegExp, ("\\w")); + DEFINE_STATIC_LOCAL(RegularExpression, wordRegExp, ("\\w", TextCaseSensitive)); String pattern("("); unsigned int numLabels = labels.size(); unsigned int i; @@ -344,8 +366,8 @@ static RegularExpression* createRegExpForLabels(const Vector<String>& labels) bool startsWithWordChar = false; bool endsWithWordChar = false; if (label.length() != 0) { - startsWithWordChar = wordRegExp.search(label.substring(0, 1)) >= 0; - endsWithWordChar = wordRegExp.search(label.substring(label.length() - 1, 1)) >= 0; + startsWithWordChar = wordRegExp.match(label.substring(0, 1)) >= 0; + endsWithWordChar = wordRegExp.match(label.substring(label.length() - 1, 1)) >= 0; } if (i != 0) @@ -362,7 +384,7 @@ static RegularExpression* createRegExpForLabels(const Vector<String>& labels) } } pattern.append(")"); - return new RegularExpression(pattern, false); + return new RegularExpression(pattern, TextCaseInsensitive); } String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellElement* cell) @@ -374,7 +396,7 @@ String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellE if (cellAboveRenderer) { HTMLTableCellElement* aboveCell = - static_cast<HTMLTableCellElement*>(cellAboveRenderer->element()); + static_cast<HTMLTableCellElement*>(cellAboveRenderer->node()); if (aboveCell) { // search within the above cell we found for a match @@ -414,8 +436,7 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element n = n->traversePreviousNode()) { if (n->hasTagName(formTag) - || (n->isHTMLElement() - && static_cast<HTMLElement*>(n)->isGenericFormElement())) + || (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement())) { // We hit another form element or the start of the form - bail out break; @@ -454,7 +475,7 @@ String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* e return String(); // Make numbers and _'s in field names behave like word boundaries, e.g., "address2" - replace(name, RegularExpression("\\d"), " "); + replace(name, RegularExpression("\\d", TextCaseSensitive), " "); name.replace('_', ' '); OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels)); @@ -465,7 +486,7 @@ String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* e int bestLength = -1; int start = 0; do { - pos = regExp->search(name, start); + pos = regExp->match(name, start); if (pos != -1) { length = regExp->matchedLength(); if (length >= bestLength) { @@ -481,19 +502,19 @@ String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* e return String(); } -const Selection& Frame::mark() const +const VisibleSelection& Frame::mark() const { - return d->m_mark; + return m_mark; } -void Frame::setMark(const Selection& s) +void Frame::setMark(const VisibleSelection& s) { ASSERT(!s.base().node() || s.base().node()->document() == document()); ASSERT(!s.extent().node() || s.extent().node()->document() == document()); ASSERT(!s.start().node() || s.start().node()->document() == document()); ASSERT(!s.end().node() || s.end().node()->document() == document()); - d->m_mark = s; + m_mark = s; } void Frame::notifyRendererOfSelectionChange(bool userTriggered) @@ -503,8 +524,8 @@ void Frame::notifyRendererOfSelectionChange(bool userTriggered) renderer = selection()->rootEditableElement()->shadowAncestorNode()->renderer(); // If the current selection is in a textfield or textarea, notify the renderer that the selection has changed - if (renderer && (renderer->isTextArea() || renderer->isTextField())) - static_cast<RenderTextControl*>(renderer)->selectionChanged(userTriggered); + if (renderer && renderer->isTextControl()) + toRenderTextControl(renderer)->selectionChanged(userTriggered); } void Frame::invalidateSelection() @@ -515,18 +536,18 @@ void Frame::invalidateSelection() void Frame::setCaretVisible(bool flag) { - if (d->m_caretVisible == flag) + if (m_caretVisible == flag) return; clearCaretRectIfNeeded(); - d->m_caretVisible = flag; + m_caretVisible = flag; selectionLayoutChanged(); } void Frame::clearCaretRectIfNeeded() { #if ENABLE(TEXT_CARET) - if (d->m_caretPaint) { - d->m_caretPaint = false; + if (m_caretPaint) { + m_caretPaint = false; selection()->invalidateCaretRect(); } #endif @@ -547,9 +568,18 @@ static bool isFrameElement(const Node *n) void Frame::setFocusedNodeIfNeeded() { - if (!document() || selection()->isNone() || !selection()->isFocusedAndActive()) + if (selection()->isNone() || !selection()->isFocused()) return; + bool caretBrowsing = settings() && settings()->caretBrowsingEnabled(); + if (caretBrowsing) { + Node* anchor = enclosingAnchorElement(selection()->base()); + if (anchor) { + page()->focusController()->setFocusedNode(anchor, this); + return; + } + } + Node* target = selection()->rootEditableElement(); if (target) { RenderObject* renderer = target->renderer(); @@ -566,10 +596,13 @@ void Frame::setFocusedNodeIfNeeded() } renderer = renderer->parent(); if (renderer) - target = renderer->element(); + target = renderer->node(); } document()->setFocusedNode(0); } + + if (caretBrowsing) + page()->focusController()->setFocusedNode(0, this); } void Frame::selectionLayoutChanged() @@ -577,22 +610,23 @@ void Frame::selectionLayoutChanged() bool caretRectChanged = selection()->recomputeCaretRect(); #if ENABLE(TEXT_CARET) - bool shouldBlink = d->m_caretVisible - && selection()->isCaret() && selection()->isContentEditable(); + bool caretBrowsing = settings() && settings()->caretBrowsingEnabled(); + bool shouldBlink = m_caretVisible + && selection()->isCaret() && (selection()->isContentEditable() || caretBrowsing); // If the caret moved, stop the blink timer so we can restart with a // black caret in the new location. if (caretRectChanged || !shouldBlink) - d->m_caretBlinkTimer.stop(); + m_caretBlinkTimer.stop(); // Start blinking with a black caret. Be sure not to restart if we're // already blinking in the right location. - if (shouldBlink && !d->m_caretBlinkTimer.isActive()) { + if (shouldBlink && !m_caretBlinkTimer.isActive()) { if (double blinkInterval = theme()->caretBlinkInterval()) - d->m_caretBlinkTimer.startRepeating(blinkInterval); + m_caretBlinkTimer.startRepeating(blinkInterval); - if (!d->m_caretPaint) { - d->m_caretPaint = true; + if (!m_caretPaint) { + m_caretPaint = true; selection()->invalidateCaretRect(); } } @@ -605,7 +639,7 @@ void Frame::selectionLayoutChanged() if (!view) return; - Selection selection = this->selection()->selection(); + VisibleSelection selection = this->selection()->selection(); if (!selection.isRange()) view->clearSelection(); @@ -626,7 +660,7 @@ void Frame::selectionLayoutChanged() if (startPos.isNotNull() && endPos.isNotNull() && selection.visibleStart() != selection.visibleEnd()) { RenderObject *startRenderer = startPos.node()->renderer(); RenderObject *endRenderer = endPos.node()->renderer(); - view->setSelection(startRenderer, startPos.offset(), endRenderer, endPos.offset()); + view->setSelection(startRenderer, startPos.deprecatedEditingOffset(), endRenderer, endPos.deprecatedEditingOffset()); } } } @@ -634,12 +668,12 @@ void Frame::selectionLayoutChanged() void Frame::caretBlinkTimerFired(Timer<Frame>*) { #if ENABLE(TEXT_CARET) - ASSERT(d->m_caretVisible); + ASSERT(m_caretVisible); ASSERT(selection()->isCaret()); - bool caretPaint = d->m_caretPaint; + bool caretPaint = m_caretPaint; if (selection()->isCaretBlinkingSuspended() && caretPaint) return; - d->m_caretPaint = !caretPaint; + m_caretPaint = !caretPaint; selection()->invalidateCaretRect(); #endif } @@ -647,7 +681,7 @@ void Frame::caretBlinkTimerFired(Timer<Frame>*) void Frame::paintCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const { #if ENABLE(TEXT_CARET) - if (d->m_caretPaint && d->m_caretVisible) + if (m_caretPaint && m_caretVisible) selection()->paintCaret(p, tx, ty, clipRect); #endif } @@ -655,7 +689,7 @@ void Frame::paintCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRe void Frame::paintDragCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const { #if ENABLE(TEXT_CARET) - SelectionController* dragCaretController = d->m_page->dragCaretController(); + SelectionController* dragCaretController = m_page->dragCaretController(); ASSERT(dragCaretController->selection().isCaret()); if (dragCaretController->selection().start().node()->document()->frame() == this) dragCaretController->paintCaret(p, tx, ty, clipRect); @@ -664,20 +698,20 @@ void Frame::paintDragCaret(GraphicsContext* p, int tx, int ty, const IntRect& cl float Frame::zoomFactor() const { - return d->m_zoomFactor; + return m_zoomFactor; } bool Frame::isZoomFactorTextOnly() const { - return d->m_page->settings()->zoomsTextOnly(); + return m_page->settings()->zoomsTextOnly(); } bool Frame::shouldApplyTextZoom() const { - if (d->m_zoomFactor == 1.0f || !isZoomFactorTextOnly()) + if (m_zoomFactor == 1.0f || !isZoomFactorTextOnly()) return false; #if ENABLE(SVG) - if (d->m_doc && d->m_doc->isSVGDocument()) + if (m_doc->isSVGDocument()) return false; #endif return true; @@ -685,10 +719,10 @@ bool Frame::shouldApplyTextZoom() const bool Frame::shouldApplyPageZoom() const { - if (d->m_zoomFactor == 1.0f || isZoomFactorTextOnly()) + if (m_zoomFactor == 1.0f || isZoomFactorTextOnly()) return false; #if ENABLE(SVG) - if (d->m_doc && d->m_doc->isSVGDocument()) + if (m_doc->isSVGDocument()) return false; #endif return true; @@ -696,45 +730,41 @@ bool Frame::shouldApplyPageZoom() const void Frame::setZoomFactor(float percent, bool isTextOnly) { - if (d->m_zoomFactor == percent && isZoomFactorTextOnly()) + if (m_zoomFactor == percent && isZoomFactorTextOnly() == isTextOnly) return; #if ENABLE(SVG) // SVG doesn't care if the zoom factor is text only. It will always apply a // zoom to the whole SVG. - if (d->m_doc && d->m_doc->isSVGDocument()) { - if (!static_cast<SVGDocument*>(d->m_doc.get())->zoomAndPanEnabled()) + if (m_doc->isSVGDocument()) { + if (!static_cast<SVGDocument*>(m_doc.get())->zoomAndPanEnabled()) return; - d->m_zoomFactor = percent; - d->m_page->settings()->setZoomsTextOnly(true); // We do this to avoid doing any scaling of CSS pixels, since the SVG has its own notion of zoom. - if (d->m_doc->renderer()) - d->m_doc->renderer()->repaint(); + m_zoomFactor = percent; + m_page->settings()->setZoomsTextOnly(true); // We do this to avoid doing any scaling of CSS pixels, since the SVG has its own notion of zoom. + if (m_doc->renderer()) + m_doc->renderer()->repaint(); return; } #endif - d->m_zoomFactor = percent; - d->m_page->settings()->setZoomsTextOnly(isTextOnly); + m_zoomFactor = percent; + m_page->settings()->setZoomsTextOnly(isTextOnly); - if (d->m_doc) - d->m_doc->recalcStyle(Node::Force); + m_doc->recalcStyle(Node::Force); for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling()) - child->setZoomFactor(d->m_zoomFactor, isTextOnly); + child->setZoomFactor(m_zoomFactor, isTextOnly); - if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout() && view()->didFirstLayout()) + if (m_doc->renderer() && m_doc->renderer()->needsLayout() && view()->didFirstLayout()) view()->layout(); } void Frame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize) { - if (!d->m_doc) - return; - - d->m_doc->setPrinting(printing); + m_doc->setPrinting(printing); view()->setMediaType(printing ? "print" : "screen"); - d->m_doc->updateStyleSelector(); - forceLayoutWithPageWidthRange(minPageWidth, maxPageWidth, adjustViewSize); + m_doc->updateStyleSelector(); + view()->forceLayoutWithPageWidthRange(minPageWidth, maxPageWidth, adjustViewSize); for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling()) child->setPrinting(printing, minPageWidth, maxPageWidth, adjustViewSize); @@ -742,34 +772,42 @@ void Frame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, b void Frame::setJSStatusBarText(const String& text) { - d->m_kjsStatusBarText = text; - if (d->m_page) - d->m_page->chrome()->setStatusbarText(this, d->m_kjsStatusBarText); + ASSERT(m_doc); // Client calls shouldn't be made when the frame is in inconsistent state. + m_kjsStatusBarText = text; + if (m_page) + m_page->chrome()->setStatusbarText(this, m_kjsStatusBarText); } void Frame::setJSDefaultStatusBarText(const String& text) { - d->m_kjsDefaultStatusBarText = text; - if (d->m_page) - d->m_page->chrome()->setStatusbarText(this, d->m_kjsDefaultStatusBarText); + ASSERT(m_doc); // Client calls shouldn't be made when the frame is in inconsistent state. + m_kjsDefaultStatusBarText = text; + if (m_page) + m_page->chrome()->setStatusbarText(this, m_kjsDefaultStatusBarText); } String Frame::jsStatusBarText() const { - return d->m_kjsStatusBarText; + return m_kjsStatusBarText; } String Frame::jsDefaultStatusBarText() const { - return d->m_kjsDefaultStatusBarText; + return m_kjsDefaultStatusBarText; } void Frame::setNeedsReapplyStyles() { - if (d->m_needsReapplyStyles) + // When the frame is not showing web content, it doesn't make sense to apply styles. + // If we tried, we'd end up doing things with the document, but the document, if one + // exists, is not currently shown and should be in the page cache. + if (!m_loader.client()->hasHTMLView()) return; - d->m_needsReapplyStyles = true; + if (m_needsReapplyStyles) + return; + + m_needsReapplyStyles = true; // FrameView's "layout" timer includes reapplyStyles, so despite its // name, it's what we want to call here. @@ -779,21 +817,19 @@ void Frame::setNeedsReapplyStyles() bool Frame::needsReapplyStyles() const { - return d->m_needsReapplyStyles; + return m_needsReapplyStyles; } void Frame::reapplyStyles() { - d->m_needsReapplyStyles = false; + m_needsReapplyStyles = false; - // FIXME: This call doesn't really make sense in a method called - // "reapplyStyles". We should probably eventually move it into its own - // method. - if (d->m_doc) - d->m_doc->docLoader()->setAutoLoadImages(d->m_page && d->m_page->settings()->loadsImagesAutomatically()); + // FIXME: This call doesn't really make sense in a function called reapplyStyles. + // We should probably eventually move it into its own function. + m_doc->docLoader()->setAutoLoadImages(m_page && m_page->settings()->loadsImagesAutomatically()); #if FRAME_LOADS_USER_STYLESHEET - const KURL userStyleSheetLocation = d->m_page ? d->m_page->settings()->userStyleSheetLocation() : KURL(); + const KURL userStyleSheetLocation = m_page ? m_page->settings()->userStyleSheetLocation() : KURL(); if (!userStyleSheetLocation.isEmpty()) setUserStyleSheetLocation(userStyleSheetLocation); else @@ -804,33 +840,30 @@ void Frame::reapplyStyles() // The document automatically does this as required when you set the style sheet. // But we had problems when this code was removed. Details are in // <http://bugs.webkit.org/show_bug.cgi?id=8079>. - if (d->m_doc) - d->m_doc->updateStyleSelector(); + m_doc->updateStyleSelector(); } -bool Frame::shouldChangeSelection(const Selection& newSelection) const +bool Frame::shouldChangeSelection(const VisibleSelection& newSelection) const { return shouldChangeSelection(selection()->selection(), newSelection, newSelection.affinity(), false); } -bool Frame::shouldChangeSelection(const Selection& oldSelection, const Selection& newSelection, EAffinity affinity, bool stillSelecting) const +bool Frame::shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity affinity, bool stillSelecting) const { - return editor()->client()->shouldChangeSelectedRange(oldSelection.toRange().get(), newSelection.toRange().get(), + return editor()->client()->shouldChangeSelectedRange(oldSelection.toNormalizedRange().get(), newSelection.toNormalizedRange().get(), affinity, stillSelecting); } -bool Frame::shouldDeleteSelection(const Selection& selection) const +bool Frame::shouldDeleteSelection(const VisibleSelection& selection) const { - return editor()->client()->shouldDeleteRange(selection.toRange().get()); + return editor()->client()->shouldDeleteRange(selection.toNormalizedRange().get()); } bool Frame::isContentEditable() const { - if (d->m_editor.clientIsEditable()) + if (m_editor.clientIsEditable()) return true; - if (!d->m_doc) - return false; - return d->m_doc->inDesignMode(); + return m_doc->inDesignMode(); } #if !PLATFORM(MAC) @@ -844,22 +877,22 @@ void Frame::setUseSecureKeyboardEntry(bool) void Frame::updateSecureKeyboardEntryIfActive() { if (selection()->isFocusedAndActive()) - setUseSecureKeyboardEntry(d->m_doc->useSecureKeyboardEntryWhenActive()); + setUseSecureKeyboardEntry(m_doc->useSecureKeyboardEntryWhenActive()); } CSSMutableStyleDeclaration *Frame::typingStyle() const { - return d->m_typingStyle.get(); + return m_typingStyle.get(); } void Frame::setTypingStyle(CSSMutableStyleDeclaration *style) { - d->m_typingStyle = style; + m_typingStyle = style; } void Frame::clearTypingStyle() { - d->m_typingStyle = 0; + m_typingStyle = 0; } void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction editingAction) @@ -898,11 +931,11 @@ void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction edit // Handle block styles, substracting these from the typing style. RefPtr<CSSMutableStyleDeclaration> blockStyle = mutableStyle->copyBlockProperties(); blockStyle->diff(mutableStyle.get()); - if (document() && blockStyle->length() > 0) + if (blockStyle->length() > 0) applyCommand(ApplyStyleCommand::create(document(), blockStyle.get(), editingAction)); // Set the remaining style as the typing style. - d->m_typingStyle = mutableStyle.release(); + m_typingStyle = mutableStyle.release(); } String Frame::selectionStartStylePropertyValue(int stylePropertyID) const @@ -927,13 +960,10 @@ PassRefPtr<CSSComputedStyleDeclaration> Frame::selectionComputedStyle(Node*& nod { nodeToRemove = 0; - if (!document()) - return 0; - if (selection()->isNone()) return 0; - RefPtr<Range> range(selection()->toRange()); + RefPtr<Range> range(selection()->toNormalizedRange()); Position pos = range->editingStartPosition(); Element *elem = pos.element(); @@ -943,11 +973,10 @@ PassRefPtr<CSSComputedStyleDeclaration> Frame::selectionComputedStyle(Node*& nod RefPtr<Element> styleElement = elem; ExceptionCode ec = 0; - if (d->m_typingStyle) { - styleElement = document()->createElementNS(xhtmlNamespaceURI, "span", ec); - ASSERT(ec == 0); + if (m_typingStyle) { + styleElement = document()->createElement(spanTag, false); - styleElement->setAttribute(styleAttr, d->m_typingStyle->cssText().impl(), ec); + styleElement->setAttribute(styleAttr, m_typingStyle->cssText().impl(), ec); ASSERT(ec == 0); styleElement->appendChild(document()->createEditingTextNode(""), ec); @@ -1013,10 +1042,7 @@ void Frame::textDidChangeInTextArea(Element* e) void Frame::applyEditingStyleToBodyElement() const { - if (!d->m_doc) - return; - - RefPtr<NodeList> list = d->m_doc->getElementsByTagName("body"); + RefPtr<NodeList> list = m_doc->getElementsByTagName("body"); unsigned len = list->length(); for (unsigned i = 0; i < len; i++) { applyEditingStyleToElement(static_cast<Element*>(list->item(i))); @@ -1025,10 +1051,7 @@ void Frame::applyEditingStyleToBodyElement() const void Frame::removeEditingStyleFromBodyElement() const { - if (!d->m_doc) - return; - - RefPtr<NodeList> list = d->m_doc->getElementsByTagName("body"); + RefPtr<NodeList> list = m_doc->getElementsByTagName("body"); unsigned len = list->length(); for (unsigned i = 0; i < len; i++) { removeEditingStyleFromElement(static_cast<Element*>(list->item(i))); @@ -1066,13 +1089,13 @@ static HashSet<Frame*>& keepAliveSet() void Frame::keepAlive() { - if (d->m_lifeSupportTimer.isActive()) + if (m_lifeSupportTimer.isActive()) return; #ifndef NDEBUG keepAliveSet().add(this); #endif ref(); - d->m_lifeSupportTimer.startOneShot(0); + m_lifeSupportTimer.startOneShot(0); } #ifndef NDEBUG @@ -1081,7 +1104,7 @@ void Frame::cancelAllKeepAlive() HashSet<Frame*>::iterator end = keepAliveSet().end(); for (HashSet<Frame*>::iterator it = keepAliveSet().begin(); it != end; ++it) { Frame* frame = *it; - frame->d->m_lifeSupportTimer.stop(); + frame->m_lifeSupportTimer.stop(); frame->deref(); } keepAliveSet().clear(); @@ -1098,11 +1121,11 @@ void Frame::lifeSupportTimerFired(Timer<Frame>*) void Frame::clearDOMWindow() { - if (d->m_domWindow) { - d->m_liveFormerWindows.add(d->m_domWindow.get()); - d->m_domWindow->clear(); + if (m_domWindow) { + m_liveFormerWindows.add(m_domWindow.get()); + m_domWindow->clear(); } - d->m_domWindow = 0; + m_domWindow = 0; } RenderView* Frame::contentRenderer() const @@ -1114,17 +1137,17 @@ RenderView* Frame::contentRenderer() const if (!object) return 0; ASSERT(object->isRenderView()); - return static_cast<RenderView*>(object); + return toRenderView(object); } HTMLFrameOwnerElement* Frame::ownerElement() const { - return d->m_ownerElement; + return m_ownerElement; } RenderPart* Frame::ownerRenderer() const { - HTMLFrameOwnerElement* ownerElement = d->m_ownerElement; + HTMLFrameOwnerElement* ownerElement = m_ownerElement; if (!ownerElement) return 0; RenderObject* object = ownerElement->renderer(); @@ -1132,7 +1155,7 @@ RenderPart* Frame::ownerRenderer() const return 0; // FIXME: If <object> is ever fixed to disassociate itself from frames // that it has started but canceled, then this can turn into an ASSERT - // since d->m_ownerElement would be 0 when the load is canceled. + // since m_ownerElement would be 0 when the load is canceled. // https://bugs.webkit.org/show_bug.cgi?id=18585 if (!object->isRenderPart()) return 0; @@ -1141,29 +1164,29 @@ RenderPart* Frame::ownerRenderer() const bool Frame::isDisconnected() const { - return d->m_isDisconnected; + return m_isDisconnected; } void Frame::setIsDisconnected(bool isDisconnected) { - d->m_isDisconnected = isDisconnected; + m_isDisconnected = isDisconnected; } bool Frame::excludeFromTextSearch() const { - return d->m_excludeFromTextSearch; + return m_excludeFromTextSearch; } void Frame::setExcludeFromTextSearch(bool exclude) { - d->m_excludeFromTextSearch = exclude; + m_excludeFromTextSearch = exclude; } // returns FloatRect because going through IntRect would truncate any floats FloatRect Frame::selectionBounds(bool clipToVisibleContent) const { RenderView* root = contentRenderer(); - FrameView* view = d->m_view.get(); + FrameView* view = m_view.get(); if (!root || !view) return IntRect(); @@ -1177,13 +1200,13 @@ void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleConte if (!root) return; - RefPtr<Range> selectedRange = selection()->toRange(); + RefPtr<Range> selectedRange = selection()->toNormalizedRange(); Vector<IntRect> intRects; - selectedRange->addLineBoxRects(intRects, true); + selectedRange->textRects(intRects, true); unsigned size = intRects.size(); - FloatRect visibleContentRect = d->m_view->visibleContentRect(); + FloatRect visibleContentRect = m_view->visibleContentRect(); for (unsigned i = 0; i < size; ++i) if (clipToVisibleContent) rects.append(intersection(intRects[i], visibleContentRect)); @@ -1192,15 +1215,6 @@ void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleConte } -bool Frame::isFrameSet() const -{ - Document* document = d->m_doc.get(); - if (!document || !document->isHTMLDocument()) - return false; - Node *body = static_cast<HTMLDocument*>(document)->body(); - return body && body->renderer() && body->hasTagName(framesetTag); -} - // Scans logically forward from "start", including any child frames static HTMLFormElement *scanForForm(Node *start) { @@ -1208,7 +1222,7 @@ static HTMLFormElement *scanForForm(Node *start) for (n = start; n; n = n->traverseNextNode()) { if (n->hasTagName(formTag)) return static_cast<HTMLFormElement*>(n); - else if (n->isHTMLElement() && static_cast<HTMLElement*>(n)->isGenericFormElement()) + else if (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement()) return static_cast<HTMLFormControlElement*>(n)->form(); else if (n->hasTagName(frameTag) || n->hasTagName(iframeTag)) { Node *childDoc = static_cast<HTMLFrameElementBase*>(n)->contentDocument(); @@ -1223,7 +1237,7 @@ static HTMLFormElement *scanForForm(Node *start) HTMLFormElement *Frame::currentForm() const { // start looking either at the active (first responder) node, or where the selection is - Node *start = d->m_doc ? d->m_doc->focusedNode() : 0; + Node *start = m_doc ? m_doc->focusedNode() : 0; if (!start) start = selection()->start().node(); @@ -1232,8 +1246,7 @@ HTMLFormElement *Frame::currentForm() const for (n = start; n; n = n->parentNode()) { if (n->hasTagName(formTag)) return static_cast<HTMLFormElement*>(n); - else if (n->isHTMLElement() - && static_cast<HTMLElement*>(n)->isGenericFormElement()) + else if (n->isHTMLElement() && static_cast<Element*>(n)->isFormControlElement()) return static_cast<HTMLFormControlElement*>(n)->form(); } @@ -1241,66 +1254,32 @@ HTMLFormElement *Frame::currentForm() const return start ? scanForForm(start) : 0; } -// FIXME: should this go in SelectionController? -void Frame::revealSelection(const RenderLayer::ScrollAlignment& alignment) const +void Frame::revealSelection(const ScrollAlignment& alignment, bool revealExtent) { IntRect rect; - - switch (selection()->state()) { - case Selection::NONE: + + switch (selection()->selectionType()) { + case VisibleSelection::NoSelection: return; - - case Selection::CARET: + case VisibleSelection::CaretSelection: rect = selection()->absoluteCaretBounds(); break; - - case Selection::RANGE: - rect = enclosingIntRect(selectionBounds(false)); + case VisibleSelection::RangeSelection: + rect = revealExtent ? VisiblePosition(selection()->extent()).absoluteCaretBounds() : enclosingIntRect(selectionBounds(false)); break; } Position start = selection()->start(); - ASSERT(start.node()); if (start.node() && start.node()->renderer()) { // FIXME: This code only handles scrolling the startContainer's layer, but // the selection rect could intersect more than just that. // See <rdar://problem/4799899>. - if (RenderLayer *layer = start.node()->renderer()->enclosingLayer()) + if (RenderLayer* layer = start.node()->renderer()->enclosingLayer()) layer->scrollRectToVisible(rect, false, alignment, alignment); } } -void Frame::revealCaret(const RenderLayer::ScrollAlignment& alignment) const -{ - if (selection()->isNone()) - return; - - Position extent = selection()->extent(); - if (extent.node() && extent.node()->renderer()) { - IntRect extentRect = VisiblePosition(extent).absoluteCaretBounds(); - RenderLayer* layer = extent.node()->renderer()->enclosingLayer(); - if (layer) - layer->scrollRectToVisible(extentRect, false, alignment, alignment); - } -} - -void Frame::adjustPageHeight(float* newBottom, float oldTop, float oldBottom, float /*bottomLimit*/) -{ - RenderView* root = contentRenderer(); - if (root) { - // Use a context with painting disabled. - GraphicsContext context((PlatformGraphicsContext*)0); - root->setTruncatedAt((int)floorf(oldBottom)); - IntRect dirtyRect(0, (int)floorf(oldTop), root->docWidth(), (int)ceilf(oldBottom - oldTop)); - root->layer()->paint(&context, dirtyRect); - *newBottom = root->bestTruncatedAt(); - if (*newBottom == 0) - *newBottom = oldBottom; - } else - *newBottom = oldBottom; -} - Frame* Frame::frameForWidget(const Widget* widget) { ASSERT_ARG(widget, widget); @@ -1315,74 +1294,11 @@ Frame* Frame::frameForWidget(const Widget* widget) return static_cast<const FrameView*>(widget)->frame(); } -void Frame::forceLayout(bool allowSubtree) -{ - FrameView *v = d->m_view.get(); - if (v) { - v->layout(allowSubtree); - // We cannot unschedule a pending relayout, since the force can be called with - // a tiny rectangle from a drawRect update. By unscheduling we in effect - // "validate" and stop the necessary full repaint from occurring. Basically any basic - // append/remove DHTML is broken by this call. For now, I have removed the optimization - // until we have a better invalidation stategy. -dwh - //v->unscheduleRelayout(); - } -} - -void Frame::forceLayoutWithPageWidthRange(float minPageWidth, float maxPageWidth, bool adjustViewSize) -{ - // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see - // the state of things before and after the layout - RenderView *root = static_cast<RenderView*>(document()->renderer()); - if (root) { - // This magic is basically copied from khtmlview::print - int pageW = (int)ceilf(minPageWidth); - root->setWidth(pageW); - root->setNeedsLayoutAndPrefWidthsRecalc(); - forceLayout(); - - // If we don't fit in the minimum page width, we'll lay out again. If we don't fit in the - // maximum page width, we will lay out to the maximum page width and clip extra content. - // FIXME: We are assuming a shrink-to-fit printing implementation. A cropping - // implementation should not do this! - int rightmostPos = root->rightmostPosition(); - if (rightmostPos > minPageWidth) { - pageW = min(rightmostPos, (int)ceilf(maxPageWidth)); - root->setWidth(pageW); - root->setNeedsLayoutAndPrefWidthsRecalc(); - forceLayout(); - } - } - - if (adjustViewSize && view()) - view()->adjustViewSize(); -} - -void Frame::sendResizeEvent() -{ - if (Document* doc = document()) - doc->dispatchWindowEvent(eventNames().resizeEvent, false, false); -} - -void Frame::sendScrollEvent() -{ - FrameView* v = d->m_view.get(); - if (!v) - return; - v->setWasScrolledByUser(true); - Document* doc = document(); - if (!doc) - return; - doc->dispatchEventForType(eventNames().scrollEvent, true, false); -} - void Frame::clearTimers(FrameView *view, Document *document) { if (view) { view->unscheduleRelayout(); if (view->frame()) { - if (document && document->renderer() && document->renderer()->hasLayer()) - document->renderer()->layer()->suspendMarquees(); view->frame()->animation()->suspendAnimations(document); view->frame()->eventHandler()->stopAutoscrollTimer(); } @@ -1391,15 +1307,13 @@ void Frame::clearTimers(FrameView *view, Document *document) void Frame::clearTimers() { - clearTimers(d->m_view.get(), document()); + clearTimers(m_view.get(), document()); } RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const { nodeToRemove = 0; - if (!document()) - return 0; if (selection()->isNone()) return 0; @@ -1410,14 +1324,13 @@ RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const if (!node) return 0; - if (!d->m_typingStyle) + if (!m_typingStyle) return node->renderer()->style(); - ExceptionCode ec = 0; - RefPtr<Element> styleElement = document()->createElementNS(xhtmlNamespaceURI, "span", ec); - ASSERT(ec == 0); + RefPtr<Element> styleElement = document()->createElement(spanTag, false); - String styleText = d->m_typingStyle->cssText() + " display: inline"; + ExceptionCode ec = 0; + String styleText = m_typingStyle->cssText() + " display: inline"; styleElement->setAttribute(styleAttr, styleText.impl(), ec); ASSERT(ec == 0); @@ -1436,42 +1349,31 @@ void Frame::setSelectionFromNone() // Put a caret inside the body if the entire frame is editable (either the // entire WebView is editable or designMode is on for this document). Document *doc = document(); - if (!doc || !selection()->isNone() || !isContentEditable()) + bool caretBrowsing = settings() && settings()->caretBrowsingEnabled(); + if (!selection()->isNone() || !(isContentEditable() || caretBrowsing)) return; Node* node = doc->documentElement(); while (node && !node->hasTagName(bodyTag)) node = node->traverseNextNode(); if (node) - selection()->setSelection(Selection(Position(node, 0), DOWNSTREAM)); + selection()->setSelection(VisibleSelection(Position(node, 0), DOWNSTREAM)); } bool Frame::inViewSourceMode() const { - return d->m_inViewSourceMode; -} - -void Frame::setInViewSourceMode(bool mode) const -{ - d->m_inViewSourceMode = mode; + return m_inViewSourceMode; } -UChar Frame::backslashAsCurrencySymbol() const +void Frame::setInViewSourceMode(bool mode) { - Document *doc = document(); - if (!doc) - return '\\'; - TextResourceDecoder *decoder = doc->decoder(); - if (!decoder) - return '\\'; - - return decoder->encoding().backslashAsCurrencySymbol(); + m_inViewSourceMode = mode; } // Searches from the beginning of the document if nothing is selected. bool Frame::findString(const String& target, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection) { - if (target.isEmpty() || !document()) + if (target.isEmpty()) return false; if (excludeFromTextSearch()) @@ -1480,7 +1382,7 @@ bool Frame::findString(const String& target, bool forward, bool caseFlag, bool w // Start from an edge of the selection, if there's a selection that's not in shadow content. Which edge // is used depends on whether we're searching forward or backward, and whether startInSelection is set. RefPtr<Range> searchRange(rangeOfContents(document())); - Selection selection = this->selection()->selection(); + VisibleSelection selection = this->selection()->selection(); if (forward) setStart(searchRange.get(), startInSelection ? selection.visibleStart() : selection.visibleEnd()); @@ -1500,7 +1402,7 @@ bool Frame::findString(const String& target, bool forward, bool caseFlag, bool w // If we started in the selection and the found range exactly matches the existing selection, find again. // Build a selection with the found range to remove collapsed whitespace. // Compare ranges instead of selection objects to ignore the way that the current selection was made. - if (startInSelection && *Selection(resultRange.get()).toRange() == *selection.toRange()) { + if (startInSelection && *VisibleSelection(resultRange.get()).toNormalizedRange() == *selection.toNormalizedRange()) { searchRange = rangeOfContents(document()); if (forward) setStart(searchRange.get(), selection.visibleEnd()); @@ -1550,14 +1452,14 @@ bool Frame::findString(const String& target, bool forward, bool caseFlag, bool w if (resultRange->collapsed(exception)) return false; - this->selection()->setSelection(Selection(resultRange.get(), DOWNSTREAM)); + this->selection()->setSelection(VisibleSelection(resultRange.get(), DOWNSTREAM)); revealSelection(); return true; } unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsigned limit) { - if (target.isEmpty() || !document()) + if (target.isEmpty()) return 0; RefPtr<Range> searchRange(rangeOfContents(document())); @@ -1600,13 +1502,13 @@ unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsig // Do a "fake" paint in order to execute the code that computes the rendered rect for // each text match. Document* doc = document(); - if (doc && d->m_view && contentRenderer()) { + if (m_view && contentRenderer()) { doc->updateLayout(); // Ensure layout is up to date. - IntRect visibleRect = d->m_view->visibleContentRect(); + IntRect visibleRect = m_view->visibleContentRect(); if (!visibleRect.isEmpty()) { GraphicsContext context((PlatformGraphicsContext*)0); context.setPaintingDisabled(true); - d->m_view->paintContents(&context, visibleRect); + m_view->paintContents(&context, visibleRect); } } @@ -1615,53 +1517,53 @@ unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsig bool Frame::markedTextMatchesAreHighlighted() const { - return d->m_highlightTextMatches; + return m_highlightTextMatches; } void Frame::setMarkedTextMatchesAreHighlighted(bool flag) { - if (flag == d->m_highlightTextMatches || !document()) + if (flag == m_highlightTextMatches) return; - d->m_highlightTextMatches = flag; + m_highlightTextMatches = flag; document()->repaintMarkers(DocumentMarker::TextMatch); } FrameTree* Frame::tree() const { - return &d->m_treeNode; + return &m_treeNode; } void Frame::setDOMWindow(DOMWindow* domWindow) { - if (d->m_domWindow) { - d->m_liveFormerWindows.add(d->m_domWindow.get()); - d->m_domWindow->clear(); + if (m_domWindow) { + m_liveFormerWindows.add(m_domWindow.get()); + m_domWindow->clear(); } - d->m_domWindow = domWindow; + m_domWindow = domWindow; } DOMWindow* Frame::domWindow() const { - if (!d->m_domWindow) - d->m_domWindow = DOMWindow::create(const_cast<Frame*>(this)); + if (!m_domWindow) + m_domWindow = DOMWindow::create(const_cast<Frame*>(this)); - return d->m_domWindow.get(); + return m_domWindow.get(); } void Frame::clearFormerDOMWindow(DOMWindow* window) { - d->m_liveFormerWindows.remove(window); + m_liveFormerWindows.remove(window); } Page* Frame::page() const { - return d->m_page; + return m_page; } EventHandler* Frame::eventHandler() const { - return &d->m_eventHandler; + return &m_eventHandler; } void Frame::pageDestroyed() @@ -1675,35 +1577,28 @@ void Frame::pageDestroyed() page()->focusController()->setFocusedFrame(0); script()->clearWindowShell(); - - // This will stop any JS timers - if (script()->haveWindowShell()) - script()->windowShell()->disconnectFrame(); - script()->clearScriptObjects(); script()->updatePlatformScriptObjects(); - d->m_page = 0; + m_page = 0; } void Frame::disconnectOwnerElement() { - if (d->m_ownerElement) { + if (m_ownerElement) { if (Document* doc = document()) doc->clearAXObjectCache(); - d->m_ownerElement->m_contentFrame = 0; - if (d->m_page) - d->m_page->decrementFrameCount(); + m_ownerElement->m_contentFrame = 0; + if (m_page) + m_page->decrementFrameCount(); } - d->m_ownerElement = 0; + m_ownerElement = 0; } String Frame::documentTypeString() const { - if (Document* doc = document()) { - if (DocumentType* doctype = doc->doctype()) - return createMarkup(doctype); - } + if (DocumentType* doctype = document()->doctype()) + return createMarkup(doctype); return String(); } @@ -1730,31 +1625,28 @@ void Frame::unfocusWindow() page()->chrome()->unfocus(); } -bool Frame::shouldClose() +bool Frame::shouldClose(RegisteredEventListenerVector* alternateEventListeners) { Chrome* chrome = page() ? page()->chrome() : 0; if (!chrome || !chrome->canRunBeforeUnloadConfirmPanel()) return true; - RefPtr<Document> doc = document(); - if (!doc) + if (!m_domWindow) return true; + + RefPtr<Document> doc = document(); HTMLElement* body = doc->body(); if (!body) return true; - RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create(); - beforeUnloadEvent->setTarget(doc); - doc->handleWindowEvent(beforeUnloadEvent.get(), false); + RefPtr<BeforeUnloadEvent> beforeUnloadEvent = m_domWindow->dispatchBeforeUnloadEvent(alternateEventListeners); - if (!beforeUnloadEvent->defaultPrevented() && doc) + if (!beforeUnloadEvent->defaultPrevented()) doc->defaultEventHandler(beforeUnloadEvent.get()); if (beforeUnloadEvent->result().isNull()) return true; - String text = beforeUnloadEvent->result(); - text.replace('\\', backslashAsCurrencySymbol()); - + String text = doc->displayStringModifiedByEncoding(beforeUnloadEvent->result()); return chrome->runBeforeUnloadConfirmPanel(text, this); } @@ -1768,52 +1660,51 @@ void Frame::scheduleClose() chrome->closeWindowSoon(); } -void Frame::respondToChangedSelection(const Selection& oldSelection, bool closeTyping) +void Frame::respondToChangedSelection(const VisibleSelection& oldSelection, bool closeTyping) { - if (document()) { - bool isContinuousSpellCheckingEnabled = editor()->isContinuousSpellCheckingEnabled(); - bool isContinuousGrammarCheckingEnabled = isContinuousSpellCheckingEnabled && editor()->isGrammarCheckingEnabled(); - if (isContinuousSpellCheckingEnabled) { - Selection newAdjacentWords; - Selection newSelectedSentence; - if (selection()->selection().isContentEditable()) { - VisiblePosition newStart(selection()->selection().visibleStart()); - newAdjacentWords = Selection(startOfWord(newStart, LeftWordIfOnBoundary), endOfWord(newStart, RightWordIfOnBoundary)); - if (isContinuousGrammarCheckingEnabled) - newSelectedSentence = Selection(startOfSentence(newStart), endOfSentence(newStart)); - } + bool isContinuousSpellCheckingEnabled = editor()->isContinuousSpellCheckingEnabled(); + bool isContinuousGrammarCheckingEnabled = isContinuousSpellCheckingEnabled && editor()->isGrammarCheckingEnabled(); + if (isContinuousSpellCheckingEnabled) { + VisibleSelection newAdjacentWords; + VisibleSelection newSelectedSentence; + bool caretBrowsing = settings() && settings()->caretBrowsingEnabled(); + if (selection()->selection().isContentEditable() || caretBrowsing) { + VisiblePosition newStart(selection()->selection().visibleStart()); + newAdjacentWords = VisibleSelection(startOfWord(newStart, LeftWordIfOnBoundary), endOfWord(newStart, RightWordIfOnBoundary)); + if (isContinuousGrammarCheckingEnabled) + newSelectedSentence = VisibleSelection(startOfSentence(newStart), endOfSentence(newStart)); + } - // When typing we check spelling elsewhere, so don't redo it here. - // If this is a change in selection resulting from a delete operation, - // oldSelection may no longer be in the document. - if (closeTyping && oldSelection.isContentEditable() && oldSelection.start().node() && oldSelection.start().node()->inDocument()) { - VisiblePosition oldStart(oldSelection.visibleStart()); - Selection oldAdjacentWords = Selection(startOfWord(oldStart, LeftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary)); - if (oldAdjacentWords != newAdjacentWords) { - editor()->markMisspellings(oldAdjacentWords); - if (isContinuousGrammarCheckingEnabled) { - Selection oldSelectedSentence = Selection(startOfSentence(oldStart), endOfSentence(oldStart)); - if (oldSelectedSentence != newSelectedSentence) - editor()->markBadGrammar(oldSelectedSentence); - } + // When typing we check spelling elsewhere, so don't redo it here. + // If this is a change in selection resulting from a delete operation, + // oldSelection may no longer be in the document. + if (closeTyping && oldSelection.isContentEditable() && oldSelection.start().node() && oldSelection.start().node()->inDocument()) { + VisiblePosition oldStart(oldSelection.visibleStart()); + VisibleSelection oldAdjacentWords = VisibleSelection(startOfWord(oldStart, LeftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary)); + if (oldAdjacentWords != newAdjacentWords) { + if (isContinuousGrammarCheckingEnabled) { + VisibleSelection oldSelectedSentence = VisibleSelection(startOfSentence(oldStart), endOfSentence(oldStart)); + editor()->markMisspellingsAndBadGrammar(oldAdjacentWords, oldSelectedSentence != newSelectedSentence, oldSelectedSentence); + } else { + editor()->markMisspellingsAndBadGrammar(oldAdjacentWords, false, oldAdjacentWords); } } - - // This only erases markers that are in the first unit (word or sentence) of the selection. - // Perhaps peculiar, but it matches AppKit. - if (RefPtr<Range> wordRange = newAdjacentWords.toRange()) - document()->removeMarkers(wordRange.get(), DocumentMarker::Spelling); - if (RefPtr<Range> sentenceRange = newSelectedSentence.toRange()) - document()->removeMarkers(sentenceRange.get(), DocumentMarker::Grammar); } - // When continuous spell checking is off, existing markers disappear after the selection changes. - if (!isContinuousSpellCheckingEnabled) - document()->removeMarkers(DocumentMarker::Spelling); - if (!isContinuousGrammarCheckingEnabled) - document()->removeMarkers(DocumentMarker::Grammar); + // This only erases markers that are in the first unit (word or sentence) of the selection. + // Perhaps peculiar, but it matches AppKit. + if (RefPtr<Range> wordRange = newAdjacentWords.toNormalizedRange()) + document()->removeMarkers(wordRange.get(), DocumentMarker::Spelling); + if (RefPtr<Range> sentenceRange = newSelectedSentence.toNormalizedRange()) + document()->removeMarkers(sentenceRange.get(), DocumentMarker::Grammar); } + // When continuous spell checking is off, existing markers disappear after the selection changes. + if (!isContinuousSpellCheckingEnabled) + document()->removeMarkers(DocumentMarker::Spelling); + if (!isContinuousGrammarCheckingEnabled) + document()->removeMarkers(DocumentMarker::Grammar); + editor()->respondToChangedSelection(oldSelection); } @@ -1826,7 +1717,7 @@ VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint) RenderObject* renderer = node->renderer(); if (!renderer) return VisiblePosition(); - VisiblePosition visiblePos = renderer->positionForCoordinates(result.localPoint().x(), result.localPoint().y()); + VisiblePosition visiblePos = renderer->positionForPoint(result.localPoint()); if (visiblePos.isNull()) visiblePos = VisiblePosition(Position(node, 0)); return visiblePos; @@ -1844,37 +1735,46 @@ Document* Frame::documentAtPoint(const IntPoint& point) result = eventHandler()->hitTestResultAtPoint(pt, false); return result.innerNode() ? result.innerNode()->document() : 0; } - -FramePrivate::FramePrivate(Page* page, Frame* parent, Frame* thisFrame, HTMLFrameOwnerElement* ownerElement, - FrameLoaderClient* frameLoaderClient) - : m_page(page) - , m_treeNode(thisFrame, parent) - , m_loader(thisFrame, frameLoaderClient) - , m_ownerElement(ownerElement) - , m_script(thisFrame) - , m_zoomFactor(parent ? parent->d->m_zoomFactor : 1.0f) - , m_selectionGranularity(CharacterGranularity) - , m_selectionController(thisFrame) - , m_caretBlinkTimer(thisFrame, &Frame::caretBlinkTimerFired) - , m_editor(thisFrame) - , m_eventHandler(thisFrame) - , m_animationController(thisFrame) - , m_lifeSupportTimer(thisFrame, &Frame::lifeSupportTimerFired) - , m_caretVisible(false) - , m_caretPaint(true) - , m_highlightTextMatches(false) - , m_inViewSourceMode(false) - , m_needsReapplyStyles(false) - , m_isDisconnected(false) - , m_excludeFromTextSearch(false) -#if FRAME_LOADS_USER_STYLESHEET - , m_userStyleSheetLoader(0) -#endif -{ -} -FramePrivate::~FramePrivate() +void Frame::createView(const IntSize& viewportSize, + const Color& backgroundColor, bool transparent, + const IntSize& fixedLayoutSize, bool useFixedLayout, + ScrollbarMode horizontalScrollbarMode, ScrollbarMode verticalScrollbarMode) { + ASSERT(this); + ASSERT(m_page); + + bool isMainFrame = this == m_page->mainFrame(); + + if (isMainFrame && view()) + view()->setParentVisible(false); + + setView(0); + + RefPtr<FrameView> frameView; + if (isMainFrame) { + frameView = FrameView::create(this, viewportSize); + frameView->setFixedLayoutSize(fixedLayoutSize); + frameView->setUseFixedLayout(useFixedLayout); + } else + frameView = FrameView::create(this); + + frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode); + frameView->updateDefaultScrollbarState(); + + setView(frameView); + + if (backgroundColor.isValid()) + frameView->updateBackgroundRecursively(backgroundColor, transparent); + + if (isMainFrame) + frameView->setParentVisible(true); + + if (ownerRenderer()) + ownerRenderer()->setWidget(frameView.get()); + + if (HTMLFrameOwnerElement* owner = ownerElement()) + view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff); } } // namespace WebCore |