diff options
author | Cary Clark <> | 2009-04-14 06:33:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-04-14 06:33:00 -0700 |
commit | 563af33bc48281d19dce701398dbb88cb54fd7ec (patch) | |
tree | 395b4502f029dea8b25b342d66dc06b5d8f99985 /WebKit/gtk | |
parent | 5cfedfef172691d0f4bcf2be5ca3cddd8c9a47f4 (diff) | |
download | external_webkit-563af33bc48281d19dce701398dbb88cb54fd7ec.zip external_webkit-563af33bc48281d19dce701398dbb88cb54fd7ec.tar.gz external_webkit-563af33bc48281d19dce701398dbb88cb54fd7ec.tar.bz2 |
AI 146110: add missing files to webkit
brings it in sync with webkit svn cl 42046
Automated import of CL 146110
Diffstat (limited to 'WebKit/gtk')
31 files changed, 3621 insertions, 206 deletions
diff --git a/WebKit/gtk/ChangeLog b/WebKit/gtk/ChangeLog index e6dc216..3691b4b 100644 --- a/WebKit/gtk/ChangeLog +++ b/WebKit/gtk/ChangeLog @@ -1,11 +1,810 @@ -2009-02-03 Mark Rowe <mrowe@apple.com> +2009-03-25 Gustavo Noronha Silva <gns@gnome.org> - Merge r40508. + Reviewed by Holger Freyther. + + https://bugs.webkit.org/show_bug.cgi?id=15793 + [GTK] tooltip position doesn't update when hovering consecutive links + + Work-around tooltips not updating their location when the elements + are consecutive, by clearing the tooltip when handling + mouseDidMoveOverElement. + + * WebCoreSupport/ChromeClientGtk.cpp: + (WebKit::ChromeClient::mouseDidMoveOverElement): + +2009-03-23 Alejandro Garcia Castro <alex@igalia.com> + + Reviewed by Holger Freyther. + + [Gtk] Current API does not allow us to open target="_blank" links + in new tabs instead of windows + https://bugs.webkit.org/show_bug.cgi?id=23932 + + Added a signal to the API (new-window-policy-decision-requested) + that allows the browser to decide the policy for the new window + request, if the signal is not handled we open the new window as + usual. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::getNavigationAction): + (WebKit::FrameLoaderClient::dispatchDecidePolicyForNewWindowAction): + (WebKit::FrameLoaderClient::dispatchDecidePolicyForNavigationAction): + * webkit/webkitwebview.cpp: + +2009-03-20 Jan Michael Alonzo <jmalonzo@gmail.com> + + Not reviewed. Fix style issues with my previous commit (r41866) as + suggested by Holger in https://bugs.webkit.org/show_bug.cgi?id=24493 + + * tests/testwebhistoryitem.c: + (test_webkit_web_history_item_get_data): + (test_webkit_web_history_item_alternate_title): + +2009-03-20 Jan Michael Alonzo <jmalonzo@gmail.com> + + Reviewed by Holger Freyther. + + [GTK] Misc patches for WebKitWebHistoryItem + https://bugs.webkit.org/show_bug.cgi?id=24493 + + Add unit test for WebKitWebHistoryItem + + * tests/testwebhistoryitem.c: Added. + (web_history_item_fixture_setup): + (web_history_item_fixture_teardown): + (test_webkit_web_history_item_get_data): + (test_webkit_web_history_item_alternate_title): + (main): + +2009-03-20 Jan Michael Alonzo <jmalonzo@gmail.com> + + Reviewed by Holger Freyther. + + Separate gtk unit tests + https://bugs.webkit.org/show_bug.cgi?id=24039 + + Split the current single-file unit test to make it more + modularized and manageable in the future as more unit tests are + written. + + * tests/main.c: Removed. + * tests/testwebbackforwardlist.c: Copied from WebKit/gtk/tests/main.c. + (main): + * tests/testwebframe.c: Copied from WebKit/gtk/tests/main.c. + (main): + +2009-03-16 Christian Dywan <christian@twotoasts.de> + + Reviewed by Adam Roben. + + [gtk] API implementation: url and title + http://bugs.webkit.org/show_bug.cgi?id=14807 + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::dispatchDidChangeLocationWithinPage): + (WebKit::FrameLoaderClient::dispatchDidReceiveTitle): + (WebKit::FrameLoaderClient::dispatchDidCommitLoad): + * webkit/webkitwebview.cpp: + * webkit/webkitwebview.h: Implement "title" and "uri" properties as well + as according functions. "uri" always reflects the current location + including navigation inside the same page. title-changed is deprecated. + +2009-03-15 Gustavo Noronha Silva <gns@gnome.org> + + Reviewed by Anders Carlsson. + + Fix default policy decision to be ignore, on MIME checks, if + WebKit doesn't know how to handle the MIME type. The documentation + is already correct, and this was an oversight when the policy + decision code was first committed. Since 1.1.2 will be the first + release to support download, there is no practical change in + behavior. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::dispatchDecidePolicyForMIMEType): + +2009-03-15 Xan Lopez <xlopez@igalia.com> + + * NEWS: update for 1.1.2. + +2009-03-14 Jan Michael Alonzo <jmalonzo@webkit.org> + + Reviewed by Holger Freyther. + + [GTK] use of confirm dialog (yes/no) causes segfault + https://bugs.webkit.org/show_bug.cgi?id=20940 + + Change the script-confirm marshaller from OBJECT,STRING,BOOLEAN to + OBJECT,STRING,POINTER + + * webkit/webkitwebview.cpp: + * webkitmarshal.list: + +2009-03-12 Gustavo Noronha Silva <gns@gnome.org> + + Reviewed by Alexey Proskuryakov. + + https://bugs.webkit.org/show_bug.cgi?id=24553 + [GTK] Improvements to WebKitDownload + + Rename 'state' to 'status' to match the naming in the frame + loader rework that we plan to land soonish, and make it a + property, for the same reason. + + * webkit/webkitdownload.cpp: + (_WebKitDownloadPrivate::): + (_WebKitDownloadPrivate::webkit_download_finalize): + (_WebKitDownloadPrivate::webkit_download_get_property): + (_WebKitDownloadPrivate::webkit_download_set_property): + (_WebKitDownloadPrivate::webkit_download_class_init): + (_WebKitDownloadPrivate::webkit_download_init): + (_WebKitDownloadPrivate::webkit_download_start): + (_WebKitDownloadPrivate::webkit_download_cancel): + (_WebKitDownloadPrivate::webkit_download_set_destination_uri): + (_WebKitDownloadPrivate::webkit_download_get_status): + (_WebKitDownloadPrivate::webkit_download_set_status): + (_WebKitDownloadPrivate::webkit_download_received_data): + (_WebKitDownloadPrivate::webkit_download_finished_loading): + (_WebKitDownloadPrivate::webkit_download_error): + * webkit/webkitdownload.h: + +2009-03-12 Gustavo Noronha Silva <gns@gnome.org> + + Reviewed by Alexey Proskuryakov. + + https://bugs.webkit.org/show_bug.cgi?id=24553 + [GTK] Improvements to WebKitDownload + + Improved documentation for the download-requested signal, to make + its usage clear. + + * webkit/webkitwebview.cpp: + +2009-03-12 Gustavo Noronha Silva <gns@gnome.org> + + Reviewed by Alp Toker. + + https://bugs.webkit.org/show_bug.cgi?id=24541 + Scrolling with home and end keys not always works + + Also make page up and page down keys be handled by the webview key + event code, so that they also work in cases where the GTK+ + scrollbars don't handle them directly, like in the bugzill's patch + review page. + + * webkit/webkitwebview.cpp: + +2009-03-12 Gustavo Noronha Silva <gns@gnome.org> + + Reviewed by Alp Toker. + + https://bugs.webkit.org/show_bug.cgi?id=24541 + Scrolling with home and end keys not always works + + Make home and end keys behave more consistently for scrolling the + view. + + * webkit/webkitwebview.cpp: + +2009-03-12 Gustavo Noronha Silva <gns@gnome.org> + + Reviewed by Alp Toker. + + https://bugs.webkit.org/show_bug.cgi?id=24254 + [GTK] spacebar doesn't scroll down + + Make spacebar and shift+spacebar scroll like page up and down + respectively would. + + * webkit/webkitwebview.cpp: + +2009-03-10 Xan Lopez <xlopez@igalia.com> + + Reviewed by Holger Freyther. + + https://bugs.webkit.org/show_bug.cgi?id=24493 + [GTK] Misc patches for WebKitWebHistoryItem + + Only run code in dispose once per instance. + + * webkit/webkitwebhistoryitem.cpp: + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_dispose): + +2009-03-10 Xan Lopez <xlopez@igalia.com> + + Reviewed by Holger Freyther. + + https://bugs.webkit.org/show_bug.cgi?id=24493 + [GTK] Misc patches for WebKitWebHistoryItem + + Call deref() on our internal HistoryItem on dispose, as we always + acquire it with a releaseRef() call to a PassRefPtr, which passes + ownership. + + * webkit/webkitwebhistoryitem.cpp: + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_dispose): + +2009-03-10 Xan Lopez <xlopez@igalia.com> + + Reviewed by Holger Freyther. + + https://bugs.webkit.org/show_bug.cgi?id=24493 + [GTK] Misc patches for WebKitWebHistoryItem + + return foo? foo : NULL == return foo + + * webkit/webkitwebhistoryitem.cpp: + (WebKit::core): + +2009-03-11 Jan Michael Alonzo <jmalonzo@webkit.org> + + Reviewed by Holger Freyther. + + Gtk] Implement LayoutTestControllerGtk::setPrivateBrowsingEnabled + https://bugs.webkit.org/show_bug.cgi?id=24487 + + Add private browsing option "enable-private-browsing" to WebKitWebSettings. + + * webkit/webkitwebsettings.cpp: + (_WebKitWebSettingsPrivate::): + (_WebKitWebSettingsPrivate::webkit_web_settings_class_init): + (_WebKitWebSettingsPrivate::webkit_web_settings_set_property): + (_WebKitWebSettingsPrivate::webkit_web_settings_get_property): + (_WebKitWebSettingsPrivate::webkit_web_settings_copy): + * webkit/webkitwebview.cpp: + +2009-03-11 Jan Michael Alonzo <jmalonzo@webkit.org> + + Reviewed by Holger Freyther. + + [GTK] BackForward history leak? + https://bugs.webkit.org/show_bug.cgi?id=19528 + + Don't ref the history items when returning the back/forward list + Added test_webkit_web_history_item_lifetime test case for this. + + * tests/main.c: + (test_webkit_web_history_item_lifetime): + (test_webkit_web_back_forward_list_order): Style fix. + (test_webkit_web_back_forward_list_add_item): Style fix. + (main): + * webkit/webkitwebbackforwardlist.cpp: + (_WebKitWebBackForwardListPrivate::webkit_web_back_forward_list_get_forward_list_with_limit): + (_WebKitWebBackForwardListPrivate::webkit_web_back_forward_list_get_back_list_with_limit): + +2009-03-10 Xan Lopez <xlopez@igalia.com> + + Reviewed by Alexey Proskuryakov. + + https://bugs.webkit.org/show_bug.cgi?id=24493 + [GTK] Misc patches for WebKitWebHistoryItem + + Use g_hash_table_new_full so we can save the manual unref on the + values when removing them from the table. + + * webkit/webkitwebhistoryitem.cpp: + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_dispose): + +2009-03-10 Xan Lopez <xan@gnome.org> + + Reviewed by Alexey Proskuryakov. + + https://bugs.webkit.org/show_bug.cgi?id=24493 + [GTK] Misc patches for WebKitWebHistoryItem + + Use 'if (foo)' instead of 'if (foo != NULL)', per coding style + guidelines. + + * webkit/webkitwebhistoryitem.cpp: + (_WebKitWebHistoryItemPrivate::webkit_history_item_remove): + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_get_title): + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_get_alternate_title): + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_get_uri): + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_get_original_uri): + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_get_last_visited_time): + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_get_target): + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_is_target_item): + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_get_children): + +2009-03-10 Xan Lopez <xlopez@igalia.com> + + Reviewed by Alexey Proskuryakov. + + Correct return value to false instead of NULL. + + * webkit/webkitwebhistoryitem.cpp: + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_is_target_item): + +2009-03-08 Holger Hans Peter Freyther <zecke@selfish.org> + + Reviewed by Mark Rowe. + + Add javascript-profiling-enabled property and implement it. This + will enable/disable the profiler on the InstpectorController. + + * webkit/webkitprivate.h: + * webkit/webkitwebinspector.cpp: + (_WebKitWebInspectorPrivate::webkit_web_inspector_class_init): + (_WebKitWebInspectorPrivate::webkit_web_inspector_set_property): + (_WebKitWebInspectorPrivate::webkit_web_inspector_get_property): + (_WebKitWebInspectorPrivate::webkit_web_inspector_set_inspector_client): + * webkit/webkitwebview.cpp: + +2009-03-05 Gustavo Noronha Silva <gns@gnome.org> + + Reviewed by Olliej. + + https://bugs.webkit.org/show_bug.cgi?id=24295 + webkit_web_back_forward_list_add_item needs a Since tag + + Add missing Since tag to webkit_web_back_forward_list_add_item + documentation. + + * webkit/webkitwebbackforwardlist.cpp: + +2009-03-05 Gustavo Noronha Silva <gns@gnome.org> + + Reviewed by Mark Rowe. + + https://bugs.webkit.org/show_bug.cgi?id=24417 + [GTK] WebKitDownload's _cancel and _dispose methods may emit warnings + + NULL-check for timer on _cancel and _dispose, to avoid bad + warnings. + + * webkit/webkitdownload.cpp: + (_WebKitDownloadPrivate::webkit_download_finalize): + (_WebKitDownloadPrivate::webkit_download_cancel): + +2009-03-02 Xan Lopez <xan@gnome.org> + + Reviewed by Mark Rowe. + + https://bugs.webkit.org/show_bug.cgi?id=24287 + [GTK] Move auth dialog feature to WebKit/ + + Add WebKitSoupAuthDialog and add it to the session in webkit_init. + + * webkit/webkitprivate.cpp: + (currentToplevelCallback): + (webkit_init): + * webkit/webkitsoupauthdialog.c: Added. + (webkit_soup_auth_dialog_class_init): + (webkit_soup_auth_dialog_init): + (webkit_soup_auth_dialog_session_feature_init): + (free_authData): + (set_password_callback): + (response_callback): + (table_add_entry): + (show_auth_dialog): + (find_password_callback): + (session_authenticate): + (attach): + * webkit/webkitsoupauthdialog.h: Added. + +2009-03-03 Gustavo Noronha Silva <gns@gnome.org> + + Reviewed by Alexey Proskuryakov. + + https://bugs.webkit.org/show_bug.cgi?id=16826 + [Gtk] Implement WebKitDownload + + Implement download, and provide a nice object wrapping the + download process. Initial work done by Marco Barisione and + Pierre-Luc Beaudoin for Collabora. + + * WebCoreSupport/ContextMenuClientGtk.cpp: + (WebKit::ContextMenuClient::downloadURL): + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::download): + (WebKit::FrameLoaderClient::startDownload): + * webkit/webkit.h: + * webkit/webkitdefines.h: + * webkit/webkitdownload.cpp: Added. + (_WebKitDownloadPrivate::): + (_WebKitDownloadPrivate::webkit_download_dispose): + (_WebKitDownloadPrivate::webkit_download_finalize): + (_WebKitDownloadPrivate::webkit_download_get_property): + (_WebKitDownloadPrivate::webkit_download_set_property): + (_WebKitDownloadPrivate::webkit_download_class_init): + (_WebKitDownloadPrivate::webkit_download_init): + (_WebKitDownloadPrivate::webkit_download_new): + (_WebKitDownloadPrivate::webkit_download_open_stream_for_uri): + (_WebKitDownloadPrivate::webkit_download_close_stream): + (_WebKitDownloadPrivate::webkit_download_start): + (_WebKitDownloadPrivate::webkit_download_cancel): + (_WebKitDownloadPrivate::webkit_download_get_uri): + (_WebKitDownloadPrivate::webkit_download_get_network_request): + (_WebKitDownloadPrivate::webkit_download_set_response): + (_WebKitDownloadPrivate::webkit_download_get_suggested_filename): + (_WebKitDownloadPrivate::webkit_download_get_destination_uri): + (_WebKitDownloadPrivate::webkit_download_set_destination_uri): + (_WebKitDownloadPrivate::webkit_download_get_state): + (_WebKitDownloadPrivate::webkit_download_get_total_size): + (_WebKitDownloadPrivate::webkit_download_get_current_size): + (_WebKitDownloadPrivate::webkit_download_get_progress): + (_WebKitDownloadPrivate::webkit_download_get_elapsed_time): + (_WebKitDownloadPrivate::webkit_download_received_data): + (_WebKitDownloadPrivate::webkit_download_finished_loading): + (_WebKitDownloadPrivate::webkit_download_error): + (_WebKitDownloadPrivate::DownloadClient::DownloadClient): + (_WebKitDownloadPrivate::DownloadClient::didReceiveResponse): + (_WebKitDownloadPrivate::DownloadClient::didReceiveData): + (_WebKitDownloadPrivate::DownloadClient::didFinishLoading): + (_WebKitDownloadPrivate::DownloadClient::didFail): + (_WebKitDownloadPrivate::DownloadClient::wasBlocked): + (_WebKitDownloadPrivate::DownloadClient::cannotShowURL): + * webkit/webkitdownload.h: Added. + * webkit/webkitprivate.h: + * webkit/webkitwebview.cpp: + * webkitmarshal.list: + +2009-03-01 Jan Michael Alonzo <jmalonzo@webkit.org> + + Reviewed by Holger Freyther. + + [Gtk] get the HTTP layout tests going + https://bugs.webkit.org/show_bug.cgi?id=24259 + + Added API to get the response mime type from a frame. We need this + so we can decide if we need to dump the frame as text or its + render tree + + * webkit/webkitprivate.h: + * webkit/webkitwebframe.cpp: + +2009-03-01 Jan Michael Alonzo <jmalonzo@webkit.org> + + Reviewed by Holger Freyther. + + [Gtk] get the HTTP layout tests going + https://bugs.webkit.org/show_bug.cgi?id=24259 + + Create a WebKitWebHistoryItem for each WebCore::HistoryItem when + necessary. + Add necessary API additions for us to be able to dump a WebKitWebHistoryItem + + * webkit/webkitprivate.h: + * webkit/webkitwebbackforwardlist.cpp: + (_WebKitWebBackForwardListPrivate::webkit_web_back_forward_list_get_forward_list_with_limit): + (_WebKitWebBackForwardListPrivate::webkit_web_back_forward_list_get_back_list_with_limit): + * webkit/webkitwebhistoryitem.cpp: + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_new_with_core_item): + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_new): + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_new_with_data): + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_get_target): + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_is_target_item): + (_WebKitWebHistoryItemPrivate::webkit_web_history_item_get_children): + (WebKit::core): + (WebKit::kit): + +2009-03-01 Christian Dywan <christian@twotoasts.de> + + Reviewed by Holger Freyther. + + * webkit/webkitprivate.h: + * webkit/webkitwebview.cpp: + (webkit_web_view_get_encoding): + * webkit/webkitwebview.h: Implement 'encoding' and 'custom-encoding' + properties as well as webkit_web_view_get_encoding. + +2009-03-01 Gustavo Noronha Silva <gns@gnome.org> + + Unreviewed simple wording fix for the NEWS file. + + * NEWS: - 2009-02-02 Geoffrey Garen <ggaren@apple.com> +2009-03-01 Xan Lopez <xan@gnome.org> + + Add NEWS file to track progress between releases. + + * NEWS: Added. + +2009-02-28 Christian Dywan <christian@twotoasts.de> + + Reviewed by Holger Freyther. + + * webkit/webkitwebview.cpp: Let webkit_web_view_open add file:// if a + locale path is passed for compatibility, since we used to support that. + +2009-02-27 Gustavo Noronha Silva <gns@gnome.org> + + Reviewed by David Hyatt. + + Automatically ignore empty requests to avoid crashing. This fixes + the crash in fast/loader/empty-embed-src-attribute.html. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::dispatchDecidePolicyForMIMEType): + (WebKit::FrameLoaderClient::dispatchDecidePolicyForNewWindowAction): + (WebKit::FrameLoaderClient::dispatchDecidePolicyForNavigationAction): + +2009-02-27 Xan Lopez <xan@gnome.org> + + Reviewed by Alexey Proskuryakov. + + https://bugs.webkit.org/show_bug.cgi?id=24221 + [GTK] Do not emit load-finished when being disposed + + webkit_web_view_stop_load() is called from dispose() on + WebKitWebView. This eventually calls postProgressFinishedNotification + in FrameLoaderClientGtk, which emits load-finished. Add + a 'disposing' flag to WebView that we can check here, so + we avoid emitting signals on objects on their way to be + destroyed. This fixes a bunch of critical warnings when + closing a loading WebView. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::postProgressFinishedNotification): + * webkit/webkitprivate.h: + * webkit/webkitwebview.cpp: + +2009-02-27 Xan Lopez <xan@gnome.org> + + Rubber-stamped by Alexey Proskuryakov. + + https://bugs.webkit.org/show_bug.cgi?id=24222 + [GTK] Remove checks for old glib versions + + libsoup, which is a hard dependency, needs at least glib 2.15.3, + so remove all glib checks for versions older than that. + + * webkit/webkitwebview.cpp: + +2009-02-26 Xan Lopez <xan@gnome.org> + + Reviewed by Holger Freyther. + + https://bugs.webkit.org/show_bug.cgi?id=16947 + [GTK] Missing HTTP Auth challenge + + Add new marshalers list. + + * webkitmarshal.list: Added. + +2009-02-26 Xan Lopez <xan@gnome.org> + + Reviewed by Alexey Proskuryakov. + + https://bugs.webkit.org/show_bug.cgi?id=24193 + [GTK] Checkbuttons not activated with space + + Do not swallow key events with GtkIMContext for non-editable + content. + + * WebCoreSupport/EditorClientGtk.cpp: + (WebKit::EditorClient::handleInputMethodKeydown): + +2009-02-26 Xan Lopez <xan@gnome.org> + + Reviewed by Alexey Proskuryakov. + + https://bugs.webkit.org/show_bug.cgi?id=24103 + [GTK] Use correct return value for WebView button-release handler + + We are returning whatever the core code tells us it did, but this + does not play well with the GTK+ model. GTK+ in general expects it + will see a button-release if it saw a button-press and no + motion/leave/etc events in between. EventHandler.cpp will, in some + cases, not handle press but handle release, confusing the parent + container of the WebView. + + As a workaround return always FALSE for button-release (this is + the same than the Windows port does). + + * webkit/webkitwebview.cpp: + +2009-02-26 Xan Lopez <xan@gnome.org> + + Reviewed by Holger Freyther. + + https://bugs.webkit.org/show_bug.cgi?id=17585 + [gtk] get|set encoding api + + Add functions to get and set a custom encoding an a view. + + * webkit/webkitprivate.h: + * webkit/webkitwebview.cpp: + (webkit_web_view_set_custom_encoding): + (webkit_web_view_get_custom_encoding): + * webkit/webkitwebview.h: + +2009-02-23 Xan Lopez <xan@gnome.org> + + Reviewed by Alexey Proskuryakov. + + https://bugs.webkit.org/show_bug.cgi?id=22624 + [SOUP][GTK] Need API to get SoupSession from WebKit. + + Add API to get the default soup session. + + * webkit/webkitwebview.cpp: + * webkit/webkitwebview.h: + +2009-02-23 Xan Lopez <xan@gnome.org> + + Reviewed by Alexey Proskuryakov. + + https://bugs.webkit.org/show_bug.cgi?id=22624 + [SOUP][GTK] Need API to get SoupSession from WebKit. + + Add soup dependency to pc file. + + * webkit.pc.in: + +2009-02-23 Jan Michael Alonzo <jmalonzo@webkit.org> + + Reviewed by Mark Rowe. + + [GTK] Back / Forward history menus are flipped + https://bugs.webkit.org/show_bug.cgi?id=22694 + + Don't call g_list_reverse when returning the back or forward list. + + * tests/main.c: + (test_webkit_web_back_forward_list_order): + (main): + * webkit/webkitwebbackforwardlist.cpp: + (_WebKitWebBackForwardListPrivate::webkit_web_back_forward_list_get_forward_list_with_limit): + (_WebKitWebBackForwardListPrivate::webkit_web_back_forward_list_get_back_list_with_limit): + +2009-02-17 Xan Lopez <xan@gnome.org> + + Rubber-stamped by Alexey Proskuryakov. + + Restoring change landed in r40715, which was accidentally undone + by r40918. + + * webkit/webkitwebframe.cpp: + +2009-02-12 Christian Dywan <christian@twotoasts.de> + + Reviewed by Holger Freyther. + + http://bugs.webkit.org/show_bug.cgi?id=17176 + [GTK] API: hovering-over-link and webkit_web_view_open /_load_foo + + * webkit/webkitwebframe.cpp: + * webkit/webkitwebframe.h: + * webkit/webkitwebview.cpp: + * webkit/webkitwebview.h: Introduce webkit_web_frame_load_uri, + webkit_web_frame_load_string, webkit_web_view_load_uri and + webkit_web_view_load_request and unify implementations. + +2009-02-11 Dimitri Dupuis-latour <dupuislatour@apple.com> + + Stub out InspectorClient::hiddenPanels. + + Reviewed by Timothy Hatcher. + + * WebCoreSupport/InspectorClientGtk.cpp: + (WebKit::InspectorClient::hiddenPanels): + * WebCoreSupport/InspectorClientGtk.h: + +2009-02-07 Holger Hans Peter Freyther <zecke@selfish.org> + + Unreviewed build fix Use toNormalizedRange(). + + * WebCoreSupport/EditorClientGtk.cpp: + (WebKit::clipboard_get_contents_cb): + +2009-02-06 Geoffrey Garen <ggaren@apple.com> + + Build fix. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::updateGlobalHistoryRedirectLinks): + * WebCoreSupport/FrameLoaderClientGtk.h: + +2009-02-06 Xan Lopez <xan@gnome.org> + + Reviewed by Holger Freyther. + + Reported by Daniel Macks. + + https://bugs.webkit.org/show_bug.cgi?id=20412 + + Use positive numbers for the target info IDs, gtk_target_list_add + casts them to 'guint'. Also just start them from 0, since the + values are not relevant or magic in any way, they are just used as + tokens for the user of the API. + + * webkit/webkitwebview.h: + +2009-02-06 Xan Lopez <xan@gnome.org> + + Reviewed by Alexey Proskuryakov. + + https://bugs.webkit.org/show_bug.cgi?id=23769 + + Do not use empty ResourceError errors. + + Rather create bogus but non-null errors, since some codepaths + expect these. For example, see DocumentLoader::mainReceivedError. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::cancelledError): + (WebKit::FrameLoaderClient::blockedError): + (WebKit::FrameLoaderClient::cannotShowURLError): + (WebKit::FrameLoaderClient::interruptForPolicyChangeError): + (WebKit::FrameLoaderClient::cannotShowMIMETypeError): + (WebKit::FrameLoaderClient::fileDoesNotExistError): + (WebKit::FrameLoaderClient::pluginWillHandleLoadError): + +2009-02-06 Xan Lopez <xan@gnome.org> + + Reviewed by Alexey Proskuryakov. + + https://bugs.webkit.org/show_bug.cgi?id=23761 + + Use two-arg KURL ctor. + + We are using the one-arg ctor currently, but: + + - It assumes the strings are already encoded, which is not + necesarily the case for us. + + - The single-argument KURL ctors expect their input to already be + the output of a previous KURL::parse call, so for the general + case (ie, random user input) we need to use the two-arg ctor + anyway. + + * webkit/webkitwebframe.cpp: + * webkit/webkitwebview.cpp: + +2009-02-05 Aaron Boodman <aa@chromium.org> + + Reviewed by Dave Hyatt. + + https://bugs.webkit.org/show_bug.cgi?id=23708 + Adds documentElementAvailable() callback to FrameLoaderClient. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::documentElementAvailable): + Stub out documentElementAvailable() + * WebCoreSupport/FrameLoaderClientGtk.h: + Ditto. + +2009-02-03 Hiroyuki Ikezoe <poincare@ikezoe.net> + + Reviewed by Holger Freyther. + + https://bugs.webkit.org/show_bug.cgi?id=22988 + [GTK] Need a public method to add a WebKitWebHistoryItem to + WebKitWebBackForwardList. + + Wrap WebCore::BackForwardList::addItem. + + * tests/main.c: + (test_webkit_web_back_forward_list_add_item): + (main): + * webkit/webkitwebbackforwardlist.cpp: + (_WebKitWebBackForwardListPrivate::webkit_web_back_forward_list_add_item): + * webkit/webkitwebbackforwardlist.h: + +2009-02-02 Geoffrey Garen <ggaren@apple.com> + + Build fix. + + * webkit/webkitwebview.cpp: + +2009-02-02 Geoffrey Garen <ggaren@apple.com> + + Build fix. + + * webkit/webkitwebframe.cpp: + +2009-02-02 Geoffrey Garen <ggaren@apple.com> + + Build fix. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::createFrame): + +2009-02-02 Geoffrey Garen <ggaren@apple.com> Reviewed by Sam Weinig. - + Track redirects in global history. Keep GTK building. @@ -15,17 +814,62 @@ (WebKit::FrameLoaderClient::updateGlobalHistoryForRedirectWithoutHistoryItem): * WebCoreSupport/FrameLoaderClientGtk.h: -2009-02-03 Mark Rowe <mrowe@apple.com> +2009-02-02 Anders Carlsson <andersca@apple.com> + + Build fix. + + * WebCoreSupport/FrameLoaderClientGtk.h: + +2009-02-02 Anders Carlsson <andersca@apple.com> + + Reviewed by Dan Bernstein. + + Update for changes to WebCore. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::createPlugin): + (WebKit::FrameLoaderClient::createJavaAppletWidget): + * WebCoreSupport/FrameLoaderClientGtk.h: + +2009-02-02 Holger Hans Peter Freyther <zecke@selfish.org> - Merge r40436. + Reviewed by Darin Adler. - 2009-01-30 Geoffrey Garen <ggaren@apple.com> + Move Frame::forceLayout, Frame::adjustPageHeight and Frame::forceLayoutWithPageWidthRange to FrameView + + https://bugs.webkit.org/show_bug.cgi?id=23428 + + FrameView::forceLayout could be killed but the comment might + contain a value over the the plain FrameView::layout... + + Adjust the WebCore/WebKit consumers of these methods. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::forceLayout): + * webkit/webkitwebview.cpp: + +2009-01-30 Geoffrey Garen <ggaren@apple.com> Build fix. * WebCoreSupport/FrameLoaderClientGtk.cpp: (WebKit::FrameLoaderClient::createFrame): +2009-01-30 Holger Hans Peter Freyther <zecke@selfish.org> + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=22056 + + Kill FrameLoaderClient.cpp, move the code over to Frame::createView + + FrameLoaderClient is supposed to be an interface, move the + to be shared code to Frame which is a controller and is + allowed to create a FrameView. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::transitionToCommittedForNewPage): + 2009-01-27 Brady Eidson <beidson@apple.com> Reviewed by Dan Bernstein @@ -157,29 +1001,29 @@ Reviewed by Darin Adler. [GTK] Fix the reference counting of WebKitWebFrames - + The ownership is the following: WebKitWebView owns a WebCore::Page. WebKitWebView is creating one WebKitWebFrame which will be the mainFrame of the WebCore::Page (having the reference on the Frame). - + The FrameLoaderClient has the reference of the WebKitWebFrame for the main frame and also any other frame. This means when the WebCore::Frame goes away the FrameLoaderClient will go away which will normally remove the last reference of the WebKitWebFrame. Because an API user might have g_object_ref'ed the WebKitWebFrame null checks had to be added to WebKitWebFrame. - + For WebCore::Frames created by the FrameLoaderClient the ownership will be passed down to the FrameTree, the WebKitWebFrame is not holding a reference to the WebCore::Frame. - + Do not g_object_unref the mainFrame in the destructor of the WebKitWebFrame as this will happen from within the WebCore::Page destruction. Do not hold a reference to the WebCore::Frame (circle) in WebKitWebFrame, add null checks as the WebCore::Frame might have gone away. Do not keep track of the FrameLoaderClient in the private structures as it was mostly unusued. - + https://bugs.webkit.org/show_bug.cgi?id=21837 * WebCoreSupport/FrameLoaderClientGtk.cpp: @@ -415,7 +1259,7 @@ Renderer::caretRect() is now localCaretRect(), which needs converting to absolute coordinates (taking transforms into account). - + * webkit/webkitwebview.cpp: 2008-12-01 Xan Lopez <xan@gnome.org> @@ -930,7 +1774,7 @@ 2008-10-06 David Hyatt <hyatt@apple.com> Enable viewless Mac WebKit to paint some basic pages. - + Reviewed by Sam Weinig * WebCoreSupport/FrameLoaderClientGtk.cpp: @@ -946,11 +1790,11 @@ 2008-10-03 David Hyatt <hyatt@apple.com> https://bugs.webkit.org/show_bug.cgi?id=21340 - + Remove "containingWindow()/setContainingWindow()" from Widget. HostWindow covers this now. Reviewed by Dan Bernstein & Darin Adler - + * WebCoreSupport/FrameLoaderClientGtk.cpp: (WebKit::FrameLoaderClient::transitionToCommittedForNewPage): @@ -970,7 +1814,7 @@ 2008-10-03 David Hyatt <hyatt@apple.com> Remove addToDirtyRegion. - + Reviewed by Oliver Hunt * WebCoreSupport/ChromeClientGtk.cpp: @@ -978,7 +1822,7 @@ 2008-10-02 David Hyatt <hyatt@apple.com> https://bugs.webkit.org/show_bug.cgi?id=21314 - + Make scrollBackingStore cross-platform. Reviewed by Sam Weinig @@ -991,9 +1835,9 @@ 2008-10-01 David Hyatt <hyatt@apple.com> https://bugs.webkit.org/show_bug.cgi?id=21282 - + Make contentsToScreen/screenToContents cross-platform. Only implemented by Mac/Win right now. - + Reviewed by Adam Roben * WebCoreSupport/ChromeClientGtk.cpp: @@ -1004,7 +1848,7 @@ 2008-09-30 Dave Hyatt <hyatt@apple.com> http://bugs.webkit.org/show_bug.cgi?id=21250 - + Rename updateContents to repaintContentRectangle and make it cross-platform by always sending repaints up through the ChromeClient. @@ -2396,9 +3240,9 @@ http://bugs.webkit.org/show_bug.cgi?id=16802 [GTK] Missing gtk properties - + Add missing properties to WebKitViewFrame and WebKitWebView. - + * WebView/webkitprivate.h: add some useful defines for param specs * WebView/webkitwebframe.cpp: (webkit_web_frame_get_property): added @@ -2415,7 +3259,7 @@ http://bugs.webkit.org/show_bug.cgi?id=16654 [GTK] Signal "navigation-requested" does not react correctly on return TRUE from callbacks - + * WebView/webkitwebview.cpp: use our own accumulator for signals returning WebKitNavigationResponse. The emission will be stopped when any callback returns anything but @@ -2587,7 +3431,7 @@ * WebView/webkitwebview.cpp: * WebView/webkitwebview.h: -2007-12-19 Christian Dywan <christian@twotoasts.de> +2007-12-19 Christian Dywan <christian@twotoasts.de> Reviewed by Alp Toker. @@ -2602,7 +3446,7 @@ Reviewed by Holger Freyther. Delete when Destroy functions are called to avoid leaks - + This matches the Mac port. * WebCoreSupport/ChromeClientGtk.cpp: @@ -2849,7 +3693,7 @@ * WebView/webkitprivate.h: (getFrameFromView): removed - + * WebView/webkitwebview.cpp: (webkit_web_view_expose_event): (webkit_web_view_key_press_event): use focused frame @@ -3275,7 +4119,7 @@ http://bugs.webkit.org/show_bug.cgi?id=15745 [GTK] Arrow keys do not Scroll - + * Api/webkitgtkpage.cpp: Support Up/Down/Right/Left keys to scroll. Slight hack, see FIXME for @@ -3848,12 +4692,12 @@ 2007-09-05 Geoffrey Garen <ggaren@apple.com> Reviewed by Darin Adler, Maciej Stachowiak, Mark Rowe, Tim Hatcher. - - Fixed <rdar://problem/5326009> Make non-browser WebKit clients have no + + Fixed <rdar://problem/5326009> Make non-browser WebKit clients have no memory cache, or a very tiny one - + Keep the GTK build working with an empty stub. - + * WebCoreSupport/FrameLoaderClientGtk.cpp: (WebKit::FrameLoaderClient::didPerformFirstNavigation): * WebCoreSupport/FrameLoaderClientGtk.h: @@ -3863,7 +4707,7 @@ Reviewed by Sam. <rdar://problem/5344848> IME is incorrectly used for key events when on non-editable regions - + EditorClient::setInputMethodState stub * WebCoreSupport/EditorClientGtk.cpp: @@ -3879,7 +4723,7 @@ 2007-08-17 Anders Carlsson <andersca@apple.com> Build fix. - + * WebCoreSupport/FrameLoaderClientGtk.cpp: (WebKit::FrameLoaderClient::createPlugin): * WebCoreSupport/FrameLoaderClientGtk.h: @@ -3931,7 +4775,7 @@ Minor changes to the WebKit::EditorClient to allow removing of text from TextFields. Remove the selectWordBeforeMenuEvent method - which is not used and not within WebCore::EditorClient. + which is not used and not within WebCore::EditorClient. * WebCoreSupport/EditorClientGtk.cpp: (WebKit::EditorClient::shouldDeleteRange): @@ -3949,7 +4793,7 @@ classes into the WebKit namespace. Change the class names to not contain Gtk. The file names have to contain the Gtk suffix to not clash with files in WebCore (e.g. bridge/EditorClient.h). - + * Api/webkitgtkframe.cpp: * Api/webkitgtkpage.cpp: @@ -4424,7 +5268,7 @@ GtkAdjustment of the GtkLayout and reimplement the set_scroll_adjustments method and pass the GtkAdjustments to ScrollView. This makes having one GdkWindow for the complete FrameTree possible. - + * gtk/Api/webkitgtkframe.cpp: * gtk/Api/webkitgtkpage.cpp: @@ -4515,7 +5359,7 @@ * gtk/Api/webkitgtkpage.cpp: Implement webkit_gtk_page_can_go_backward() and webkit_gtk_page_can_go_forward() functions. -2007-07-30 Diego Escalante Urrelo <diegoe@gnome.org> +2007-07-30 Diego Escalante Urrelo <diegoe@gnome.org> Reviewed by Alp Toker. diff --git a/WebKit/gtk/NEWS b/WebKit/gtk/NEWS new file mode 100644 index 0000000..c8f656c --- /dev/null +++ b/WebKit/gtk/NEWS @@ -0,0 +1,54 @@ +================ +WebKitGTK+ 1.1.2 +================ + +What's new in WebKitGTK+ 1.1.2? + + - Added support for downloads: a new signal, 'download-requested', + will be emitted by WebKit when a dowload is requested. On top of + that, the download process has been encapsulated in a new object, + WebKitDownload, which allows the user to control it or to start + new downloads from the client side. + - Added webkit_web_view_get_encoding to get the automatic encoding + of the current page. + - Added GObject properties for 'encoding' and 'custom-encoding'. + - Added 'javascript-profiling-enabled' property to the WebInspector, + which allows to enable and disable the profiling functionality. + - Added API to create and add history items to WebKit's history. + - Improved debugging support with WEBKIT_DEBUG environment + variable. Most of the settings will only give useful output for + debug builds, but WEBKIT_DEBUG=Network will log all HTTP traffic + form libsoup to console. See WebCore/platform/gtk/LoggingGtk.cpp + for all the options available. + - Lots of bugfixes. + +================ +WebKitGTK+ 1.1.1 +================ + +What's new in WebKitGTK+ 1.1.1? + + - ABI compatibility with 1.0.3 was broken, so you will need to + recompile your application against 1.1.1 + - Support for the CURL backend was dropped, libsoup is the only HTTP + backend now. + - webkit_get_default_session, to get the SoupSession used internally + by WebKit. + - 'create-web-view' signal, emitted when the creation of a new + window is requested. + - 'navigation-policy-decision-requested' signal, emitted when a + navigation to another page is requested. + - 'mime-type-policy-decision-requested' signal, emitted each time + WebKit is about to show a URI with a given MIME type. + - Support for the Web Inspector + (see http://webkit.org/blog/197/web-inspector-redesign/) + - HTTP authentication support, with optional gnome-keyring storage. + - New load functions: webkit_web_view_open, webkit_web_view_load_uri + and webkit_web_view_load_request. The old + webkit_web_view_load_string and webkit_web_view_load_html_string + are now deprecated. + - webkit_web_view_reload_bypass_cache + - webkit_web_view_{get,set}_custom_encoding, to override the + encoding of the current page. + - Improved stability and lots of bugfixes. + diff --git a/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp b/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp index 3557a3f..85f704a 100644 --- a/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp +++ b/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp @@ -358,6 +358,20 @@ void ChromeClient::contentsSizeChanged(Frame*, const IntSize&) const void ChromeClient::mouseDidMoveOverElement(const HitTestResult& hit, unsigned modifierFlags) { + // If a tooltip must be displayed it will be, afterwards, when + // setToolTip is called; this is just a work-around to make sure + // it updates its location correctly; see + // https://bugs.webkit.org/show_bug.cgi?id=15793. + g_object_set(m_webView, "has-tooltip", FALSE, NULL); + + GdkDisplay* gdkDisplay; + GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(m_webView)); + if (GTK_WIDGET_TOPLEVEL(window)) + gdkDisplay = gtk_widget_get_display(window); + else + gdkDisplay = gdk_display_get_default(); + gtk_tooltip_trigger_tooltip_query(gdkDisplay); + // check if the element is a link... bool isLink = hit.isLiveLink(); if (isLink) { diff --git a/WebKit/gtk/WebCoreSupport/ContextMenuClientGtk.cpp b/WebKit/gtk/WebCoreSupport/ContextMenuClientGtk.cpp index 490370c..42d4813 100644 --- a/WebKit/gtk/WebCoreSupport/ContextMenuClientGtk.cpp +++ b/WebKit/gtk/WebCoreSupport/ContextMenuClientGtk.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2008 Nuanti Ltd. + * Copyright (C) 2009 Gustavo Noronha Silva <gns@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,6 +21,7 @@ #include "ContextMenu.h" #include "ContextMenuClientGtk.h" +#include "CString.h" #include "HitTestResult.h" #include "KURL.h" #include "NotImplemented.h" @@ -163,7 +165,20 @@ void ContextMenuClient::contextMenuItemSelected(ContextMenuItem*, const ContextM void ContextMenuClient::downloadURL(const KURL& url) { - notImplemented(); + WebKitNetworkRequest* network_request = webkit_network_request_new(url.string().utf8().data()); + WebKitDownload* download = webkit_download_new(network_request); + g_object_unref(network_request); + + gboolean handled; + g_signal_emit_by_name(m_webView, "download-requested", download, &handled); + + if (!handled) { + webkit_download_cancel(download); + g_object_unref(download); + return; + } + + webkit_download_start(download); } void ContextMenuClient::copyImageToClipboard(const HitTestResult&) diff --git a/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp b/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp index e09178e..a1f2509 100644 --- a/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp +++ b/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp @@ -169,7 +169,7 @@ static void clipboard_get_contents_cb(GtkClipboard* clipboard, GtkSelectionData* { WebKitWebView* webView = reinterpret_cast<WebKitWebView*>(data); Frame* frame = core(webView)->focusController()->focusedOrMainFrame(); - PassRefPtr<Range> selectedRange = frame->selection()->toRange(); + PassRefPtr<Range> selectedRange = frame->selection()->toNormalizedRange(); if (static_cast<gint>(info) == WEBKIT_WEB_VIEW_TARGET_INFO_HTML) { String markup = createMarkup(selectedRange.get(), 0, AnnotateForInterchange); @@ -457,8 +457,11 @@ void EditorClient::handleKeyboardEvent(KeyboardEvent* event) void EditorClient::handleInputMethodKeydown(KeyboardEvent* event) { - WebKitWebViewPrivate* priv = m_webView->priv; + Frame* targetFrame = core(m_webView)->focusController()->focusedOrMainFrame(); + if (!targetFrame || !targetFrame->editor()->canEdit()) + return; + WebKitWebViewPrivate* priv = m_webView->priv; // TODO: Dispatch IE-compatible text input events for IM events. if (gtk_im_context_filter_keypress(priv->imContext, event->keyEvent()->gdkEventKey())) event->setDefaultHandled(); diff --git a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp index 55d5024..a54aecc 100644 --- a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp +++ b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp @@ -3,6 +3,7 @@ * Copyright (C) 2007, 2008 Holger Hans Peter Freyther * Copyright (C) 2007 Christian Dywan <christian@twotoasts.de> * Copyright (C) 2008 Collabora Ltd. All rights reserved. + * Copyright (C) 2009 Gustavo Noronha Silva <gns@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,10 +29,12 @@ #include "FrameLoader.h" #include "FrameView.h" #include "FrameTree.h" +#include "HTMLAppletElement.h" #include "HTMLFormElement.h" #include "HTMLFrameElement.h" #include "HTMLFrameOwnerElement.h" #include "HTMLNames.h" +#include "HTMLPlugInElement.h" #include "JSDOMWindow.h" #include "Language.h" #include "MIMETypeRegistry.h" @@ -40,6 +43,7 @@ #include "PlatformString.h" #include "PluginDatabase.h" #include "RenderPart.h" +#include "ResourceHandle.h" #include "ResourceRequest.h" #include "CString.h" #include "ProgressTracker.h" @@ -245,8 +249,12 @@ void FrameLoaderClient::postProgressEstimateChangedNotification() void FrameLoaderClient::postProgressFinishedNotification() { WebKitWebView* webView = getViewFromFrame(m_frame); + WebKitWebViewPrivate* privateData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView); - g_signal_emit_by_name(webView, "load-finished", m_frame); + // We can get a stopLoad() from dispose when the object is being + // destroyed, don't emit the signal in that case. + if (!privateData->disposing) + g_signal_emit_by_name(webView, "load-finished", m_frame); } void FrameLoaderClient::frameLoaderDestroyed() @@ -268,6 +276,11 @@ void FrameLoaderClient::dispatchDecidePolicyForMIMEType(FramePolicyFunction poli if (!policyFunction) return; + if (resourceRequest.isNull()) { + (core(m_frame)->loader()->*policyFunction)(PolicyIgnore); + return; + } + WebKitWebView* page = getViewFromFrame(m_frame); WebKitNetworkRequest* request = webkit_network_request_new(resourceRequest.url().string().utf8().data()); @@ -287,7 +300,40 @@ void FrameLoaderClient::dispatchDecidePolicyForMIMEType(FramePolicyFunction poli if (canShowMIMEType(mimeType)) webkit_web_policy_decision_use (policyDecision); else - webkit_web_policy_decision_download (policyDecision); + webkit_web_policy_decision_ignore (policyDecision); +} + +static WebKitWebNavigationAction* getNavigationAction(const NavigationAction& action) +{ + gint button = -1; + + const Event* event = action.event(); + if (event && event->isMouseEvent()) { + const MouseEvent* mouseEvent = static_cast<const MouseEvent*>(event); + // DOM button values are 0, 1 and 2 for left, middle and right buttons. + // GTK+ uses 1, 2 and 3, so let's add 1 to remain consistent. + button = mouseEvent->button() + 1; + } + + gint modifierFlags = 0; + UIEventWithKeyState* keyStateEvent = findEventWithKeyState(const_cast<Event*>(event)); + if (keyStateEvent) { + if (keyStateEvent->shiftKey()) + modifierFlags |= GDK_SHIFT_MASK; + if (keyStateEvent->ctrlKey()) + modifierFlags |= GDK_CONTROL_MASK; + if (keyStateEvent->altKey()) + modifierFlags |= GDK_MOD1_MASK; + if (keyStateEvent->metaKey()) + modifierFlags |= GDK_MOD2_MASK; + } + + return WEBKIT_WEB_NAVIGATION_ACTION(g_object_new(WEBKIT_TYPE_WEB_NAVIGATION_ACTION, + "reason", kit(action.type()), + "original-uri", action.url().string().utf8().data(), + "button", button, + "modifier-state", modifierFlags, + NULL)); } void FrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction policyFunction, const NavigationAction& action, const ResourceRequest& resourceRequest, PassRefPtr<FormState>, const String& s) @@ -295,9 +341,32 @@ void FrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFuncti ASSERT(policyFunction); if (!policyFunction) return; + + if (resourceRequest.isNull()) { + (core(m_frame)->loader()->*policyFunction)(PolicyIgnore); + return; + } + + WebKitWebPolicyDecision* policyDecision = webkit_web_policy_decision_new(m_frame, policyFunction); + + if (m_policyDecision) + g_object_unref(m_policyDecision); + m_policyDecision = policyDecision; + + WebKitWebView* webView = getViewFromFrame(m_frame); + WebKitNetworkRequest* request = webkit_network_request_new(resourceRequest.url().string().utf8().data()); + WebKitWebNavigationAction* navigationAction = getNavigationAction(action); + gboolean isHandled = false; + + g_signal_emit_by_name(webView, "new-window-policy-decision-requested", m_frame, request, navigationAction, policyDecision, &isHandled); + + g_object_unref(navigationAction); + g_object_unref(request); + // FIXME: I think Qt version marshals this to another thread so when we // have multi-threaded download, we might need to do the same - (core(m_frame)->loader()->*policyFunction)(PolicyUse); + if (!isHandled) + (core(m_frame)->loader()->*policyFunction)(PolicyUse); } void FrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction policyFunction, const NavigationAction& action, const ResourceRequest& resourceRequest, PassRefPtr<FormState>) @@ -306,6 +375,11 @@ void FrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunct if (!policyFunction) return; + if (resourceRequest.isNull()) { + (core(m_frame)->loader()->*policyFunction)(PolicyIgnore); + return; + } + WebKitWebView* webView = getViewFromFrame(m_frame); WebKitNetworkRequest* request = webkit_network_request_new(resourceRequest.url().string().utf8().data()); WebKitNavigationResponse response; @@ -329,36 +403,7 @@ void FrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunct g_object_unref(m_policyDecision); m_policyDecision = policyDecision; - gint button = -1; - gint modifierFlags = 0; - - const Event* event = action.event(); - if (event && event->isMouseEvent()) { - const MouseEvent* mouseEvent = static_cast<const MouseEvent*>(event); - // DOM button values are 0, 1 and 2 for left, middle and right buttons. - // GTK+ uses 1, 2 and 3, so let's add 1 to remain consistent. - button = mouseEvent->button() + 1; - } - - UIEventWithKeyState* keyStateEvent = findEventWithKeyState(const_cast<Event*>(event)); - if (keyStateEvent) { - if (keyStateEvent->shiftKey()) - modifierFlags |= GDK_SHIFT_MASK; - if (keyStateEvent->ctrlKey()) - modifierFlags |= GDK_CONTROL_MASK; - if (keyStateEvent->altKey()) - modifierFlags |= GDK_MOD1_MASK; - if (keyStateEvent->metaKey()) - modifierFlags |= GDK_MOD2_MASK; - } - - GObject* navigationAction = G_OBJECT(g_object_new(WEBKIT_TYPE_WEB_NAVIGATION_ACTION, - "reason", kit(action.type()), - "original-uri", action.url().string().utf8().data(), - "button", button, - "modifier-state", modifierFlags, - NULL)); - + WebKitWebNavigationAction* navigationAction = getNavigationAction(action); gboolean isHandled = false; g_signal_emit_by_name(webView, "navigation-policy-decision-requested", m_frame, request, navigationAction, policyDecision, &isHandled); @@ -370,7 +415,7 @@ void FrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunct webkit_web_policy_decision_use(m_policyDecision); } -Widget* FrameLoaderClient::createPlugin(const IntSize& pluginSize, Element* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually) +Widget* FrameLoaderClient::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually) { PluginView* pluginView = PluginView::create(core(m_frame), pluginSize, element, url, paramNames, paramValues, mimeType, loadManually); @@ -393,7 +438,7 @@ PassRefPtr<Frame> FrameLoaderClient::createFrame(const KURL& url, const String& childFrame->tree()->setName(name); childFrame->init(); - childFrame->loader()->loadURL(url, referrer, String(), FrameLoadTypeRedirectWithLockedBackForwardList, 0, 0); + childFrame->loader()->loadURL(url, referrer, String(), false, FrameLoadTypeRedirectWithLockedBackForwardList, 0, 0); // The frame's onload handler may have removed it from the document. if (!childFrame->tree()->parent()) @@ -409,7 +454,7 @@ void FrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget) m_hasSentResponseToPlugin = false; } -Widget* FrameLoaderClient::createJavaAppletWidget(const IntSize&, Element*, const KURL& baseURL, +Widget* FrameLoaderClient::createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues) { notImplemented(); @@ -469,6 +514,10 @@ void FrameLoaderClient::windowObjectCleared() // The Win port has an example of how we might do this. } +void FrameLoaderClient::documentElementAvailable() +{ +} + void FrameLoaderClient::didPerformFirstNavigation() const { } @@ -524,7 +573,9 @@ void FrameLoaderClient::makeRepresentation(DocumentLoader*) void FrameLoaderClient::forceLayout() { - core(m_frame)->forceLayout(true); + FrameView* view = core(m_frame)->view(); + if (view) + view->forceLayout(true); } void FrameLoaderClient::forceLayoutForNonHTML() @@ -569,7 +620,10 @@ void FrameLoaderClient::dispatchWillPerformClientRedirect(const KURL&, double, d void FrameLoaderClient::dispatchDidChangeLocationWithinPage() { - notImplemented(); + WebKitWebFramePrivate* priv = m_frame->priv; + g_free(priv->uri); + priv->uri = g_strdup(core(m_frame)->loader()->url().prettyURL().utf8().data()); + g_object_notify(G_OBJECT(m_frame), "uri"); } void FrameLoaderClient::dispatchWillClose() @@ -590,11 +644,18 @@ void FrameLoaderClient::dispatchDidStartProvisionalLoad() void FrameLoaderClient::dispatchDidReceiveTitle(const String& title) { - g_signal_emit_by_name(m_frame, "title-changed", title.utf8().data()); + WebKitWebFramePrivate* priv = m_frame->priv; + g_free(priv->title); + priv->title = g_strdup(title.utf8().data()); + + g_signal_emit_by_name(m_frame, "title-changed", priv->title); + g_object_notify(G_OBJECT(m_frame), "title"); WebKitWebView* webView = getViewFromFrame(m_frame); - if (m_frame == webkit_web_view_get_main_frame(webView)) + if (m_frame == webkit_web_view_get_main_frame(webView)) { g_signal_emit_by_name(webView, "title-changed", m_frame, title.utf8().data()); + g_object_notify(G_OBJECT(webView), "title"); + } } void FrameLoaderClient::dispatchDidCommitLoad() @@ -602,15 +663,28 @@ void FrameLoaderClient::dispatchDidCommitLoad() /* Update the URI once first data has been received. * This means the URI is valid and successfully identify the page that's going to be loaded. */ - WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(m_frame); - g_free(frameData->uri); - frameData->uri = g_strdup(core(m_frame)->loader()->url().prettyURL().utf8().data()); + g_object_freeze_notify(G_OBJECT(m_frame)); + + WebKitWebFramePrivate* priv = m_frame->priv; + g_free(priv->uri); + priv->uri = g_strdup(core(m_frame)->loader()->url().prettyURL().utf8().data()); + g_free(priv->title); + priv->title = NULL; + g_object_notify(G_OBJECT(m_frame), "uri"); + g_object_notify(G_OBJECT(m_frame), "title"); g_signal_emit_by_name(m_frame, "load-committed"); WebKitWebView* webView = getViewFromFrame(m_frame); - if (m_frame == webkit_web_view_get_main_frame(webView)) + if (m_frame == webkit_web_view_get_main_frame(webView)) { + g_object_freeze_notify(G_OBJECT(webView)); + g_object_notify(G_OBJECT(webView), "uri"); + g_object_notify(G_OBJECT(webView), "title"); + g_object_thaw_notify(G_OBJECT(webView)); g_signal_emit_by_name(webView, "load-committed", m_frame); + } + + g_object_thaw_notify(G_OBJECT(m_frame)); } void FrameLoaderClient::dispatchDidFinishDocumentLoad() @@ -746,51 +820,57 @@ void FrameLoaderClient::dispatchDidFailLoad(const ResourceError&) g_signal_emit_by_name(m_frame, "load-done", false); } -void FrameLoaderClient::download(ResourceHandle*, const ResourceRequest&, const ResourceRequest&, const ResourceResponse&) +void FrameLoaderClient::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest&, const ResourceResponse&) { - notImplemented(); + // FIXME: We could reuse the same handle here, but when I tried + // implementing that the main load would fail and stop, so I have + // simplified this case for now. + handle->cancel(); + startDownload(request); } ResourceError FrameLoaderClient::cancelledError(const ResourceRequest&) { notImplemented(); - return ResourceError(); + ResourceError error("", 0, "", ""); + error.setIsCancellation(true); + return error; } ResourceError FrameLoaderClient::blockedError(const ResourceRequest&) { notImplemented(); - return ResourceError(); + return ResourceError("", 0, "", ""); } ResourceError FrameLoaderClient::cannotShowURLError(const ResourceRequest&) { notImplemented(); - return ResourceError(); + return ResourceError("", 0, "", ""); } ResourceError FrameLoaderClient::interruptForPolicyChangeError(const ResourceRequest&) { notImplemented(); - return ResourceError(); + return ResourceError("", 0, "", ""); } ResourceError FrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse&) { notImplemented(); - return ResourceError(); + return ResourceError("", 0, "", ""); } ResourceError FrameLoaderClient::fileDoesNotExistError(const ResourceResponse&) { notImplemented(); - return ResourceError(); + return ResourceError("", 0, "", ""); } ResourceError FrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse&) { notImplemented(); - return ResourceError(); + return ResourceError("", 0, "", ""); } bool FrameLoaderClient::shouldFallBack(const ResourceError&) @@ -832,9 +912,23 @@ void FrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceErro } } -void FrameLoaderClient::startDownload(const ResourceRequest&) +void FrameLoaderClient::startDownload(const ResourceRequest& request) { - notImplemented(); + WebKitNetworkRequest* networkRequest = webkit_network_request_new(request.url().string().utf8().data()); + WebKitDownload* download = webkit_download_new(networkRequest); + g_object_unref(networkRequest); + + WebKitWebView* view = getViewFromFrame(m_frame); + gboolean handled; + g_signal_emit_by_name(view, "download-requested", download, &handled); + + if (!handled) { + webkit_download_cancel(download); + g_object_unref(download); + return; + } + + webkit_download_start(download); } void FrameLoaderClient::updateGlobalHistory() @@ -842,7 +936,7 @@ void FrameLoaderClient::updateGlobalHistory() notImplemented(); } -void FrameLoaderClient::updateGlobalHistoryForRedirectWithoutHistoryItem() +void FrameLoaderClient::updateGlobalHistoryRedirectLinks() { notImplemented(); } @@ -865,7 +959,7 @@ void FrameLoaderClient::transitionToCommittedForNewPage() Frame* frame = core(m_frame); ASSERT(frame); - WebCore::FrameLoaderClient::transitionToCommittedForNewPage(frame, size, backgroundColor, transparent, IntSize(), false); + frame->createView(size, backgroundColor, transparent, IntSize(), false); // We need to do further manipulation on the FrameView if it was the mainFrame if (frame != frame->page()->mainFrame()) diff --git a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h index 82286e8..cb4786d 100644 --- a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h +++ b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h @@ -109,11 +109,12 @@ namespace WebKit { virtual PassRefPtr<WebCore::Frame> createFrame(const WebCore::KURL& url, const WebCore::String& name, WebCore::HTMLFrameOwnerElement* ownerElement, const WebCore::String& referrer, bool allowsScrolling, int marginWidth, int marginHeight); - virtual WebCore::Widget* createPlugin(const WebCore::IntSize&, WebCore::Element*, const WebCore::KURL&, const WTF::Vector<WebCore::String>&, const WTF::Vector<WebCore::String>&, const WebCore::String&, bool); + virtual WebCore::Widget* createPlugin(const WebCore::IntSize&, WebCore::HTMLPlugInElement*, const WebCore::KURL&, const WTF::Vector<WebCore::String>&, const WTF::Vector<WebCore::String>&, const WebCore::String&, bool); virtual void redirectDataToPlugin(WebCore::Widget* pluginWidget); - virtual WebCore::Widget* createJavaAppletWidget(const WebCore::IntSize&, WebCore::Element*, const WebCore::KURL& baseURL, const WTF::Vector<WebCore::String>& paramNames, const WTF::Vector<WebCore::String>& paramValues); + virtual WebCore::Widget* createJavaAppletWidget(const WebCore::IntSize&, WebCore::HTMLAppletElement*, const WebCore::KURL& baseURL, const WTF::Vector<WebCore::String>& paramNames, const WTF::Vector<WebCore::String>& paramValues); virtual WebCore::String overrideMediaType() const; virtual void windowObjectCleared(); + virtual void documentElementAvailable(); virtual void didPerformFirstNavigation() const; virtual void registerForIconNotification(bool); @@ -131,7 +132,7 @@ namespace WebKit { virtual void finishedLoading(WebCore::DocumentLoader*); virtual void updateGlobalHistory(); - virtual void updateGlobalHistoryForRedirectWithoutHistoryItem(); + virtual void updateGlobalHistoryRedirectLinks(); virtual bool shouldGoToHistoryItem(WebCore::HistoryItem*) const; virtual WebCore::ResourceError cancelledError(const WebCore::ResourceRequest&); diff --git a/WebKit/gtk/WebCoreSupport/InspectorClientGtk.cpp b/WebKit/gtk/WebCoreSupport/InspectorClientGtk.cpp index ba3721a..faa3e28 100644 --- a/WebKit/gtk/WebCoreSupport/InspectorClientGtk.cpp +++ b/WebKit/gtk/WebCoreSupport/InspectorClientGtk.cpp @@ -104,6 +104,12 @@ String InspectorClient::localizedStringsURL() return String(); } +String InspectorClient::hiddenPanels() +{ + notImplemented(); + return String(); +} + void InspectorClient::showWindow() { if (!m_webView) diff --git a/WebKit/gtk/WebCoreSupport/InspectorClientGtk.h b/WebKit/gtk/WebCoreSupport/InspectorClientGtk.h index 4fba55d..43894b3 100644 --- a/WebKit/gtk/WebCoreSupport/InspectorClientGtk.h +++ b/WebKit/gtk/WebCoreSupport/InspectorClientGtk.h @@ -52,6 +52,8 @@ namespace WebKit { virtual WebCore::String localizedStringsURL(); + virtual WebCore::String hiddenPanels(); + virtual void showWindow(); virtual void closeWindow(); diff --git a/WebKit/gtk/tests/testwebbackforwardlist.c b/WebKit/gtk/tests/testwebbackforwardlist.c new file mode 100644 index 0000000..8d53c3e --- /dev/null +++ b/WebKit/gtk/tests/testwebbackforwardlist.c @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2008 Holger Hans Peter Freyther + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <glib.h> +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +#if GLIB_CHECK_VERSION(2, 16, 0) && GTK_CHECK_VERSION(2, 14, 0) + +static void test_webkit_web_history_item_lifetime(void) +{ + WebKitWebView* webView; + WebKitWebBackForwardList* backForwardList; + WebKitWebHistoryItem* currentItem; + WebKitWebHistoryItem* forwardItem; + WebKitWebHistoryItem* backItem; + WebKitWebHistoryItem* nthItem; + WebKitWebHistoryItem* item1; + WebKitWebHistoryItem* item2; + WebKitWebHistoryItem* item3; + WebKitWebHistoryItem* item4; + GList* backList = NULL; + GList* forwardList = NULL; + g_test_bug("19898"); + + webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + backForwardList = webkit_web_view_get_back_forward_list(webView); + g_assert_cmpint(G_OBJECT(backForwardList)->ref_count, ==, 1); + + /* add test items */ + item1 = webkit_web_history_item_new_with_data("http://example.com/1/", "Site 1"); + webkit_web_back_forward_list_add_item(backForwardList, item1); + + item2 = webkit_web_history_item_new_with_data("http://example.com/2/", "Site 2"); + webkit_web_back_forward_list_add_item(backForwardList, item2); + + item3 = webkit_web_history_item_new_with_data("http://example.com/3/", "Site 3"); + webkit_web_back_forward_list_add_item(backForwardList, item3); + + item4 = webkit_web_history_item_new_with_data("http://example.com/4/", "Site 4"); + webkit_web_back_forward_list_add_item(backForwardList, item4); + + /* make sure these functions don't add unnecessary ref to the history item */ + backItem = webkit_web_back_forward_list_get_back_item(backForwardList); + g_object_ref(backItem); + g_assert_cmpint(G_OBJECT(backItem)->ref_count, ==, 2); + g_object_unref(backItem); + g_assert_cmpint(G_OBJECT(backItem)->ref_count, ==, 1); + + currentItem = webkit_web_back_forward_list_get_current_item(backForwardList); + g_object_ref(currentItem); + g_assert_cmpint(G_OBJECT(currentItem)->ref_count, ==, 2); + g_object_unref(currentItem); + g_assert_cmpint(G_OBJECT(currentItem)->ref_count, ==, 1); + + webkit_web_back_forward_list_go_to_item(backForwardList, item2); + forwardItem = webkit_web_back_forward_list_get_forward_item(backForwardList); + g_object_ref(forwardItem); + g_assert_cmpint(G_OBJECT(forwardItem)->ref_count, ==, 2); + g_object_unref(forwardItem); + g_assert_cmpint(G_OBJECT(forwardItem)->ref_count, ==, 1); + + nthItem = webkit_web_back_forward_list_get_nth_item(backForwardList, 1); + g_object_ref(nthItem); + g_assert_cmpint(G_OBJECT(nthItem)->ref_count, ==, 2); + g_object_unref(nthItem); + g_assert_cmpint(G_OBJECT(nthItem)->ref_count, ==, 1); + + backList = webkit_web_back_forward_list_get_back_list_with_limit(backForwardList, 5); + for (; backList; backList = backList->next) + g_assert_cmpint(G_OBJECT(backList->data)->ref_count, ==, 1); + + forwardList = webkit_web_back_forward_list_get_forward_list_with_limit(backForwardList, 5); + for (; forwardList; forwardList = forwardList->next) + g_assert_cmpint(G_OBJECT(forwardList->data)->ref_count, ==, 1); + + g_list_free(forwardList); + g_list_free(backList); + g_object_unref(item1); + g_object_unref(item2); + g_object_unref(item3); + g_object_unref(item4); + + g_object_ref(backForwardList); + g_object_unref(webView); + + g_assert_cmpint(G_OBJECT(backForwardList)->ref_count, ==, 1); + g_object_unref(backForwardList); +} + +static void test_webkit_web_back_forward_list_order(void) +{ + WebKitWebView* webView; + WebKitWebBackForwardList* webBackForwardList; + WebKitWebHistoryItem* item1; + WebKitWebHistoryItem* item2; + WebKitWebHistoryItem* item3; + WebKitWebHistoryItem* item4; + WebKitWebHistoryItem* currentItem; + GList* backList = NULL; + GList* forwardList = NULL; + g_test_bug("22694"); + + webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + + webkit_web_view_set_maintains_back_forward_list(webView, TRUE); + webBackForwardList = webkit_web_view_get_back_forward_list(webView); + g_assert(webBackForwardList); + + // Check that there is no item. + g_assert(!webkit_web_back_forward_list_get_current_item(webBackForwardList)); + g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0); + g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0); + g_assert(!webkit_web_view_can_go_forward(webView)); + g_assert(!webkit_web_view_can_go_back(webView)); + + // Add a new items + item1 = webkit_web_history_item_new_with_data("http://example.com/1/", "Site 1"); + webkit_web_back_forward_list_add_item(webBackForwardList, item1); + g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, item1)); + + item2 = webkit_web_history_item_new_with_data("http://example.com/2/", "Site 2"); + webkit_web_back_forward_list_add_item(webBackForwardList, item2); + g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, item2)); + + item3 = webkit_web_history_item_new_with_data("http://example.com/3/", "Site 3"); + webkit_web_back_forward_list_add_item(webBackForwardList, item3); + g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, item3)); + + item4 = webkit_web_history_item_new_with_data("http://example.com/4/", "Site 4"); + webkit_web_back_forward_list_add_item(webBackForwardList, item4); + g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, item4)); + + // check the back list order + backList = webkit_web_back_forward_list_get_back_list_with_limit(webBackForwardList, 5); + g_assert(backList); + + currentItem = WEBKIT_WEB_HISTORY_ITEM(backList->data); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/3/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 3"); + backList = backList->next; + + currentItem = WEBKIT_WEB_HISTORY_ITEM(backList->data); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/2/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 2"); + backList = backList->next; + + currentItem = WEBKIT_WEB_HISTORY_ITEM(backList->data); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/1/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 1"); + g_list_free(backList); + + // check the forward list order + g_assert(webkit_web_view_go_to_back_forward_item(webView, item1)); + forwardList = webkit_web_back_forward_list_get_forward_list_with_limit(webBackForwardList,5); + g_assert(forwardList); + + currentItem = WEBKIT_WEB_HISTORY_ITEM(forwardList->data); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/4/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 4"); + forwardList = forwardList->next; + + currentItem = WEBKIT_WEB_HISTORY_ITEM(forwardList->data); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/3/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 3"); + forwardList = forwardList->next; + + currentItem = WEBKIT_WEB_HISTORY_ITEM(forwardList->data); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/2/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 2"); + + g_object_unref(item1); + g_object_unref(item2); + g_object_unref(item3); + g_object_unref(item4); + g_list_free(forwardList); + g_object_unref(webView); +} + +static void test_webkit_web_back_forward_list_add_item(void) +{ + WebKitWebView* webView; + WebKitWebBackForwardList* webBackForwardList; + WebKitWebHistoryItem* addItem1; + WebKitWebHistoryItem* addItem2; + WebKitWebHistoryItem* backItem; + WebKitWebHistoryItem* currentItem; + g_test_bug("22988"); + + webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + + webkit_web_view_set_maintains_back_forward_list(webView, TRUE); + webBackForwardList = webkit_web_view_get_back_forward_list(webView); + g_assert(webBackForwardList); + + // Check that there is no item. + g_assert(!webkit_web_back_forward_list_get_current_item(webBackForwardList)); + g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0); + g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0); + g_assert(!webkit_web_view_can_go_forward(webView)); + g_assert(!webkit_web_view_can_go_back(webView)); + + // Add a new item + addItem1 = webkit_web_history_item_new_with_data("http://example.com/", "Added site"); + webkit_web_back_forward_list_add_item(webBackForwardList, addItem1); + g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, addItem1)); + + // Check that the added item is the current item. + currentItem = webkit_web_back_forward_list_get_current_item(webBackForwardList); + g_assert(currentItem); + g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0); + g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0); + g_assert(!webkit_web_view_can_go_forward(webView)); + g_assert(!webkit_web_view_can_go_back(webView)); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Added site"); + + // Add another item. + addItem2 = webkit_web_history_item_new_with_data("http://example.com/2/", "Added site 2"); + webkit_web_back_forward_list_add_item(webBackForwardList, addItem2); + g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, addItem2)); + g_object_unref(addItem2); + + // Check that the added item is new current item. + currentItem = webkit_web_back_forward_list_get_current_item(webBackForwardList); + g_assert(currentItem); + g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0); + g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 1); + g_assert(!webkit_web_view_can_go_forward(webView)); + g_assert(webkit_web_view_can_go_back(webView)); + g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/2/"); + g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Added site 2"); + + backItem = webkit_web_back_forward_list_get_back_item(webBackForwardList); + g_assert(backItem); + g_assert_cmpstr(webkit_web_history_item_get_uri(backItem), ==, "http://example.com/"); + g_assert_cmpstr(webkit_web_history_item_get_title(backItem), ==, "Added site"); + + // Go to the first added item. + g_assert(webkit_web_view_go_to_back_forward_item(webView, addItem1)); + g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 1); + g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0); + g_assert(webkit_web_view_can_go_forward(webView)); + g_assert(!webkit_web_view_can_go_back(webView)); + + g_object_unref(addItem1); + g_object_unref(webView); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add_func("/webkit/webbackforwardlist/add_item", test_webkit_web_back_forward_list_add_item); + g_test_add_func("/webkit/webbackforwardlist/list_order", test_webkit_web_back_forward_list_order); + g_test_add_func("/webkit/webhistoryitem/lifetime", test_webkit_web_history_item_lifetime); + return g_test_run (); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need at least glib-2.16.0 and gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/WebKit/gtk/tests/main.c b/WebKit/gtk/tests/testwebframe.c index 68f6d70..e2da29c 100644 --- a/WebKit/gtk/tests/main.c +++ b/WebKit/gtk/tests/testwebframe.c @@ -70,7 +70,6 @@ int main(int argc, char** argv) g_test_bug_base("https://bugs.webkit.org/"); g_test_add_func("/webkit/webview/create_destroy", test_webkit_web_frame_create_destroy); g_test_add_func("/webkit/webframe/lifetime", test_webkit_web_frame_lifetime); - return g_test_run (); } diff --git a/WebKit/gtk/tests/testwebhistoryitem.c b/WebKit/gtk/tests/testwebhistoryitem.c new file mode 100644 index 0000000..6038c647 --- /dev/null +++ b/WebKit/gtk/tests/testwebhistoryitem.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2009 Jan Michael Alonzo + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <glib.h> +#include <gtk/gtk.h> +#include <webkit/webkit.h> + +#if GLIB_CHECK_VERSION(2, 16, 0) && GTK_CHECK_VERSION(2, 14, 0) + +typedef struct { + WebKitWebHistoryItem* item; +} WebHistoryItemFixture; + +static void web_history_item_fixture_setup(WebHistoryItemFixture* fixture, + gconstpointer data) +{ + fixture->item = webkit_web_history_item_new_with_data("http://example.com/", "Example1"); + g_assert_cmpint(G_OBJECT(fixture->item)->ref_count, == , 2); + g_assert(fixture->item != NULL); +} + +static void web_history_item_fixture_teardown(WebHistoryItemFixture* fixture, + gconstpointer data) +{ + g_assert(fixture->item != NULL); + g_assert_cmpint(G_OBJECT(fixture->item)->ref_count, ==, 2); + g_object_unref(fixture->item); + g_assert_cmpint(G_OBJECT(fixture->item)->ref_count, ==, 1); +} + +static void test_webkit_web_history_item_get_data(WebHistoryItemFixture* fixture, + gconstpointer data) +{ + g_assert_cmpstr(webkit_web_history_item_get_title(fixture->item), ==, "Example1"); + g_assert_cmpstr(webkit_web_history_item_get_uri(fixture->item), ==, "http://example.com/"); +} + +static void test_webkit_web_history_item_alternate_title(WebHistoryItemFixture* fixture, + gconstpointer data) +{ + webkit_web_history_item_set_alternate_title(fixture->item, "Alternate title"); + g_assert_cmpstr(webkit_web_history_item_get_alternate_title(fixture->item), ==, "Alternate title"); +} + +int main(int argc, char** argv) +{ + g_thread_init(NULL); + gtk_test_init(&argc, &argv, NULL); + + g_test_bug_base("https://bugs.webkit.org/"); + g_test_add("/webkit/webhistoryitem/get_data", + WebHistoryItemFixture, 0, web_history_item_fixture_setup, + test_webkit_web_history_item_get_data, web_history_item_fixture_teardown); + g_test_add("/webkit/webhistoryitem/alternate_title", + WebHistoryItemFixture, 0, web_history_item_fixture_setup, + test_webkit_web_history_item_alternate_title, web_history_item_fixture_teardown); + return g_test_run (); +} + +#else +int main(int argc, char** argv) +{ + g_critical("You will need at least glib-2.16.0 and gtk-2.14.0 to run the unit tests. Doing nothing now."); + return 0; +} + +#endif diff --git a/WebKit/gtk/webkit.pc.in b/WebKit/gtk/webkit.pc.in index 0ce6f71..84d6115 100644 --- a/WebKit/gtk/webkit.pc.in +++ b/WebKit/gtk/webkit.pc.in @@ -6,6 +6,6 @@ includedir=@includedir@ Name: WebKit Description: Web content engine for GTK+ Version: @VERSION@ -Requires: gtk+-2.0 +Requires: gtk+-2.0 libsoup-2.4 Libs: -L${libdir} -lwebkit-1.0 Cflags: -I${includedir}/webkit-1.0 diff --git a/WebKit/gtk/webkit/webkit.h b/WebKit/gtk/webkit/webkit.h index 8c868a2..c22165e 100644 --- a/WebKit/gtk/webkit/webkit.h +++ b/WebKit/gtk/webkit/webkit.h @@ -23,7 +23,9 @@ #include <webkit/webkitversion.h> #include <webkit/webkitdefines.h> +#include <webkit/webkitdownload.h> #include <webkit/webkitnetworkrequest.h> +#include <webkit/webkitsoupauthdialog.h> #include <webkit/webkitwebframe.h> #include <webkit/webkitwebsettings.h> #include <webkit/webkitwebinspector.h> diff --git a/WebKit/gtk/webkit/webkitdefines.h b/WebKit/gtk/webkit/webkitdefines.h index f94e710..b0ab5e9 100644 --- a/WebKit/gtk/webkit/webkitdefines.h +++ b/WebKit/gtk/webkit/webkitdefines.h @@ -68,6 +68,9 @@ typedef struct _WebKitWebWindowFeaturesClass WebKitWebWindowFeaturesClass; typedef struct _WebKitWebView WebKitWebView; typedef struct _WebKitWebViewClass WebKitWebViewClass; +typedef struct _WebKitDownload WebKitDownload; +typedef struct _WebKitDownloadClass WebKitDownloadClass; + G_END_DECLS #endif diff --git a/WebKit/gtk/webkit/webkitdownload.cpp b/WebKit/gtk/webkit/webkitdownload.cpp new file mode 100644 index 0000000..4488304 --- /dev/null +++ b/WebKit/gtk/webkit/webkitdownload.cpp @@ -0,0 +1,818 @@ +/* + * Copyright (C) 2008 Collabora Ltd. + * Copyright (C) 2009 Gustavo Noronha Silva <gns@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "CString.h" +#include "Noncopyable.h" +#include "NotImplemented.h" +#include "ResourceHandleClient.h" +#include "ResourceRequest.h" +#include "ResourceResponse.h" +#include "webkitdownload.h" +#include "webkitenumtypes.h" +#include "webkitmarshal.h" +#include "webkitprivate.h" + +#include <glib/gstdio.h> + +using namespace WebKit; +using namespace WebCore; + +class DownloadClient : Noncopyable, public ResourceHandleClient { + public: + DownloadClient(WebKitDownload*); + + virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); + virtual void didReceiveData(ResourceHandle*, const char*, int, int); + virtual void didFinishLoading(ResourceHandle*); + virtual void didFail(ResourceHandle*, const ResourceError&); + virtual void wasBlocked(ResourceHandle*); + virtual void cannotShowURL(ResourceHandle*); + + private: + WebKitDownload* m_download; +}; + +extern "C" { + +#define WEBKIT_DOWNLOAD_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_DOWNLOAD, WebKitDownloadPrivate)) + +struct _WebKitDownloadPrivate { + gchar* destinationURI; + gchar* suggestedFilename; + guint currentSize; + GTimer* timer; + WebKitDownloadStatus status; + GFileOutputStream* outputStream; + DownloadClient* downloadClient; + WebKitNetworkRequest* networkRequest; + ResourceResponse* networkResponse; + RefPtr<ResourceHandle> resourceHandle; +}; + +enum { + // Normal signals. + ERROR, + LAST_SIGNAL +}; + +static guint webkit_download_signals[LAST_SIGNAL] = { 0 }; + +enum { + PROP_0, + + PROP_NETWORK_REQUEST, + PROP_DESTINATION_URI, + PROP_SUGGESTED_FILENAME, + PROP_PROGRESS, + PROP_STATUS, + PROP_CURRENT_SIZE, + PROP_TOTAL_SIZE +}; + +G_DEFINE_TYPE(WebKitDownload, webkit_download, G_TYPE_OBJECT); + + +static void webkit_download_set_status(WebKitDownload* download, WebKitDownloadStatus status); + +static void webkit_download_dispose(GObject* object) +{ + WebKitDownload* download = WEBKIT_DOWNLOAD(object); + WebKitDownloadPrivate* priv = download->priv; + + if (priv->outputStream) { + g_object_unref(priv->outputStream); + priv->outputStream = NULL; + } + + if (priv->networkRequest) { + g_object_unref(priv->networkRequest); + priv->networkRequest = NULL; + } + + G_OBJECT_CLASS(webkit_download_parent_class)->dispose(object); +} + +static void webkit_download_finalize(GObject* object) +{ + WebKitDownload* download = WEBKIT_DOWNLOAD(object); + WebKitDownloadPrivate* priv = download->priv; + + // We don't call webkit_download_cancel() because we don't want to emit + // signals when finalizing an object. + if (priv->resourceHandle) { + if (priv->status == WEBKIT_DOWNLOAD_STATUS_STARTED) { + priv->resourceHandle->setClient(0); + priv->resourceHandle->cancel(); + } + priv->resourceHandle.release(); + } + + delete priv->downloadClient; + delete priv->networkResponse; + + // The download object may never have _start called on it, so we + // need to make sure timer is non-NULL. + if (priv->timer) + g_timer_destroy(priv->timer); + + g_free(priv->destinationURI); + g_free(priv->suggestedFilename); + + G_OBJECT_CLASS(webkit_download_parent_class)->finalize(object); +} + +static void webkit_download_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec) +{ + WebKitDownload* download = WEBKIT_DOWNLOAD(object); + + switch(prop_id) { + case PROP_NETWORK_REQUEST: + g_value_set_object(value, webkit_download_get_network_request(download)); + break; + case PROP_DESTINATION_URI: + g_value_set_string(value, webkit_download_get_destination_uri(download)); + break; + case PROP_SUGGESTED_FILENAME: + g_value_set_string(value, webkit_download_get_suggested_filename(download)); + break; + case PROP_PROGRESS: + g_value_set_double(value, webkit_download_get_progress(download)); + break; + case PROP_STATUS: + g_value_set_enum(value, webkit_download_get_status(download)); + break; + case PROP_CURRENT_SIZE: + g_value_set_uint64(value, webkit_download_get_current_size(download)); + break; + case PROP_TOTAL_SIZE: + g_value_set_uint64(value, webkit_download_get_total_size(download)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + +static void webkit_download_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec *pspec) +{ + WebKitDownload* download = WEBKIT_DOWNLOAD(object); + WebKitDownloadPrivate* priv = download->priv; + + switch(prop_id) { + case PROP_NETWORK_REQUEST: + priv->networkRequest = WEBKIT_NETWORK_REQUEST(g_value_dup_object(value)); + // This is safe as network-request is a construct only property and + // suggestedFilename is initially null. + priv->suggestedFilename = g_path_get_basename(webkit_network_request_get_uri(priv->networkRequest)); + break; + case PROP_DESTINATION_URI: + webkit_download_set_destination_uri(download, g_value_get_string(value)); + break; + case PROP_STATUS: + webkit_download_set_status(download, static_cast<WebKitDownloadStatus>(g_value_get_enum(value))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + +static void webkit_download_class_init(WebKitDownloadClass* downloadClass) +{ + GObjectClass* objectClass = G_OBJECT_CLASS(downloadClass); + objectClass->dispose = webkit_download_dispose; + objectClass->finalize = webkit_download_finalize; + objectClass->get_property = webkit_download_get_property; + objectClass->set_property = webkit_download_set_property; + + /** + * WebKitDownload::error: + * @download: the object on which the signal is emitted + * @current_bytes: the current count of bytes downloaded + * @total_bytes: the total bytes count in the downloaded file, aka file size. + * + * Indicates an error in the download. + * + * Since: 1.1.2 + */ + webkit_download_signals[ERROR] = g_signal_new("error", + G_TYPE_FROM_CLASS(downloadClass), + (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), + 0, + g_signal_accumulator_true_handled, + NULL, + webkit_marshal_BOOLEAN__INT_INT_STRING, + G_TYPE_BOOLEAN, 3, + G_TYPE_INT, + G_TYPE_INT, + G_TYPE_STRING); + + // Properties. + + /** + * WebKitDownload:network-request + * + * The #WebKitNetworkRequest instance associated with the download. + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, + PROP_NETWORK_REQUEST, + g_param_spec_object("network-request", + "Network Request", + "The network request for the URI that should be downloaded", + WEBKIT_TYPE_NETWORK_REQUEST, + (GParamFlags)(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitDownload:destination-uri + * + * The URI of the save location for this download. + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, + PROP_DESTINATION_URI, + g_param_spec_string("destination-uri", + "Destination URI", + "The destination URI where to save the file", + "", + WEBKIT_PARAM_READWRITE)); + + /** + * WebKitDownload:suggested-filename + * + * The file name suggested as default when saving + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, + PROP_SUGGESTED_FILENAME, + g_param_spec_string("suggested-filename", + "Suggested Filename", + "The filename suggested as default when saving", + "", + WEBKIT_PARAM_READABLE)); + + /** + * WebKitDownload:progress: + * + * Determines the current progress of the download. + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, PROP_PROGRESS, + g_param_spec_double("progress", + "Progress", + "Determines the current progress of the download", + 0.0, 1.0, 1.0, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitDownload:status: + * + * Determines the current status of the download. + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, PROP_STATUS, + g_param_spec_enum("status", + "Status", + "Determines the current status of the download", + WEBKIT_TYPE_DOWNLOAD_STATUS, + WEBKIT_DOWNLOAD_STATUS_CREATED, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitDownload:current-size + * + * The length of the data already downloaded + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, + PROP_CURRENT_SIZE, + g_param_spec_uint64("current-size", + "Current Size", + "The length of the data already downloaded", + 0, G_MAXUINT64, 0, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitDownload:total-size + * + * The total size of the file + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, + PROP_CURRENT_SIZE, + g_param_spec_uint64("total-size", + "Total Size", + "The total size of the file", + 0, G_MAXUINT64, 0, + WEBKIT_PARAM_READABLE)); + + g_type_class_add_private(downloadClass, sizeof(WebKitDownloadPrivate)); +} + +static void webkit_download_init(WebKitDownload* download) +{ + WebKitDownloadPrivate* priv = WEBKIT_DOWNLOAD_GET_PRIVATE(download); + download->priv = priv; + + priv->downloadClient = new DownloadClient(download); + priv->currentSize = 0; + priv->status = WEBKIT_DOWNLOAD_STATUS_CREATED; +} + +/** + * webkit_download_new: + * @request: a #WebKitNetworkRequest + * + * Creates a new #WebKitDownload object for the given + * #WebKitNetworkRequest object. + * + * Returns: the new #WebKitDownload + * + * Since: 1.1.2 + */ +WebKitDownload* webkit_download_new(WebKitNetworkRequest* request) +{ + g_return_val_if_fail(request, NULL); + + return WEBKIT_DOWNLOAD(g_object_new(WEBKIT_TYPE_DOWNLOAD, "network-request", request, NULL)); +} + +static gboolean webkit_download_open_stream_for_uri(WebKitDownload* download, const gchar* uri, gboolean append=FALSE) +{ + g_return_val_if_fail(uri, FALSE); + + WebKitDownloadPrivate* priv = download->priv; + GFile* file = g_file_new_for_uri(uri); + GError* error = NULL; + + if (append) + priv->outputStream = g_file_append_to(file, G_FILE_CREATE_NONE, NULL, &error); + else + priv->outputStream = g_file_replace(file, NULL, TRUE, G_FILE_CREATE_NONE, NULL, &error); + + g_object_unref(file); + + if (error) { + gboolean handled; + g_signal_emit_by_name(download, "error", 0, WEBKIT_DOWNLOAD_ERROR_DESTINATION, error->message, &handled); + g_error_free(error); + return FALSE; + } + + return TRUE; +} + +static void webkit_download_close_stream(WebKitDownload* download) +{ + WebKitDownloadPrivate* priv = download->priv; + if (priv->outputStream) { + g_object_unref(priv->outputStream); + priv->outputStream = NULL; + } +} + +/** + * webkit_download_start: + * @download: the #WebKitDownload + * + * Initiates the download. Notice that you must have set the + * destination-uri property before calling this method. + * + * Since: 1.1.2 + */ +void webkit_download_start(WebKitDownload* download) +{ + g_return_if_fail(WEBKIT_IS_DOWNLOAD(download)); + + WebKitDownloadPrivate* priv = download->priv; + g_return_if_fail(priv->destinationURI); + g_return_if_fail(priv->status == WEBKIT_DOWNLOAD_STATUS_CREATED); + g_return_if_fail(priv->timer == NULL); + + if (priv->resourceHandle) + priv->resourceHandle->setClient(priv->downloadClient); + else { + // FIXME: Use the actual request object when WebKitNetworkRequest is finished. + ResourceRequest request(webkit_network_request_get_uri(priv->networkRequest)); + priv->resourceHandle = ResourceHandle::create(request, priv->downloadClient, 0, false, false, false); + } + + priv->timer = g_timer_new(); + webkit_download_open_stream_for_uri(download, priv->destinationURI); +} + +/** + * webkit_download_cancel: + * @download: the #WebKitDownload + * + * Cancels the download. Calling this will not free the + * #WebKitDownload object, so you still need to call + * g_object_unref() on it, if you are the owner of a reference. Notice + * that cancelling the download provokes the emission of the + * WebKitDownload::error signal, reporting that the download was + * cancelled. + * + * Since: 1.1.2 + */ +void webkit_download_cancel(WebKitDownload* download) +{ + g_return_if_fail(WEBKIT_IS_DOWNLOAD(download)); + + WebKitDownloadPrivate* priv = download->priv; + + // Cancel may be called even if start was not called, so we need + // to make sure timer is non-NULL. + if (priv->timer) + g_timer_stop(priv->timer); + + if (priv->resourceHandle) + priv->resourceHandle->cancel(); + + webkit_download_set_status(download, WEBKIT_DOWNLOAD_STATUS_CANCELLED); + + gboolean handled; + g_signal_emit_by_name(download, "error", 0, WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER, "User cancelled the download", &handled); +} + +/** + * webkit_download_get_uri: + * @download: the #WebKitDownload + * + * Convenience method to retrieve the URI from the + * #WebKitNetworkRequest which is being downloaded. + * + * Returns: the uri + * + * Since: 1.1.2 + */ +const gchar* webkit_download_get_uri(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), NULL); + + WebKitDownloadPrivate* priv = download->priv; + return webkit_network_request_get_uri(priv->networkRequest); +} + +/** + * webkit_download_get_network_request: + * @download: the #WebKitDownload + * + * Retrieves the #WebKitNetworkRequest object that backs the download + * process. + * + * Returns: the #WebKitNetworkRequest instance + * + * Since: 1.1.2 + */ +WebKitNetworkRequest* webkit_download_get_network_request(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), NULL); + + WebKitDownloadPrivate* priv = download->priv; + return priv->networkRequest; +} + +static void webkit_download_set_response(WebKitDownload* download, const ResourceResponse& response) +{ + // FIXME Use WebKitNetworkResponse when it's merged. + WebKitDownloadPrivate* priv = download->priv; + priv->networkResponse = new ResourceResponse(response); +} + +/** + * webkit_download_get_suggested_filename: + * @download: the #WebKitDownload + * + * Retrieves the filename that was suggested by the server, or the one + * derived by WebKit from the URI. + * + * Returns: the suggested filename + * + * Since: 1.1.2 + */ +const gchar* webkit_download_get_suggested_filename(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), NULL); + + WebKitDownloadPrivate* priv = download->priv; + return priv->suggestedFilename; +} + +/** + * webkit_download_get_destination_uri: + * @download: the #WebKitDownload + * + * Obtains the URI to which the downloaded file will be written. This + * must have been set by the application before calling + * webkit_download_start(), and may be %NULL. + * + * Returns: the destination URI or %NULL + * + * Since: 1.1.2 + */ +const gchar* webkit_download_get_destination_uri(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), NULL); + + WebKitDownloadPrivate* priv = download->priv; + return priv->destinationURI; +} + +/** + * webkit_download_set_destination_uri: + * @download: the #WebKitDownload + * @destination_uri: the destination URI + * + * Defines the URI that should be used to save the downloaded file to. + * + * Since: 1.1.2 + */ +void webkit_download_set_destination_uri(WebKitDownload* download, const gchar* destination_uri) +{ + g_return_if_fail(WEBKIT_IS_DOWNLOAD(download)); + g_return_if_fail(destination_uri); + + WebKitDownloadPrivate* priv = download->priv; + if (priv->destinationURI && !strcmp(priv->destinationURI, destination_uri)) + return; + + if (priv->status != WEBKIT_DOWNLOAD_STATUS_CREATED && priv->status != WEBKIT_DOWNLOAD_STATUS_CANCELLED) { + ASSERT(priv->destinationURI); + + gboolean downloading = priv->outputStream != NULL; + if (downloading) + webkit_download_close_stream(download); + + GFile* src = g_file_new_for_uri(priv->destinationURI); + GFile* dest = g_file_new_for_uri(destination_uri); + GError* error = NULL; + + g_file_move(src, dest, G_FILE_COPY_BACKUP, NULL, NULL, NULL, &error); + + g_object_unref(src); + g_object_unref(dest); + + g_free(priv->destinationURI); + priv->destinationURI = g_strdup(destination_uri); + + if (error) { + gboolean handled; + g_signal_emit_by_name(download, "error", 0, WEBKIT_DOWNLOAD_ERROR_DESTINATION, error->message, &handled); + g_error_free(error); + return; + } + + if (downloading) { + if (!webkit_download_open_stream_for_uri(download, destination_uri, TRUE)) { + webkit_download_cancel(download); + return; + } + } + } else { + g_free(priv->destinationURI); + priv->destinationURI = g_strdup(destination_uri); + } + + // Only notify change if everything went fine. + g_object_notify(G_OBJECT(download), "destination-uri"); +} + +/** + * webkit_download_get_status: + * @download: the #WebKitDownload + * + * Obtains the current status of the download, as a + * #WebKitDownloadStatus. + * + * Returns: the current #WebKitDownloadStatus + * + * Since: 1.1.2 + */ +WebKitDownloadStatus webkit_download_get_status(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), WEBKIT_DOWNLOAD_STATUS_ERROR); + + WebKitDownloadPrivate* priv = download->priv; + return priv->status; +} + +static void webkit_download_set_status(WebKitDownload* download, WebKitDownloadStatus status) +{ + g_return_if_fail(WEBKIT_IS_DOWNLOAD(download)); + + WebKitDownloadPrivate* priv = download->priv; + priv->status = status; + + g_object_notify(G_OBJECT(download), "status"); +} + +/** + * webkit_download_get_total_size: + * @download: the #WebKitDownload + * + * Returns the expected total size of the download. This is expected + * because the server may provide incorrect or missing + * Content-Length. Notice that this may grow over time, as it will be + * always the same as current_size in the cases where current size + * surpasses it. + * + * Returns: the expected total size of the downloaded file + * + * Since: 1.1.2 + */ +guint64 webkit_download_get_total_size(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 0); + + WebKitDownloadPrivate* priv = download->priv; + if (!priv->networkResponse) + return 0; + + return MAX(priv->currentSize, priv->networkResponse->expectedContentLength()); +} + +/** + * webkit_download_get_current_size: + * @download: the #WebKitDownload + * + * Current already downloaded size. + * + * Returns: the already downloaded size + * + * Since: 1.1.2 + */ +guint64 webkit_download_get_current_size(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 0); + + WebKitDownloadPrivate* priv = download->priv; + return priv->currentSize; +} + +/** + * webkit_download_get_progress: + * @download: a #WebKitDownload + * + * Determines the current progress of the download. + * + * Returns: a #gdouble ranging from 0.0 to 1.0. + * + * Since: 1.1.2 + */ +gdouble webkit_download_get_progress(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 1.0); + + WebKitDownloadPrivate* priv = download->priv; + gdouble total_size = (gdouble)priv->networkResponse->expectedContentLength(); + + if (total_size == 0) + return 1.0; + + return ((gdouble)priv->currentSize) / total_size; +} + +/** + * webkit_download_get_elapsed_time: + * @download: a #WebKitDownload + * + * Elapsed time for the download in seconds, including any fractional + * part. If the download is finished, had an error or was cancelled + * this is the time between its start and the event. + * + * Returns: seconds since the download was started, as a #gdouble + * + * Since: 1.1.2 + */ +gdouble webkit_download_get_elapsed_time(WebKitDownload* download) +{ + g_return_val_if_fail(WEBKIT_IS_DOWNLOAD(download), 0.0); + + WebKitDownloadPrivate* priv = download->priv; + return g_timer_elapsed(priv->timer, NULL); +} + +static void webkit_download_received_data(WebKitDownload* download, const gchar* data, int length) +{ + WebKitDownloadPrivate* priv = download->priv; + + if (priv->currentSize == 0) + webkit_download_set_status(download, WEBKIT_DOWNLOAD_STATUS_STARTED); + + ASSERT(priv->outputStream); + + gsize bytes_written; + GError* error = NULL; + + g_output_stream_write_all(G_OUTPUT_STREAM(priv->outputStream), + data, length, &bytes_written, NULL, &error); + + if (error) { + gboolean handled; + g_signal_emit_by_name(download, "error", 0, WEBKIT_DOWNLOAD_ERROR_DESTINATION, error->message, &handled); + g_error_free(error); + return; + } + + priv->currentSize += length; + g_object_notify(G_OBJECT(download), "current-size"); + + ASSERT(priv->networkResponse); + if (priv->currentSize > priv->networkResponse->expectedContentLength()) + g_object_notify(G_OBJECT(download), "total-size"); + + // FIXME: Throttle the number of updates? Should we remove the + // previous g_object_notify()s if we are going to throttle the + // progress updates? + g_object_notify(G_OBJECT(download), "progress"); +} + +static void webkit_download_finished_loading(WebKitDownload* download) +{ + webkit_download_close_stream(download); + + WebKitDownloadPrivate* priv = download->priv; + + g_timer_stop(priv->timer); + + g_object_notify(G_OBJECT(download), "progress"); + webkit_download_set_status(download, WEBKIT_DOWNLOAD_STATUS_FINISHED); +} + +static void webkit_download_error(WebKitDownload* download, const ResourceError& error) +{ + webkit_download_close_stream(download); + + WebKitDownloadPrivate* priv = download->priv; + + g_timer_stop(priv->timer); + webkit_download_set_status(download, WEBKIT_DOWNLOAD_STATUS_ERROR); + + gboolean handled; + g_signal_emit_by_name(download, "error", 0, WEBKIT_DOWNLOAD_ERROR_NETWORK, error.localizedDescription().utf8().data(), &handled); +} + +DownloadClient::DownloadClient(WebKitDownload* download) + : m_download(download) +{ +} + +void DownloadClient::didReceiveResponse(ResourceHandle*, const ResourceResponse& response) +{ + webkit_download_set_response(m_download, response); +} + +void DownloadClient::didReceiveData(ResourceHandle*, const char* data, int length, int lengthReceived) +{ + webkit_download_received_data(m_download, data, length); +} + +void DownloadClient::didFinishLoading(ResourceHandle*) +{ + webkit_download_finished_loading(m_download); +} + +void DownloadClient::didFail(ResourceHandle*, const ResourceError& error) +{ + webkit_download_error(m_download, error); +} + +void DownloadClient::wasBlocked(ResourceHandle*) +{ + // FIXME: Implement this when we have the new frame loader signals + // and error handling. + notImplemented(); +} + +void DownloadClient::cannotShowURL(ResourceHandle*) +{ + // FIXME: Implement this when we have the new frame loader signals + // and error handling. + notImplemented(); +} + +} diff --git a/WebKit/gtk/webkit/webkitdownload.h b/WebKit/gtk/webkit/webkitdownload.h new file mode 100644 index 0000000..7c86c65 --- /dev/null +++ b/WebKit/gtk/webkit/webkitdownload.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2008 Collabora Ltd. + * Copyright (C) 2009 Gustavo Noronha Silva <gns@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WEBKIT_DOWNLOAD_H +#define WEBKIT_DOWNLOAD_H + +#include <webkit/webkitdefines.h> + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_DOWNLOAD (webkit_download_get_type()) +#define WEBKIT_DOWNLOAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_DOWNLOAD, WebKitDownload)) +#define WEBKIT_DOWNLOAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_DOWNLOAD, WebKitDownloadClass)) +#define WEBKIT_IS_DOWNLOAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_DOWNLOAD)) +#define WEBKIT_IS_DOWNLOAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_DOWNLOAD)) +#define WEBKIT_DOWNLOAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_DOWNLOAD, WebKitDownloadClass)) + +typedef enum { + WEBKIT_DOWNLOAD_STATUS_ERROR = -1, + WEBKIT_DOWNLOAD_STATUS_CREATED = 0, + WEBKIT_DOWNLOAD_STATUS_STARTED, + WEBKIT_DOWNLOAD_STATUS_CANCELLED, + WEBKIT_DOWNLOAD_STATUS_FINISHED +} WebKitDownloadStatus; + +typedef enum { + WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER, + WEBKIT_DOWNLOAD_ERROR_DESTINATION, + WEBKIT_DOWNLOAD_ERROR_NETWORK +} WebKitDownloadError; + +typedef struct _WebKitDownloadPrivate WebKitDownloadPrivate; + +struct _WebKitDownload { + GObject parent_instance; + + WebKitDownloadPrivate *priv; +}; + +struct _WebKitDownloadClass { + GObjectClass parent_class; + + /* Padding for future expansion */ + void (*_webkit_reserved0) (void); + void (*_webkit_reserved1) (void); + void (*_webkit_reserved2) (void); + void (*_webkit_reserved3) (void); +}; + +WEBKIT_API GType +webkit_download_get_type (void); + +WEBKIT_API WebKitDownload* +webkit_download_new (WebKitNetworkRequest *request); + +WEBKIT_API void +webkit_download_start (WebKitDownload *download); + +WEBKIT_API void +webkit_download_cancel (WebKitDownload *download); + +WEBKIT_API const gchar* +webkit_download_get_uri (WebKitDownload *download); + +WEBKIT_API WebKitNetworkRequest* +webkit_download_get_network_request (WebKitDownload *download); + +WEBKIT_API const gchar* +webkit_download_get_suggested_filename (WebKitDownload *download); + +WEBKIT_API const gchar* +webkit_download_get_destination_uri (WebKitDownload *download); + +WEBKIT_API void +webkit_download_set_destination_uri (WebKitDownload *download, + const gchar *destination_uri); + +WEBKIT_API gdouble +webkit_download_get_progress (WebKitDownload *download); + +WEBKIT_API gdouble +webkit_download_get_elapsed_time (WebKitDownload *download); + +WEBKIT_API guint64 +webkit_download_get_total_size (WebKitDownload *download); + +WEBKIT_API guint64 +webkit_download_get_current_size (WebKitDownload *download); + +WEBKIT_API WebKitDownloadStatus +webkit_download_get_status (WebKitDownload *download); + +G_END_DECLS + +#endif diff --git a/WebKit/gtk/webkit/webkitprivate.cpp b/WebKit/gtk/webkit/webkitprivate.cpp index e801981..c4264c9 100644 --- a/WebKit/gtk/webkit/webkitprivate.cpp +++ b/WebKit/gtk/webkit/webkitprivate.cpp @@ -20,8 +20,10 @@ #include "config.h" +#include "webkitsoupauthdialog.h" #include "webkitprivate.h" #include "ChromeClientGtk.h" +#include "Frame.h" #include "FrameLoader.h" #include "FrameLoaderClientGtk.h" #include "Logging.h" @@ -30,6 +32,9 @@ #include "PageGroup.h" #include "Pasteboard.h" #include "PasteboardHelperGtk.h" +#include "ResourceHandle.h" +#include "ResourceHandleClient.h" +#include "ResourceHandleInternal.h" #include <runtime/InitializeThreading.h> #if ENABLE(DATABASE) @@ -96,6 +101,31 @@ WebCore::NavigationType core(WebKitWebNavigationReason type) } /** end namespace WebKit */ +static GtkWidget* currentToplevelCallback(WebKitSoupAuthDialog* feature, SoupMessage* message, gpointer userData) +{ + gpointer messageData = g_object_get_data(G_OBJECT(message), "resourceHandle"); + if (!messageData) + return NULL; + + ResourceHandle* handle = static_cast<ResourceHandle*>(messageData); + if (!handle) + return NULL; + + ResourceHandleInternal* d = handle->getInternal(); + if (!d) + return NULL; + + WebCore::Frame* frame = d->m_frame; + if (!frame) + return NULL; + + GtkWidget* toplevel = gtk_widget_get_toplevel(GTK_WIDGET(frame->page()->chrome()->platformWindow())); + if (GTK_WIDGET_TOPLEVEL(toplevel)) + return toplevel; + else + return NULL; +} + void webkit_init() { static bool isInitialized = false; @@ -121,4 +151,10 @@ void webkit_init() PageGroup::setShouldTrackVisitedLinks(true); Pasteboard::generalPasteboard()->setHelper(new WebKit::PasteboardHelperGtk()); + + SoupSession* session = webkit_get_default_session(); + SoupSessionFeature* authDialog = static_cast<SoupSessionFeature*>(g_object_new(WEBKIT_TYPE_SOUP_AUTH_DIALOG, NULL)); + g_signal_connect(authDialog, "current-toplevel", G_CALLBACK(currentToplevelCallback), NULL); + soup_session_add_feature(session, authDialog); + g_object_unref(authDialog); } diff --git a/WebKit/gtk/webkit/webkitprivate.h b/WebKit/gtk/webkit/webkitprivate.h index ace996d..0b83a11 100644 --- a/WebKit/gtk/webkit/webkitprivate.h +++ b/WebKit/gtk/webkit/webkitprivate.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Holger Hans Peter Freyther + * Copyright (C) 2007, 2008, 2009 Holger Hans Peter Freyther * Copyright (C) 2008 Jan Michael C. Alonzo * Copyright (C) 2008 Collabora Ltd. * @@ -28,6 +28,7 @@ */ #include <webkit/webkitdefines.h> +#include <webkit/webkitdownload.h> #include <webkit/webkitwebview.h> #include <webkit/webkitwebframe.h> #include <webkit/webkitwebpolicydecision.h> @@ -43,10 +44,14 @@ #include "Frame.h" #include "InspectorClientGtk.h" #include "FrameLoaderClient.h" +#include "ResourceHandle.h" +#include "ResourceResponse.h" #include "WindowFeatures.h" #include <glib.h> +class DownloadClient; + namespace WebKit { WebKitWebView* getViewFromFrame(WebKitWebFrame*); @@ -57,7 +62,7 @@ namespace WebKit { WebKitWebView* kit(WebCore::Page*); WebCore::HistoryItem* core(WebKitWebHistoryItem*); - WebKitWebHistoryItem* kit(WebCore::HistoryItem*); + WebKitWebHistoryItem* kit(PassRefPtr<WebCore::HistoryItem>); WebCore::BackForwardList* core(WebKitWebBackForwardList*); @@ -101,6 +106,10 @@ extern "C" { GtkAdjustment* verticalAdjustment; gboolean zoomFullContent; + char* encoding; + char* customEncoding; + + gboolean disposing; }; #define WEBKIT_WEB_FRAME_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_WEB_FRAME, WebKitWebFramePrivate)) @@ -120,11 +129,22 @@ extern "C" { void webkit_web_frame_core_frame_gone(WebKitWebFrame*); + // WebKitWebHistoryItem private WebKitWebHistoryItem* - webkit_web_history_item_new_with_core_item(WebCore::HistoryItem*); + webkit_web_history_item_new_with_core_item(PassRefPtr<WebCore::HistoryItem> historyItem); + + WEBKIT_API G_CONST_RETURN gchar* + webkit_web_history_item_get_target(WebKitWebHistoryItem*); + + WEBKIT_API gboolean + webkit_web_history_item_is_target_item(WebKitWebHistoryItem*); + + WEBKIT_API GList* + webkit_web_history_item_get_children(WebKitWebHistoryItem*); + // end WebKitWebHistoryItem private void - webkit_web_inspector_set_inspector_client(WebKitWebInspector*, WebKit::InspectorClient*); + webkit_web_inspector_set_inspector_client(WebKitWebInspector*, WebCore::Page*); void webkit_web_inspector_set_web_view(WebKitWebInspector *web_inspector, WebKitWebView *web_view); @@ -144,6 +164,10 @@ extern "C" { void webkit_web_policy_decision_cancel (WebKitWebPolicyDecision* decision); + // FIXME: move this functionality into a 'WebKitWebDataSource' once implemented + WEBKIT_API gchar* + webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame); + // FIXME: Move these to webkitwebframe.h once their API has been discussed. WEBKIT_API GSList* diff --git a/WebKit/gtk/webkit/webkitsoupauthdialog.c b/WebKit/gtk/webkit/webkitsoupauthdialog.c new file mode 100644 index 0000000..139000b --- /dev/null +++ b/WebKit/gtk/webkit/webkitsoupauthdialog.c @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2009 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include <gtk/gtk.h> +#include <libsoup/soup.h> +#if USE(GNOMEKEYRING) +#include <gnome-keyring.h> +#endif + +#include "webkitmarshal.h" +#include "webkitsoupauthdialog.h" + +static void webkit_soup_auth_dialog_session_feature_init(SoupSessionFeatureInterface* feature_interface, gpointer interface_data); +static void attach(SoupSessionFeature* manager, SoupSession* session); +static void detach(SoupSessionFeature* manager, SoupSession* session); + +enum { + CURRENT_TOPLEVEL, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE_WITH_CODE(WebKitSoupAuthDialog, webkit_soup_auth_dialog, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(SOUP_TYPE_SESSION_FEATURE, + webkit_soup_auth_dialog_session_feature_init)) + +static void webkit_soup_auth_dialog_class_init(WebKitSoupAuthDialogClass* klass) +{ + GObjectClass* object_class = G_OBJECT_CLASS(klass); + + signals[CURRENT_TOPLEVEL] = + g_signal_new("current-toplevel", + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitSoupAuthDialogClass, current_toplevel), + NULL, NULL, + webkit_marshal_OBJECT__OBJECT, + GTK_TYPE_WIDGET, 1, + SOUP_TYPE_MESSAGE); +} + +static void webkit_soup_auth_dialog_init(WebKitSoupAuthDialog* instance) +{ +} + +static void webkit_soup_auth_dialog_session_feature_init(SoupSessionFeatureInterface *feature_interface, + gpointer interface_data) +{ + feature_interface->attach = attach; + feature_interface->detach = detach; +} + +typedef struct _WebKitAuthData { + SoupMessage* msg; + SoupAuth* auth; + SoupSession* session; + SoupSessionFeature* manager; + GtkWidget* loginEntry; + GtkWidget* passwordEntry; +#if USE(GNOMEKEYRING) + GtkWidget* checkButton; +#endif +} WebKitAuthData; + +static void free_authData(WebKitAuthData* authData) +{ + g_object_unref(authData->msg); + g_slice_free(WebKitAuthData, authData); +} + +#if USE(GNOMEKEYRING) +static void set_password_callback(GnomeKeyringResult result, guint32 val, gpointer user_data) +{ + /* Dummy callback, gnome_keyring_set_network_password does not accept a NULL one */ +} +#endif + +static void response_callback(GtkDialog* dialog, gint response_id, WebKitAuthData* authData) +{ + const char* login; + const char* password; +#if USE(GNOMEKEYRING) + SoupURI* uri; + gboolean storePassword; +#endif + + switch(response_id) { + case GTK_RESPONSE_OK: + login = gtk_entry_get_text(GTK_ENTRY(authData->loginEntry)); + password = gtk_entry_get_text(GTK_ENTRY(authData->passwordEntry)); + soup_auth_authenticate(authData->auth, login, password); + +#if USE(GNOMEKEYRING) + storePassword = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(authData->checkButton)); + if (storePassword) { + uri = soup_message_get_uri(authData->msg); + gnome_keyring_set_network_password(NULL, + login, + soup_auth_get_realm(authData->auth), + uri->host, + NULL, + uri->scheme, + soup_auth_get_scheme_name(authData->auth), + uri->port, + password, + (GnomeKeyringOperationGetIntCallback)set_password_callback, + NULL, + NULL); + } +#endif + default: + break; + } + + soup_session_unpause_message(authData->session, authData->msg); + free_authData(authData); + gtk_widget_destroy(GTK_WIDGET(dialog)); +} + +static GtkWidget * +table_add_entry (GtkWidget* table, + int row, + const char* label_text, + const char* value, + gpointer user_data) +{ + GtkWidget* entry; + GtkWidget* label; + + label = gtk_label_new(label_text); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + + entry = gtk_entry_new(); + gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); + + if (value) + gtk_entry_set_text(GTK_ENTRY(entry), value); + + gtk_table_attach(GTK_TABLE(table), label, + 0, 1, row, row + 1, + GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), entry, + 1, 2, row, row + 1); + + return entry; +} + +static void show_auth_dialog(WebKitAuthData* authData, const char* login, const char* password) +{ + GtkWidget* toplevel; + GtkWidget* widget; + GtkDialog* dialog; + GtkWindow* window; + GtkWidget* entryContainer; + GtkWidget* hbox; + GtkWidget* mainVBox; + GtkWidget* vbox; + GtkWidget* icon; + GtkWidget* table; + GtkWidget* messageLabel; + char* message; + SoupURI* uri; +#if USE(GNOMEKEYRING) + GtkWidget* rememberBox; + GtkWidget* checkButton; +#endif + + /* From GTK+ gtkmountoperation.c, modified and simplified. LGPL 2 license */ + + widget = gtk_dialog_new(); + window = GTK_WINDOW(widget); + dialog = GTK_DIALOG(widget); + + gtk_dialog_add_buttons(dialog, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, + NULL); + + /* Set the dialog up with HIG properties */ + gtk_dialog_set_has_separator(dialog, FALSE); + gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); + gtk_box_set_spacing(GTK_BOX(dialog->vbox), 2); /* 2 * 5 + 2 = 12 */ + gtk_container_set_border_width(GTK_CONTAINER (dialog->action_area), 5); + gtk_box_set_spacing(GTK_BOX(dialog->action_area), 6); + + gtk_window_set_resizable(window, FALSE); + gtk_window_set_title(window, ""); + gtk_window_set_icon_name(window, GTK_STOCK_DIALOG_AUTHENTICATION); + + gtk_dialog_set_default_response(dialog, GTK_RESPONSE_OK); + + /* Get the current toplevel */ + g_signal_emit(authData->manager, signals[CURRENT_TOPLEVEL], 0, authData->msg, &toplevel); + + if (toplevel) + gtk_window_set_transient_for(window, GTK_WINDOW(toplevel)); + + /* Build contents */ + hbox = gtk_hbox_new(FALSE, 12); + gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); + gtk_box_pack_start(GTK_BOX(dialog->vbox), hbox, TRUE, TRUE, 0); + + icon = gtk_image_new_from_stock(GTK_STOCK_DIALOG_AUTHENTICATION, + GTK_ICON_SIZE_DIALOG); + + gtk_misc_set_alignment(GTK_MISC(icon), 0.5, 0.0); + gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, 0); + + mainVBox = gtk_vbox_new(FALSE, 18); + gtk_box_pack_start(GTK_BOX(hbox), mainVBox, TRUE, TRUE, 0); + + uri = soup_message_get_uri(authData->msg); + message = g_strdup_printf("A username and password are being requested by the site %s", uri->host); + messageLabel = gtk_label_new(message); + g_free(message); + gtk_misc_set_alignment(GTK_MISC(messageLabel), 0.0, 0.5); + gtk_label_set_line_wrap(GTK_LABEL(messageLabel), TRUE); + gtk_box_pack_start(GTK_BOX(mainVBox), GTK_WIDGET(messageLabel), + FALSE, FALSE, 0); + + vbox = gtk_vbox_new(FALSE, 6); + gtk_box_pack_start(GTK_BOX (mainVBox), vbox, FALSE, FALSE, 0); + + /* The table that holds the entries */ + entryContainer = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); + + gtk_alignment_set_padding(GTK_ALIGNMENT(entryContainer), + 0, 0, 0, 0); + + gtk_box_pack_start(GTK_BOX(vbox), entryContainer, + FALSE, FALSE, 0); + + table = gtk_table_new(2, 2, FALSE); + gtk_table_set_col_spacings(GTK_TABLE (table), 12); + gtk_table_set_row_spacings(GTK_TABLE (table), 6); + gtk_container_add(GTK_CONTAINER(entryContainer), table); + + authData->loginEntry = table_add_entry(table, 0, "Username:", + login, NULL); + authData->passwordEntry = table_add_entry(table, 1, "Password:", + password, NULL); + + gtk_entry_set_visibility(GTK_ENTRY(authData->passwordEntry), FALSE); + +#if USE(GNOMEKEYRING) + rememberBox = gtk_vbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (vbox), rememberBox, + FALSE, FALSE, 0); + + checkButton = gtk_check_button_new_with_label("Remember password"); + if (login && password) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkButton), TRUE); + gtk_label_set_line_wrap(GTK_LABEL(gtk_bin_get_child(GTK_BIN(checkButton))), TRUE); + gtk_box_pack_start (GTK_BOX (rememberBox), checkButton, FALSE, FALSE, 0); + authData->checkButton = checkButton; +#endif + + g_signal_connect(dialog, "response", G_CALLBACK(response_callback), authData); + gtk_widget_show_all(widget); +} + +#if USE(GNOMEKEYRING) +static void find_password_callback(GnomeKeyringResult result, GList* list, WebKitAuthData* authData) +{ + GList* p; + const char* login = NULL; + const char* password = NULL; + + for (p = list; p; p = p->next) { + /* FIXME: support multiple logins/passwords ? */ + GnomeKeyringNetworkPasswordData* data = (GnomeKeyringNetworkPasswordData*)p->data; + login = data->user; + password = data->password; + break; + } + + show_auth_dialog(authData, login, password); +} +#endif + +static void session_authenticate(SoupSession* session, SoupMessage* msg, SoupAuth* auth, gboolean retrying, gpointer user_data) +{ + SoupURI* uri; + WebKitAuthData* authData; + SoupSessionFeature* manager = (SoupSessionFeature*)user_data; + + soup_session_pause_message(session, msg); + /* We need to make sure the message sticks around when pausing it */ + g_object_ref(msg); + + uri = soup_message_get_uri(msg); + authData = g_slice_new(WebKitAuthData); + authData->msg = msg; + authData->auth = auth; + authData->session = session; + authData->manager = manager; + + /* + * If we have gnome-keyring let's try to find the password first in the ring. + * Otherwise just show the dialog straight away + */ +#if USE(GNOMEKEYRING) + gnome_keyring_find_network_password(NULL, + soup_auth_get_realm(auth), + uri->host, + NULL, + uri->scheme, + soup_auth_get_scheme_name(auth), + uri->port, + (GnomeKeyringOperationGetListCallback)find_password_callback, + authData, + NULL); +#else + show_auth_dialog(authData, NULL, NULL); +#endif +} + +static void attach(SoupSessionFeature* manager, SoupSession* session) +{ + g_signal_connect(session, "authenticate", G_CALLBACK(session_authenticate), manager); +} + +static void detach(SoupSessionFeature* manager, SoupSession* session) +{ + g_signal_handlers_disconnect_by_func(session, session_authenticate, manager); +} + + diff --git a/WebKit/gtk/webkit/webkitsoupauthdialog.h b/WebKit/gtk/webkit/webkitsoupauthdialog.h new file mode 100644 index 0000000..2c030b4 --- /dev/null +++ b/WebKit/gtk/webkit/webkitsoupauthdialog.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2009 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <gtk/gtk.h> +#include <libsoup/soup.h> + +#ifndef WEBKIT_SOUP_AUTH_DIALOG_H +#define WEBKIT_SOUP_AUTH_DIALOG_H 1 + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_SOUP_AUTH_DIALOG (webkit_soup_auth_dialog_get_type ()) +#define WEBKIT_SOUP_AUTH_DIALOG(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), WEBKIT_TYPE_SOUP_AUTH_DIALOG, WebKitSoupAuthDialog)) +#define WEBKIT_SOUP_AUTH_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), WEBKIT_TYPE_SOUP_AUTH_DIALOG, WebKitSoupAuthDialog)) +#define WEBKIT_IS_SOUP_AUTH_DIALOG(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), WEBKIT_TYPE_SOUP_AUTH_DIALOG)) +#define WEBKIT_IS_SOUP_AUTH_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), WEBKIT_TYPE_SOUP_AUTH_DIALOG)) +#define WEBKIT_SOUP_AUTH_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), WEBKIT_TYPE_SOUP_AUTH_DIALOG, WebKitSoupAuthDialog)) + +typedef struct { + GObject parent_instance; +} WebKitSoupAuthDialog; + +typedef struct { + GObjectClass parent_class; + + GtkWidget* (*current_toplevel) (WebKitSoupAuthDialog* feature, SoupMessage* message); +} WebKitSoupAuthDialogClass; + +GType webkit_soup_auth_dialog_get_type (void); + +G_END_DECLS + +#endif /* WEBKIT_SOUP_AUTH_DIALOG_H */ diff --git a/WebKit/gtk/webkit/webkitwebbackforwardlist.cpp b/WebKit/gtk/webkit/webkitwebbackforwardlist.cpp index 3899f4b..5c93df0 100644 --- a/WebKit/gtk/webkit/webkitwebbackforwardlist.cpp +++ b/WebKit/gtk/webkit/webkitwebbackforwardlist.cpp @@ -189,11 +189,11 @@ GList* webkit_web_back_forward_list_get_forward_list_with_limit(WebKitWebBackFor backForwardList->forwardListWithLimit(limit, items); for (unsigned i = 0; i < items.size(); i++) { - WebKitWebHistoryItem* webHistoryItem = webkit_web_history_item_new_with_core_item(items[i].get()); - forwardItems = g_list_prepend(forwardItems, g_object_ref(webHistoryItem)); + WebKitWebHistoryItem* webHistoryItem = kit(items[i]); + forwardItems = g_list_prepend(forwardItems, webHistoryItem); } - return g_list_reverse(forwardItems); + return forwardItems; } /** @@ -219,12 +219,13 @@ GList* webkit_web_back_forward_list_get_back_list_with_limit(WebKitWebBackForwar backForwardList->backListWithLimit(limit, items); for (unsigned i = 0; i < items.size(); i++) { - WebKitWebHistoryItem* webHistoryItem = webkit_web_history_item_new_with_core_item(items[i].get()); - backItems = g_list_prepend(backItems, g_object_ref(webHistoryItem)); + WebKitWebHistoryItem* webHistoryItem = kit(items[i]); + backItems = g_list_prepend(backItems, webHistoryItem); } - return g_list_reverse(backItems); + return backItems; } + /** * webkit_web_back_forward_list_get_back_item: * @web_back_forward_list: a #WebBackForwardList @@ -389,6 +390,25 @@ void webkit_web_back_forward_list_set_limit(WebKitWebBackForwardList* webBackFor backForwardList->setCapacity(limit); } +/** + * webkit_web_back_forward_list_add_item: + * @web_back_forward_list: a #WebKitWebBackForwardList + * @history_item: the #WebKitWebHistoryItem to add + * + * Adds the item to the #WebKitWebBackForwardList. + * + * Since: 1.1.1 + */ +void webkit_web_back_forward_list_add_item(WebKitWebBackForwardList *webBackForwardList, WebKitWebHistoryItem *webHistoryItem) +{ + g_return_if_fail(WEBKIT_IS_WEB_BACK_FORWARD_LIST(webBackForwardList)); + + WebCore::BackForwardList* backForwardList = core(webBackForwardList); + WebCore::HistoryItem* historyItem = core(webHistoryItem); + + backForwardList->addItem(historyItem); +} + } /* end extern "C" */ WebCore::BackForwardList* WebKit::core(WebKitWebBackForwardList* webBackForwardList) diff --git a/WebKit/gtk/webkit/webkitwebbackforwardlist.h b/WebKit/gtk/webkit/webkitwebbackforwardlist.h index fb641f0..a44cbcd 100644 --- a/WebKit/gtk/webkit/webkitwebbackforwardlist.h +++ b/WebKit/gtk/webkit/webkitwebbackforwardlist.h @@ -107,6 +107,9 @@ webkit_web_back_forward_list_get_limit (WebKitWebBackForwardLi WEBKIT_API void webkit_web_back_forward_list_set_limit (WebKitWebBackForwardList *web_back_forward_list, gint limit); +WEBKIT_API void +webkit_web_back_forward_list_add_item (WebKitWebBackForwardList *web_back_forward_list, + WebKitWebHistoryItem *history_item); G_END_DECLS diff --git a/WebKit/gtk/webkit/webkitwebframe.cpp b/WebKit/gtk/webkit/webkitwebframe.cpp index 38e23a4..e2b10b6 100644 --- a/WebKit/gtk/webkit/webkitwebframe.cpp +++ b/WebKit/gtk/webkit/webkitwebframe.cpp @@ -5,6 +5,7 @@ * Copyright (C) 2008 Christian Dywan <christian@imendio.com> * Copyright (C) 2008 Collabora Ltd. * Copyright (C) 2008 Nuanti Ltd. + * Copyright (C) 2009 Jan Alonzo <jmalonzo@gmail.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -31,6 +32,7 @@ #include "AnimationController.h" #include "CString.h" +#include "DocumentLoader.h" #include "FrameLoader.h" #include "FrameLoaderClientGtk.h" #include "FrameTree.h" @@ -43,6 +45,7 @@ #include "RenderTreeAsText.h" #include "JSDOMBinding.h" #include "ScriptController.h" +#include "SubstituteData.h" #include <JavaScriptCore/APICast.h> @@ -373,6 +376,60 @@ WebKitWebFrame* webkit_web_frame_get_parent(WebKitWebFrame* frame) } /** + * webkit_web_frame_load_uri: + * @frame: a #WebKitWebFrame + * @uri: an URI string + * + * Requests loading of the specified URI string. + * + * Since: 1.1.1 + */ +void webkit_web_frame_load_uri(WebKitWebFrame* frame, const gchar* uri) +{ + g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame)); + g_return_if_fail(uri); + + Frame* coreFrame = core(frame); + if (!coreFrame) + return; + + coreFrame->loader()->load(ResourceRequest(KURL(KURL(), String::fromUTF8(uri))), false); +} + +/** + * webkit_web_frame_load_string: + * @frame: a #WebKitWebFrame + * @content: an URI string + * @mime_type: the MIME type, or %NULL + * @encoding: the encoding, or %NULL + * @base_uri: the base URI for relative locations + * + * Requests loading of the given @content with the specified @mime_type, + * @encoding and @base_uri. + * + * If @mime_type is %NULL, "text/html" is assumed. + * + * If @encoding is %NULL, "UTF-8" is assumed. + * + * Since: 1.1.1 + */ +void webkit_web_frame_load_string(WebKitWebFrame* frame, const gchar* content, const gchar* contentMimeType, const gchar* contentEncoding, const gchar* baseUri) +{ + g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame)); + g_return_if_fail(content); + + Frame* coreFrame = core(frame); + if (!coreFrame) + return; + + KURL url(KURL(), baseUri ? String::fromUTF8(baseUri) : ""); + RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(content, strlen(content)); + SubstituteData substituteData(sharedBuffer.release(), contentMimeType ? String(contentMimeType) : "text/html", contentEncoding ? String(contentEncoding) : "UTF-8", blankURL(), url); + + coreFrame->loader()->load(ResourceRequest(url), substituteData, false); +} + +/** * webkit_web_frame_load_request: * @frame: a #WebKitWebFrame * @request: a #WebKitNetworkRequest @@ -394,7 +451,7 @@ void webkit_web_frame_load_request(WebKitWebFrame* frame, WebKitNetworkRequest* // TODO: Use the ResourceRequest carried by WebKitNetworkRequest when it is implemented. String string = String::fromUTF8(webkit_network_request_get_uri(request)); - coreFrame->loader()->load(ResourceRequest(KURL(string))); + coreFrame->loader()->load(ResourceRequest(KURL(KURL(), string)), false); } /** @@ -662,4 +719,12 @@ unsigned int webkit_web_frame_number_of_active_animations(WebKitWebFrame* frame) return controller->numberOfActiveAnimations(); } +gchar* webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame) +{ + Frame* coreFrame = core(frame); + DocumentLoader* docLoader = coreFrame->loader()->documentLoader(); + String mimeType = docLoader->responseMIMEType(); + return g_strdup(mimeType.utf8().data()); +} + } diff --git a/WebKit/gtk/webkit/webkitwebframe.h b/WebKit/gtk/webkit/webkitwebframe.h index fcdace6..7e24565 100644 --- a/WebKit/gtk/webkit/webkitwebframe.h +++ b/WebKit/gtk/webkit/webkitwebframe.h @@ -81,6 +81,17 @@ WEBKIT_API WebKitWebFrame* webkit_web_frame_get_parent (WebKitWebFrame *frame); WEBKIT_API void +webkit_web_frame_load_uri (WebKitWebFrame *frame, + const gchar *uri); + +WEBKIT_API void +webkit_web_frame_load_string (WebKitWebFrame *frame, + const gchar *content, + const gchar *mime_type, + const gchar *encoding, + const gchar *base_uri); + +WEBKIT_API void webkit_web_frame_load_request (WebKitWebFrame *frame, WebKitNetworkRequest *request); diff --git a/WebKit/gtk/webkit/webkitwebhistoryitem.cpp b/WebKit/gtk/webkit/webkitwebhistoryitem.cpp index 8cdaa90..42e6a9b 100644 --- a/WebKit/gtk/webkit/webkitwebhistoryitem.cpp +++ b/WebKit/gtk/webkit/webkitwebhistoryitem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Jan Michael C. Alonzo + * Copyright (C) 2008, 2009 Jan Michael C. Alonzo * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -17,7 +17,6 @@ * Boston, MA 02110-1301, USA. */ - #include "config.h" #include "webkitwebhistoryitem.h" @@ -53,12 +52,14 @@ using namespace WebKit; extern "C" { struct _WebKitWebHistoryItemPrivate { - WTF::RefPtr<WebCore::HistoryItem> historyItem; + WebCore::HistoryItem* historyItem; WebCore::CString title; WebCore::CString alternateTitle; WebCore::CString uri; WebCore::CString originalUri; + + gboolean disposed; }; #define WEBKIT_WEB_HISTORY_ITEM_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_WEB_HISTORY_ITEM, WebKitWebHistoryItemPrivate)) @@ -81,7 +82,7 @@ static void webkit_web_history_item_get_property(GObject* object, guint prop_id, static GHashTable* webkit_history_items() { - static GHashTable* historyItems = g_hash_table_new(g_direct_hash, g_direct_equal); + static GHashTable* historyItems = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref); return historyItems; } @@ -94,27 +95,24 @@ static void webkit_history_item_add(WebKitWebHistoryItem* webHistoryItem, WebCor g_hash_table_insert(table, historyItem, g_object_ref(webHistoryItem)); } -static void webkit_history_item_remove(WebCore::HistoryItem* historyItem) -{ - GHashTable* table = webkit_history_items(); - WebKitWebHistoryItem* webHistoryItem = (WebKitWebHistoryItem*) g_hash_table_lookup(table, historyItem); - - g_return_if_fail(webHistoryItem != NULL); - - g_hash_table_remove(table, historyItem); - g_object_unref(webHistoryItem); -} - static void webkit_web_history_item_dispose(GObject* object) { WebKitWebHistoryItem* webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(object); + WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; + WebCore::HistoryItem* item = core(webHistoryItem); - webkit_history_item_remove(core(webHistoryItem)); + if (!priv->disposed) { + GHashTable* table = webkit_history_items(); - /* destroy table if empty */ - GHashTable* table = webkit_history_items(); - if (!g_hash_table_size(table)) - g_hash_table_destroy(table); + g_hash_table_remove(table, item); + item->deref(); + + /* destroy table if empty */ + if (!g_hash_table_size(table)) + g_hash_table_destroy(table); + + priv->disposed = true; + } G_OBJECT_CLASS(webkit_web_history_item_parent_class)->dispose(object); } @@ -270,21 +268,9 @@ static void webkit_web_history_item_get_property(GObject* object, guint prop_id, } /* Helper function to create a new WebHistoryItem instance when needed */ -WebKitWebHistoryItem* webkit_web_history_item_new_with_core_item(WebCore::HistoryItem* item) +WebKitWebHistoryItem* webkit_web_history_item_new_with_core_item(PassRefPtr<WebCore::HistoryItem> historyItem) { - WebKitWebHistoryItem* webHistoryItem = kit(item); - - if (webHistoryItem) - g_object_ref(webHistoryItem); - else { - webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(g_object_new(WEBKIT_TYPE_WEB_HISTORY_ITEM, NULL)); - WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; - - priv->historyItem = item; - webkit_history_item_add(webHistoryItem, priv->historyItem.get()); - } - - return webHistoryItem; + return kit(historyItem); } @@ -300,8 +286,9 @@ WebKitWebHistoryItem* webkit_web_history_item_new() WebKitWebHistoryItem* webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(g_object_new(WEBKIT_TYPE_WEB_HISTORY_ITEM, NULL)); WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; - priv->historyItem = WebCore::HistoryItem::create(); - webkit_history_item_add(webHistoryItem, priv->historyItem.get()); + RefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::create(); + priv->historyItem = item.release().releaseRef(); + webkit_history_item_add(webHistoryItem, priv->historyItem); return webHistoryItem; } @@ -323,8 +310,9 @@ WebKitWebHistoryItem* webkit_web_history_item_new_with_data(const gchar* uri, co WebKitWebHistoryItem* webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(g_object_new(WEBKIT_TYPE_WEB_HISTORY_ITEM, NULL)); WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; - priv->historyItem = WebCore::HistoryItem::create(historyUri, historyTitle, 0); - webkit_history_item_add(webHistoryItem, priv->historyItem.get()); + RefPtr<WebCore::HistoryItem> item = WebCore::HistoryItem::create(historyUri, historyTitle, 0); + priv->historyItem = item.release().releaseRef(); + webkit_history_item_add(webHistoryItem, priv->historyItem); return webHistoryItem; } @@ -341,7 +329,7 @@ G_CONST_RETURN gchar* webkit_web_history_item_get_title(WebKitWebHistoryItem* we WebCore::HistoryItem* item = core(webHistoryItem); - g_return_val_if_fail(item != NULL, NULL); + g_return_val_if_fail(item, NULL); WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; priv->title = item->title().utf8(); @@ -363,7 +351,7 @@ G_CONST_RETURN gchar* webkit_web_history_item_get_alternate_title(WebKitWebHisto WebCore::HistoryItem* item = core(webHistoryItem); - g_return_val_if_fail(item != NULL, NULL); + g_return_val_if_fail(item, NULL); WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; priv->alternateTitle = item->alternateTitle().utf8(); @@ -403,7 +391,7 @@ G_CONST_RETURN gchar* webkit_web_history_item_get_uri(WebKitWebHistoryItem* webH WebCore::HistoryItem* item = core(WEBKIT_WEB_HISTORY_ITEM(webHistoryItem)); - g_return_val_if_fail(item != NULL, NULL); + g_return_val_if_fail(item, NULL); WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; priv->uri = item->urlString().utf8(); @@ -425,7 +413,7 @@ G_CONST_RETURN gchar* webkit_web_history_item_get_original_uri(WebKitWebHistoryI WebCore::HistoryItem* item = core(WEBKIT_WEB_HISTORY_ITEM(webHistoryItem)); - g_return_val_if_fail(item != NULL, NULL); + g_return_val_if_fail(item, NULL); WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; priv->originalUri = item->originalURLString().utf8(); @@ -447,31 +435,84 @@ gdouble webkit_web_history_item_get_last_visited_time(WebKitWebHistoryItem* webH WebCore::HistoryItem* item = core(WEBKIT_WEB_HISTORY_ITEM(webHistoryItem)); - g_return_val_if_fail(item != NULL, 0); + g_return_val_if_fail(item, 0); return item->lastVisitedTime(); } +/* private methods */ + +G_CONST_RETURN gchar* webkit_web_history_item_get_target(WebKitWebHistoryItem* webHistoryItem) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), NULL); + + WebCore::HistoryItem* item = core(webHistoryItem); + + g_return_val_if_fail(item, NULL); + + WebCore::CString t = item->target().utf8(); + return g_strdup(t.data()); +} + +gboolean webkit_web_history_item_is_target_item(WebKitWebHistoryItem* webHistoryItem) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), false); + + WebCore::HistoryItem* item = core(webHistoryItem); + + g_return_val_if_fail(item, false); + + return item->isTargetItem(); +} + +GList* webkit_web_history_item_get_children(WebKitWebHistoryItem* webHistoryItem) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), NULL); + + WebCore::HistoryItem* item = core(webHistoryItem); + + g_return_val_if_fail(item, NULL); + + const WebCore::HistoryItemVector& children = item->children(); + if (!children.size()) + return NULL; + + unsigned size = children.size(); + GList* kids = NULL; + for (unsigned i = 0; i < size; ++i) + kids = g_list_prepend(kids, kit(children[i].get())); + + return g_list_reverse(kids); +} + } /* end extern "C" */ WebCore::HistoryItem* WebKit::core(WebKitWebHistoryItem* webHistoryItem) { g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(webHistoryItem), NULL); - WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; - WTF::RefPtr<WebCore::HistoryItem> historyItem = priv->historyItem; - - return historyItem ? historyItem.get() : 0; + return webHistoryItem->priv->historyItem; } -WebKitWebHistoryItem* WebKit::kit(WebCore::HistoryItem* historyItem) +WebKitWebHistoryItem* WebKit::kit(PassRefPtr<WebCore::HistoryItem> historyItem) { - g_return_val_if_fail(historyItem != NULL, NULL); + g_return_val_if_fail(historyItem, NULL); + + RefPtr<WebCore::HistoryItem> item = historyItem; WebKitWebHistoryItem* webHistoryItem; GHashTable* table = webkit_history_items(); - webHistoryItem = (WebKitWebHistoryItem*) g_hash_table_lookup(table, historyItem); + webHistoryItem = (WebKitWebHistoryItem*) g_hash_table_lookup(table, item.get()); + + if (!webHistoryItem) { + webHistoryItem = WEBKIT_WEB_HISTORY_ITEM(g_object_new(WEBKIT_TYPE_WEB_HISTORY_ITEM, NULL)); + WebKitWebHistoryItemPrivate* priv = webHistoryItem->priv; + + priv->historyItem = item.release().releaseRef(); + webkit_history_item_add(webHistoryItem, priv->historyItem); + } + return webHistoryItem; } diff --git a/WebKit/gtk/webkit/webkitwebinspector.cpp b/WebKit/gtk/webkit/webkitwebinspector.cpp index b8f8d9e..8e1c8c0 100644 --- a/WebKit/gtk/webkit/webkitwebinspector.cpp +++ b/WebKit/gtk/webkit/webkitwebinspector.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2008 Gustavo Noronha Silva - * Copyright (C) 2008 Holger Hans Peter Freyther + * Copyright (C) 2008, 2009 Holger Hans Peter Freyther * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -75,12 +75,13 @@ enum { PROP_WEB_VIEW, PROP_INSPECTED_URI, + PROP_JAVASCRIPT_PROFILING_ENABLED }; G_DEFINE_TYPE(WebKitWebInspector, webkit_web_inspector, G_TYPE_OBJECT) struct _WebKitWebInspectorPrivate { - InspectorClient* inspectorClient; + WebCore::Page* page; WebKitWebView* inspector_view; gchar* inspected_uri; }; @@ -274,6 +275,23 @@ static void webkit_web_inspector_class_init(WebKitWebInspectorClass* klass) NULL, WEBKIT_PARAM_READABLE)); + /** + * WebKitWebInspector:javascript-profiling-enabled + * + * This is enabling JavaScript profiling in the Inspector. This means + * that Console.profiles will return the profiles. + * + * Since: 1.1.1 + */ + g_object_class_install_property(gobject_class, + PROP_JAVASCRIPT_PROFILING_ENABLED, + g_param_spec_boolean( + "javascript-profiling-enabled", + "Enable JavaScript profiling", + "Profile the executed JavaScript.", + FALSE, + WEBKIT_PARAM_READWRITE)); + g_type_class_add_private(klass, sizeof(WebKitWebInspectorPrivate)); } @@ -298,7 +316,19 @@ static void webkit_web_inspector_finalize(GObject* object) static void webkit_web_inspector_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec) { + WebKitWebInspector* web_inspector = WEBKIT_WEB_INSPECTOR(object); + WebKitWebInspectorPrivate* priv = web_inspector->priv; + switch(prop_id) { + case PROP_JAVASCRIPT_PROFILING_ENABLED: { + bool enabled = g_value_get_boolean(value); + WebCore::InspectorController* controller = priv->page->inspectorController(); + if (enabled) + controller->enableProfiler(); + else + controller->disableProfiler(); + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -317,6 +347,9 @@ static void webkit_web_inspector_get_property(GObject* object, guint prop_id, GV case PROP_INSPECTED_URI: g_value_set_string(value, priv->inspected_uri); break; + case PROP_JAVASCRIPT_PROFILING_ENABLED: + g_value_set_boolean(value, priv->page->inspectorController()->profilerEnabled()); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -388,11 +421,11 @@ const gchar* webkit_web_inspector_get_inspected_uri(WebKitWebInspector *web_insp } void -webkit_web_inspector_set_inspector_client(WebKitWebInspector* web_inspector, WebKit::InspectorClient* inspectorClient) +webkit_web_inspector_set_inspector_client(WebKitWebInspector* web_inspector, WebCore::Page* page) { WebKitWebInspectorPrivate* priv = web_inspector->priv; - priv->inspectorClient = inspectorClient; + priv->page = page; } } diff --git a/WebKit/gtk/webkit/webkitwebsettings.cpp b/WebKit/gtk/webkit/webkitwebsettings.cpp index aa38c6c..d31ec2f 100644 --- a/WebKit/gtk/webkit/webkitwebsettings.cpp +++ b/WebKit/gtk/webkit/webkitwebsettings.cpp @@ -74,6 +74,7 @@ struct _WebKitWebSettingsPrivate { gchar* user_stylesheet_uri; gfloat zoom_step; gboolean enable_developer_extras; + gboolean enable_private_browsing; }; #define WEBKIT_WEB_SETTINGS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_WEB_SETTINGS, WebKitWebSettingsPrivate)) @@ -101,7 +102,8 @@ enum { PROP_RESIZABLE_TEXT_AREAS, PROP_USER_STYLESHEET_URI, PROP_ZOOM_STEP, - PROP_ENABLE_DEVELOPER_EXTRAS + PROP_ENABLE_DEVELOPER_EXTRAS, + PROP_ENABLE_PRIVATE_BROWSING }; static void webkit_web_settings_finalize(GObject* object); @@ -335,6 +337,22 @@ static void webkit_web_settings_class_init(WebKitWebSettingsClass* klass) FALSE, flags)); + /** + * WebKitWebSettings:enable-private-browsing: + * + * Whether to enable private browsing mode. + * + * Since 1.1.2 + */ + g_object_class_install_property(gobject_class, + PROP_ENABLE_PRIVATE_BROWSING, + g_param_spec_boolean( + "enable-private-browsing", + "Enable Private Browsing", + "Enables private browsing mode", + FALSE, + flags)); + g_type_class_add_private(klass, sizeof(WebKitWebSettingsPrivate)); } @@ -437,6 +455,9 @@ static void webkit_web_settings_set_property(GObject* object, guint prop_id, con case PROP_ENABLE_DEVELOPER_EXTRAS: priv->enable_developer_extras = g_value_get_boolean(value); break; + case PROP_ENABLE_PRIVATE_BROWSING: + priv->enable_private_browsing = g_value_get_boolean(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -512,6 +533,9 @@ static void webkit_web_settings_get_property(GObject* object, guint prop_id, GVa case PROP_ENABLE_DEVELOPER_EXTRAS: g_value_set_boolean(value, priv->enable_developer_extras); break; + case PROP_ENABLE_PRIVATE_BROWSING: + g_value_set_boolean(value, priv->enable_private_browsing); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -563,6 +587,7 @@ WebKitWebSettings* webkit_web_settings_copy(WebKitWebSettings* web_settings) "user-stylesheet-uri", priv->user_stylesheet_uri, "zoom-step", priv->zoom_step, "enable-developer-extras", priv->enable_developer_extras, + "enable-private-browsing", priv->enable_private_browsing, NULL)); return copy; diff --git a/WebKit/gtk/webkit/webkitwebview.cpp b/WebKit/gtk/webkit/webkitwebview.cpp index 0ea6ed5..d6a0d54 100644 --- a/WebKit/gtk/webkit/webkitwebview.cpp +++ b/WebKit/gtk/webkit/webkitwebview.cpp @@ -1,12 +1,13 @@ /* * Copyright (C) 2007, 2008 Holger Hans Peter Freyther - * Copyright (C) 2007, 2008 Christian Dywan <christian@imendio.com> + * Copyright (C) 2007, 2008, 2009 Christian Dywan <christian@imendio.com> * Copyright (C) 2007 Xan Lopez <xan@gnome.org> * Copyright (C) 2007, 2008 Alp Toker <alp@atoker.com> * Copyright (C) 2008 Jan Alonzo <jmalonzo@unpluggable.com> * Copyright (C) 2008 Gustavo Noronha Silva <gns@gnome.org> * Copyright (C) 2008 Nuanti Ltd. * Copyright (C) 2008 Collabora Ltd. + * Copyright (C) 2009 Igalia S.L. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,6 +26,7 @@ #include "config.h" +#include "webkitdownload.h" #include "webkitwebview.h" #include "webkitenumtypes.h" #include "webkitmarshal.h" @@ -43,6 +45,7 @@ #include "ContextMenuController.h" #include "Cursor.h" #include "Document.h" +#include "DocumentLoader.h" #include "DragClientGtk.h" #include "Editor.h" #include "EditorClientGtk.h" @@ -56,13 +59,12 @@ #include "InspectorClientGtk.h" #include "FrameLoader.h" #include "FrameView.h" -#include "Editor.h" #include "PasteboardHelper.h" #include "PlatformKeyboardEvent.h" #include "PlatformWheelEvent.h" +#include "ResourceHandle.h" #include "ScriptValue.h" #include "Scrollbar.h" -#include "SubstituteData.h" #include <wtf/GOwnPtr.h> #include <gdk/gdkkeysyms.h> @@ -110,6 +112,7 @@ extern "C" { enum { /* normal signals */ NAVIGATION_REQUESTED, + NEW_WINDOW_POLICY_DECISION_REQUESTED, NAVIGATION_POLICY_DECISION_REQUESTED, MIME_TYPE_POLICY_DECISION_REQUESTED, CREATE_WEB_VIEW, @@ -133,12 +136,15 @@ enum { COPY_CLIPBOARD, PASTE_CLIPBOARD, CUT_CLIPBOARD, + DOWNLOAD_REQUESTED, LAST_SIGNAL }; enum { PROP_0, + PROP_TITLE, + PROP_URI, PROP_COPY_TARGET_LIST, PROP_PASTE_TARGET_LIST, PROP_EDITABLE, @@ -147,7 +153,9 @@ enum { PROP_WINDOW_FEATURES, PROP_TRANSPARENT, PROP_ZOOM_LEVEL, - PROP_FULL_CONTENT_ZOOM + PROP_FULL_CONTENT_ZOOM, + PROP_ENCODING, + PROP_CUSTOM_ENCODING }; static guint webkit_web_view_signals[LAST_SIGNAL] = { 0, }; @@ -276,6 +284,12 @@ static void webkit_web_view_get_property(GObject* object, guint prop_id, GValue* WebKitWebView* webView = WEBKIT_WEB_VIEW(object); switch(prop_id) { + case PROP_TITLE: + g_value_set_string(value, webkit_web_view_get_title(webView)); + break; + case PROP_URI: + g_value_set_string(value, webkit_web_view_get_uri(webView)); + break; #if GTK_CHECK_VERSION(2,10,0) case PROP_COPY_TARGET_LIST: g_value_set_boxed(value, webkit_web_view_get_copy_target_list(webView)); @@ -305,6 +319,12 @@ static void webkit_web_view_get_property(GObject* object, guint prop_id, GValue* case PROP_FULL_CONTENT_ZOOM: g_value_set_boolean(value, webkit_web_view_get_full_content_zoom(webView)); break; + case PROP_ENCODING: + g_value_set_string(value, webkit_web_view_get_encoding(webView)); + break; + case PROP_CUSTOM_ENCODING: + g_value_set_string(value, webkit_web_view_get_custom_encoding(webView)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); } @@ -333,6 +353,9 @@ static void webkit_web_view_set_property(GObject* object, guint prop_id, const G case PROP_FULL_CONTENT_ZOOM: webkit_web_view_set_full_content_zoom(webView, g_value_get_boolean(value)); break; + case PROP_CUSTOM_ENCODING: + webkit_web_view_set_custom_encoding(webView, g_value_get_string(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); } @@ -436,11 +459,23 @@ static gboolean webkit_web_view_key_press_event(GtkWidget* widget, GdkEventKey* case GDK_Left: view->scrollBy(IntSize(-cScrollbarPixelsPerLineStep, 0)); return TRUE; + case GDK_space: + if ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) + view->scrollBy(IntSize(0, -view->visibleHeight())); + else + view->scrollBy(IntSize(0, view->visibleHeight())); + return TRUE; + case GDK_Page_Up: + view->scrollBy(IntSize(0, -view->visibleHeight())); + return TRUE; + case GDK_Page_Down: + view->scrollBy(IntSize(0, view->visibleHeight())); + return TRUE; case GDK_Home: - frame->selection()->modify(alteration, SelectionController::BACKWARD, DocumentBoundary, true); + view->scrollBy(IntSize(0, -view->contentsHeight())); return TRUE; case GDK_End: - frame->selection()->modify(alteration, SelectionController::FORWARD, DocumentBoundary, true); + view->scrollBy(IntSize(0, view->contentsHeight())); return TRUE; } @@ -496,10 +531,17 @@ static gboolean webkit_web_view_button_release_event(GtkWidget* widget, GdkEvent } Frame* mainFrame = core(webView)->mainFrame(); - if (!mainFrame->view()) - return FALSE; + if (mainFrame->view()) + mainFrame->eventHandler()->handleMouseReleaseEvent(PlatformMouseEvent(event)); + + /* We always return FALSE here because WebKit can, for the same click, decide + * to not handle press-event but handle release-event, which can totally confuse + * some GTK+ containers when there are no other events in between. This way we + * guarantee that this case never happens, and that if press-event goes through + * release-event also goes through. + */ - return mainFrame->eventHandler()->handleMouseReleaseEvent(PlatformMouseEvent(event)); + return FALSE; } static gboolean webkit_web_view_motion_event(GtkWidget* widget, GdkEventMotion* event) @@ -536,7 +578,7 @@ static void webkit_web_view_size_allocate(GtkWidget* widget, GtkAllocation* allo return; frame->view()->resize(allocation->width, allocation->height); - frame->forceLayout(); + frame->view()->forceLayout(); frame->view()->adjustViewSize(); } @@ -816,6 +858,8 @@ static void webkit_web_view_dispose(GObject* object) WebKitWebView* webView = WEBKIT_WEB_VIEW(object); WebKitWebViewPrivate* priv = webView->priv; + priv->disposing = TRUE; + if (priv->corePage) { webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(object)); @@ -864,6 +908,17 @@ static void webkit_web_view_dispose(GObject* object) G_OBJECT_CLASS(webkit_web_view_parent_class)->dispose(object); } +static void webkit_web_view_finalize(GObject* object) +{ + WebKitWebView* webView = WEBKIT_WEB_VIEW(object); + WebKitWebViewPrivate* priv = webView->priv; + + g_free(priv->encoding); + g_free(priv->customEncoding); + + G_OBJECT_CLASS(webkit_web_view_parent_class)->finalize(object); +} + static gboolean webkit_create_web_view_request_handled(GSignalInvocationHint* ihint, GValue* returnAccu, const GValue* handlerReturn, gpointer dummy) { gpointer newWebView = g_value_get_object(handlerReturn); @@ -998,6 +1053,45 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) WEBKIT_TYPE_NETWORK_REQUEST); /** + * WebKitWebView::new-window-policy-decision-requested: + * @web_view: the object on which the signal is emitted + * @frame: the #WebKitWebFrame that required the navigation + * @request: a #WebKitNetworkRequest + * @navigation_action: a #WebKitWebNavigation + * @policy_decision: a #WebKitWebPolicyDecision + * @return: TRUE if the signal will be handled, FALSE to have the + * default behavior apply + * + * Emitted when @frame requests opening a new window. With this + * signal the browser can use the context of the request to decide + * about the new window. If the request is not handled the default + * behavior is to allow opening the new window to load the url, + * which will cause a create-web-view signal emission where the + * browser handles the new window action but without information + * of the context that caused the navigation. The following + * navigation-policy-decision-requested emissions will load the + * page after the creation of the new window just with the + * information of this new navigation context, without any + * information about the action that made this new window to be + * opened. + * + * Since: 1.1.4 + */ + webkit_web_view_signals[NEW_WINDOW_POLICY_DECISION_REQUESTED] = + g_signal_new("new-window-policy-decision-requested", + G_TYPE_FROM_CLASS(webViewClass), + (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), + 0, + g_signal_accumulator_true_handled, + NULL, + webkit_marshal_BOOLEAN__OBJECT_OBJECT_OBJECT_OBJECT, + G_TYPE_BOOLEAN, 4, + WEBKIT_TYPE_WEB_FRAME, + WEBKIT_TYPE_NETWORK_REQUEST, + WEBKIT_TYPE_WEB_NAVIGATION_ACTION, + WEBKIT_TYPE_WEB_POLICY_DECISION); + + /** * WebKitWebView::navigation-policy-decision-requested: * @web_view: the object on which the signal is emitted * @frame: the #WebKitWebFrame that required the navigation @@ -1085,6 +1179,34 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) G_TYPE_POINTER); /** + * WebKitWebView::download-requested: + * @web_view: the object on which the signal is emitted + * @download: a #WebKitDownload object that lets you control the + * download process + * @return: %TRUE if the download should be performed, %FALSE to cancel it. + * + * A new Download is being requested. By default, if the signal is + * not handled, the download is cancelled. Notice that while + * handling this signal you must set the target URI using + * webkit_download_set_target_uri(). + * + * If you intend to handle downloads yourself rather than using + * the #WebKitDownload helper object you must handle this signal, + * and return %FALSE. + * + * Since: 1.1.2 + */ + webkit_web_view_signals[DOWNLOAD_REQUESTED] = g_signal_new("download-requested", + G_TYPE_FROM_CLASS(webViewClass), + (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), + 0, + g_signal_accumulator_true_handled, + NULL, + webkit_marshal_BOOLEAN__OBJECT, + G_TYPE_BOOLEAN, 1, + G_TYPE_OBJECT); + + /** * WebKitWebView::load-started: * @web_view: the object on which the signal is emitted * @frame: the frame going to do the load @@ -1151,6 +1273,8 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * @title: the new title * * When a #WebKitWebFrame changes the document title this signal is emitted. + * + * Deprecated: 1.1.4: Use "notify::title" instead. */ webkit_web_view_signals[TITLE_CHANGED] = g_signal_new("title-changed", G_TYPE_FROM_CLASS(webViewClass), @@ -1284,9 +1408,9 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) G_STRUCT_OFFSET(WebKitWebViewClass, script_confirm), g_signal_accumulator_true_handled, NULL, - webkit_marshal_BOOLEAN__OBJECT_STRING_BOOLEAN, + webkit_marshal_BOOLEAN__OBJECT_STRING_POINTER, G_TYPE_BOOLEAN, 3, - WEBKIT_TYPE_WEB_FRAME, G_TYPE_STRING, G_TYPE_BOOLEAN); + WEBKIT_TYPE_WEB_FRAME, G_TYPE_STRING, G_TYPE_POINTER); /** * WebKitWebView::script-prompt: @@ -1396,6 +1520,7 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) GObjectClass* objectClass = G_OBJECT_CLASS(webViewClass); objectClass->dispose = webkit_web_view_dispose; + objectClass->finalize = webkit_web_view_finalize; objectClass->get_property = webkit_web_view_get_property; objectClass->set_property = webkit_web_view_set_property; @@ -1461,6 +1586,34 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) * properties */ + /** + * WebKitWebView:title: + * + * Returns the @web_view's document title. + * + * Since: 1.1.4 + */ + g_object_class_install_property(objectClass, PROP_TITLE, + g_param_spec_string("title", + "Title", + "Returns the @web_view's document title", + NULL, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitWebView:uri: + * + * Returns the current URI of the contents displayed by the @web_view. + * + * Since: 1.1.4 + */ + g_object_class_install_property(objectClass, PROP_URI, + g_param_spec_string("uri", + "URI", + "Returns the current URI of the contents displayed by the @web_view", + NULL, + WEBKIT_PARAM_READABLE)); + #if GTK_CHECK_VERSION(2,10,0) /** * WebKitWebView:copy-target-list: @@ -1570,6 +1723,34 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) FALSE, WEBKIT_PARAM_READWRITE)); + /** + * WebKitWebView:encoding: + * + * The default encoding of the web view. + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, PROP_ENCODING, + g_param_spec_string("encoding", + "Encoding", + "The default encoding of the web view", + NULL, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitWebView:custom-encoding: + * + * The custom encoding of the web view. + * + * Since: 1.1.2 + */ + g_object_class_install_property(objectClass, PROP_CUSTOM_ENCODING, + g_param_spec_string("custom-encoding", + "Custom Encoding", + "The custom encoding of the web view", + NULL, + WEBKIT_PARAM_READWRITE)); + g_type_class_add_private(webViewClass, sizeof(WebKitWebViewPrivate)); } @@ -1625,7 +1806,9 @@ static void webkit_web_view_update_settings(WebKitWebView* webView) Settings* settings = core(webView)->settings(); gchar* defaultEncoding, *cursiveFontFamily, *defaultFontFamily, *fantasyFontFamily, *monospaceFontFamily, *sansSerifFontFamily, *serifFontFamily, *userStylesheetUri; - gboolean autoLoadImages, autoShrinkImages, printBackgrounds, enableScripts, enablePlugins, enableDeveloperExtras, resizableTextAreas; + gboolean autoLoadImages, autoShrinkImages, printBackgrounds, + enableScripts, enablePlugins, enableDeveloperExtras, resizableTextAreas, + enablePrivateBrowsing; g_object_get(webSettings, "default-encoding", &defaultEncoding, @@ -1643,6 +1826,7 @@ static void webkit_web_view_update_settings(WebKitWebView* webView) "resizable-text-areas", &resizableTextAreas, "user-stylesheet-uri", &userStylesheetUri, "enable-developer-extras", &enableDeveloperExtras, + "enable-private-browsing", &enablePrivateBrowsing, NULL); settings->setDefaultTextEncodingName(defaultEncoding); @@ -1658,8 +1842,9 @@ static void webkit_web_view_update_settings(WebKitWebView* webView) settings->setJavaScriptEnabled(enableScripts); settings->setPluginsEnabled(enablePlugins); settings->setTextAreasAreResizable(resizableTextAreas); - settings->setUserStyleSheetLocation(KURL(userStylesheetUri)); + settings->setUserStyleSheetLocation(KURL(KURL(), userStylesheetUri)); settings->setDeveloperExtrasEnabled(enableDeveloperExtras); + settings->setPrivateBrowsingEnabled(enablePrivateBrowsing); g_free(defaultEncoding); g_free(cursiveFontFamily); @@ -1725,9 +1910,11 @@ static void webkit_web_view_settings_notify(WebKitWebSettings* webSettings, GPar else if (name == g_intern_string("resizable-text-areas")) settings->setTextAreasAreResizable(g_value_get_boolean(&value)); else if (name == g_intern_string("user-stylesheet-uri")) - settings->setUserStyleSheetLocation(KURL(g_value_get_string(&value))); + settings->setUserStyleSheetLocation(KURL(KURL(), g_value_get_string(&value))); else if (name == g_intern_string("enable-developer-extras")) settings->setDeveloperExtrasEnabled(g_value_get_boolean(&value)); + else if (name == g_intern_string("enable-private-browsing")) + settings->setPrivateBrowsingEnabled(g_value_get_boolean(&value)); else if (!g_object_class_find_property(G_OBJECT_GET_CLASS(webSettings), name)) g_warning("Unexpected setting '%s'", name); g_value_unset(&value); @@ -1746,20 +1933,13 @@ static void webkit_web_view_init(WebKitWebView* webView) // We also add a simple wrapper class to provide the public // interface for the Web Inspector. priv->webInspector = WEBKIT_WEB_INSPECTOR(g_object_new(WEBKIT_TYPE_WEB_INSPECTOR, NULL)); - webkit_web_inspector_set_inspector_client(priv->webInspector, inspectorClient); + webkit_web_inspector_set_inspector_client(priv->webInspector, priv->corePage); priv->horizontalAdjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); priv->verticalAdjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); -#if GLIB_CHECK_VERSION(2,10,0) g_object_ref_sink(priv->horizontalAdjustment); g_object_ref_sink(priv->verticalAdjustment); -#else - g_object_ref(priv->horizontalAdjustment); - gtk_object_sink(GTK_OBJECT(priv->horizontalAdjustment)); - g_object_ref(priv->verticalAdjustment); - gtk_object_sink(GTK_OBJECT(priv->verticalAdjustment)); -#endif GTK_WIDGET_SET_FLAGS(webView, GTK_CAN_FOCUS); priv->mainFrame = WEBKIT_WEB_FRAME(webkit_web_frame_new(webView)); @@ -1890,6 +2070,42 @@ WebKitWebWindowFeatures* webkit_web_view_get_window_features(WebKitWebView* webV } /** + * webkit_web_view_get_title: + * @web_view: a #WebKitWebView + * + * Returns the @web_view's document title + * + * Since: 1.1.4 + * + * Return value: the title of @web_view + */ +G_CONST_RETURN gchar* webkit_web_view_get_title(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); + + WebKitWebViewPrivate* priv = webView->priv; + return priv->mainFrame->priv->title; +} + +/** + * webkit_web_view_get_uri: + * @web_view: a #WebKitWebView + * + * Returns the current URI of the contents displayed by the @web_view + * + * Since: 1.1.4 + * + * Return value: the URI of @web_view + */ +G_CONST_RETURN gchar* webkit_web_view_get_uri(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); + + WebKitWebViewPrivate* priv = webView->priv; + return priv->mainFrame->priv->uri; +} + +/** * webkit_web_view_set_maintains_back_forward_list: * @web_view: a #WebKitWebView * @flag: to tell the view to maintain a back or forward list @@ -2048,13 +2264,29 @@ gboolean webkit_web_view_can_go_forward(WebKitWebView* webView) return TRUE; } +/** + * webkit_web_view_open: + * @web_view: a #WebKitWebView + * @uri: an URI + * + * Requests loading of the specified URI string. + * + * Deprecated: 1.1.1: Use webkit_web_view_load_uri() instead. + */ void webkit_web_view_open(WebKitWebView* webView, const gchar* uri) { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); g_return_if_fail(uri); - Frame* frame = core(webView)->mainFrame(); - frame->loader()->load(ResourceRequest(KURL(String::fromUTF8(uri)))); + // We used to support local paths, unlike the newer + // function webkit_web_view_load_uri + if (g_path_is_absolute(uri)) { + gchar* fileUri = g_strdup_printf("file://%s", uri); + webkit_web_view_load_uri(webView, fileUri); + g_free(fileUri); + } + else + webkit_web_view_load_uri(webView, uri); } void webkit_web_view_reload(WebKitWebView* webView) @@ -2079,20 +2311,57 @@ void webkit_web_view_reload_bypass_cache(WebKitWebView* webView) core(webView)->mainFrame()->loader()->reload(true); } -void webkit_web_view_load_string(WebKitWebView* webView, const gchar* content, const gchar* contentMimeType, const gchar* contentEncoding, const gchar* baseUri) +/** + * webkit_web_view_load_uri: + * @web_view: a #WebKitWebView + * @uri: an URI string + * + * Requests loading of the specified URI string. + * + * Since: 1.1.1 + */ +void webkit_web_view_load_uri(WebKitWebView* webView, const gchar* uri) { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); - g_return_if_fail(content); + g_return_if_fail(uri); - Frame* frame = core(webView)->mainFrame(); + WebKitWebFrame* frame = webView->priv->mainFrame; + webkit_web_frame_load_uri(frame, uri); +} - KURL url(baseUri ? String::fromUTF8(baseUri) : ""); - RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(content, strlen(content)); - SubstituteData substituteData(sharedBuffer.release(), contentMimeType ? String(contentMimeType) : "text/html", contentEncoding ? String(contentEncoding) : "UTF-8", KURL("about:blank"), url); +/** ++ * webkit_web_view_load_string: ++ * @web_view: a #WebKitWebView ++ * @content: an URI string ++ * @mime_type: the MIME type, or %NULL ++ * @encoding: the encoding, or %NULL ++ * @base_uri: the base URI for relative locations ++ * ++ * Requests loading of the given @content with the specified @mime_type, ++ * @encoding and @base_uri. ++ * ++ * If @mime_type is %NULL, "text/html" is assumed. ++ * ++ * If @encoding is %NULL, "UTF-8" is assumed. ++ */ +void webkit_web_view_load_string(WebKitWebView* webView, const gchar* content, const gchar* mimeType, const gchar* encoding, const gchar* baseUri) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(content); - frame->loader()->load(ResourceRequest(url), substituteData); + WebKitWebFrame* frame = webView->priv->mainFrame; + webkit_web_frame_load_string(frame, content, mimeType, encoding, baseUri); } - +/** + * webkit_web_view_load_html_string: + * @web_view: a #WebKitWebView + * @content: an URI string + * @base_uri: the base URI for relative locations + * + * Requests loading of the given @content with the specified @base_uri. + * + * Deprecated: 1.1.1: Use webkit_web_view_load_string() instead. + */ void webkit_web_view_load_html_string(WebKitWebView* webView, const gchar* content, const gchar* baseUri) { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); @@ -2101,6 +2370,28 @@ void webkit_web_view_load_html_string(WebKitWebView* webView, const gchar* conte webkit_web_view_load_string(webView, content, NULL, NULL, baseUri); } +/** + * webkit_web_view_load_request: + * @web_view: a #WebKitWebView + * @request: a #WebKitNetworkRequest + * + * Requests loading of the specified asynchronous client request. + * + * Creates a provisional data source that will transition to a committed data + * source once any data has been received. Use webkit_web_view_stop_loading() to + * stop the load. + * + * Since: 1.1.1 + */ +void webkit_web_view_load_request(WebKitWebView* webView, WebKitNetworkRequest* request) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + g_return_if_fail(WEBKIT_IS_NETWORK_REQUEST(request)); + + WebKitWebFrame* frame = webView->priv->mainFrame; + webkit_web_frame_load_request(frame, request); +} + void webkit_web_view_stop_loading(WebKitWebView* webView) { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); @@ -2673,4 +2964,89 @@ void webkit_web_view_set_full_content_zoom(WebKitWebView* webView, gboolean zoom g_object_notify(G_OBJECT(webView), "full-content-zoom"); } +/** + * webkit_get_default_session: + * + * Retrieves the default #SoupSession used by all web views. + * Note that the session features are added by WebKit on demand, + * so if you insert your own #SoupCookieJar before any network + * traffic occurs, WebKit will use it instead of the default. + * + * Return value: the default #SoupSession + * + * Since: 1.1.1 + */ +SoupSession* webkit_get_default_session () +{ + return ResourceHandle::defaultSession(); +} + +} + +/** + * webkit_web_view_get_encoding: + * @web_view: a #WebKitWebView + * + * Returns the default encoding of the #WebKitWebView. + * + * Return value: the default encoding + * + * Since: 1.1.1 + */ +const gchar* webkit_web_view_get_encoding(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); + + String encoding = core(webView)->mainFrame()->loader()->encoding(); + + if (!encoding.isEmpty()) { + WebKitWebViewPrivate* priv = webView->priv; + g_free(priv->encoding); + priv->encoding = g_strdup(encoding.utf8().data()); + return priv->encoding; + } else + return NULL; +} + +/** + * webkit_web_view_set_custom_encoding: + * @web_view: a #WebKitWebView + * @encoding: the new encoding, or %NULL to restore the default encoding + * + * Sets the current #WebKitWebView encoding, without modifying the default one, + * and reloads the page. + * + * Since: 1.1.1 + */ +void webkit_web_view_set_custom_encoding(WebKitWebView* webView, const char* encoding) +{ + g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); + + core(webView)->mainFrame()->loader()->reloadWithOverrideEncoding(String::fromUTF8(encoding)); +} + +/** + * webkit_web_view_get_custom_encoding: + * @web_view: a #WebKitWebView + * + * Returns the current encoding of the #WebKitWebView, not the default-encoding + * of WebKitWebSettings. + * + * Return value: a string containing the current custom encoding for @web_view, or %NULL if there's none set. + * + * Since: 1.1.1 + */ +const char* webkit_web_view_get_custom_encoding(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); + + String overrideEncoding = core(webView)->mainFrame()->loader()->documentLoader()->overrideEncoding(); + + if (!overrideEncoding.isEmpty()) { + WebKitWebViewPrivate* priv = webView->priv; + g_free (priv->customEncoding); + priv->customEncoding = g_strdup(overrideEncoding.utf8().data()); + return priv->customEncoding; + } else + return NULL; } diff --git a/WebKit/gtk/webkit/webkitwebview.h b/WebKit/gtk/webkit/webkitwebview.h index 2bb8c61..1455a79 100644 --- a/WebKit/gtk/webkit/webkitwebview.h +++ b/WebKit/gtk/webkit/webkitwebview.h @@ -23,6 +23,7 @@ #define WEBKIT_WEB_VIEW_H #include <gtk/gtk.h> +#include <libsoup/soup.h> #include <JavaScriptCore/JSBase.h> #include <webkit/webkitdefines.h> @@ -49,8 +50,8 @@ typedef enum { typedef enum { - WEBKIT_WEB_VIEW_TARGET_INFO_HTML = - 1, - WEBKIT_WEB_VIEW_TARGET_INFO_TEXT = - 2 + WEBKIT_WEB_VIEW_TARGET_INFO_HTML, + WEBKIT_WEB_VIEW_TARGET_INFO_TEXT } WebKitWebViewTargetInfo; struct _WebKitWebView { @@ -126,6 +127,12 @@ webkit_web_view_get_type (void); WEBKIT_API GtkWidget * webkit_web_view_new (void); +WEBKIT_API G_CONST_RETURN gchar * +webkit_web_view_get_title (WebKitWebView *web_view); + +WEBKIT_API G_CONST_RETURN gchar * +webkit_web_view_get_uri (WebKitWebView *web_view); + WEBKIT_API void webkit_web_view_set_maintains_back_forward_list (WebKitWebView *web_view, gboolean flag); @@ -171,10 +178,14 @@ WEBKIT_API void webkit_web_view_reload_bypass_cache (WebKitWebView *web_view); WEBKIT_API void +webkit_web_view_load_uri (WebKitWebView *web_view, + const gchar *uri); + +WEBKIT_API void webkit_web_view_load_string (WebKitWebView *web_view, const gchar *content, - const gchar *content_mime_type, - const gchar *content_encoding, + const gchar *mime_type, + const gchar *encoding, const gchar *base_uri); WEBKIT_API void @@ -182,6 +193,10 @@ webkit_web_view_load_html_string (WebKitWebView *web_view, const gchar *content, const gchar *base_uri); +WEBKIT_API void +webkit_web_view_load_request (WebKitWebView *web_view, + WebKitNetworkRequest *request); + WEBKIT_API gboolean webkit_web_view_search_text (WebKitWebView *web_view, const gchar *text, @@ -296,6 +311,19 @@ WEBKIT_API void webkit_web_view_set_full_content_zoom (WebKitWebView *web_view, gboolean full_content_zoom); +WEBKIT_API SoupSession* +webkit_get_default_session (void); + +WEBKIT_API const gchar* +webkit_web_view_get_encoding (WebKitWebView * webView); + +WEBKIT_API void +webkit_web_view_set_custom_encoding (WebKitWebView * webView, + const gchar * encoding); + +WEBKIT_API const char* +webkit_web_view_get_custom_encoding (WebKitWebView * webView); + G_END_DECLS #endif diff --git a/WebKit/gtk/webkitmarshal.list b/WebKit/gtk/webkitmarshal.list new file mode 100644 index 0000000..b714a7c --- /dev/null +++ b/WebKit/gtk/webkitmarshal.list @@ -0,0 +1,17 @@ +BOOLEAN:INT,INT,STRING +BOOLEAN:OBJECT +BOOLEAN:OBJECT,OBJECT,OBJECT,OBJECT +BOOLEAN:OBJECT,OBJECT,STRING,OBJECT +BOOLEAN:OBJECT,STRING +BOOLEAN:OBJECT,STRING,POINTER +BOOLEAN:OBJECT,STRING,STRING,STRING +BOOLEAN:STRING,INT,STRING +BOOLEAN:VOID +ENUM:OBJECT,OBJECT +OBJECT:OBJECT +OBJECT:VOID +VOID:OBJECT,OBJECT +VOID:OBJECT,POINTER,POINTER +VOID:OBJECT,STRING +VOID:STRING +VOID:STRING,STRING |