c92ef7771cc621dd50eb12f8cbf9f2ad09456976
[WebKit-https.git] / WebKit / gtk / Api / webkitgtkpage.cpp
1 /*
2  * Copyright (C) 2007 Holger Hans Peter Freyther
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer. 
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution. 
13  * 3.  Neither the name of Apple, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30
31 #include "webkitgtkpage.h"
32 #include "webkitgtk-marshal.h"
33 #include "webkitgtkprivate.h"
34
35 #include "NotImplemented.h"
36 #include "ChromeClientGtk.h"
37 #include "ContextMenuClientGtk.h"
38 #include "DragClientGtk.h"
39 #include "EditorClientGtk.h"
40 #include "EventHandler.h"
41 #include "HitTestRequest.h"
42 #include "HitTestResult.h"
43 #include "GraphicsContext.h"
44 #include "InspectorClientGtk.h"
45 #include "FrameLoader.h"
46 #include "FrameView.h"
47 #include "PlatformKeyboardEvent.h"
48 #include "PlatformWheelEvent.h"
49 #include "SubstituteData.h"
50
51
52 using namespace WebKit;
53 using namespace WebCore;
54
55 extern "C" {
56
57 enum {
58     /* normal signals */
59     LOAD_STARTED,
60     LOAD_PROGRESS_CHANGED,
61     LOAD_FINISHED,
62     TITLE_CHANGED,
63     HOVERING_OVER_LINK,
64     STATUS_BAR_TEXT_CHANGED,
65     ICOND_LOADED,
66     SELECTION_CHANGED,
67     LAST_SIGNAL
68 };
69
70 static guint webkit_page_signals[LAST_SIGNAL] = { 0, };
71
72 G_DEFINE_TYPE(WebKitPage, webkit_page, GTK_TYPE_CONTAINER)
73
74 static gboolean webkit_page_expose_event(GtkWidget* widget, GdkEventExpose* event)
75 {
76     Frame* frame = core(getFrameFromPage(WEBKIT_PAGE(widget)));
77     GdkRectangle clip;
78     gdk_region_get_clipbox(event->region, &clip);
79     cairo_t* cr = gdk_cairo_create(event->window);
80     GraphicsContext ctx(cr);
81     ctx.setGdkExposeEvent(event);
82     if (frame->renderer()) {
83         frame->view()->layoutIfNeededRecursive();
84         IntRect rect(clip.x, clip.y, clip.width, clip.height);
85         frame->view()->paint(&ctx, rect);
86     }
87     cairo_destroy(cr);
88
89     return FALSE;
90 }
91
92 static gboolean webkit_page_key_event(GtkWidget* widget, GdkEventKey* event)
93 {
94     Frame* frame = core(getFrameFromPage(WEBKIT_PAGE(widget)));
95     frame->eventHandler()->keyEvent(PlatformKeyboardEvent(event));
96     return FALSE;
97 }
98
99 static gboolean webkit_page_button_event(GtkWidget* widget, GdkEventButton* event)
100 {
101     Frame* frame = core(getFrameFromPage(WEBKIT_PAGE(widget)));
102
103     if (event->type == GDK_BUTTON_RELEASE)
104         frame->eventHandler()->handleMouseReleaseEvent(PlatformMouseEvent(event));
105     else {
106         frame->eventHandler()->handleMousePressEvent(PlatformMouseEvent(event));
107
108         //FIXME need to keep track of subframe focus for key events!
109         gtk_widget_grab_focus(GTK_WIDGET(widget));
110     }
111
112     return FALSE;
113 }
114
115 static gboolean webkit_page_motion_event(GtkWidget* widget, GdkEventMotion* event)
116 {
117     Frame* frame = core(getFrameFromPage(WEBKIT_PAGE(widget)));
118     frame->eventHandler()->mouseMoved(PlatformMouseEvent(event));
119     return FALSE;
120 }
121
122 static gboolean webkit_page_scroll_event(GtkWidget* widget, GdkEventScroll* event)
123 {
124     Frame* frame = core(getFrameFromPage(WEBKIT_PAGE(widget)));
125
126     PlatformWheelEvent wheelEvent(event);
127     frame->eventHandler()->handleWheelEvent(wheelEvent);
128     return FALSE;
129 }
130
131 static void webkit_page_size_allocate(GtkWidget* widget, GtkAllocation* allocation)
132 {
133     GTK_WIDGET_CLASS(webkit_page_parent_class)->size_allocate(widget,allocation);
134
135     Frame* frame = core(getFrameFromPage(WEBKIT_PAGE(widget)));
136     frame->view()->resize(allocation->width, allocation->height);
137     frame->forceLayout();
138     frame->view()->adjustViewSize();
139     frame->sendResizeEvent();
140 }
141
142 static void webkit_page_realize(GtkWidget* widget)
143 {
144     GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
145
146     GdkWindowAttr attributes;
147     attributes.window_type = GDK_WINDOW_CHILD;
148     attributes.x = widget->allocation.x;
149     attributes.y = widget->allocation.y;
150     attributes.width = widget->allocation.width;
151     attributes.height = widget->allocation.height;
152     attributes.wclass = GDK_INPUT_OUTPUT;
153     attributes.visual = gtk_widget_get_visual (widget);
154     attributes.colormap = gtk_widget_get_colormap (widget);
155     attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK
156                             | GDK_EXPOSURE_MASK
157                             | GDK_BUTTON_PRESS_MASK
158                             | GDK_BUTTON_RELEASE_MASK
159                             | GDK_POINTER_MOTION_MASK
160                             | GDK_KEY_PRESS_MASK
161                             | GDK_KEY_RELEASE_MASK
162                             | GDK_BUTTON_MOTION_MASK
163                             | GDK_BUTTON1_MOTION_MASK
164                             | GDK_BUTTON2_MOTION_MASK
165                             | GDK_BUTTON3_MOTION_MASK;
166
167     gint attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
168     widget->window = gdk_window_new(gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
169     gdk_window_set_user_data(widget->window, widget);
170 }
171
172 static void webkit_page_map(GtkWidget* widget)
173 {
174     GTK_WIDGET_SET_FLAGS(widget, GTK_MAPPED);
175     WebKitPagePrivate* private_data = WEBKIT_PAGE_GET_PRIVATE(WEBKIT_PAGE(widget));
176
177     HashSet<GtkWidget*>::const_iterator end = private_data->children.end();
178     for (HashSet<GtkWidget*>::const_iterator current = private_data->children.begin(); current != end; ++current)
179         if (GTK_WIDGET_VISIBLE(*current) && !GTK_WIDGET_MAPPED(*current))
180             gtk_widget_map((*current));
181
182     gdk_window_show(widget->window);
183 }
184
185 static void webkit_page_set_scroll_adjustments(WebKitPage* page, GtkAdjustment* hadj, GtkAdjustment* vadj)
186 {
187     FrameView* view = core(getFrameFromPage(page))->view();
188     view->setGtkAdjustments(hadj, vadj);
189 }
190
191 static void webkit_page_container_add(GtkContainer* container, GtkWidget* widget)
192 {
193     WebKitPage* page = WEBKIT_PAGE(container);
194     WebKitPagePrivate* private_data = WEBKIT_PAGE_GET_PRIVATE(page);
195
196     private_data->children.add(widget);
197     if (GTK_WIDGET_REALIZED(container))
198         gtk_widget_set_parent_window(widget, GTK_WIDGET(page)->window);
199     gtk_widget_set_parent(widget, GTK_WIDGET(container));
200 }
201
202 static void webkit_page_container_remove(GtkContainer* container, GtkWidget* widget)
203 {
204     WebKitPagePrivate* private_data = WEBKIT_PAGE_GET_PRIVATE(WEBKIT_PAGE(container));
205
206     if (private_data->children.contains(widget)) {
207         gtk_widget_unparent(widget);
208         private_data->children.remove(widget);
209     }
210 }
211
212 static void webkit_page_container_forall(GtkContainer* container, gboolean, GtkCallback callback, gpointer callbackData)
213 {
214     WebKitPagePrivate* privateData = WEBKIT_PAGE_GET_PRIVATE(WEBKIT_PAGE(container));
215
216     HashSet<GtkWidget*> children = privateData->children;
217     HashSet<GtkWidget*>::const_iterator end = children.end();
218     for (HashSet<GtkWidget*>::const_iterator current = children.begin(); current != end; ++current)
219         (*callback)(*current, callbackData);
220 }
221
222 static WebKitPage* webkit_page_real_create_page(WebKitPage*)
223 {
224     notImplemented();
225     return 0;
226 }
227
228 static WEBKIT_NAVIGATION_REQUEST_RESPONSE webkit_page_real_navigation_requested(WebKitPage*, WebKitFrame* frame, WebKitNetworkRequest*)
229 {
230     notImplemented();
231     return WEBKIT_ACCEPT_NAVIGATION_REQUEST;
232 }
233
234 static gchar* webkit_page_real_choose_file(WebKitPage*, WebKitFrame*, const gchar* old_name)
235 {
236     notImplemented();
237     return g_strdup(old_name);
238 }
239
240 static void webkit_page_real_java_script_alert(WebKitPage*, WebKitFrame*, const gchar*)
241 {
242     notImplemented();
243 }
244
245 static gboolean webkit_page_real_java_script_confirm(WebKitPage*, WebKitFrame*, const gchar*)
246 {
247     notImplemented();
248     return FALSE;
249 }
250
251 /**
252  * WebKitPage::java_script_prompt
253  *
254  * @return: NULL to cancel the prompt
255  */
256 static gchar* webkit_page_real_java_script_prompt(WebKitPage*, WebKitFrame*, const gchar*, const gchar* defaultValue)
257 {
258     notImplemented();
259     return g_strdup(defaultValue);
260 }
261
262 static void webkit_page_real_java_script_console_message(WebKitPage*, const gchar*, unsigned int, const gchar*)
263 {
264     notImplemented();
265 }
266
267 static void webkit_page_finalize(GObject* object)
268 {
269     webkit_page_stop_loading(WEBKIT_PAGE(object));
270
271     WebKitPagePrivate* pageData = WEBKIT_PAGE_GET_PRIVATE(WEBKIT_PAGE(object));
272     delete pageData->page;
273     delete pageData->settings;
274     g_object_unref(pageData->mainFrame);
275     delete pageData->userAgent;
276
277     G_OBJECT_CLASS(webkit_page_parent_class)->finalize(object);
278 }
279
280 static void webkit_page_class_init(WebKitPageClass* pageClass)
281 {
282     g_type_class_add_private(pageClass, sizeof(WebKitPagePrivate));
283
284
285     /*
286      * signals
287      */
288     /**
289      * WebKitPage::load-started
290      * @page: the object on which the signal is emitted
291      * @frame: the frame going to do the load
292      *
293      * When a WebKitFrame begins to load this signal is emitted.
294      */
295     webkit_page_signals[LOAD_STARTED] = g_signal_new("load_started",
296             G_TYPE_FROM_CLASS(pageClass),
297             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
298             0,
299             NULL,
300             NULL,
301             g_cclosure_marshal_VOID__OBJECT,
302             G_TYPE_NONE, 1,
303             WEBKIT_TYPE_FRAME);
304
305     /**
306      * WebKitPage::load-progress-changed
307      * @page: The WebKitPage
308      * @progress: Global progress
309      */
310     webkit_page_signals[LOAD_PROGRESS_CHANGED] = g_signal_new("load_progress_changed",
311             G_TYPE_FROM_CLASS(pageClass),
312             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
313             0,
314             NULL,
315             NULL,
316             g_cclosure_marshal_VOID__INT,
317             G_TYPE_NONE, 1,
318             G_TYPE_INT);
319     
320     webkit_page_signals[LOAD_FINISHED] = g_signal_new("load_finished",
321             G_TYPE_FROM_CLASS(pageClass),
322             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
323             0,
324             NULL,
325             NULL,
326             g_cclosure_marshal_VOID__OBJECT,
327             G_TYPE_NONE, 1,
328             WEBKIT_TYPE_FRAME);
329
330     webkit_page_signals[TITLE_CHANGED] = g_signal_new("title_changed",
331             G_TYPE_FROM_CLASS(pageClass),
332             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
333             0,
334             NULL,
335             NULL,
336             webkit_marshal_VOID__STRING_STRING,
337             G_TYPE_NONE, 2,
338             G_TYPE_STRING, G_TYPE_STRING);
339
340     webkit_page_signals[HOVERING_OVER_LINK] = g_signal_new("hovering_over_link",
341             G_TYPE_FROM_CLASS(pageClass),
342             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
343             0,
344             NULL,
345             NULL,
346             webkit_marshal_VOID__STRING_STRING,
347             G_TYPE_NONE, 2,
348             G_TYPE_STRING,
349             G_TYPE_STRING);
350
351     webkit_page_signals[STATUS_BAR_TEXT_CHANGED] = g_signal_new("status_bar_text_changed",
352             G_TYPE_FROM_CLASS(pageClass),
353             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
354             0,
355             NULL,
356             NULL,
357             g_cclosure_marshal_VOID__STRING,
358             G_TYPE_NONE, 1,
359             G_TYPE_STRING);
360
361     webkit_page_signals[ICOND_LOADED] = g_signal_new("icon_loaded",
362             G_TYPE_FROM_CLASS(pageClass),
363             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
364             0,
365             NULL,
366             NULL,
367             g_cclosure_marshal_VOID__VOID,
368             G_TYPE_NONE, 0);
369
370     webkit_page_signals[SELECTION_CHANGED] = g_signal_new("selection_changed",
371             G_TYPE_FROM_CLASS(pageClass),
372             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
373             0,
374             NULL,
375             NULL,
376             g_cclosure_marshal_VOID__VOID,
377             G_TYPE_NONE, 0);
378
379
380     /*
381      * implementations of virtual methods
382      */
383     pageClass->create_page = webkit_page_real_create_page;
384     pageClass->navigation_requested = webkit_page_real_navigation_requested;
385     pageClass->choose_file = webkit_page_real_choose_file;
386     pageClass->java_script_alert = webkit_page_real_java_script_alert;
387     pageClass->java_script_confirm = webkit_page_real_java_script_confirm;
388     pageClass->java_script_prompt = webkit_page_real_java_script_prompt;
389     pageClass->java_script_console_message = webkit_page_real_java_script_console_message;
390
391     G_OBJECT_CLASS(pageClass)->finalize = webkit_page_finalize;
392
393     GtkWidgetClass* widgetClass = GTK_WIDGET_CLASS(pageClass);
394     widgetClass->realize = webkit_page_realize;
395     widgetClass->map = webkit_page_map;
396     widgetClass->expose_event = webkit_page_expose_event;
397     widgetClass->key_press_event = webkit_page_key_event;
398     widgetClass->key_release_event = webkit_page_key_event;
399     widgetClass->button_press_event = webkit_page_button_event;
400     widgetClass->button_release_event = webkit_page_button_event;
401     widgetClass->motion_notify_event = webkit_page_motion_event;
402     widgetClass->scroll_event = webkit_page_scroll_event;
403     widgetClass->size_allocate = webkit_page_size_allocate;
404
405     GtkContainerClass* containerClass = GTK_CONTAINER_CLASS(pageClass);
406     containerClass->add = webkit_page_container_add;
407     containerClass->remove = webkit_page_container_remove;
408     containerClass->forall = webkit_page_container_forall;
409
410     /*
411      * make us scrollable (e.g. addable to a GtkScrolledWindow)
412      */
413     pageClass->set_scroll_adjustments = webkit_page_set_scroll_adjustments;
414     GTK_WIDGET_CLASS(pageClass)->set_scroll_adjustments_signal = g_signal_new("set_scroll_adjustments",
415             G_TYPE_FROM_CLASS(pageClass),
416             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
417             G_STRUCT_OFFSET(WebKitPageClass, set_scroll_adjustments),
418             NULL, NULL,
419             webkit_marshal_VOID__OBJECT_OBJECT,
420             G_TYPE_NONE, 2,
421             GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
422 }
423
424 static void webkit_page_init(WebKitPage* page)
425 {
426     WebKitPagePrivate* pageData = WEBKIT_PAGE_GET_PRIVATE(WEBKIT_PAGE(page));
427     pageData->page = new Page(new WebKit::ChromeClient(page), new WebKit::ContextMenuClient, new WebKit::EditorClient(page), new WebKit::DragClient, new WebKit::InspectorClient);
428
429     Settings* settings = pageData->page->settings();
430     settings->setLoadsImagesAutomatically(true);
431     settings->setMinimumFontSize(5);
432     settings->setMinimumLogicalFontSize(5);
433     settings->setShouldPrintBackgrounds(true);
434     settings->setJavaScriptEnabled(true);
435     settings->setDefaultFixedFontSize(14);
436     settings->setDefaultFontSize(14);
437     settings->setSerifFontFamily("Times New Roman");
438     settings->setSansSerifFontFamily("Arial");
439     settings->setFixedFontFamily("Courier");
440     settings->setStandardFontFamily("Arial");
441
442     GTK_WIDGET_SET_FLAGS(page, GTK_CAN_FOCUS);
443     pageData->mainFrame = WEBKIT_FRAME(webkit_frame_new(page));
444 }
445
446 GtkWidget* webkit_page_new(void)
447 {
448     WebKitPage* page = WEBKIT_PAGE(g_object_new(WEBKIT_TYPE_PAGE, NULL));
449
450     return GTK_WIDGET(page);
451 }
452
453 void webkit_page_set_settings(WebKitPage* page, WebKitSettings* settings)
454 {
455     notImplemented();
456 }
457
458 WebKitSettings* webkit_page_get_settings(WebKitPage* page)
459 {
460     notImplemented();
461     return 0;
462 }
463
464 void webkit_page_go_backward(WebKitPage* page)
465 {
466     WebKitPagePrivate* pageData = WEBKIT_PAGE_GET_PRIVATE(page);
467     WebKitFramePrivate* frameData = WEBKIT_FRAME_GET_PRIVATE(pageData->mainFrame);
468     frameData->frame->loader()->goBackOrForward(-1);
469 }
470
471 void webkit_page_go_forward(WebKitPage* page)
472 {
473     WebKitPagePrivate* pageData = WEBKIT_PAGE_GET_PRIVATE(page);
474     WebKitFramePrivate* frameData = WEBKIT_FRAME_GET_PRIVATE(pageData->mainFrame);
475     frameData->frame->loader()->goBackOrForward(1);
476 }
477
478 gboolean webkit_page_can_go_backward(WebKitPage* page)
479 {
480     WebKitPagePrivate* pageData = WEBKIT_PAGE_GET_PRIVATE(page);
481     WebKitFramePrivate* frameData = WEBKIT_FRAME_GET_PRIVATE(pageData->mainFrame);
482     return frameData->frame->loader()->canGoBackOrForward(-1);
483 }
484
485 gboolean webkit_page_can_go_forward(WebKitPage* page)
486 {
487     WebKitPagePrivate* pageData = WEBKIT_PAGE_GET_PRIVATE(page);
488     WebKitFramePrivate* frameData = WEBKIT_FRAME_GET_PRIVATE(pageData->mainFrame);
489     return frameData->frame->loader()->canGoBackOrForward(1);
490 }
491
492 void webkit_page_open(WebKitPage* page, const gchar* url)
493 {
494     WebKitPagePrivate* pageData = WEBKIT_PAGE_GET_PRIVATE(page);
495     WebKitFramePrivate* frameData = WEBKIT_FRAME_GET_PRIVATE(pageData->mainFrame);
496
497     DeprecatedString string = DeprecatedString::fromUtf8(url);
498     frameData->frame->loader()->load(ResourceRequest(KURL(string)));
499 }
500
501 void webkit_page_reload(WebKitPage* page)
502 {
503     WebKitPagePrivate* pageData = WEBKIT_PAGE_GET_PRIVATE(page);
504     WebKitFramePrivate* frameData = WEBKIT_FRAME_GET_PRIVATE(pageData->mainFrame);
505     frameData->frame->loader()->reload();
506 }
507
508 void webkit_page_load_string(WebKitPage* page, const gchar* content, const gchar* contentMimeType, const gchar* contentEncoding, const gchar* baseUrl)
509 {
510     WebKitPagePrivate* pageData = WEBKIT_PAGE_GET_PRIVATE(page);
511     WebKitFramePrivate* frameData = WEBKIT_FRAME_GET_PRIVATE(pageData->mainFrame);
512     
513     KURL url(DeprecatedString::fromUtf8(baseUrl));
514     RefPtr<SharedBuffer> sharedBuffer = new SharedBuffer(strdup(content), strlen(content));    
515     SubstituteData substituteData(sharedBuffer.release(), String(contentMimeType), String(contentEncoding), KURL("about:blank"), url);
516
517     frameData->frame->loader()->load(ResourceRequest(url), substituteData);
518 }
519
520 void webkit_page_load_html_string(WebKitPage* page, const gchar* content, const gchar* baseUrl)
521 {
522     webkit_page_load_string(page, content, "text/html", "UTF-8", baseUrl);
523 }
524
525 void webkit_page_stop_loading(WebKitPage* page)
526 {
527     WebKitPagePrivate* pageData = WEBKIT_PAGE_GET_PRIVATE(page);
528     WebKitFramePrivate* frameData = WEBKIT_FRAME_GET_PRIVATE(pageData->mainFrame);
529     
530     if (FrameLoader* loader = frameData->frame->loader())
531         loader->stopAllLoaders();
532         
533 }
534
535 WebKitFrame* webkit_page_get_main_frame(WebKitPage* page)
536 {
537     WebKitPagePrivate* pageData = WEBKIT_PAGE_GET_PRIVATE(page);
538     return pageData->mainFrame;
539 }
540
541 void webkit_page_execute_script(WebKitPage* page, const gchar* script)
542 {
543     WebKitPagePrivate* pageData = WEBKIT_PAGE_GET_PRIVATE(page);
544     WebKitFramePrivate* frameData = WEBKIT_FRAME_GET_PRIVATE(pageData->mainFrame);
545
546     if (FrameLoader* loader = frameData->frame->loader())
547         loader->executeScript(String::fromUTF8(script), true);
548 }
549 }