summaryrefslogtreecommitdiffstats
path: root/Source/WebKit/gtk/WebCoreSupport
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-24 11:24:40 +0100
committerBen Murdoch <benm@google.com>2011-06-02 09:53:15 +0100
commit81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch)
tree7a9e5ed86ff429fd347a25153107221543909b19 /Source/WebKit/gtk/WebCoreSupport
parent94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff)
downloadexternal_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.zip
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.gz
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.bz2
Merge WebKit at r80534: Intial merge by Git
Change-Id: Ia7a83357124c9e1cdb1debf55d9661ec0bd09a61
Diffstat (limited to 'Source/WebKit/gtk/WebCoreSupport')
-rw-r--r--Source/WebKit/gtk/WebCoreSupport/AssertMatchingEnums.cpp28
-rw-r--r--Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp62
-rw-r--r--Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h3
-rw-r--r--Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.cpp33
-rw-r--r--Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.h10
-rw-r--r--Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp139
-rw-r--r--Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.h27
-rw-r--r--Source/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp60
-rw-r--r--Source/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h3
-rw-r--r--Source/WebKit/gtk/WebCoreSupport/TextCheckerClientEnchant.cpp216
-rw-r--r--Source/WebKit/gtk/WebCoreSupport/TextCheckerClientEnchant.h63
11 files changed, 470 insertions, 174 deletions
diff --git a/Source/WebKit/gtk/WebCoreSupport/AssertMatchingEnums.cpp b/Source/WebKit/gtk/WebCoreSupport/AssertMatchingEnums.cpp
index 9c596f8..298f329 100644
--- a/Source/WebKit/gtk/WebCoreSupport/AssertMatchingEnums.cpp
+++ b/Source/WebKit/gtk/WebCoreSupport/AssertMatchingEnums.cpp
@@ -22,15 +22,29 @@
#include "config.h"
#include "DumpRenderTreeSupportGtk.h"
+#include "EditingBehaviorTypes.h"
#include "FindOptions.h"
+#include "FrameLoaderTypes.h"
+#include "webkitwebnavigationaction.h"
+#include "webkitwebsettings.h"
#include <wtf/Assertions.h>
#define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, webcore_name) \
- COMPILE_ASSERT(int(WebKit::webkit_name) == int(WebCore::webcore_name), mismatching_enums)
+ COMPILE_ASSERT(int(webkit_name) == int(WebCore::webcore_name), mismatching_enums)
-COMPILE_ASSERT_MATCHING_ENUM(WebFindOptionsCaseInsensitive , CaseInsensitive);
-COMPILE_ASSERT_MATCHING_ENUM(WebFindOptionsAtWordStarts, AtWordStarts);
-COMPILE_ASSERT_MATCHING_ENUM(WebFindOptionsTreatMedialCapitalAsWordStart, TreatMedialCapitalAsWordStart);
-COMPILE_ASSERT_MATCHING_ENUM(WebFindOptionsBackwards, Backwards);
-COMPILE_ASSERT_MATCHING_ENUM(WebFindOptionsWrapAround, WrapAround);
-COMPILE_ASSERT_MATCHING_ENUM(WebFindOptionsStartInSelection, StartInSelection);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_EDITING_BEHAVIOR_MAC, EditingMacBehavior);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_EDITING_BEHAVIOR_WINDOWS, EditingWindowsBehavior);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_EDITING_BEHAVIOR_UNIX, EditingUnixBehavior);
+
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED, NavigationTypeLinkClicked);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_WEB_NAVIGATION_REASON_FORM_SUBMITTED, NavigationTypeFormSubmitted);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_WEB_NAVIGATION_REASON_BACK_FORWARD, NavigationTypeBackForward);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_WEB_NAVIGATION_REASON_RELOAD, NavigationTypeReload);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_WEB_NAVIGATION_REASON_FORM_RESUBMITTED, NavigationTypeFormResubmitted);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_WEB_NAVIGATION_REASON_OTHER, NavigationTypeOther);
+
+COMPILE_ASSERT_MATCHING_ENUM(WebKit::WebFindOptionsAtWordStarts, AtWordStarts);
+COMPILE_ASSERT_MATCHING_ENUM(WebKit::WebFindOptionsTreatMedialCapitalAsWordStart, TreatMedialCapitalAsWordStart);
+COMPILE_ASSERT_MATCHING_ENUM(WebKit::WebFindOptionsBackwards, Backwards);
+COMPILE_ASSERT_MATCHING_ENUM(WebKit::WebFindOptionsWrapAround, WrapAround);
+COMPILE_ASSERT_MATCHING_ENUM(WebKit::WebFindOptionsStartInSelection, StartInSelection);
diff --git a/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp b/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp
index bbfdd72..8e828ac 100644
--- a/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp
+++ b/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp
@@ -72,6 +72,7 @@ namespace WebKit {
ChromeClient::ChromeClient(WebKitWebView* webView)
: m_webView(webView)
, m_closeSoonTimer(0)
+ , m_pendingScrollInvalidations(false)
{
ASSERT(m_webView);
}
@@ -218,7 +219,8 @@ void ChromeClient::setScrollbarsVisible(bool visible)
g_object_set(webWindowFeatures, "scrollbar-visible", visible, NULL);
}
-bool ChromeClient::scrollbarsVisible() {
+bool ChromeClient::scrollbarsVisible()
+{
WebKitWebWindowFeatures* webWindowFeatures = webkit_web_view_get_window_features(m_webView);
gboolean visible;
@@ -353,12 +355,13 @@ bool ChromeClient::shouldInterruptJavaScript()
return false;
}
-bool ChromeClient::tabsToLinks() const
+KeyboardUIMode ChromeClient::keyboardUIMode()
{
+ bool tabsToLinks = true;
if (DumpRenderTreeSupportGtk::dumpRenderTreeModeEnabled())
- return DumpRenderTreeSupportGtk::linksIncludedInFocusChain();
+ tabsToLinks = DumpRenderTreeSupportGtk::linksIncludedInFocusChain();
- return true;
+ return tabsToLinks ? KeyboardAccessTabsToLinks : KeyboardAccessDefault;
}
IntRect ChromeClient::windowResizerRect() const
@@ -367,9 +370,16 @@ IntRect ChromeClient::windowResizerRect() const
return IntRect();
}
-void ChromeClient::invalidateWindow(const IntRect&, bool)
+void ChromeClient::invalidateWindow(const IntRect&, bool immediate)
{
- notImplemented();
+ // 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)
@@ -396,6 +406,8 @@ void ChromeClient::scroll(const IntSize& delta, const IntRect& rectToScroll, con
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).
@@ -433,8 +445,6 @@ void ChromeClient::scroll(const IntSize& delta, const IntRect& rectToScroll, con
gdk_window_invalidate_region(window, invalidRegion, FALSE);
cairo_region_destroy(invalidRegion);
#endif
-
- gdk_window_process_updates(window, TRUE);
}
// FIXME: this does not take into account the WM decorations
@@ -577,11 +587,9 @@ void ChromeClient::exceededDatabaseQuota(Frame* frame, const String& databaseNam
DatabaseTracker::tracker().setQuota(frame->document()->securityOrigin(), defaultQuota);
WebKitWebFrame* webFrame = kit(frame);
- WebKitWebView* webView = getViewFromFrame(webFrame);
-
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(webView, "database-quota-exceeded", webFrame, webDatabase);
+ g_signal_emit_by_name(m_webView, "database-quota-exceeded", webFrame, webDatabase);
}
#endif
@@ -603,7 +611,7 @@ 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(platformPageClient()))),
+ 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,
@@ -644,29 +652,33 @@ void ChromeClient::dispatchViewportDataDidChange(const ViewportArguments& argume
webkitViewportAttributesRecompute(webkit_web_view_get_viewport_attributes(m_webView));
}
-void ChromeClient::setCursor(const Cursor&)
+void ChromeClient::setCursor(const Cursor& cursor)
{
- notImplemented();
+ // [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);
- WebKitWebView* webView = getViewFromFrame(webFrame);
-
GRefPtr<WebKitGeolocationPolicyDecision> policyDecision(adoptGRef(webkit_geolocation_policy_decision_new(webFrame, geolocation)));
gboolean isHandled = FALSE;
- g_signal_emit_by_name(webView, "geolocation-policy-decision-requested", webFrame, policyDecision.get(), &isHandled);
+ 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*)
{
- WebKitWebFrame* webFrame = kit(frame);
- WebKitWebView* webView = getViewFromFrame(webFrame);
- g_signal_emit_by_name(webView, "geolocation-policy-decision-cancelled", webFrame);
+ g_signal_emit_by_name(m_webView, "geolocation-policy-decision-cancelled", kit(frame));
}
bool ChromeClient::selectItemWritingDirectionIsNatural()
@@ -698,18 +710,12 @@ bool ChromeClient::supportsFullscreenForNode(const Node* node)
void ChromeClient::enterFullscreenForNode(Node* node)
{
- WebCore::Frame* frame = node->document()->frame();
- WebKitWebFrame* webFrame = kit(frame);
- WebKitWebView* webView = getViewFromFrame(webFrame);
- webViewEnterFullscreen(webView, node);
+ webViewEnterFullscreen(m_webView, node);
}
void ChromeClient::exitFullscreenForNode(Node* node)
{
- WebCore::Frame* frame = node->document()->frame();
- WebKitWebFrame* webFrame = kit(frame);
- WebKitWebView* webView = getViewFromFrame(webFrame);
- webViewExitFullscreen(webView);
+ webViewExitFullscreen(m_webView);
}
#endif
diff --git a/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h b/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h
index d7644eb..462ddc4 100644
--- a/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h
+++ b/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h
@@ -91,7 +91,7 @@ namespace WebKit {
virtual bool runJavaScriptPrompt(WebCore::Frame*, const WTF::String& message, const WTF::String& defaultValue, WTF::String& result);
virtual void setStatusbarText(const WTF::String&);
virtual bool shouldInterruptJavaScript();
- virtual bool tabsToLinks() const;
+ virtual WebCore::KeyboardUIMode keyboardUIMode();
virtual WebCore::IntRect windowResizerRect() const;
@@ -154,6 +154,7 @@ namespace WebKit {
WebKitWebView* m_webView;
WebCore::KURL m_hoveredLinkURL;
unsigned int m_closeSoonTimer;
+ bool m_pendingScrollInvalidations;
};
}
diff --git a/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.cpp b/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.cpp
index 83f7c21..6db2c81 100644
--- a/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.cpp
+++ b/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.cpp
@@ -48,6 +48,7 @@
#include "RenderTreeAsText.h"
#include "RenderView.h"
#include "SecurityOrigin.h"
+#include "Settings.h"
#include "TextIterator.h"
#include "WorkerThread.h"
#include "webkitglobalsprivate.h"
@@ -68,6 +69,7 @@ using namespace WebKit;
bool DumpRenderTreeSupportGtk::s_drtRun = false;
bool DumpRenderTreeSupportGtk::s_linksIncludedInTabChain = true;
+bool DumpRenderTreeSupportGtk::s_selectTrailingWhitespaceEnabled = false;
DumpRenderTreeSupportGtk::DumpRenderTreeSupportGtk()
{
@@ -101,6 +103,16 @@ void DumpRenderTreeSupportGtk::setIconDatabaseEnabled(bool enabled)
WebKit::setIconDatabaseEnabled(enabled);
}
+void DumpRenderTreeSupportGtk::setSelectTrailingWhitespaceEnabled(bool enabled)
+{
+ s_selectTrailingWhitespaceEnabled = enabled;
+}
+
+bool DumpRenderTreeSupportGtk::selectTrailingWhitespaceEnabled()
+{
+ return s_selectTrailingWhitespaceEnabled;
+}
+
JSValueRef DumpRenderTreeSupportGtk::nodesFromRect(JSContextRef context, JSValueRef value, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping)
{
JSLock lock(SilenceAssertionsOnly);
@@ -610,17 +622,23 @@ void DumpRenderTreeSupportGtk::layoutFrame(WebKitWebFrame* frame)
}
// For testing fast/viewport.
-void DumpRenderTreeSupportGtk::dumpConfigurationForViewport(WebKitWebView* webView, gint availableWidth, gint availableHeight)
+void DumpRenderTreeSupportGtk::dumpConfigurationForViewport(WebKitWebView* webView, gint deviceDPI, gint deviceWidth, gint deviceHeight, gint availableWidth, gint availableHeight)
{
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
ViewportArguments arguments = webView->priv->corePage->mainFrame()->document()->viewportArguments();
- // desktopWidth = 980, deviceWidth = 320, deviceHeight = 480, deviceDPI = 160
- ViewportAttributes attrs = computeViewportAttributes(arguments, 980, 320, 480, 160, IntSize(availableWidth, availableHeight));
+ ViewportAttributes attrs = computeViewportAttributes(arguments, /* default layout width for non-mobile pages */ 980, deviceWidth, deviceHeight, deviceDPI, IntSize(availableWidth, availableHeight));
fprintf(stdout, "viewport size %dx%d scale %f with limits [%f, %f]\n", attrs.layoutSize.width(), attrs.layoutSize.height(), attrs.initialScale, attrs.minimumScale, attrs.maximumScale);
}
+void DumpRenderTreeSupportGtk::clearOpener(WebKitWebFrame* frame)
+{
+ Frame* coreFrame = core(frame);
+ if (coreFrame)
+ coreFrame->loader()->setOpener(0);
+}
+
unsigned int DumpRenderTreeSupportGtk::workerThreadCount()
{
#if ENABLE(WORKERS)
@@ -642,3 +660,12 @@ bool DumpRenderTreeSupportGtk::findString(WebKitWebView* webView, const gchar* t
return core(webView)->findString(String::fromUTF8(targetString), findOptions);
}
+double DumpRenderTreeSupportGtk::defaultMinimumTimerInterval()
+{
+ return Settings::defaultMinDOMTimerInterval();
+}
+
+void DumpRenderTreeSupportGtk::setMinimumTimerInterval(WebKitWebView* webView, double interval)
+{
+ core(webView)->settings()->setMinDOMTimerInterval(interval);
+}
diff --git a/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.h b/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.h
index 553d7bb..595d6da 100644
--- a/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.h
+++ b/Source/WebKit/gtk/WebCoreSupport/DumpRenderTreeSupportGtk.h
@@ -54,8 +54,13 @@ public:
static void setLinksIncludedInFocusChain(bool);
static bool linksIncludedInFocusChain();
static void setIconDatabaseEnabled(bool);
+ static void setSelectTrailingWhitespaceEnabled(bool);
+ static bool selectTrailingWhitespaceEnabled();
+
static JSValueRef nodesFromRect(JSContextRef context, JSValueRef value, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping);
- static void dumpConfigurationForViewport(WebKitWebView* webView, gint availableWidth, gint availableHeight);
+ static void dumpConfigurationForViewport(WebKitWebView* webView, gint deviceDPI, gint deviceWidth, gint deviceHeight, gint availableWidth, gint availableHeight);
+
+ static void clearOpener(WebKitWebFrame*);
// FIXME: Move these to webkitwebframe.h once their API has been discussed.
static GSList* getFrameChildren(WebKitWebFrame*);
@@ -89,6 +94,8 @@ public:
static void confirmComposition(WebKitWebView*, const char* text);
static bool firstRectForCharacterRange(WebKitWebView*, int location, int length, GdkRectangle*);
static bool selectedRange(WebKitWebView*, int* start, int* end);
+ static double defaultMinimumTimerInterval(); // Not really tied to WebView
+ static void setMinimumTimerInterval(WebKitWebView*, double);
// GC
static void gcCollectJavascriptObjects();
@@ -103,6 +110,7 @@ public:
private:
static bool s_drtRun;
static bool s_linksIncludedInTabChain;
+ static bool s_selectTrailingWhitespaceEnabled;
};
#endif
diff --git a/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp b/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp
index ee9bf9a..33fafaa 100644
--- a/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp
+++ b/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp
@@ -25,9 +25,9 @@
#include "EditorClientGtk.h"
#include "DataObjectGtk.h"
+#include "DumpRenderTreeSupportGtk.h"
#include "EditCommand.h"
#include "Editor.h"
-#include <enchant.h>
#include "EventNames.h"
#include "FocusController.h"
#include "Frame.h"
@@ -481,11 +481,6 @@ void EditorClient::didSetSelectionTypesForPasteboard()
notImplemented();
}
-bool EditorClient::isEditable()
-{
- return webkit_web_view_get_editable(m_webView);
-}
-
void EditorClient::registerCommandForUndo(WTF::PassRefPtr<WebCore::EditCommand> command)
{
if (undoStack.size() == maximumUndoStackDepth)
@@ -506,6 +501,16 @@ void EditorClient::clearUndoRedoOperations()
redoStack.clear();
}
+bool EditorClient::canCopyCut(bool defaultValue) const
+{
+ return defaultValue;
+}
+
+bool EditorClient::canPaste(bool defaultValue) const
+{
+ return defaultValue;
+}
+
bool EditorClient::canUndo() const
{
return !undoStack.isEmpty();
@@ -562,8 +567,9 @@ bool EditorClient::smartInsertDeleteEnabled()
bool EditorClient::isSelectTrailingWhitespaceEnabled()
{
- notImplemented();
- return false;
+ if (!DumpRenderTreeSupportGtk::dumpRenderTreeModeEnabled())
+ return false;
+ return DumpRenderTreeSupportGtk::selectTrailingWhitespaceEnabled();
}
void EditorClient::toggleContinuousSpellChecking()
@@ -832,6 +838,9 @@ void EditorClient::handleInputMethodMousePress()
EditorClient::EditorClient(WebKitWebView* webView)
: m_isInRedo(false)
+#if ENABLE(SPELLCHECK)
+ , m_textCheckerClient(webView)
+#endif
, m_webView(webView)
, m_preventNextCompositionCommit(false)
, m_treatContextCommitAsKeyEvent(false)
@@ -887,100 +896,6 @@ void EditorClient::textDidChangeInTextArea(Element*)
notImplemented();
}
-void EditorClient::ignoreWordInSpellDocument(const String& text)
-{
- GSList* dicts = webkitWebViewGetEnchantDicts(m_webView);
-
- for (; dicts; dicts = dicts->next) {
- EnchantDict* dict = static_cast<EnchantDict*>(dicts->data);
-
- enchant_dict_add_to_session(dict, text.utf8().data(), -1);
- }
-}
-
-void EditorClient::learnWord(const String& text)
-{
- GSList* dicts = webkitWebViewGetEnchantDicts(m_webView);
-
- for (; dicts; dicts = dicts->next) {
- EnchantDict* dict = static_cast<EnchantDict*>(dicts->data);
-
- enchant_dict_add_to_personal(dict, text.utf8().data(), -1);
- }
-}
-
-void EditorClient::checkSpellingOfString(const UChar* text, int length, int* misspellingLocation, int* misspellingLength)
-{
- GSList* dicts = webkitWebViewGetEnchantDicts(m_webView);
- if (!dicts)
- return;
-
- gchar* ctext = g_utf16_to_utf8(const_cast<gunichar2*>(text), length, 0, 0, 0);
- int utflen = g_utf8_strlen(ctext, -1);
-
- PangoLanguage* language = pango_language_get_default();
- PangoLogAttr* attrs = g_new(PangoLogAttr, utflen+1);
-
- // pango_get_log_attrs uses an aditional position at the end of the text.
- pango_get_log_attrs(ctext, -1, -1, language, attrs, utflen+1);
-
- for (int i = 0; i < length+1; i++) {
- // We go through each character until we find an is_word_start,
- // then we get into an inner loop to find the is_word_end corresponding
- // to it.
- if (attrs[i].is_word_start) {
- int start = i;
- int end = i;
- int wordLength;
-
- while (attrs[end].is_word_end < 1)
- end++;
-
- wordLength = end - start;
- // Set the iterator to be at the current word end, so we don't
- // check characters twice.
- i = end;
-
- for (; dicts; dicts = dicts->next) {
- EnchantDict* dict = static_cast<EnchantDict*>(dicts->data);
- gchar* cstart = g_utf8_offset_to_pointer(ctext, start);
- gint bytes = static_cast<gint>(g_utf8_offset_to_pointer(ctext, end) - cstart);
- gchar* word = g_new0(gchar, bytes+1);
- int result;
-
- g_utf8_strncpy(word, cstart, end - start);
-
- result = enchant_dict_check(dict, word, -1);
- g_free(word);
- if (result) {
- *misspellingLocation = start;
- *misspellingLength = wordLength;
- } else {
- // Stop checking, this word is ok in at least one dict.
- *misspellingLocation = -1;
- *misspellingLength = 0;
- break;
- }
- }
- }
- }
-
- g_free(attrs);
- g_free(ctext);
-}
-
-String EditorClient::getAutoCorrectSuggestionForMisspelledWord(const String& inputWord)
-{
- // This method can be implemented using customized algorithms for the particular browser.
- // Currently, it computes an empty string.
- return String();
-}
-
-void EditorClient::checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*)
-{
- notImplemented();
-}
-
void EditorClient::updateSpellingUIWithGrammarString(const String&, const GrammarDetail&)
{
notImplemented();
@@ -1002,24 +917,4 @@ bool EditorClient::spellingUIIsShowing()
return false;
}
-void EditorClient::getGuessesForWord(const String& word, const String& context, WTF::Vector<String>& guesses)
-{
- GSList* dicts = webkitWebViewGetEnchantDicts(m_webView);
- guesses.clear();
-
- for (; dicts; dicts = dicts->next) {
- size_t numberOfSuggestions;
- size_t i;
-
- EnchantDict* dict = static_cast<EnchantDict*>(dicts->data);
- gchar** suggestions = enchant_dict_suggest(dict, word.utf8().data(), -1, &numberOfSuggestions);
-
- for (i = 0; i < numberOfSuggestions && i < 10; i++)
- guesses.append(String::fromUTF8(suggestions[i]));
-
- if (numberOfSuggestions > 0)
- enchant_dict_free_suggestions(dict, suggestions);
- }
-}
-
}
diff --git a/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.h b/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.h
index 214dbd6..8aafe45 100644
--- a/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.h
+++ b/Source/WebKit/gtk/WebCoreSupport/EditorClientGtk.h
@@ -32,12 +32,19 @@
#define EditorClientGtk_h
#include "EditorClient.h"
+#include "TextCheckerClient.h"
#include <wtf/Deque.h>
#include <wtf/Forward.h>
#include <wtf/gobject/GOwnPtr.h>
#include <wtf/gobject/GRefPtr.h>
+#if ENABLE(SPELLCHECK)
+#include "TextCheckerClientEnchant.h"
+#else
+#include "EmptyClients.h"
+#endif
+
typedef struct _WebKitWebView WebKitWebView;
namespace WebCore {
@@ -47,7 +54,7 @@ class KeyboardEvent;
namespace WebKit {
- class EditorClient : public WebCore::EditorClient {
+class EditorClient : public WebCore::EditorClient {
protected:
bool m_isInRedo;
@@ -80,8 +87,6 @@ namespace WebKit {
virtual void toggleGrammarChecking();
virtual int spellCheckerDocumentTag();
- virtual bool isEditable();
-
virtual bool shouldBeginEditing(WebCore::Range*);
virtual bool shouldEndEditing(WebCore::Range*);
virtual bool shouldInsertNode(WebCore::Node*, WebCore::Range*, WebCore::EditorInsertAction);
@@ -103,6 +108,8 @@ namespace WebKit {
virtual void registerCommandForRedo(WTF::PassRefPtr<WebCore::EditCommand>);
virtual void clearUndoRedoOperations();
+ virtual bool canCopyCut(bool defaultValue) const;
+ virtual bool canPaste(bool defaultValue) const;
virtual bool canUndo() const;
virtual bool canRedo() const;
@@ -120,21 +127,21 @@ namespace WebKit {
virtual void textWillBeDeletedInTextField(WebCore::Element*);
virtual void textDidChangeInTextArea(WebCore::Element*);
- virtual void ignoreWordInSpellDocument(const WTF::String&);
- virtual void learnWord(const WTF::String&);
- virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength);
- virtual WTF::String getAutoCorrectSuggestionForMisspelledWord(const WTF::String&);
- virtual void checkGrammarOfString(const UChar*, int length, WTF::Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength);
+ virtual WebCore::TextCheckerClient* textChecker() { return &m_textCheckerClient; }
+
virtual void updateSpellingUIWithGrammarString(const WTF::String&, const WebCore::GrammarDetail&);
virtual void updateSpellingUIWithMisspelledWord(const WTF::String&);
virtual void showSpellingUI(bool show);
virtual bool spellingUIIsShowing();
- virtual void getGuessesForWord(const WTF::String& word, const WTF::String& context, WTF::Vector<WTF::String>& guesses);
virtual void willSetInputMethodState();
virtual void setInputMethodState(bool enabled);
- virtual void requestCheckingOfString(WebCore::SpellChecker*, int, const WTF::String&) {}
private:
+#if ENABLE(SPELLCHECK)
+ TextCheckerClientEnchant m_textCheckerClient;
+#else
+ WebCore::EmptyTextCheckerClient m_textCheckerClient;
+#endif
WebKitWebView* m_webView;
bool m_preventNextCompositionCommit;
bool m_treatContextCommitAsKeyEvent;
diff --git a/Source/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp b/Source/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp
index 875455a..d8ea90e 100644
--- a/Source/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp
+++ b/Source/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp
@@ -25,6 +25,8 @@
#include "config.h"
#include "FrameLoaderClientGtk.h"
+#include "AXObjectCache.h"
+#include "AccessibilityObject.h"
#include "ArchiveResource.h"
#include "CachedFrame.h"
#include "Color.h"
@@ -55,6 +57,7 @@
#include "PluginDatabase.h"
#include "ProgressTracker.h"
#include "RenderPart.h"
+#include "RenderView.h"
#include "ResourceHandle.h"
#include "ResourceRequest.h"
#include "ScriptController.h"
@@ -222,6 +225,51 @@ String FrameLoaderClient::userAgent(const KURL& url)
return String::fromUTF8(webkit_web_settings_get_user_agent(settings));
}
+static void notifyAccessibilityStatus(WebKitWebFrame* frame, WebKitLoadStatus loadStatus)
+{
+ if (loadStatus != WEBKIT_LOAD_PROVISIONAL
+ && loadStatus != WEBKIT_LOAD_FAILED
+ && loadStatus != WEBKIT_LOAD_FINISHED)
+ return;
+
+ WebKitWebFramePrivate* priv = frame->priv;
+ if (!priv->coreFrame || !priv->coreFrame->document())
+ return;
+
+ RenderView* contentRenderer = priv->coreFrame->contentRenderer();
+ if (!contentRenderer)
+ return;
+
+ AXObjectCache* axObjectCache = priv->coreFrame->document()->axObjectCache();
+ if (!axObjectCache)
+ return;
+
+ AccessibilityObject* coreAxObject = axObjectCache->getOrCreate(contentRenderer);
+ if (!coreAxObject)
+ return;
+
+ AtkObject* axObject = coreAxObject->wrapper();
+ if (!axObject || !ATK_IS_DOCUMENT(axObject))
+ return;
+
+ switch (loadStatus) {
+ case WEBKIT_LOAD_PROVISIONAL:
+ g_signal_emit_by_name(axObject, "state-change", "busy", true);
+ if (core(frame)->loader()->loadType() == FrameLoadTypeReload)
+ g_signal_emit_by_name(axObject, "reload");
+ break;
+ case WEBKIT_LOAD_FAILED:
+ g_signal_emit_by_name(axObject, "load-stopped");
+ g_signal_emit_by_name(axObject, "state-change", "busy", false);
+ break;
+ case WEBKIT_LOAD_FINISHED:
+ g_signal_emit_by_name(axObject, "load-complete");
+ g_signal_emit_by_name(axObject, "state-change", "busy", false);
+ default:
+ break;
+ }
+}
+
static void notifyStatus(WebKitWebFrame* frame, WebKitLoadStatus loadStatus)
{
frame->priv->loadStatus = loadStatus;
@@ -231,6 +279,9 @@ static void notifyStatus(WebKitWebFrame* frame, WebKitLoadStatus loadStatus)
if (frame == webkit_web_view_get_main_frame(webView)) {
webView->priv->loadStatus = loadStatus;
g_object_notify(G_OBJECT(webView), "load-status");
+
+ if (AXObjectCache::accessibilityEnabled())
+ notifyAccessibilityStatus(frame, loadStatus);
}
}
@@ -407,7 +458,7 @@ void FrameLoaderClient::dispatchDidReceiveResponse(WebCore::DocumentLoader* load
m_response = response;
}
-void FrameLoaderClient::dispatchDecidePolicyForMIMEType(FramePolicyFunction policyFunction, const String& mimeType, const ResourceRequest& resourceRequest)
+void FrameLoaderClient::dispatchDecidePolicyForResponse(FramePolicyFunction policyFunction, const ResourceResponse& response, const ResourceRequest& resourceRequest)
{
ASSERT(policyFunction);
if (!policyFunction)
@@ -426,6 +477,8 @@ void FrameLoaderClient::dispatchDecidePolicyForMIMEType(FramePolicyFunction poli
g_object_unref(m_policyDecision);
m_policyDecision = policyDecision;
+ String mimeType = response.mimeType();
+
gboolean isHandled = false;
g_signal_emit_by_name(page, "mime-type-policy-decision-requested", m_frame, request.get(), mimeType.utf8().data(), policyDecision, &isHandled);
@@ -757,6 +810,11 @@ bool FrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
return item != 0;
}
+bool FrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem* item) const
+{
+ return true;
+}
+
void FrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const
{
}
diff --git a/Source/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h b/Source/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h
index 2e8a2dd..3340837 100644
--- a/Source/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h
+++ b/Source/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h
@@ -94,7 +94,7 @@ namespace WebKit {
virtual WebCore::Frame* dispatchCreatePage(const WebCore::NavigationAction&);
virtual void dispatchShow();
- virtual void dispatchDecidePolicyForMIMEType(WebCore::FramePolicyFunction, const WTF::String& MIMEType, const WebCore::ResourceRequest&);
+ virtual void dispatchDecidePolicyForResponse(WebCore::FramePolicyFunction, const WebCore::ResourceResponse&, const WebCore::ResourceRequest&);
virtual void dispatchDecidePolicyForNewWindowAction(WebCore::FramePolicyFunction, const WebCore::NavigationAction&, const WebCore::ResourceRequest&, WTF::PassRefPtr<WebCore::FormState>, const WTF::String& frameName);
virtual void dispatchDecidePolicyForNavigationAction(WebCore::FramePolicyFunction, const WebCore::NavigationAction&, const WebCore::ResourceRequest&, WTF::PassRefPtr<WebCore::FormState>);
virtual void cancelPolicyCheck();
@@ -141,6 +141,7 @@ namespace WebKit {
virtual void updateGlobalHistory();
virtual void updateGlobalHistoryRedirectLinks();
virtual bool shouldGoToHistoryItem(WebCore::HistoryItem*) const;
+ virtual bool shouldStopLoadingForHistoryItem(WebCore::HistoryItem*) const;
virtual void dispatchDidAddBackForwardItem(WebCore::HistoryItem*) const;
virtual void dispatchDidRemoveBackForwardItem(WebCore::HistoryItem*) const;
virtual void dispatchDidChangeBackForwardIndex() const;
diff --git a/Source/WebKit/gtk/WebCoreSupport/TextCheckerClientEnchant.cpp b/Source/WebKit/gtk/WebCoreSupport/TextCheckerClientEnchant.cpp
new file mode 100644
index 0000000..74e8132
--- /dev/null
+++ b/Source/WebKit/gtk/WebCoreSupport/TextCheckerClientEnchant.cpp
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2008 Nuanti Ltd.
+ * Copyright (C) 2009 Diego Escalante Urrelo <diegoe@gnome.org>
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010 Igalia S.L.
+ * Copyright (C) 2010, Martin Robinson <mrobinson@webkit.org>
+ *
+ * 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 "TextCheckerClientEnchant.h"
+
+#include "NotImplemented.h"
+#include "webkitwebsettingsprivate.h"
+#include "webkitwebviewprivate.h"
+#include <enchant.h>
+#include <glib.h>
+#include <wtf/text/CString.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+EnchantBroker* TextCheckerClientEnchant::broker = 0;
+
+TextCheckerClientEnchant::TextCheckerClientEnchant(WebKitWebView* webView)
+ : m_webView(webView)
+ , m_enchantDicts(0)
+{
+}
+
+TextCheckerClientEnchant::~TextCheckerClientEnchant()
+{
+ g_slist_foreach(m_enchantDicts, freeSpellCheckingLanguage, 0);
+ g_slist_free(m_enchantDicts);
+}
+
+void TextCheckerClientEnchant::ignoreWordInSpellDocument(const String& text)
+{
+ GSList* dicts = m_enchantDicts;
+
+ for (; dicts; dicts = dicts->next) {
+ EnchantDict* dict = static_cast<EnchantDict*>(dicts->data);
+
+ enchant_dict_add_to_session(dict, text.utf8().data(), -1);
+ }
+}
+
+void TextCheckerClientEnchant::learnWord(const String& text)
+{
+ GSList* dicts = m_enchantDicts;
+
+ for (; dicts; dicts = dicts->next) {
+ EnchantDict* dict = static_cast<EnchantDict*>(dicts->data);
+
+ enchant_dict_add_to_personal(dict, text.utf8().data(), -1);
+ }
+}
+
+void TextCheckerClientEnchant::checkSpellingOfString(const UChar* text, int length, int* misspellingLocation, int* misspellingLength)
+{
+ GSList* dicts = m_enchantDicts;
+ if (!dicts)
+ return;
+
+ gchar* ctext = g_utf16_to_utf8(const_cast<gunichar2*>(text), length, 0, 0, 0);
+ int utflen = g_utf8_strlen(ctext, -1);
+
+ PangoLanguage* language(pango_language_get_default());
+ GOwnPtr<PangoLogAttr> attrs(g_new(PangoLogAttr, utflen+1));
+
+ // pango_get_log_attrs uses an aditional position at the end of the text.
+ pango_get_log_attrs(ctext, -1, -1, language, attrs.get(), utflen+1);
+
+ for (int i = 0; i < length+1; i++) {
+ // We go through each character until we find an is_word_start,
+ // then we get into an inner loop to find the is_word_end corresponding
+ // to it.
+ if (attrs.get()[i].is_word_start) {
+ int start = i;
+ int end = i;
+ int wordLength;
+
+ while (attrs.get()[end].is_word_end < 1)
+ end++;
+
+ wordLength = end - start;
+ // Set the iterator to be at the current word end, so we don't
+ // check characters twice.
+ i = end;
+
+ for (; dicts; dicts = dicts->next) {
+ EnchantDict* dict = static_cast<EnchantDict*>(dicts->data);
+ gchar* cstart = g_utf8_offset_to_pointer(ctext, start);
+ gint bytes = static_cast<gint>(g_utf8_offset_to_pointer(ctext, end) - cstart);
+ gchar* word = g_new0(gchar, bytes+1);
+ int result;
+
+ g_utf8_strncpy(word, cstart, end - start);
+
+ result = enchant_dict_check(dict, word, -1);
+ g_free(word);
+ if (result) {
+ *misspellingLocation = start;
+ *misspellingLength = wordLength;
+ } else {
+ // Stop checking, this word is ok in at least one dict.
+ *misspellingLocation = -1;
+ *misspellingLength = 0;
+ break;
+ }
+ }
+ }
+ }
+}
+
+String TextCheckerClientEnchant::getAutoCorrectSuggestionForMisspelledWord(const String& inputWord)
+{
+ // This method can be implemented using customized algorithms for the particular browser.
+ // Currently, it computes an empty string.
+ return String();
+}
+
+void TextCheckerClientEnchant::checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*)
+{
+ notImplemented();
+}
+
+void TextCheckerClientEnchant::getGuessesForWord(const String& word, const String& context, WTF::Vector<String>& guesses)
+{
+ GSList* dicts = m_enchantDicts;
+ guesses.clear();
+
+ for (; dicts; dicts = dicts->next) {
+ size_t numberOfSuggestions;
+ size_t i;
+
+ EnchantDict* dict = static_cast<EnchantDict*>(dicts->data);
+ gchar** suggestions = enchant_dict_suggest(dict, word.utf8().data(), -1, &numberOfSuggestions);
+
+ for (i = 0; i < numberOfSuggestions && i < 10; i++)
+ guesses.append(String::fromUTF8(suggestions[i]));
+
+ if (numberOfSuggestions > 0)
+ enchant_dict_free_suggestions(dict, suggestions);
+ }
+}
+
+static void getAvailableDictionariesCallback(const char* const languageTag, const char* const, const char* const, const char* const, void* data)
+{
+ Vector<CString>* dicts = static_cast<Vector<CString>*>(data);
+
+ dicts->append(languageTag);
+}
+
+void TextCheckerClientEnchant::updateSpellCheckingLanguage(const char* spellCheckingLanguages)
+{
+ EnchantDict* dict;
+ GSList* spellDictionaries = 0;
+
+ if (!broker)
+ broker = enchant_broker_init();
+
+ if (spellCheckingLanguages) {
+ char** langs = g_strsplit(spellCheckingLanguages, ",", -1);
+ for (int i = 0; langs[i]; i++) {
+ if (enchant_broker_dict_exists(broker, langs[i])) {
+ dict = enchant_broker_request_dict(broker, langs[i]);
+ spellDictionaries = g_slist_append(spellDictionaries, dict);
+ }
+ }
+ g_strfreev(langs);
+ } else {
+ const char* language = pango_language_to_string(gtk_get_default_language());
+ if (enchant_broker_dict_exists(broker, language)) {
+ dict = enchant_broker_request_dict(broker, language);
+ spellDictionaries = g_slist_append(spellDictionaries, dict);
+ } else {
+ // No dictionaries selected, we get one from the list
+ Vector<CString> allDictionaries;
+ enchant_broker_list_dicts(broker, getAvailableDictionariesCallback, &allDictionaries);
+ if (!allDictionaries.isEmpty()) {
+ dict = enchant_broker_request_dict(broker, allDictionaries[0].data());
+ spellDictionaries = g_slist_append(spellDictionaries, dict);
+ }
+ }
+ }
+ g_slist_foreach(m_enchantDicts, freeSpellCheckingLanguage, 0);
+ g_slist_free(m_enchantDicts);
+ m_enchantDicts = spellDictionaries;
+}
+
+void TextCheckerClientEnchant::freeSpellCheckingLanguage(gpointer data, gpointer)
+{
+ if (!broker)
+ broker = enchant_broker_init();
+
+ EnchantDict* dict = static_cast<EnchantDict*>(data);
+ enchant_broker_free_dict(broker, dict);
+}
+
+}
diff --git a/Source/WebKit/gtk/WebCoreSupport/TextCheckerClientEnchant.h b/Source/WebKit/gtk/WebCoreSupport/TextCheckerClientEnchant.h
new file mode 100644
index 0000000..c294a3d
--- /dev/null
+++ b/Source/WebKit/gtk/WebCoreSupport/TextCheckerClientEnchant.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2006 Zack Rusin <zack@kde.org>
+ * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2010 Martin Robinson <mrobinson@webkit.org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TextCheckerClientEnchant_h
+#define TextCheckerClientEnchant_h
+
+#include "TextCheckerClient.h"
+
+typedef struct _GSList GSList;
+typedef struct _WebKitWebView WebKitWebView;
+typedef struct str_enchant_broker EnchantBroker;
+
+namespace WebKit {
+
+class TextCheckerClientEnchant : public WebCore::TextCheckerClient {
+ public:
+ TextCheckerClientEnchant(WebKitWebView*);
+ ~TextCheckerClientEnchant();
+ virtual void ignoreWordInSpellDocument(const WTF::String&);
+ virtual void learnWord(const WTF::String&);
+ virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength);
+ virtual WTF::String getAutoCorrectSuggestionForMisspelledWord(const WTF::String&);
+ virtual void checkGrammarOfString(const UChar*, int length, WTF::Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength);
+ virtual void getGuessesForWord(const WTF::String& word, const WTF::String& context, WTF::Vector<WTF::String>& guesses);
+ virtual void requestCheckingOfString(WebCore::SpellChecker*, int, const WTF::String&) {}
+
+ void updateSpellCheckingLanguage(const char*);
+ static void freeSpellCheckingLanguage(gpointer, gpointer);
+ private:
+ WebKitWebView* m_webView;
+ GSList* m_enchantDicts;
+ static EnchantBroker* broker;
+ };
+}
+#endif
+