2 Copyright (C) 2007 Trolltech ASA
3 Copyright (C) 2007 Staikos Computing Services Inc.
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
20 This class provides all functionality needed for loading images, style sheets and html
21 pages from the web. It has a memory cache for these objects.
24 #include "qwebframe.h"
26 #include "qwebpage_p.h"
27 #include "qwebframe_p.h"
28 #include "qwebnetworkinterface.h"
30 #include "FocusController.h"
31 #include "FrameLoaderClientQt.h"
33 #include "FrameTree.h"
34 #include "FrameView.h"
35 #include "IconDatabase.h"
37 #include "ResourceRequest.h"
38 #include "SelectionController.h"
39 #include "PlatformScrollBar.h"
40 #include "SubstituteData.h"
43 #include "RenderTreeAsText.h"
47 #include "RenderObject.h"
48 #include "GraphicsContext.h"
49 #include "PlatformScrollBar.h"
50 #include "PlatformMouseEvent.h"
51 #include "PlatformWheelEvent.h"
52 #include "GraphicsContext.h"
53 #include "HitTestResult.h"
55 #include "bindings/runtime.h"
56 #include "bindings/runtime_root.h"
57 #include "kjs_proxy.h"
58 #include "kjs_window.h"
59 #include "kjs_binding.h"
60 #include "ExecState.h"
63 #include "wtf/HashMap.h"
68 #if QT_VERSION >= 0x040400
69 #include <qnetworkrequest.h>
72 using namespace WebCore;
74 void QWebFramePrivate::init(QWebFrame *qframe, WebCore::Page *webcorePage, QWebFrameData *frameData)
78 frameLoaderClient = new FrameLoaderClientQt();
79 frame = new Frame(webcorePage, frameData->ownerElement, frameLoaderClient);
80 frameLoaderClient->setFrame(qframe, frame.get());
82 frameView = new FrameView(frame.get());
84 frameView->setQWebFrame(qframe);
85 if (!frameData->allowsScrolling)
86 frameView->setScrollbarsMode(ScrollbarAlwaysOff);
87 if (frameData->marginWidth != -1)
88 frameView->setMarginWidth(frameData->marginWidth);
89 if (frameData->marginHeight != -1)
90 frameView->setMarginHeight(frameData->marginHeight);
92 frame->setView(frameView.get());
94 eventHandler = frame->eventHandler();
96 QObject::connect(q, SIGNAL(hoveringOverLink(const QString&, const QString&, const QString&)),
97 page, SIGNAL(hoveringOverLink(const QString&, const QString&, const QString&)));
100 QWebFrame *QWebFramePrivate::parentFrame()
102 return qobject_cast<QWebFrame*>(q->parent());
105 WebCore::PlatformScrollbar *QWebFramePrivate::horizontalScrollBar() const
108 return frameView->horizontalScrollBar();
111 WebCore::PlatformScrollbar *QWebFramePrivate::verticalScrollBar() const
114 return frameView->verticalScrollBar();
117 QWebFrame::QWebFrame(QWebPage *parent, QWebFrameData *frameData)
119 , d(new QWebFramePrivate)
122 d->init(this, parent->d->page, frameData);
124 if (!frameData->url.isEmpty()) {
125 ResourceRequest request(frameData->url, frameData->referrer);
126 d->frame->loader()->load(request, frameData->name);
130 QWebFrame::QWebFrame(QWebFrame *parent, QWebFrameData *frameData)
132 , d(new QWebFramePrivate)
134 d->page = parent->d->page;
135 d->init(this, parent->d->page->d->page, frameData);
138 QWebFrame::~QWebFrame()
140 Q_ASSERT(d->frame == 0);
141 Q_ASSERT(d->frameView == 0);
145 void QWebFrame::addToJSWindowObject(const QString &name, QObject *object)
148 KJS::Window *window = KJS::Window::retrieveWindow(d->frame.get());
149 KJS::Bindings::RootObject *root = d->frame->bindingRootObject();
151 qDebug() << "Warning: couldn't get window object";
155 KJS::JSObject *runtimeObject =
156 KJS::Bindings::Instance::createRuntimeObject(KJS::Bindings::Instance::QtLanguage,
159 window->put(window->globalExec(), KJS::Identifier((const KJS::UChar *) name.constData(), name.length()), runtimeObject);
163 QString QWebFrame::markup() const
165 if (!d->frame->document())
167 return createMarkup(d->frame->document());
170 QString QWebFrame::innerText() const
172 if (d->frameView->layoutPending())
173 d->frameView->layout();
175 Element *documentElement = d->frame->document()->documentElement();
176 return documentElement->innerText();
179 QString QWebFrame::renderTreeDump() const
181 if (d->frameView->layoutPending())
182 d->frameView->layout();
184 return externalRepresentation(d->frame->renderer());
187 QString QWebFrame::title() const
189 if (d->frame->document())
190 return d->frame->document()->title();
191 else return QString();
194 QUrl QWebFrame::url() const
196 return QUrl((QString)d->frame->loader()->url().string());
199 QPixmap QWebFrame::icon() const
201 String url = d->frame->loader()->url().string();
202 Image* image = iconDatabase()->iconForPageURL(url, IntSize(16, 16));
203 if (!image || image->isNull()) {
204 image = iconDatabase()->defaultIcon(IntSize(16, 16));
211 QPixmap *icon = image->getPixmap();
219 QString QWebFrame::name() const
221 return d->frame->tree()->name();
224 QWebPage * QWebFrame::page() const
229 void QWebFrame::load(const QUrl &url)
231 #if QT_VERSION < 0x040400
232 load(QWebNetworkRequest(url));
234 load(QNetworkRequest(url));
238 #if QT_VERSION < 0x040400
239 void QWebFrame::load(const QWebNetworkRequest &req)
241 if (d->parentFrame())
242 d->page->d->insideOpenCall = true;
244 QUrl url = req.url();
245 QHttpRequestHeader httpHeader = req.httpHeader();
246 QByteArray postData = req.postData();
248 WebCore::ResourceRequest request(KURL(url.toString()));
250 QString method = httpHeader.method();
251 if (!method.isEmpty())
252 request.setHTTPMethod(method);
254 QList<QPair<QString, QString> > values = httpHeader.values();
255 for (int i = 0; i < values.size(); ++i) {
256 const QPair<QString, QString> &val = values.at(i);
257 request.addHTTPHeaderField(val.first, val.second);
260 if (!postData.isEmpty()) {
261 WTF::RefPtr<WebCore::FormData> formData = new WebCore::FormData(postData.constData(), postData.size());
262 request.setHTTPBody(formData);
265 d->frame->loader()->load(request);
267 if (d->parentFrame())
268 d->page->d->insideOpenCall = false;
273 void QWebFrame::load(const QNetworkRequest &req)
275 if (d->parentFrame())
276 d->page->d->insideOpenCall = true;
278 QUrl url = req.url();
279 QByteArray postData; // ### FIXME = req.postData();
281 WebCore::ResourceRequest request(KURL(url.toString()));
283 // ### FIXME httpHeader.method();
285 QList<QByteArray> httpHeaders = req.rawHeaderList();
286 for (int i = 0; i < httpHeaders.size(); ++i) {
287 const QByteArray &headerName = httpHeaders.at(i);
288 request.addHTTPHeaderField(QString::fromLatin1(headerName), QString::fromLatin1(req.rawHeader(headerName)));
291 if (!postData.isEmpty()) {
292 WTF::RefPtr<WebCore::FormData> formData = new WebCore::FormData(postData.constData(), postData.size());
293 request.setHTTPBody(formData);
296 d->frame->loader()->load(request);
298 if (d->parentFrame())
299 d->page->d->insideOpenCall = false;
303 void QWebFrame::setHtml(const QString &html, const QUrl &baseUrl)
305 KURL kurl(baseUrl.toString());
306 WebCore::ResourceRequest request(kurl);
307 WTF::RefPtr<WebCore::SharedBuffer> data = new WebCore::SharedBuffer(reinterpret_cast<const uchar *>(html.unicode()), html.length() * 2);
308 WebCore::SubstituteData substituteData(data, WebCore::String("text/html"), WebCore::String("utf-16"), kurl);
309 d->frame->loader()->load(request, substituteData);
312 void QWebFrame::setHtml(const QByteArray &html, const QUrl &baseUrl)
314 setContent(html, QString(), baseUrl);
317 void QWebFrame::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
319 KURL kurl(baseUrl.toString());
320 WebCore::ResourceRequest request(kurl);
321 WTF::RefPtr<WebCore::SharedBuffer> buffer = new WebCore::SharedBuffer(data.constData(), data.length());
322 QString actualMimeType = mimeType;
323 if (actualMimeType.isEmpty())
324 actualMimeType = QLatin1String("text/html");
325 WebCore::SubstituteData substituteData(buffer, WebCore::String(actualMimeType), WebCore::String(), kurl);
326 d->frame->loader()->load(request, substituteData);
329 QList<QWebFrame*> QWebFrame::childFrames() const
331 QList<QWebFrame*> rc;
333 FrameTree *tree = d->frame->tree();
334 for (Frame *child = tree->firstChild(); child; child = child->tree()->nextSibling()) {
335 FrameLoader *loader = child->loader();
336 FrameLoaderClientQt *client = static_cast<FrameLoaderClientQt*>(loader->client());
338 rc.append(client->webFrame());
346 Qt::ScrollBarPolicy QWebFrame::verticalScrollBarPolicy() const
348 return (Qt::ScrollBarPolicy) d->frameView->vScrollbarMode();
351 void QWebFrame::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy)
353 Q_ASSERT((int)ScrollbarAuto == (int)Qt::ScrollBarAsNeeded);
354 Q_ASSERT((int)ScrollbarAlwaysOff == (int)Qt::ScrollBarAlwaysOff);
355 Q_ASSERT((int)ScrollbarAlwaysOn == (int)Qt::ScrollBarAlwaysOn);
356 d->frameView->setVScrollbarMode((ScrollbarMode)policy);
359 Qt::ScrollBarPolicy QWebFrame::horizontalScrollBarPolicy() const
361 return (Qt::ScrollBarPolicy) d->frameView->hScrollbarMode();
364 void QWebFrame::setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy)
366 d->frameView->setHScrollbarMode((ScrollbarMode)policy);
369 void QWebFrame::render(QPainter *painter, const QRect &source)
371 if (!d->frameView || !d->frame->renderer())
376 GraphicsContext ctx(painter);
377 d->frameView->paint(&ctx, source);
380 void QWebFrame::layout()
385 d->frameView->layoutIfNeededRecursive();
388 QPoint QWebFrame::pos() const
390 Q_ASSERT(d->frameView);
394 QRect QWebFrame::geometry() const
396 Q_ASSERT(d->frameView);
397 return d->frameView->frameGeometry();
400 QString QWebFrame::evaluateJavaScript(const QString& scriptSource)
402 KJSProxy *proxy = d->frame->scriptProxy();
405 KJS::JSValue *v = proxy->evaluate(String(), 0, scriptSource);
407 rc = String(v->toString(proxy->globalObject()->globalExec()));