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"
29 #include "DocumentLoader.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"
56 #include "runtime_root.h"
57 #include "JSDOMWindow.h"
58 #include "qt_instance.h"
59 #include "kjs_proxy.h"
60 #include "kjs_binding.h"
61 #include "ExecState.h"
64 #include "wtf/HashMap.h"
69 #if QT_VERSION >= 0x040400
70 #include <qnetworkrequest.h>
72 #include "qwebnetworkinterface.h"
76 using namespace WebCore;
78 void QWebFramePrivate::init(QWebFrame *qframe, WebCore::Page *webcorePage, QWebFrameData *frameData)
82 allowsScrolling = frameData->allowsScrolling;
83 marginWidth = frameData->marginWidth;
84 marginHeight = frameData->marginHeight;
86 frameLoaderClient = new FrameLoaderClientQt();
87 frame = new Frame(webcorePage, frameData->ownerElement, frameLoaderClient);
88 frameLoaderClient->setFrame(qframe, frame);
91 QObject::connect(q, SIGNAL(hoveringOverLink(const QString&, const QString&, const QString&)),
92 page, SIGNAL(hoveringOverLink(const QString&, const QString&, const QString&)));
95 WebCore::PlatformScrollbar *QWebFramePrivate::horizontalScrollBar() const
99 return frame->view()->horizontalScrollBar();
102 WebCore::PlatformScrollbar *QWebFramePrivate::verticalScrollBar() const
106 return frame->view()->verticalScrollBar();
112 \brief The QWebFrame class represents a frame in a web page.
114 QWebFrame represents a frame inside a web page. Each QWebPage
115 object contains at least one frame, the mainFrame(). Additional
116 frames will be created for HTML <frame> or <iframe>
119 QWebFrame objects are created and controlled by the web page. You
120 can connect to the web pages frameCreated() signal to find out
121 about creation of new frames.
126 QWebFrame::QWebFrame(QWebPage *parent, QWebFrameData *frameData)
128 , d(new QWebFramePrivate)
131 d->init(this, parent->d->page, frameData);
133 if (!frameData->url.isEmpty()) {
134 ResourceRequest request(frameData->url, frameData->referrer);
135 d->frame->loader()->load(request, frameData->name);
139 QWebFrame::QWebFrame(QWebFrame *parent, QWebFrameData *frameData)
141 , d(new QWebFramePrivate)
143 d->page = parent->d->page;
144 d->init(this, parent->d->page->d->page, frameData);
147 QWebFrame::~QWebFrame()
149 if (d->frame && d->frame->loader() && d->frame->loader()->client())
150 static_cast<FrameLoaderClientQt*>(d->frame->loader()->client())->m_webFrame = 0;
156 Make \a object available under \a name from within the frames
157 JavaScript context. The \a object will be inserted as a child of the
158 frames window object.
160 Qt properties will be exposed as JavaScript properties and slots as
163 void QWebFrame::addToJSWindowObject(const QString &name, QObject *object)
166 JSDOMWindow *window = toJSDOMWindow(d->frame);
167 KJS::Bindings::RootObject *root = d->frame->bindingRootObject();
169 qDebug() << "Warning: couldn't get window object";
173 KJS::JSObject *runtimeObject =
174 KJS::Bindings::Instance::createRuntimeObject(KJS::Bindings::QtInstance::create(object, root));
176 window->put(window->globalExec(), KJS::Identifier((const UChar *) name.constData(), name.length()), runtimeObject);
180 returns the markup (HTML) contained in the current frame.
182 QString QWebFrame::markup() const
184 if (!d->frame->document())
186 return createMarkup(d->frame->document());
190 returns the content of this frame as plain text.
192 QString QWebFrame::innerText() const
194 if (d->frame->view() && d->frame->view()->layoutPending())
195 d->frame->view()->layout();
197 Element *documentElement = d->frame->document()->documentElement();
198 return documentElement->innerText();
202 returns a dump of the rendering tree. Mainly useful for debugging html.
204 QString QWebFrame::renderTreeDump() const
206 if (d->frame->view() && d->frame->view()->layoutPending())
207 d->frame->view()->layout();
209 return externalRepresentation(d->frame->renderer());
213 The title of the frame as defined by the HTML <title>
216 QString QWebFrame::title() const
218 if (d->frame->document())
219 return d->frame->loader()->documentLoader()->title();
220 else return QString();
224 The url of this frame.
226 QUrl QWebFrame::url() const
228 return d->frame->loader()->url();
232 The icon associated with this frame.
234 QPixmap QWebFrame::icon() const
236 String url = d->frame->loader()->url().string();
239 if (!url.isEmpty()) {
240 image = iconDatabase()->iconForPageURL(url, IntSize(16, 16));
243 if (!image || image->isNull()) {
244 image = iconDatabase()->defaultIcon(IntSize(16, 16));
251 QPixmap *icon = image->getPixmap();
259 The name of this frame as defined by the parent frame.
261 QString QWebFrame::name() const
263 return d->frame->tree()->name();
267 The web page that contains this frame.
269 QWebPage *QWebFrame::page() const
275 Load \a url into this frame.
277 void QWebFrame::load(const QUrl &url)
279 #if QT_VERSION < 0x040400
280 load(QWebNetworkRequest(url));
282 load(QNetworkRequest(url));
286 #if QT_VERSION < 0x040400
288 Load network request \a req into this frame.
290 void QWebFrame::load(const QWebNetworkRequest &req)
292 if (d->parentFrame())
293 d->page->d->insideOpenCall = true;
295 QUrl url = req.url();
296 QHttpRequestHeader httpHeader = req.httpHeader();
297 QByteArray postData = req.postData();
299 WebCore::ResourceRequest request(url);
301 QString method = httpHeader.method();
302 if (!method.isEmpty())
303 request.setHTTPMethod(method);
305 QList<QPair<QString, QString> > values = httpHeader.values();
306 for (int i = 0; i < values.size(); ++i) {
307 const QPair<QString, QString> &val = values.at(i);
308 request.addHTTPHeaderField(val.first, val.second);
311 if (!postData.isEmpty())
312 request.setHTTPBody(WebCore::FormData::create(postData.constData(), postData.size()));
314 d->frame->loader()->load(request);
316 if (d->parentFrame())
317 d->page->d->insideOpenCall = false;
323 Load network request \a req into this frame. Use the method specified in \a
324 operation. \a body is optional and is only used for POST operations.
326 void QWebFrame::load(const QNetworkRequest &req,
327 QNetworkAccessManager::Operation operation,
328 const QByteArray &body)
330 if (d->parentFrame())
331 d->page->d->insideOpenCall = true;
333 QUrl url = req.url();
335 WebCore::ResourceRequest request(url);
338 case QNetworkAccessManager::HeadOperation:
339 request.setHTTPMethod("HEAD");
341 case QNetworkAccessManager::GetOperation:
342 request.setHTTPMethod("GET");
344 case QNetworkAccessManager::PutOperation:
345 request.setHTTPMethod("PUT");
347 case QNetworkAccessManager::PostOperation:
348 request.setHTTPMethod("POST");
350 case QNetworkAccessManager::UnknownOperation:
355 QList<QByteArray> httpHeaders = req.rawHeaderList();
356 for (int i = 0; i < httpHeaders.size(); ++i) {
357 const QByteArray &headerName = httpHeaders.at(i);
358 request.addHTTPHeaderField(QString::fromLatin1(headerName), QString::fromLatin1(req.rawHeader(headerName)));
362 request.setHTTPBody(WebCore::FormData::create(body.constData(), body.size()));
364 d->frame->loader()->load(request);
366 if (d->parentFrame())
367 d->page->d->insideOpenCall = false;
372 Sets the content of this frame to \a html. \a baseUrl is optional and used to resolve relative
373 URLs in the document.
375 void QWebFrame::setHtml(const QString &html, const QUrl &baseUrl)
378 WebCore::ResourceRequest request(kurl);
379 WTF::RefPtr<WebCore::SharedBuffer> data = WebCore::SharedBuffer::create(reinterpret_cast<const uchar *>(html.unicode()), html.length() * 2);
380 WebCore::SubstituteData substituteData(data, WebCore::String("text/html"), WebCore::String("utf-16"), kurl);
381 d->frame->loader()->load(request, substituteData);
387 void QWebFrame::setHtml(const QByteArray &html, const QUrl &baseUrl)
389 setContent(html, QString(), baseUrl);
393 Sets the content of this frame to \a data assuming \a mimeType. If
394 \a mimeType is not specified it defaults to 'text/html'. \a baseUrl
395 us optional and used to resolve relative URLs in the document.
397 void QWebFrame::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
400 WebCore::ResourceRequest request(kurl);
401 WTF::RefPtr<WebCore::SharedBuffer> buffer = WebCore::SharedBuffer::create(data.constData(), data.length());
402 QString actualMimeType = mimeType;
403 if (actualMimeType.isEmpty())
404 actualMimeType = QLatin1String("text/html");
405 WebCore::SubstituteData substituteData(buffer, WebCore::String(actualMimeType), WebCore::String(), kurl);
406 d->frame->loader()->load(request, substituteData);
411 Returns the parent frame of this frame, or 0 if the frame is the web pages
414 This is equivalent to qobject_cast<QWebFrame*>(frame->parent()).
416 QWebFrame *QWebFrame::parentFrame() const
418 return d->parentFrame();
422 Returns a list of all frames that are direct children of this frame.
424 QList<QWebFrame*> QWebFrame::childFrames() const
426 QList<QWebFrame*> rc;
428 FrameTree *tree = d->frame->tree();
429 for (Frame *child = tree->firstChild(); child; child = child->tree()->nextSibling()) {
430 FrameLoader *loader = child->loader();
431 FrameLoaderClientQt *client = static_cast<FrameLoaderClientQt*>(loader->client());
433 rc.append(client->webFrame());
441 \property QWebFrame::verticalScrollBarPolicy
443 This property defines the vertical scrollbar policy.
445 \sa Qt::ScrollBarPolicy
447 Qt::ScrollBarPolicy QWebFrame::verticalScrollBarPolicy() const
449 return d->verticalScrollBarPolicy;
452 void QWebFrame::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy)
454 Q_ASSERT((int)ScrollbarAuto == (int)Qt::ScrollBarAsNeeded);
455 Q_ASSERT((int)ScrollbarAlwaysOff == (int)Qt::ScrollBarAlwaysOff);
456 Q_ASSERT((int)ScrollbarAlwaysOn == (int)Qt::ScrollBarAlwaysOn);
458 d->verticalScrollBarPolicy = policy;
459 if (d->frame->view())
460 d->frame->view()->setVScrollbarMode((ScrollbarMode)policy);
464 \property QWebFrame::horizontalScrollBarPolicy
466 This property defines the horizontal scrollbar policy.
468 \sa Qt::ScrollBarPolicy
470 Qt::ScrollBarPolicy QWebFrame::horizontalScrollBarPolicy() const
472 return d->horizontalScrollBarPolicy;
475 void QWebFrame::setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy)
477 d->horizontalScrollBarPolicy = policy;
478 if (d->frame->view())
479 d->frame->view()->setHScrollbarMode((ScrollbarMode)policy);
483 Render the frame into \a painter clipping to \a clip.
485 void QWebFrame::render(QPainter *painter, const QRegion &clip)
487 if (!d->frame->view() || !d->frame->renderer())
492 GraphicsContext ctx(painter);
493 QVector<QRect> vector = clip.rects();
494 WebCore::FrameView* view = d->frame->view();
495 for (int i = 0; i < vector.size(); ++i)
496 view->paint(&ctx, vector.at(i));
500 Ensure that the content of the frame and all subframes are correctly layouted.
502 void QWebFrame::layout()
504 if (!d->frame->view())
507 d->frame->view()->layoutIfNeededRecursive();
511 returns the position of the frame relative to it's parent frame.
513 QPoint QWebFrame::pos() const
515 if (!d->frame->view())
518 return d->frame->view()->frameGeometry().topLeft();
522 return the geometry of the frame relative to it's parent frame.
524 QRect QWebFrame::geometry() const
526 if (!d->frame->view())
528 return d->frame->view()->frameGeometry();
532 Evaluate JavaScript defined by \a scriptSource using this frame as context.
534 QString QWebFrame::evaluateJavaScript(const QString& scriptSource)
536 KJSProxy *proxy = d->frame->scriptProxy();
539 KJS::JSValue *v = proxy->evaluate(String(), 0, scriptSource);
541 rc = String(v->toString(proxy->globalObject()->globalExec()));
547 WebCore::Frame* QWebFramePrivate::core(QWebFrame* webFrame)
549 return webFrame->d->frame;
552 QWebFrame* QWebFramePrivate::kit(WebCore::Frame* coreFrame)
554 return static_cast<FrameLoaderClientQt*>(coreFrame->loader()->client())->webFrame();
559 \fn void QWebFrame::cleared()
561 This signal is emitted whenever the content of the frame is cleared
562 (e.g. before starting a new load).
566 \fn void QWebFrame::loadDone(bool ok)
568 This signal is emitted when the frame is completely loaded. \a ok will indicate whether the load
569 was successful or any error occurred.
573 \fn void QWebFrame::provisionalLoad()
579 \fn void QWebFrame::titleChanged(const QString &title)
581 This signal is emitted whenever the title of the frame changes.
582 The \a title string specifies the new title.
588 \fn void QWebFrame::urlChanged(const QUrl &url)
590 This signal is emitted whenever the \a url of the frame changes.
596 \fn void QWebFrame::hoveringOverLink(const QString &link, const QString &title, const QString &textContent)
598 This signal is emitted whenever the mouse cursor is hovering over a
599 link. It can be used to display information about the link in
600 e.g. the status bar. The signal arguments consist of the \a link destination, the \a title and the
601 link text as \a textContent .
606 \fn void QWebFrame::loadStarted()
608 This signal is emitted when a new load of the frame is started.
612 \fn void QWebFrame::loadFinished()
614 This signal is emitted when a load of the frame is finished.
618 \fn void QWebFrame::initialLayoutComplete()
620 This signal is emitted when the first (initial) layout of the frame
621 has happened. This is the earliest time something can be shown on
626 \fn void QWebFrame::iconLoaded()
628 This signal is emitted when the icon ("favicon") associated with the frame has been loaded.