diff -r 000000000000 -r 4f2f89ce4247 WebKit/qt/Api/qwebframe.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebKit/qt/Api/qwebframe.cpp Fri Sep 17 09:02:29 2010 +0300 @@ -0,0 +1,1790 @@ +/* + Copyright (C) 2008,2009 Nokia Corporation and/or its subsidiary(-ies) + Copyright (C) 2007 Staikos Computing Services Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "qwebframe.h" + +#include "Bridge.h" +#include "CallFrame.h" +#include "Document.h" +#include "DocumentLoader.h" +#include "DragData.h" +#include "Element.h" +#include "FocusController.h" +#include "Frame.h" +#include "FrameLoaderClientQt.h" +#include "FrameTree.h" +#include "FrameView.h" +#include "GCController.h" +#include "GraphicsContext.h" +#include "HTMLMetaElement.h" +#include "HitTestResult.h" +#include "IconDatabase.h" +#include "InspectorController.h" +#include "JSDOMBinding.h" +#include "JSDOMWindowBase.h" +#include "JSLock.h" +#include "JSObject.h" +#include "NodeList.h" +#include "Page.h" +#include "PlatformMouseEvent.h" +#include "PlatformWheelEvent.h" +#include "PrintContext.h" +#include "PutPropertySlot.h" +#include "RenderLayer.h" +#include "RenderTreeAsText.h" +#include "RenderView.h" +#include "ResourceRequest.h" +#include "ScriptController.h" +#include "ScriptSourceCode.h" +#include "ScriptValue.h" +#include "Scrollbar.h" +#include "Settings.h" +#include "SelectionController.h" +#include "SubstituteData.h" +#include "SVGSMILElement.h" +#include "TiledBackingStore.h" +#include "htmlediting.h" +#include "markup.h" +#include "qt_instance.h" +#include "qt_runtime.h" +#include "qwebelement.h" +#include "qwebframe_p.h" +#include "qwebpage.h" +#include "qwebpage_p.h" +#include "qwebsecurityorigin.h" +#include "qwebsecurityorigin_p.h" +#include "qwebscriptworld.h" +#include "qwebscriptworld_p.h" +#include "runtime_object.h" +#include "runtime_root.h" +#include "wtf/HashMap.h" +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace WebCore; + +// from text/qfont.cpp +QT_BEGIN_NAMESPACE +extern Q_GUI_EXPORT int qt_defaultDpi(); +QT_END_NAMESPACE + +bool QWEBKIT_EXPORT qtwebkit_webframe_scrollOverflow(QWebFrame* qFrame, int dx, int dy, const QPoint& pos) +{ + WebCore::Frame* frame = QWebFramePrivate::core(qFrame); + if (!frame || !frame->document() || !frame->view() || !frame->eventHandler()) + return false; + + QPoint contentsPos = frame->view()->windowToContents(pos); + Node* node = frame->document()->elementFromPoint(contentsPos.x(), contentsPos.y()); + if (!node) + return false; + + RenderObject* renderer = node->renderer(); + if (!renderer) + return false; + + if (renderer->isListBox()) + return false; + + RenderLayer* renderLayer = renderer->enclosingLayer(); + if (!renderLayer) + return false; + + bool scrolledHorizontal = false; + bool scrolledVertical = false; + + do { + if (dx > 0) + scrolledHorizontal = renderLayer->scroll(ScrollRight, ScrollByPixel, dx); + else if (dx < 0) + scrolledHorizontal = renderLayer->scroll(ScrollLeft, ScrollByPixel, qAbs(dx)); + + if (dy > 0) + scrolledVertical = renderLayer->scroll(ScrollDown, ScrollByPixel, dy); + else if (dy < 0) + scrolledVertical = renderLayer->scroll(ScrollUp, ScrollByPixel, qAbs(dy)); + + if (scrolledHorizontal || scrolledVertical) + return true; + + renderLayer = renderLayer->parent(); + } while (renderLayer); + + return false; +} + + +/*! + \internal + Scrolls nested frames starting at this frame, \a dx pixels to the right + and \a dy pixels downward. Both \a dx and \a dy may be negative. First attempts + to scroll elements with CSS overflow at position pos, followed by this frame. If this + frame doesn't scroll, attempts to scroll the parent +*/ +void QWEBKIT_EXPORT qtwebkit_webframe_scrollRecursively(QWebFrame* qFrame, int dx, int dy, const QPoint& pos) +{ + if (!qFrame) + return; + + if (qtwebkit_webframe_scrollOverflow(qFrame, dx, dy, pos)) + return; + + bool scrollHorizontal = false; + bool scrollVertical = false; + + do { + if (dx > 0) // scroll right + scrollHorizontal = qFrame->scrollBarValue(Qt::Horizontal) < qFrame->scrollBarMaximum(Qt::Horizontal); + else if (dx < 0) // scroll left + scrollHorizontal = qFrame->scrollBarValue(Qt::Horizontal) > qFrame->scrollBarMinimum(Qt::Horizontal); + + if (dy > 0) // scroll down + scrollVertical = qFrame->scrollBarValue(Qt::Vertical) < qFrame->scrollBarMaximum(Qt::Vertical); + else if (dy < 0) //scroll up + scrollVertical = qFrame->scrollBarValue(Qt::Vertical) > qFrame->scrollBarMinimum(Qt::Vertical); + + if (scrollHorizontal || scrollVertical) { + qFrame->scroll(dx, dy); + return; + } + + qFrame = qFrame->parentFrame(); + } while (qFrame); +} + +QWebFrameData::QWebFrameData(WebCore::Page* parentPage, WebCore::Frame* parentFrame, + WebCore::HTMLFrameOwnerElement* ownerFrameElement, + const WebCore::String& frameName) + : name(frameName) + , ownerElement(ownerFrameElement) + , page(parentPage) + , allowsScrolling(true) + , marginWidth(0) + , marginHeight(0) +{ + frameLoaderClient = new FrameLoaderClientQt(); + frame = Frame::create(page, ownerElement, frameLoaderClient); + + // FIXME: All of the below should probably be moved over into WebCore + frame->tree()->setName(name); + if (parentFrame) + parentFrame->tree()->appendChild(frame); +} + +void QWebFramePrivate::init(QWebFrame *qframe, QWebFrameData *frameData) +{ + q = qframe; + + allowsScrolling = frameData->allowsScrolling; + marginWidth = frameData->marginWidth; + marginHeight = frameData->marginHeight; + frame = frameData->frame.get(); + frameLoaderClient = frameData->frameLoaderClient; + frameLoaderClient->setFrame(qframe, frame); + + frame->init(); +} + +void QWebFramePrivate::setPage(QWebPage* newPage) +{ + if (page == newPage) + return; + + // The QWebFrame is created as a child of QWebPage or a parent QWebFrame. + // That adds it to QObject's internal children list and ensures it will be + // deleted when parent QWebPage is deleted. Reparent if needed. + if (q->parent() == qobject_cast(page)) + q->setParent(newPage); + + page = newPage; + emit q->pageChanged(); +} + +WebCore::Scrollbar* QWebFramePrivate::horizontalScrollBar() const +{ + if (!frame->view()) + return 0; + return frame->view()->horizontalScrollbar(); +} + +WebCore::Scrollbar* QWebFramePrivate::verticalScrollBar() const +{ + if (!frame->view()) + return 0; + return frame->view()->verticalScrollbar(); +} + +#if ENABLE(TILED_BACKING_STORE) +void QWebFramePrivate::renderFromTiledBackingStore(GraphicsContext* context, const QRegion& clip) +{ + ASSERT(frame->tiledBackingStore()); + + if (!frame->view() || !frame->contentRenderer()) + return; + + QVector vector = clip.rects(); + if (vector.isEmpty()) + return; + + QPainter* painter = context->platformContext(); + + WebCore::FrameView* view = frame->view(); + + int scrollX = view->scrollX(); + int scrollY = view->scrollY(); + context->translate(-scrollX, -scrollY); + + for (int i = 0; i < vector.size(); ++i) { + const QRect& clipRect = vector.at(i); + + painter->save(); + + QRect rect = clipRect.translated(scrollX, scrollY); + painter->setClipRect(rect, Qt::IntersectClip); + + frame->tiledBackingStore()->paint(context, rect); + + painter->restore(); + } +} +#endif + +void QWebFramePrivate::renderRelativeCoords(GraphicsContext* context, QWebFrame::RenderLayer layer, const QRegion& clip) +{ + if (!frame->view() || !frame->contentRenderer()) + return; + + QVector vector = clip.rects(); + if (vector.isEmpty()) + return; + + QPainter* painter = context->platformContext(); + + WebCore::FrameView* view = frame->view(); + view->layoutIfNeededRecursive(); + + for (int i = 0; i < vector.size(); ++i) { + const QRect& clipRect = vector.at(i); + + QRect intersectedRect = clipRect.intersected(view->frameRect()); + + painter->save(); + painter->setClipRect(clipRect, Qt::IntersectClip); + + int x = view->x(); + int y = view->y(); + + if (layer & QWebFrame::ContentsLayer) { + context->save(); + + int scrollX = view->scrollX(); + int scrollY = view->scrollY(); + + QRect rect = intersectedRect; + context->translate(x, y); + rect.translate(-x, -y); + context->translate(-scrollX, -scrollY); + rect.translate(scrollX, scrollY); + context->clip(view->visibleContentRect()); + + view->paintContents(context, rect); + + context->restore(); + } + + if (layer & QWebFrame::ScrollBarLayer + && !view->scrollbarsSuppressed() + && (view->horizontalScrollbar() || view->verticalScrollbar())) { + context->save(); + + QRect rect = intersectedRect; + context->translate(x, y); + rect.translate(-x, -y); + + view->paintScrollbars(context, rect); + + context->restore(); + } + +#if ENABLE(PAN_SCROLLING) + if (layer & QWebFrame::PanIconLayer) + view->paintPanScrollIcon(context); +#endif + + painter->restore(); + } +} + +/*! + \class QWebFrame + \since 4.4 + \brief The QWebFrame class represents a frame in a web page. + + \inmodule QtWebKit + + QWebFrame represents a frame inside a web page. Each QWebPage + object contains at least one frame, the main frame, obtained using + QWebPage::mainFrame(). Additional frames will be created for HTML + \c{} or \c{