blob: 4ee9c1a4a992b0a7562e27840791f7e1ca910294 [file] [log] [blame]
/*
* Copyright (C) 2007, 2008 Holger Hans Peter Freyther
* Copyright (C) 2007, 2008 Christian Dywan <christian@imendio.com>
* Copyright (C) 2008 Nuanti Ltd.
* Copyright (C) 2008 Alp Toker <alp@atoker.com>
* Copyright (C) 2008 Gustavo Noronha Silva <gns@gnome.org>
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "ChromeClientGtk.h"
#include "Chrome.h"
#include "Console.h"
#include "DumpRenderTreeSupportGtk.h"
#include "Element.h"
#include "FileChooser.h"
#include "FileSystem.h"
#include "FloatRect.h"
#include "FrameLoadRequest.h"
#include "FrameView.h"
#include "GtkVersioning.h"
#include "HTMLNames.h"
#include "HitTestResult.h"
#include "Icon.h"
#include "IntRect.h"
#include "KURL.h"
#include "NavigationAction.h"
#include "NotImplemented.h"
#include "PlatformString.h"
#include "PopupMenuClient.h"
#include "PopupMenuGtk.h"
#include "SearchPopupMenuGtk.h"
#include "SecurityOrigin.h"
#include "WindowFeatures.h"
#include "webkitgeolocationpolicydecision.h"
#include "webkitgeolocationpolicydecisionprivate.h"
#include "webkitnetworkrequest.h"
#include "webkitsecurityoriginprivate.h"
#include "webkitviewportattributesprivate.h"
#include "webkitwebframeprivate.h"
#include "webkitwebview.h"
#include "webkitwebviewprivate.h"
#include "webkitwebwindowfeaturesprivate.h"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
#include <wtf/text/CString.h>
#if ENABLE(DATABASE)
#include "DatabaseTracker.h"
#endif
using namespace WebCore;
namespace WebKit {
ChromeClient::ChromeClient(WebKitWebView* webView)
: m_webView(webView)
, m_closeSoonTimer(0)
, m_pendingScrollInvalidations(false)
{
ASSERT(m_webView);
}
void ChromeClient::chromeDestroyed()
{
if (m_closeSoonTimer)
g_source_remove(m_closeSoonTimer);
delete this;
}
FloatRect ChromeClient::windowRect()
{
GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(m_webView));
if (gtk_widget_is_toplevel(window)) {
gint left, top, width, height;
gtk_window_get_position(GTK_WINDOW(window), &left, &top);
gtk_window_get_size(GTK_WINDOW(window), &width, &height);
return IntRect(left, top, width, height);
}
return FloatRect();
}
void ChromeClient::setWindowRect(const FloatRect& rect)
{
IntRect intrect = IntRect(rect);
WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView);
g_object_set(webWindowFeatures,
"x", intrect.x(),
"y", intrect.y(),
"width", intrect.width(),
"height", intrect.height(),
NULL);
gboolean autoResizeWindow;
WebKitWebSettings* settings = webkit_web_view_get_settings(m_webView);
g_object_get(settings, "auto-resize-window", &autoResizeWindow, NULL);
if (!autoResizeWindow)
return;
GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(m_webView));
if (gtk_widget_is_toplevel(window)) {
gtk_window_move(GTK_WINDOW(window), intrect.x(), intrect.y());
gtk_window_resize(GTK_WINDOW(window), intrect.width(), intrect.height());
}
}
FloatRect ChromeClient::pageRect()
{
GtkAllocation allocation;
#if GTK_CHECK_VERSION(2, 18, 0)
gtk_widget_get_allocation(GTK_WIDGET(m_webView), &allocation);
#else
allocation = GTK_WIDGET(m_webView)->allocation;
#endif
return IntRect(allocation.x, allocation.y, allocation.width, allocation.height);
}
float ChromeClient::scaleFactor()
{
// Not implementable
return 1.0;
}
void ChromeClient::focus()
{
gtk_widget_grab_focus(GTK_WIDGET(m_webView));
}
void ChromeClient::unfocus()
{
GtkWidget* window = gtk_widget_get_toplevel(GTK_WIDGET(m_webView));
if (gtk_widget_is_toplevel(window))
gtk_window_set_focus(GTK_WINDOW(window), NULL);
}
Page* ChromeClient::createWindow(Frame* frame, const FrameLoadRequest& frameLoadRequest, const WindowFeatures& coreFeatures, const NavigationAction&)
{
WebKitWebView* webView = 0;
g_signal_emit_by_name(m_webView, "create-web-view", kit(frame), &webView);
if (!webView)
return 0;
GRefPtr<WebKitWebWindowFeatures> webWindowFeatures(adoptGRef(kitNew(coreFeatures)));
g_object_set(webView, "window-features", webWindowFeatures.get(), NULL);
return core(webView);
}
void ChromeClient::show()
{
webkit_web_view_notify_ready(m_webView);
}
bool ChromeClient::canRunModal()
{
notImplemented();
return false;
}
void ChromeClient::runModal()
{
notImplemented();
}
void ChromeClient::setToolbarsVisible(bool visible)
{
WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView);
g_object_set(webWindowFeatures, "toolbar-visible", visible, NULL);
}
bool ChromeClient::toolbarsVisible()
{
WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView);
gboolean visible;
g_object_get(webWindowFeatures, "toolbar-visible", &visible, NULL);
return visible;
}
void ChromeClient::setStatusbarVisible(bool visible)
{
WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView);
g_object_set(webWindowFeatures, "statusbar-visible", visible, NULL);
}
bool ChromeClient::statusbarVisible()
{
WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView);
gboolean visible;
g_object_get(webWindowFeatures, "statusbar-visible", &visible, NULL);
return visible;
}
void ChromeClient::setScrollbarsVisible(bool visible)
{
WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView);
g_object_set(webWindowFeatures, "scrollbar-visible", visible, NULL);
}
bool ChromeClient::scrollbarsVisible()
{
WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView);
gboolean visible;
g_object_get(webWindowFeatures, "scrollbar-visible", &visible, NULL);
return visible;
}
void ChromeClient::setMenubarVisible(bool visible)
{
WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView);
g_object_set(webWindowFeatures, "menubar-visible", visible, NULL);
}
bool ChromeClient::menubarVisible()
{
WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView);
gboolean visible;
g_object_get(webWindowFeatures, "menubar-visible", &visible, NULL);
return visible;
}
void ChromeClient::setResizable(bool)
{
// Ignored for now
}
static gboolean emitCloseWebViewSignalLater(WebKitWebView* view)
{
gboolean isHandled;
g_signal_emit_by_name(view, "close-web-view", &isHandled);
return FALSE;
}
void ChromeClient::closeWindowSoon()
{
// We may not have a WebView as create-web-view can return NULL.
if (!m_webView)
return;
if (m_closeSoonTimer) // Don't call close-web-view more than once.
return;
// We need to remove the parent WebView from WebViewSets here, before it actually
// closes, to make sure that JavaScript code that executes before it closes
// can't find it. Otherwise, window.open will select a closed WebView instead of
// opening a new one <rdar://problem/3572585>.
m_webView->priv->corePage->setGroupName("");
// We also need to stop the load to prevent further parsing or JavaScript execution
// after the window has torn down <rdar://problem/4161660>.
webkit_web_view_stop_loading(m_webView);
// Clients commonly destroy the web view during the close-web-view signal, but our caller
// may need to send more signals to the web view. For instance, if this happened in the
// onload handler, it will need to call FrameLoaderClient::dispatchDidHandleOnloadEvents.
// Instead of firing the close-web-view signal now, fire it after the caller finishes.
// This seems to match the Mac/Windows port behavior.
m_closeSoonTimer = g_timeout_add(0, reinterpret_cast<GSourceFunc>(emitCloseWebViewSignalLater), m_webView);
}
bool ChromeClient::canTakeFocus(FocusDirection)
{
return gtk_widget_get_can_focus(GTK_WIDGET(m_webView));
}
void ChromeClient::takeFocus(FocusDirection)
{
unfocus();
}
void ChromeClient::focusedNodeChanged(Node*)
{
}
void ChromeClient::focusedFrameChanged(Frame*)
{
}
bool ChromeClient::canRunBeforeUnloadConfirmPanel()
{
return true;
}
bool ChromeClient::runBeforeUnloadConfirmPanel(const WTF::String& message, WebCore::Frame* frame)
{
return runJavaScriptConfirm(frame, message);
}
void ChromeClient::addMessageToConsole(WebCore::MessageSource source, WebCore::MessageType type, WebCore::MessageLevel level, const WTF::String& message, unsigned int lineNumber, const WTF::String& sourceId)
{
gboolean retval;
g_signal_emit_by_name(m_webView, "console-message", message.utf8().data(), lineNumber, sourceId.utf8().data(), &retval);
}
void ChromeClient::runJavaScriptAlert(Frame* frame, const String& message)
{
gboolean retval;
g_signal_emit_by_name(m_webView, "script-alert", kit(frame), message.utf8().data(), &retval);
}
bool ChromeClient::runJavaScriptConfirm(Frame* frame, const String& message)
{
gboolean retval;
gboolean didConfirm;
g_signal_emit_by_name(m_webView, "script-confirm", kit(frame), message.utf8().data(), &didConfirm, &retval);
return didConfirm == TRUE;
}
bool ChromeClient::runJavaScriptPrompt(Frame* frame, const String& message, const String& defaultValue, String& result)
{
gboolean retval;
gchar* value = 0;
g_signal_emit_by_name(m_webView, "script-prompt", kit(frame), message.utf8().data(), defaultValue.utf8().data(), &value, &retval);
if (value) {
result = String::fromUTF8(value);
g_free(value);
return true;
}
return false;
}
void ChromeClient::setStatusbarText(const String& string)
{
CString stringMessage = string.utf8();
g_signal_emit_by_name(m_webView, "status-bar-text-changed", stringMessage.data());
}
bool ChromeClient::shouldInterruptJavaScript()
{
notImplemented();
return false;
}
KeyboardUIMode ChromeClient::keyboardUIMode()
{
bool tabsToLinks = true;
if (DumpRenderTreeSupportGtk::dumpRenderTreeModeEnabled())
tabsToLinks = DumpRenderTreeSupportGtk::linksIncludedInFocusChain();
return tabsToLinks ? KeyboardAccessTabsToLinks : KeyboardAccessDefault;
}
IntRect ChromeClient::windowResizerRect() const
{
notImplemented();
return IntRect();
}
void ChromeClient::invalidateWindow(const IntRect&, bool immediate)
{
// If we've invalidated regions for scrolling, force GDK to process those invalidations
// now. This will also cause child windows to move right away. This prevents redraw
// artifacts with child windows (e.g. Flash plugin instances).
if (immediate && m_pendingScrollInvalidations) {
m_pendingScrollInvalidations = false;
if (GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(m_webView)))
gdk_window_process_updates(window, TRUE);
}
}
void ChromeClient::invalidateContentsAndWindow(const IntRect& updateRect, bool immediate)
{
GdkRectangle rect = updateRect;
GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(m_webView));
if (window && !updateRect.isEmpty()) {
gdk_window_invalidate_rect(window, &rect, FALSE);
// We don't currently do immediate updates since they delay other UI elements.
//if (immediate)
// gdk_window_process_updates(window, FALSE);
}
}
void ChromeClient::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate)
{
invalidateContentsAndWindow(updateRect, immediate);
}
void ChromeClient::scroll(const IntSize& delta, const IntRect& rectToScroll, const IntRect& clipRect)
{
GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(m_webView));
if (!window)
return;
m_pendingScrollInvalidations = true;
// We cannot use gdk_window_scroll here because it is only able to
// scroll the whole window at once, and we often need to scroll
// portions of the window only (think frames).
GdkRectangle area = clipRect;
GdkRectangle moveRect;
GdkRectangle sourceRect = area;
sourceRect.x -= delta.width();
sourceRect.y -= delta.height();
#ifdef GTK_API_VERSION_2
GdkRegion* invalidRegion = gdk_region_rectangle(&area);
if (gdk_rectangle_intersect(&area, &sourceRect, &moveRect)) {
GdkRegion* moveRegion = gdk_region_rectangle(&moveRect);
gdk_window_move_region(window, moveRegion, delta.width(), delta.height());
gdk_region_offset(moveRegion, delta.width(), delta.height());
gdk_region_subtract(invalidRegion, moveRegion);
gdk_region_destroy(moveRegion);
}
gdk_window_invalidate_region(window, invalidRegion, FALSE);
gdk_region_destroy(invalidRegion);
#else
cairo_region_t* invalidRegion = cairo_region_create_rectangle(&area);
if (gdk_rectangle_intersect(&area, &sourceRect, &moveRect)) {
cairo_region_t* moveRegion = cairo_region_create_rectangle(&moveRect);
gdk_window_move_region(window, moveRegion, delta.width(), delta.height());
cairo_region_translate(moveRegion, delta.width(), delta.height());
cairo_region_subtract(invalidRegion, moveRegion);
cairo_region_destroy(moveRegion);
}
gdk_window_invalidate_region(window, invalidRegion, FALSE);
cairo_region_destroy(invalidRegion);
#endif
}
// FIXME: this does not take into account the WM decorations
static IntPoint widgetScreenPosition(GtkWidget* widget)
{
GtkWidget* window = gtk_widget_get_toplevel(widget);
int widgetX = 0, widgetY = 0;
gtk_widget_translate_coordinates(widget, window, 0, 0, &widgetX, &widgetY);
IntPoint result(widgetX, widgetY);
int originX, originY;
gdk_window_get_origin(gtk_widget_get_window(window), &originX, &originY);
result.move(originX, originY);
return result;
}
IntRect ChromeClient::windowToScreen(const IntRect& rect) const
{
IntRect result(rect);
IntPoint screenPosition = widgetScreenPosition(GTK_WIDGET(m_webView));
result.move(screenPosition.x(), screenPosition.y());
return result;
}
IntPoint ChromeClient::screenToWindow(const IntPoint& point) const
{
IntPoint result(point);
IntPoint screenPosition = widgetScreenPosition(GTK_WIDGET(m_webView));
result.move(-screenPosition.x(), -screenPosition.y());
return result;
}
PlatformPageClient ChromeClient::platformPageClient() const
{
return GTK_WIDGET(m_webView);
}
void ChromeClient::contentsSizeChanged(Frame* frame, const IntSize& size) const
{
// We need to queue a resize request only if the size changed,
// otherwise we get into an infinite loop!
GtkWidget* widget = GTK_WIDGET(m_webView);
GtkRequisition requisition;
#if GTK_CHECK_VERSION(2, 20, 0)
gtk_widget_get_requisition(widget, &requisition);
#else
requisition = widget->requisition;
#endif
if (gtk_widget_get_realized(widget)
&& (requisition.height != size.height())
|| (requisition.width != size.width()))
gtk_widget_queue_resize_no_redraw(widget);
}
void ChromeClient::scrollbarsModeDidChange() const
{
WebKitWebFrame* webFrame = webkit_web_view_get_main_frame(m_webView);
g_object_notify(G_OBJECT(webFrame), "horizontal-scrollbar-policy");
g_object_notify(G_OBJECT(webFrame), "vertical-scrollbar-policy");
gboolean isHandled;
g_signal_emit_by_name(webFrame, "scrollbars-policy-changed", &isHandled);
if (isHandled)
return;
GtkWidget* parent = gtk_widget_get_parent(GTK_WIDGET(m_webView));
if (!parent || !GTK_IS_SCROLLED_WINDOW(parent))
return;
GtkPolicyType horizontalPolicy = webkit_web_frame_get_horizontal_scrollbar_policy(webFrame);
GtkPolicyType verticalPolicy = webkit_web_frame_get_vertical_scrollbar_policy(webFrame);
// ScrolledWindow doesn't like to display only part of a widget if
// the scrollbars are completely disabled; We have a disparity
// here on what the policy requested by the web app is and what we
// can represent; the idea is not to show scrollbars, only.
if (horizontalPolicy == GTK_POLICY_NEVER)
horizontalPolicy = GTK_POLICY_AUTOMATIC;
if (verticalPolicy == GTK_POLICY_NEVER)
verticalPolicy = GTK_POLICY_AUTOMATIC;
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(parent),
horizontalPolicy, verticalPolicy);
}
void ChromeClient::mouseDidMoveOverElement(const HitTestResult& hit, unsigned modifierFlags)
{
// check if the element is a link...
bool isLink = hit.isLiveLink();
if (isLink) {
KURL url = hit.absoluteLinkURL();
if (!url.isEmpty() && url != m_hoveredLinkURL) {
TextDirection dir;
CString titleString = hit.title(dir).utf8();
CString urlString = url.string().utf8();
g_signal_emit_by_name(m_webView, "hovering-over-link", titleString.data(), urlString.data());
m_hoveredLinkURL = url;
}
} else if (!isLink && !m_hoveredLinkURL.isEmpty()) {
g_signal_emit_by_name(m_webView, "hovering-over-link", 0, 0);
m_hoveredLinkURL = KURL();
}
if (Node* node = hit.innerNonSharedNode()) {
Frame* frame = node->document()->frame();
FrameView* view = frame ? frame->view() : 0;
m_webView->priv->tooltipArea = view ? view->contentsToWindow(node->getRect()) : IntRect();
} else
m_webView->priv->tooltipArea = IntRect();
}
void ChromeClient::setToolTip(const String& toolTip, TextDirection)
{
webkit_web_view_set_tooltip_text(m_webView, toolTip.utf8().data());
}
void ChromeClient::print(Frame* frame)
{
WebKitWebFrame* webFrame = kit(frame);
gboolean isHandled = false;
g_signal_emit_by_name(m_webView, "print-requested", webFrame, &isHandled);
if (isHandled)
return;
webkit_web_frame_print(webFrame);
}
#if ENABLE(DATABASE)
void ChromeClient::exceededDatabaseQuota(Frame* frame, const String& databaseName)
{
guint64 defaultQuota = webkit_get_default_web_database_quota();
DatabaseTracker::tracker().setQuota(frame->document()->securityOrigin(), defaultQuota);
WebKitWebFrame* webFrame = kit(frame);
WebKitSecurityOrigin* origin = webkit_web_frame_get_security_origin(webFrame);
WebKitWebDatabase* webDatabase = webkit_security_origin_get_web_database(origin, databaseName.utf8().data());
g_signal_emit_by_name(m_webView, "database-quota-exceeded", webFrame, webDatabase);
}
#endif
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
void ChromeClient::reachedMaxAppCacheSize(int64_t spaceNeeded)
{
// FIXME: Free some space.
notImplemented();
}
void ChromeClient::reachedApplicationCacheOriginQuota(SecurityOrigin*)
{
notImplemented();
}
#endif
void ChromeClient::runOpenPanel(Frame*, PassRefPtr<FileChooser> prpFileChooser)
{
RefPtr<FileChooser> chooser = prpFileChooser;
GtkWidget* dialog = gtk_file_chooser_dialog_new(_("Upload File"),
GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(m_webView))),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), chooser->allowsMultipleFiles());
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
if (gtk_file_chooser_get_select_multiple(GTK_FILE_CHOOSER(dialog))) {
GSList* filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
Vector<String> names;
for (GSList* item = filenames ; item ; item = item->next) {
if (!item->data)
continue;
names.append(filenameToString(static_cast<char*>(item->data)));
g_free(item->data);
}
g_slist_free(filenames);
chooser->chooseFiles(names);
} else {
gchar* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
if (filename)
chooser->chooseFile(filenameToString(filename));
g_free(filename);
}
}
gtk_widget_destroy(dialog);
}
void ChromeClient::chooseIconForFiles(const Vector<WTF::String>& filenames, WebCore::FileChooser* chooser)
{
chooser->iconLoaded(Icon::createIconForFiles(filenames));
}
void ChromeClient::dispatchViewportDataDidChange(const ViewportArguments& arguments) const
{
// Recompute the viewport attributes making it valid.
webkitViewportAttributesRecompute(webkit_web_view_get_viewport_attributes(m_webView));
}
void ChromeClient::setCursor(const Cursor& cursor)
{
// [GTK] Widget::setCursor() gets called frequently
// http://bugs.webkit.org/show_bug.cgi?id=16388
// Setting the cursor may be an expensive operation in some backends,
// so don't re-set the cursor if it's already set to the target value.
GdkWindow* window = gtk_widget_get_window(platformPageClient());
GdkCursor* currentCursor = gdk_window_get_cursor(window);
GdkCursor* newCursor = cursor.platformCursor().get();
if (currentCursor != newCursor)
gdk_window_set_cursor(window, newCursor);
}
void ChromeClient::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation)
{
WebKitWebFrame* webFrame = kit(frame);
GRefPtr<WebKitGeolocationPolicyDecision> policyDecision(adoptGRef(webkit_geolocation_policy_decision_new(webFrame, geolocation)));
gboolean isHandled = FALSE;
g_signal_emit_by_name(m_webView, "geolocation-policy-decision-requested", webFrame, policyDecision.get(), &isHandled);
if (!isHandled)
webkit_geolocation_policy_deny(policyDecision.get());
}
void ChromeClient::cancelGeolocationPermissionRequestForFrame(WebCore::Frame* frame, WebCore::Geolocation*)
{
g_signal_emit_by_name(m_webView, "geolocation-policy-decision-cancelled", kit(frame));
}
bool ChromeClient::selectItemWritingDirectionIsNatural()
{
return true;
}
bool ChromeClient::selectItemAlignmentFollowsMenuWritingDirection()
{
return false;
}
PassRefPtr<WebCore::PopupMenu> ChromeClient::createPopupMenu(WebCore::PopupMenuClient* client) const
{
return adoptRef(new PopupMenuGtk(client));
}
PassRefPtr<WebCore::SearchPopupMenu> ChromeClient::createSearchPopupMenu(WebCore::PopupMenuClient* client) const
{
return adoptRef(new SearchPopupMenuGtk(client));
}
#if ENABLE(VIDEO)
bool ChromeClient::supportsFullscreenForNode(const Node* node)
{
return node->hasTagName(HTMLNames::videoTag);
}
void ChromeClient::enterFullscreenForNode(Node* node)
{
webViewEnterFullscreen(m_webView, node);
}
void ChromeClient::exitFullscreenForNode(Node* node)
{
webViewExitFullscreen(m_webView);
}
#endif
#if ENABLE(FULLSCREEN_API)
bool ChromeClient::supportsFullScreenForElement(const WebCore::Element* element, bool withKeyboard)
{
if (withKeyboard)
return false;
return true;
}
void ChromeClient::enterFullScreenForElement(WebCore::Element* element)
{
element->document()->webkitWillEnterFullScreenForElement(element);
element->document()->webkitDidEnterFullScreenForElement(element);
}
void ChromeClient::exitFullScreenForElement(WebCore::Element* element)
{
element->document()->webkitWillExitFullScreenForElement(element);
element->document()->webkitDidExitFullScreenForElement(element);
}
#endif
}