Added the missing parameters to make it possible to do POST operations from the publi...
[WebKit-https.git] / WebKit / qt / Api / qwebframe.cpp
1 /*
2     Copyright (C) 2007 Trolltech ASA
3     Copyright (C) 2007 Staikos Computing Services Inc.
4
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.
9
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.
14
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.
19
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.
22 */
23 #include "config.h"
24 #include "qwebframe.h"
25 #include "qwebpage.h"
26 #include "qwebpage_p.h"
27 #include "qwebframe_p.h"
28 #include "qwebnetworkinterface.h"
29
30 #include "FocusController.h"
31 #include "FrameLoaderClientQt.h"
32 #include "Frame.h"
33 #include "FrameTree.h"
34 #include "FrameView.h"
35 #include "IconDatabase.h"
36 #include "Page.h"
37 #include "ResourceRequest.h"
38 #include "SelectionController.h"
39 #include "PlatformScrollBar.h"
40 #include "SubstituteData.h"
41
42 #include "markup.h"
43 #include "RenderTreeAsText.h"
44 #include "Element.h"
45 #include "Document.h"
46 #include "DragData.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"
54
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"
61 #include "object.h"
62
63 #include "wtf/HashMap.h"
64
65 #include <qdebug.h>
66 #include <qevent.h>
67 #include <qpainter.h>
68 #if QT_VERSION >= 0x040400
69 #include <qnetworkrequest.h>
70 #endif
71
72 using namespace WebCore;
73
74 void QWebFramePrivate::init(QWebFrame *qframe, WebCore::Page *webcorePage, QWebFrameData *frameData)
75 {
76     q = qframe;
77
78     frameLoaderClient = new FrameLoaderClientQt();
79     frame = new Frame(webcorePage, frameData->ownerElement, frameLoaderClient);
80     frameLoaderClient->setFrame(qframe, frame.get());
81
82     frameView = new FrameView(frame.get());
83     frameView->deref();
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);
91
92     frame->setView(frameView.get());
93     frame->init();
94     eventHandler = frame->eventHandler();
95
96     QObject::connect(q, SIGNAL(hoveringOverLink(const QString&, const QString&, const QString&)),
97                      page, SIGNAL(hoveringOverLink(const QString&, const QString&, const QString&)));
98 }
99
100 QWebFrame *QWebFramePrivate::parentFrame()
101 {
102     return qobject_cast<QWebFrame*>(q->parent());
103 }
104
105 WebCore::PlatformScrollbar *QWebFramePrivate::horizontalScrollBar() const
106 {
107     Q_ASSERT(frameView);
108     return frameView->horizontalScrollBar();
109 }
110
111 WebCore::PlatformScrollbar *QWebFramePrivate::verticalScrollBar() const
112 {
113     Q_ASSERT(frameView);
114     return frameView->verticalScrollBar();
115 }
116
117 QWebFrame::QWebFrame(QWebPage *parent, QWebFrameData *frameData)
118     : QObject(parent)
119     , d(new QWebFramePrivate)
120 {
121     d->page = parent;
122     d->init(this, parent->d->page, frameData);
123
124     if (!frameData->url.isEmpty()) {
125         ResourceRequest request(frameData->url, frameData->referrer);
126         d->frame->loader()->load(request, frameData->name);
127     }
128 }
129
130 QWebFrame::QWebFrame(QWebFrame *parent, QWebFrameData *frameData)
131     : QObject(parent)
132     , d(new QWebFramePrivate)
133 {
134     d->page = parent->d->page;
135     d->init(this, parent->d->page->d->page, frameData);
136 }
137
138 QWebFrame::~QWebFrame()
139 {
140     Q_ASSERT(d->frame == 0);
141     Q_ASSERT(d->frameView == 0);
142     delete d;
143 }
144
145 void QWebFrame::addToJSWindowObject(const QString &name, QObject *object)
146 {
147       KJS::JSLock lock;
148       KJS::Window *window = KJS::Window::retrieveWindow(d->frame.get());
149       KJS::Bindings::RootObject *root = d->frame->bindingRootObject();
150       if (!window) {
151           qDebug() << "Warning: couldn't get window object";
152           return;
153       }
154
155       KJS::JSObject *runtimeObject =
156         KJS::Bindings::Instance::createRuntimeObject(KJS::Bindings::Instance::QtLanguage,
157                                                      object, root);
158
159       window->put(window->globalExec(), KJS::Identifier((const KJS::UChar *) name.constData(), name.length()), runtimeObject);
160 }
161
162
163 QString QWebFrame::markup() const
164 {
165     if (!d->frame->document())
166         return QString();
167     return createMarkup(d->frame->document());
168 }
169
170 QString QWebFrame::innerText() const
171 {
172     if (d->frameView->layoutPending())
173         d->frameView->layout();
174
175     Element *documentElement = d->frame->document()->documentElement();
176     return documentElement->innerText();
177 }
178
179 QString QWebFrame::renderTreeDump() const
180 {
181     if (d->frameView->layoutPending())
182         d->frameView->layout();
183
184     return externalRepresentation(d->frame->renderer());
185 }
186
187 QString QWebFrame::title() const
188 {
189     if (d->frame->document())
190         return d->frame->document()->title();
191     else return QString();
192 }
193
194 QUrl QWebFrame::url() const
195 {
196     return QUrl((QString)d->frame->loader()->url().string());
197 }
198
199 QPixmap QWebFrame::icon() const
200 {
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));
205     }
206
207     if (!image) {
208         return QPixmap();
209     }
210
211     QPixmap *icon = image->getPixmap();
212     if (!icon) {
213         return QPixmap();
214     }
215     return *icon;
216 }
217
218
219 QString QWebFrame::name() const
220 {
221     return d->frame->tree()->name();
222 }
223
224 QWebPage * QWebFrame::page() const
225 {
226     return d->page;
227 }
228
229 void QWebFrame::load(const QUrl &url)
230 {
231 #if QT_VERSION < 0x040400
232     load(QWebNetworkRequest(url));
233 #else
234     load(QNetworkRequest(url));
235 #endif
236 }
237
238 #if QT_VERSION < 0x040400
239 void QWebFrame::load(const QWebNetworkRequest &req)
240 {
241     if (d->parentFrame())
242         d->page->d->insideOpenCall = true;
243
244     QUrl url = req.url();
245     QHttpRequestHeader httpHeader = req.httpHeader();
246     QByteArray postData = req.postData();
247
248     WebCore::ResourceRequest request(KURL(url.toString()));
249
250     QString method = httpHeader.method();
251     if (!method.isEmpty())
252         request.setHTTPMethod(method);
253
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);
258     }
259
260     if (!postData.isEmpty()) {
261         WTF::RefPtr<WebCore::FormData> formData = new WebCore::FormData(postData.constData(), postData.size());
262         request.setHTTPBody(formData);
263     }
264
265     d->frame->loader()->load(request);
266
267     if (d->parentFrame())
268         d->page->d->insideOpenCall = false;
269 }
270
271 #else
272
273 void QWebFrame::load(const QNetworkRequest &req,
274                      QNetworkAccessManager::Operation operation,
275                      const QByteArray &body)
276 {
277     if (d->parentFrame())
278         d->page->d->insideOpenCall = true;
279
280     QUrl url = req.url();
281
282     WebCore::ResourceRequest request(KURL(url.toString()));
283
284     switch (operation) {
285         case QNetworkAccessManager::HeadOperation:
286             request.setHTTPMethod("HEAD");
287             break;
288         case QNetworkAccessManager::GetOperation:
289             request.setHTTPMethod("GET");
290             break;
291         case QNetworkAccessManager::PutOperation:
292             request.setHTTPMethod("PUT");
293             break;
294         case QNetworkAccessManager::PostOperation:
295             request.setHTTPMethod("POST");
296             break;
297         case QNetworkAccessManager::UnknownOperation:
298             // eh?
299             break;
300     }
301
302     QList<QByteArray> httpHeaders = req.rawHeaderList();
303     for (int i = 0; i < httpHeaders.size(); ++i) {
304         const QByteArray &headerName = httpHeaders.at(i);
305         request.addHTTPHeaderField(QString::fromLatin1(headerName), QString::fromLatin1(req.rawHeader(headerName)));
306     }
307
308     if (!body.isEmpty()) {
309         WTF::RefPtr<WebCore::FormData> formData = new WebCore::FormData(body.constData(), body.size());
310         request.setHTTPBody(formData);
311     }
312
313     d->frame->loader()->load(request);
314
315     if (d->parentFrame())
316         d->page->d->insideOpenCall = false;
317 }
318 #endif
319
320 void QWebFrame::setHtml(const QString &html, const QUrl &baseUrl)
321 {
322     KURL kurl(baseUrl.toString());
323     WebCore::ResourceRequest request(kurl);
324     WTF::RefPtr<WebCore::SharedBuffer> data = new WebCore::SharedBuffer(reinterpret_cast<const uchar *>(html.unicode()), html.length() * 2);
325     WebCore::SubstituteData substituteData(data, WebCore::String("text/html"), WebCore::String("utf-16"), kurl);
326     d->frame->loader()->load(request, substituteData);
327 }
328
329 void QWebFrame::setHtml(const QByteArray &html, const QUrl &baseUrl)
330 {
331     setContent(html, QString(), baseUrl);
332 }
333
334 void QWebFrame::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
335 {
336     KURL kurl(baseUrl.toString());
337     WebCore::ResourceRequest request(kurl);
338     WTF::RefPtr<WebCore::SharedBuffer> buffer = new WebCore::SharedBuffer(data.constData(), data.length());
339     QString actualMimeType = mimeType;
340     if (actualMimeType.isEmpty())
341         actualMimeType = QLatin1String("text/html");
342     WebCore::SubstituteData substituteData(buffer, WebCore::String(actualMimeType), WebCore::String(), kurl);
343     d->frame->loader()->load(request, substituteData);
344 }
345
346 QList<QWebFrame*> QWebFrame::childFrames() const
347 {
348     QList<QWebFrame*> rc;
349     if (d->frame) {
350         FrameTree *tree = d->frame->tree();
351         for (Frame *child = tree->firstChild(); child; child = child->tree()->nextSibling()) {
352             FrameLoader *loader = child->loader();
353             FrameLoaderClientQt *client = static_cast<FrameLoaderClientQt*>(loader->client());
354             if (client)
355                 rc.append(client->webFrame());
356         }
357
358     }
359     return rc;
360 }
361
362
363 Qt::ScrollBarPolicy QWebFrame::verticalScrollBarPolicy() const
364 {
365     return (Qt::ScrollBarPolicy) d->frameView->vScrollbarMode();
366 }
367
368 void QWebFrame::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy)
369 {
370     Q_ASSERT((int)ScrollbarAuto == (int)Qt::ScrollBarAsNeeded);
371     Q_ASSERT((int)ScrollbarAlwaysOff == (int)Qt::ScrollBarAlwaysOff);
372     Q_ASSERT((int)ScrollbarAlwaysOn == (int)Qt::ScrollBarAlwaysOn);
373     d->frameView->setVScrollbarMode((ScrollbarMode)policy);
374 }
375
376 Qt::ScrollBarPolicy QWebFrame::horizontalScrollBarPolicy() const
377 {
378     return (Qt::ScrollBarPolicy) d->frameView->hScrollbarMode();
379 }
380
381 void QWebFrame::setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy)
382 {
383     d->frameView->setHScrollbarMode((ScrollbarMode)policy);
384 }
385
386 void QWebFrame::render(QPainter *painter, const QRect &source)
387 {
388     if (!d->frameView || !d->frame->renderer())
389         return;
390
391     layout();
392
393     GraphicsContext ctx(painter);
394     d->frameView->paint(&ctx, source);
395 }
396
397 void QWebFrame::layout()
398 {
399     if (!d->frameView)
400         return;
401
402     d->frameView->layoutIfNeededRecursive();
403 }
404
405 QPoint QWebFrame::pos() const
406 {
407     Q_ASSERT(d->frameView);
408     return d->pos();
409 }
410
411 QRect QWebFrame::geometry() const
412 {
413     Q_ASSERT(d->frameView);
414     return d->frameView->frameGeometry();
415 }
416
417 QString QWebFrame::evaluateJavaScript(const QString& scriptSource)
418 {
419     KJSProxy *proxy = d->frame->scriptProxy();
420     QString rc;
421     if (proxy) {
422         KJS::JSValue *v = proxy->evaluate(String(), 0, scriptSource);
423         if (v) {
424             rc = String(v->toString(proxy->globalObject()->globalExec()));
425         }
426     }
427     return rc;
428 }
429