take a QString as identifier in QWebFrame::addToJSWindowObject.
[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
69 using namespace WebCore;
70
71 void QWebFramePrivate::init(QWebFrame *qframe, WebCore::Page *webcorePage, QWebFrameData *frameData)
72 {
73     q = qframe;
74
75     frameLoaderClient = new FrameLoaderClientQt();
76     frame = new Frame(webcorePage, frameData->ownerElement, frameLoaderClient);
77     frameLoaderClient->setFrame(qframe, frame.get());
78
79     frameView = new FrameView(frame.get());
80     frameView->deref();
81     frameView->setQWebFrame(qframe);
82     if (!frameData->allowsScrolling)
83         frameView->setScrollbarsMode(ScrollbarAlwaysOff);
84     if (frameData->marginWidth != -1)
85         frameView->setMarginWidth(frameData->marginWidth);
86     if (frameData->marginHeight != -1)
87         frameView->setMarginHeight(frameData->marginHeight);
88
89     frame->setView(frameView.get());
90     frame->init();
91     eventHandler = frame->eventHandler();
92
93     QObject::connect(q, SIGNAL(hoveringOverLink(const QString&, const QString&, const QString&)),
94                      page, SIGNAL(hoveringOverLink(const QString&, const QString&, const QString&)));
95 }
96
97 QWebFrame *QWebFramePrivate::parentFrame()
98 {
99     return qobject_cast<QWebFrame*>(q->parent());
100 }
101
102 WebCore::PlatformScrollbar *QWebFramePrivate::horizontalScrollBar() const
103 {
104     Q_ASSERT(frameView);
105     return frameView->horizontalScrollBar();
106 }
107
108 WebCore::PlatformScrollbar *QWebFramePrivate::verticalScrollBar() const
109 {
110     Q_ASSERT(frameView);
111     return frameView->verticalScrollBar();
112 }
113
114 QWebFrame::QWebFrame(QWebPage *parent, QWebFrameData *frameData)
115     : QObject(parent)
116     , d(new QWebFramePrivate)
117 {
118     d->page = parent;
119     d->init(this, parent->d->page, frameData);
120
121     if (!frameData->url.isEmpty()) {
122         ResourceRequest request(frameData->url, frameData->referrer);
123         d->frame->loader()->load(request, frameData->name);
124     }
125 }
126
127 QWebFrame::QWebFrame(QWebFrame *parent, QWebFrameData *frameData)
128     : QObject(parent)
129     , d(new QWebFramePrivate)
130 {
131     d->page = parent->d->page;
132     d->init(this, parent->d->page->d->page, frameData);
133 }
134
135 QWebFrame::~QWebFrame()
136 {
137     Q_ASSERT(d->frame == 0);
138     Q_ASSERT(d->frameView == 0);
139     delete d;
140 }
141
142 void QWebFrame::addToJSWindowObject(const QString &name, QObject *object)
143 {
144       KJS::JSLock lock;
145       KJS::Window *window = KJS::Window::retrieveWindow(d->frame.get());
146       KJS::Bindings::RootObject *root = d->frame->bindingRootObject();
147       if (!window) {
148           qDebug() << "Warning: couldn't get window object";
149           return;
150       }
151
152       KJS::JSObject *runtimeObject =
153         KJS::Bindings::Instance::createRuntimeObject(KJS::Bindings::Instance::QtLanguage,
154                                                      object, root);
155
156       window->put(window->globalExec(), KJS::Identifier((const KJS::UChar *) name.constData(), name.length()), runtimeObject);
157 }
158
159
160 QString QWebFrame::markup() const
161 {
162     if (!d->frame->document())
163         return QString();
164     return createMarkup(d->frame->document());
165 }
166
167 QString QWebFrame::innerText() const
168 {
169     if (d->frameView->layoutPending())
170         d->frameView->layout();
171
172     Element *documentElement = d->frame->document()->documentElement();
173     return documentElement->innerText();
174 }
175
176 QString QWebFrame::renderTreeDump() const
177 {
178     if (d->frameView->layoutPending())
179         d->frameView->layout();
180
181     return externalRepresentation(d->frame->renderer());
182 }
183
184 QString QWebFrame::title() const
185 {
186     if (d->frame->document())
187         return d->frame->document()->title();
188     else return QString();
189 }
190
191 QUrl QWebFrame::url() const
192 {
193     return QUrl((QString)d->frame->loader()->url().string());
194 }
195
196 QPixmap QWebFrame::icon() const
197 {
198     String url = d->frame->loader()->url().string();
199     Image* image = iconDatabase()->iconForPageURL(url, IntSize(16, 16));
200     if (!image || image->isNull()) {
201         image = iconDatabase()->defaultIcon(IntSize(16, 16));
202     }
203
204     if (!image) {
205         return QPixmap();
206     }
207
208     QPixmap *icon = image->getPixmap();
209     if (!icon) {
210         return QPixmap();
211     }
212     return *icon;
213 }
214
215
216 QString QWebFrame::name() const
217 {
218     return d->frame->tree()->name();
219 }
220
221 QWebPage * QWebFrame::page() const
222 {
223     return d->page;
224 }
225
226 void QWebFrame::load(const QUrl &url)
227 {
228     load(QWebNetworkRequest(url));
229 }
230
231 void QWebFrame::load(const QWebNetworkRequest &req)
232 {
233     if (d->parentFrame())
234         d->page->d->insideOpenCall = true;
235
236     QUrl url = req.url();
237     QHttpRequestHeader httpHeader = req.httpHeader();
238     QByteArray postData = req.postData();
239
240     WebCore::ResourceRequest request(KURL(url.toString()));
241
242     QString method = httpHeader.method();
243     if (!method.isEmpty())
244         request.setHTTPMethod(method);
245
246     QList<QPair<QString, QString> > values = httpHeader.values();
247     for (int i = 0; i < values.size(); ++i) {
248         const QPair<QString, QString> &val = values.at(i);
249         request.addHTTPHeaderField(val.first, val.second);
250     }
251
252     if (!postData.isEmpty()) {
253         WTF::RefPtr<WebCore::FormData> formData = new WebCore::FormData(postData.constData(), postData.size());
254         request.setHTTPBody(formData);
255     }
256
257     d->frame->loader()->load(request);
258
259     if (d->parentFrame())
260         d->page->d->insideOpenCall = false;
261 }
262
263 void QWebFrame::setHtml(const QString &html, const QUrl &baseUrl)
264 {
265     KURL kurl(baseUrl.toString());
266     WebCore::ResourceRequest request(kurl);
267     WTF::RefPtr<WebCore::SharedBuffer> data = new WebCore::SharedBuffer(reinterpret_cast<const uchar *>(html.unicode()), html.length() * 2);
268     WebCore::SubstituteData substituteData(data, WebCore::String("text/html"), WebCore::String("utf-16"), kurl);
269     d->frame->loader()->load(request, substituteData);
270 }
271
272 void QWebFrame::setHtml(const QByteArray &html, const QUrl &baseUrl)
273 {
274     setContent(html, QString(), baseUrl);
275 }
276
277 void QWebFrame::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
278 {
279     KURL kurl(baseUrl.toString());
280     WebCore::ResourceRequest request(kurl);
281     WTF::RefPtr<WebCore::SharedBuffer> buffer = new WebCore::SharedBuffer(data.constData(), data.length());
282     QString actualMimeType = mimeType;
283     if (actualMimeType.isEmpty())
284         actualMimeType = QLatin1String("text/html");
285     WebCore::SubstituteData substituteData(buffer, WebCore::String(actualMimeType), WebCore::String(), kurl);
286     d->frame->loader()->load(request, substituteData);
287 }
288
289 QList<QWebFrame*> QWebFrame::childFrames() const
290 {
291     QList<QWebFrame*> rc;
292     if (d->frame) {
293         FrameTree *tree = d->frame->tree();
294         for (Frame *child = tree->firstChild(); child; child = child->tree()->nextSibling()) {
295             FrameLoader *loader = child->loader();
296             FrameLoaderClientQt *client = static_cast<FrameLoaderClientQt*>(loader->client());
297             if (client)
298                 rc.append(client->webFrame());
299         }
300
301     }
302     return rc;
303 }
304
305
306 Qt::ScrollBarPolicy QWebFrame::verticalScrollBarPolicy() const
307 {
308     return (Qt::ScrollBarPolicy) d->frameView->vScrollbarMode();
309 }
310
311 void QWebFrame::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy)
312 {
313     Q_ASSERT((int)ScrollbarAuto == (int)Qt::ScrollBarAsNeeded);
314     Q_ASSERT((int)ScrollbarAlwaysOff == (int)Qt::ScrollBarAlwaysOff);
315     Q_ASSERT((int)ScrollbarAlwaysOn == (int)Qt::ScrollBarAlwaysOn);
316     d->frameView->setVScrollbarMode((ScrollbarMode)policy);
317 }
318
319 Qt::ScrollBarPolicy QWebFrame::horizontalScrollBarPolicy() const
320 {
321     return (Qt::ScrollBarPolicy) d->frameView->hScrollbarMode();
322 }
323
324 void QWebFrame::setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy)
325 {
326     d->frameView->setHScrollbarMode((ScrollbarMode)policy);
327 }
328
329 void QWebFrame::render(QPainter *painter, const QRect &source)
330 {
331     if (!d->frameView || !d->frame->renderer())
332         return;
333
334     layout();
335
336     GraphicsContext ctx(painter);
337     d->frameView->paint(&ctx, source);
338 }
339
340 void QWebFrame::layout()
341 {
342     if (!d->frameView)
343         return;
344
345     d->frameView->layoutIfNeededRecursive();
346 }
347
348 QPoint QWebFrame::pos() const
349 {
350     Q_ASSERT(d->frameView);
351     return d->pos();
352 }
353
354 QRect QWebFrame::geometry() const
355 {
356     Q_ASSERT(d->frameView);
357     return d->frameView->frameGeometry();
358 }
359
360 QString QWebFrame::evaluateJavaScript(const QString& scriptSource)
361 {
362     KJSProxy *proxy = d->frame->scriptProxy();
363     QString rc;
364     if (proxy) {
365         KJS::JSValue *v = proxy->evaluate(String(), 0, scriptSource);
366         if (v) {
367             rc = String(v->toString(proxy->globalObject()->globalExec()));
368         }
369     }
370     return rc;
371 }
372