Title: [187100] trunk
Revision
187100
Author
[email protected]
Date
2015-07-20 23:06:18 -0700 (Mon, 20 Jul 2015)

Log Message

[GTK] Add API to be notified about editor state changes
https://bugs.webkit.org/show_bug.cgi?id=145875

Reviewed by Gustavo Noronha Silva.

Source/WebKit2:

Add WebKitEditorState object, that is created on demand by the
WebKitWebView and can be used to get the typing attributes of the
editor at the current position or selection.

* PlatformGTK.cmake:
* Shared/EditorState.cpp: Use part of the PostLayoutData struct
for the GTK port too.
(WebKit::EditorState::encode): Encode PostLayoutData for GTK and
remove our custom cursorRect.
(WebKit::EditorState::decode): Decode PostLayoutData for GTK and
remove our custom cursorRect.
(WebKit::EditorState::PostLayoutData::encode): Reorder it to
reduce the amonut of ifdefs.
(WebKit::EditorState::PostLayoutData::decode): Ditto.
* Shared/EditorState.h: Add AttributeStrikeThrough to
TypingAttributes enum.
* UIProcess/API/gtk/PageClientImpl.cpp:
(WebKit::PageClientImpl::selectionDidChange): Rename
updateTextInputState() to selectionDidChange() and also notify the
WebKitWebView.
* UIProcess/API/gtk/PageClientImpl.h:
* UIProcess/API/gtk/WebKitEditorState.cpp: Added.
(webkitEditorStateGetProperty):
(webkit_editor_state_class_init):
(webkitEditorStateSetTypingAttributes):
(webkitEditorStateCreate):
(webkitEditorStateChanged):
(webkit_editor_state_get_typing_attributes):
* UIProcess/API/gtk/WebKitEditorState.h: Added.
* UIProcess/API/gtk/WebKitEditorStatePrivate.h: Added.
* UIProcess/API/gtk/WebKitWebView.cpp:
(webkitWebViewSelectionDidChange): Notify the WebKitEditorState if
it has already been created.
(webkit_web_view_get_editor_state): Ensure a WebKitEditorState and
return it.
* UIProcess/API/gtk/WebKitWebView.h:
* UIProcess/API/gtk/WebKitWebViewBase.cpp:
(webkitWebViewBaseUpdateTextInputState): Get the caret cursor rect
from PostLayoutData.
* UIProcess/API/gtk/WebKitWebViewPrivate.h:
* UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt: Add new symbols.
* UIProcess/API/gtk/docs/webkit2gtk-4.0.types: Add webkit_editor_state_get_type.
* UIProcess/API/gtk/docs/webkit2gtk-docs.sgml: Add new section for WebKitEditorState.
* UIProcess/API/gtk/webkit2.h: Include WebKitEditorState.h.
* UIProcess/PageClient.h:
* UIProcess/gtk/WebPageProxyGtk.cpp:
(WebKit::WebPageProxy::editorStateChanged): Call PageClientImpl::selectionDidChange().
* WebProcess/WebPage/gtk/WebPageGtk.cpp:
(WebKit::WebPage::platformEditorState): Add typing attributes to EditorState.

Tools:

Update the typing attributes toggle buttons state according to the
editor state in MiniBrowser, and add a test case to the
WebViewEditor unit tests.

* MiniBrowser/gtk/BrowserWindow.c:
(browserWindowEditingCommandToggleButtonSetActive):
(typingAttributesChanged):
(browserWindowSetupEditorToolbar):
(browserWindowConstructed):
(browser_window_init):
* TestWebKitAPI/Tests/WebKit2Gtk/TestWebViewEditor.cpp:
(testWebViewEditorEditorStateTypingAttributes):
(beforeAll):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (187099 => 187100)


--- trunk/Source/WebKit2/ChangeLog	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/ChangeLog	2015-07-21 06:06:18 UTC (rev 187100)
@@ -1,3 +1,60 @@
+2015-07-20  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Add API to be notified about editor state changes
+        https://bugs.webkit.org/show_bug.cgi?id=145875
+
+        Reviewed by Gustavo Noronha Silva.
+
+        Add WebKitEditorState object, that is created on demand by the
+        WebKitWebView and can be used to get the typing attributes of the
+        editor at the current position or selection.
+
+        * PlatformGTK.cmake:
+        * Shared/EditorState.cpp: Use part of the PostLayoutData struct
+        for the GTK port too.
+        (WebKit::EditorState::encode): Encode PostLayoutData for GTK and
+        remove our custom cursorRect.
+        (WebKit::EditorState::decode): Decode PostLayoutData for GTK and
+        remove our custom cursorRect.
+        (WebKit::EditorState::PostLayoutData::encode): Reorder it to
+        reduce the amonut of ifdefs.
+        (WebKit::EditorState::PostLayoutData::decode): Ditto.
+        * Shared/EditorState.h: Add AttributeStrikeThrough to
+        TypingAttributes enum.
+        * UIProcess/API/gtk/PageClientImpl.cpp:
+        (WebKit::PageClientImpl::selectionDidChange): Rename
+        updateTextInputState() to selectionDidChange() and also notify the
+        WebKitWebView.
+        * UIProcess/API/gtk/PageClientImpl.h:
+        * UIProcess/API/gtk/WebKitEditorState.cpp: Added.
+        (webkitEditorStateGetProperty):
+        (webkit_editor_state_class_init):
+        (webkitEditorStateSetTypingAttributes):
+        (webkitEditorStateCreate):
+        (webkitEditorStateChanged):
+        (webkit_editor_state_get_typing_attributes):
+        * UIProcess/API/gtk/WebKitEditorState.h: Added.
+        * UIProcess/API/gtk/WebKitEditorStatePrivate.h: Added.
+        * UIProcess/API/gtk/WebKitWebView.cpp:
+        (webkitWebViewSelectionDidChange): Notify the WebKitEditorState if
+        it has already been created.
+        (webkit_web_view_get_editor_state): Ensure a WebKitEditorState and
+        return it.
+        * UIProcess/API/gtk/WebKitWebView.h:
+        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+        (webkitWebViewBaseUpdateTextInputState): Get the caret cursor rect
+        from PostLayoutData.
+        * UIProcess/API/gtk/WebKitWebViewPrivate.h:
+        * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt: Add new symbols.
+        * UIProcess/API/gtk/docs/webkit2gtk-4.0.types: Add webkit_editor_state_get_type.
+        * UIProcess/API/gtk/docs/webkit2gtk-docs.sgml: Add new section for WebKitEditorState.
+        * UIProcess/API/gtk/webkit2.h: Include WebKitEditorState.h.
+        * UIProcess/PageClient.h:
+        * UIProcess/gtk/WebPageProxyGtk.cpp:
+        (WebKit::WebPageProxy::editorStateChanged): Call PageClientImpl::selectionDidChange().
+        * WebProcess/WebPage/gtk/WebPageGtk.cpp:
+        (WebKit::WebPage::platformEditorState): Add typing attributes to EditorState.
+
 2015-07-20  Simon Fraser  <[email protected]>
 
         Fix the iOS build.

Modified: trunk/Source/WebKit2/PlatformGTK.cmake (187099 => 187100)


--- trunk/Source/WebKit2/PlatformGTK.cmake	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/PlatformGTK.cmake	2015-07-21 06:06:18 UTC (rev 187100)
@@ -139,6 +139,7 @@
     UIProcess/API/gtk/WebKitDownloadClient.h
     UIProcess/API/gtk/WebKitDownloadPrivate.h
     UIProcess/API/gtk/WebKitEditingCommands.h
+    UIProcess/API/gtk/WebKitEditorState.cpp
     UIProcess/API/gtk/WebKitError.cpp
     UIProcess/API/gtk/WebKitError.h
     UIProcess/API/gtk/WebKitFaviconDatabase.cpp
@@ -378,6 +379,7 @@
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitDefines.h
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitDownload.h
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitEditingCommands.h
+    ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitEditorState.h
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitError.h
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitFaviconDatabase.h
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitFileChooserRequest.h

Modified: trunk/Source/WebKit2/Shared/EditorState.cpp (187099 => 187100)


--- trunk/Source/WebKit2/Shared/EditorState.cpp	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/Shared/EditorState.cpp	2015-07-21 06:06:18 UTC (rev 187100)
@@ -43,18 +43,16 @@
     encoder << hasComposition;
     encoder << isMissingPostLayoutData;
 
-#if PLATFORM(IOS)
+#if PLATFORM(IOS) || PLATFORM(GTK)
     if (!isMissingPostLayoutData)
         m_postLayoutData.encode(encoder);
+#endif
 
+#if PLATFORM(IOS)
     encoder << firstMarkedRect;
     encoder << lastMarkedRect;
     encoder << markedText;
 #endif
-
-#if PLATFORM(GTK)
-    encoder << cursorRect;
-#endif
 }
 
 bool EditorState::decode(IPC::ArgumentDecoder& decoder, EditorState& result)
@@ -86,12 +84,14 @@
     if (!decoder.decode(result.isMissingPostLayoutData))
         return false;
 
-#if PLATFORM(IOS)
+#if PLATFORM(IOS) || PLATFORM(GTK)
     if (!result.isMissingPostLayoutData) {
         if (!PostLayoutData::decode(decoder, result.postLayoutData()))
             return false;
     }
+#endif
 
+#if PLATFORM(IOS)
     if (!decoder.decode(result.firstMarkedRect))
         return false;
     if (!decoder.decode(result.lastMarkedRect))
@@ -100,41 +100,41 @@
         return false;
 #endif
 
-#if PLATFORM(GTK)
-    if (!decoder.decode(result.cursorRect))
-        return false;
-#endif
-
     return true;
 }
 
-#if PLATFORM(IOS)
+#if PLATFORM(IOS) || PLATFORM(GTK)
 void EditorState::PostLayoutData::encode(IPC::ArgumentEncoder& encoder) const
 {
-    encoder << selectionClipRect;
-    encoder << selectionRects;
+    encoder << typingAttributes;
     encoder << caretRectAtStart;
+#if PLATFORM(IOS)
     encoder << caretRectAtEnd;
+    encoder << selectionClipRect;
+    encoder << selectionRects;
     encoder << wordAtSelection;
     encoder << selectedTextLength;
     encoder << characterAfterSelection;
     encoder << characterBeforeSelection;
     encoder << twoCharacterBeforeSelection;
-    encoder << typingAttributes;
     encoder << isReplaceAllowed;
     encoder << hasContent;
+#endif
 }
 
 bool EditorState::PostLayoutData::decode(IPC::ArgumentDecoder& decoder, PostLayoutData& result)
 {
-    if (!decoder.decode(result.selectionClipRect))
+    if (!decoder.decode(result.typingAttributes))
         return false;
-    if (!decoder.decode(result.selectionRects))
-        return false;
     if (!decoder.decode(result.caretRectAtStart))
         return false;
+#if PLATFORM(IOS)
     if (!decoder.decode(result.caretRectAtEnd))
         return false;
+    if (!decoder.decode(result.selectionClipRect))
+        return false;
+    if (!decoder.decode(result.selectionRects))
+        return false;
     if (!decoder.decode(result.wordAtSelection))
         return false;
     if (!decoder.decode(result.selectedTextLength))
@@ -145,12 +145,11 @@
         return false;
     if (!decoder.decode(result.twoCharacterBeforeSelection))
         return false;
-    if (!decoder.decode(result.typingAttributes))
-        return false;
     if (!decoder.decode(result.isReplaceAllowed))
         return false;
     if (!decoder.decode(result.hasContent))
         return false;
+#endif
 
     return true;
 }

Modified: trunk/Source/WebKit2/Shared/EditorState.h (187099 => 187100)


--- trunk/Source/WebKit2/Shared/EditorState.h	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/Shared/EditorState.h	2015-07-21 06:06:18 UTC (rev 187100)
@@ -40,7 +40,8 @@
     AttributeNone = 0,
     AttributeBold = 1,
     AttributeItalics = 2,
-    AttributeUnderline = 4
+    AttributeUnderline = 4,
+    AttributeStrikeThrough = 8
 };
 
 struct EditorState {
@@ -59,20 +60,24 @@
     WebCore::IntRect firstMarkedRect;
     WebCore::IntRect lastMarkedRect;
     String markedText;
+#endif
 
+#if PLATFORM(IOS) || PLATFORM(GTK)
     struct PostLayoutData {
+        uint32_t typingAttributes { AttributeNone };
+        WebCore::IntRect caretRectAtStart;
+#if PLATFORM(IOS)
+        WebCore::IntRect caretRectAtEnd;
         WebCore::IntRect selectionClipRect;
         Vector<WebCore::SelectionRect> selectionRects;
-        WebCore::IntRect caretRectAtStart;
-        WebCore::IntRect caretRectAtEnd;
         String wordAtSelection;
         uint64_t selectedTextLength { 0 };
         UChar32 characterAfterSelection { 0 };
         UChar32 characterBeforeSelection { 0 };
         UChar32 twoCharacterBeforeSelection { 0 };
-        uint32_t typingAttributes { AttributeNone };
         bool isReplaceAllowed { false };
         bool hasContent { false };
+#endif
 
         void encode(IPC::ArgumentEncoder&) const;
         static bool decode(IPC::ArgumentDecoder&, PostLayoutData&);
@@ -80,22 +85,18 @@
 
     const PostLayoutData& postLayoutData() const;
     PostLayoutData& postLayoutData();
-#endif
+#endif // PLATFORM(IOS) || PLATFORM(GTK)
 
-#if PLATFORM(GTK)
-    WebCore::IntRect cursorRect;
-#endif
-
     void encode(IPC::ArgumentEncoder&) const;
     static bool decode(IPC::ArgumentDecoder&, EditorState&);
 
-#if PLATFORM(IOS)
+#if PLATFORM(IOS) || PLATFORM(GTK)
 private:
     PostLayoutData m_postLayoutData;
 #endif
 };
 
-#if PLATFORM(IOS)
+#if PLATFORM(IOS) || PLATFORM(GTK)
 inline auto EditorState::postLayoutData() -> PostLayoutData&
 {
     ASSERT_WITH_MESSAGE(!isMissingPostLayoutData, "Attempt to access post layout data before receiving it");

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp (187099 => 187100)


--- trunk/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp	2015-07-21 06:06:18 UTC (rev 187100)
@@ -36,8 +36,8 @@
 #include "WebContextMenuProxyGtk.h"
 #include "WebEventFactory.h"
 #include "WebKitColorChooser.h"
-#include "WebKitWebView.h"
 #include "WebKitWebViewBasePrivate.h"
+#include "WebKitWebViewPrivate.h"
 #include "WebPageProxy.h"
 #include "WebPopupMenuProxyGtk.h"
 #include "WebProcessPool.h"
@@ -263,9 +263,11 @@
     notImplemented();
 }
 
-void PageClientImpl::updateTextInputState()
+void PageClientImpl::selectionDidChange()
 {
     webkitWebViewBaseUpdateTextInputState(WEBKIT_WEB_VIEW_BASE(m_viewWidget));
+    if (WEBKIT_IS_WEB_VIEW(m_viewWidget))
+        webkitWebViewSelectionDidChange(WEBKIT_WEB_VIEW(m_viewWidget));
 }
 
 #if ENABLE(DRAG_SUPPORT)

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h (187099 => 187100)


--- trunk/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h	2015-07-21 06:06:18 UTC (rev 187100)
@@ -90,7 +90,7 @@
     virtual void setTextIndicator(Ref<WebCore::TextIndicator>, WebCore::TextIndicatorLifetime = WebCore::TextIndicatorLifetime::Permanent) override;
     virtual void clearTextIndicator(WebCore::TextIndicatorDismissalAnimation = WebCore::TextIndicatorDismissalAnimation::FadeOut) override;
     virtual void setTextIndicatorAnimationProgress(float) override;
-    virtual void updateTextInputState() override;
+    virtual void selectionDidChange() override;
 #if ENABLE(DRAG_SUPPORT)
     virtual void startDrag(const WebCore::DragData&, PassRefPtr<ShareableBitmap> dragImage) override;
 #endif

Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.cpp (0 => 187100)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.cpp	                        (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.cpp	2015-07-21 06:06:18 UTC (rev 187100)
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2015 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 "WebKitEditorState.h"
+
+#include "EditorState.h"
+#include "WebKitEditorStatePrivate.h"
+#include <glib/gi18n-lib.h>
+
+using namespace WebKit;
+
+/**
+ * SECTION: WebKitEditorState
+ * @Short_description: Web editor state
+ * @Title: WebKitEditorState
+ * @See_also: #WebKitWebView
+ *
+ * WebKitEditorState represents the state of a #WebKitWebView editor.
+ * Use webkit_web_view_get_editor_state() to get WebKitEditorState of
+ * a #WebKitWebView.
+ *
+ * Since: 2.10
+ */
+
+enum {
+    PROP_0,
+
+    PROP_TYPING_ATTRIBUTES
+};
+
+struct _WebKitEditorStatePrivate {
+    unsigned typingAttributes;
+};
+
+WEBKIT_DEFINE_TYPE(WebKitEditorState, webkit_editor_state, G_TYPE_OBJECT)
+
+static void webkitEditorStateGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
+{
+    WebKitEditorState* editorState = WEBKIT_EDITOR_STATE(object);
+
+    switch (propId) {
+    case PROP_TYPING_ATTRIBUTES:
+        g_value_set_uint(value, webkit_editor_state_get_typing_attributes(editorState));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
+    }
+}
+
+static void webkit_editor_state_class_init(WebKitEditorStateClass* editorStateClass)
+{
+    GObjectClass* objectClass = G_OBJECT_CLASS(editorStateClass);
+    objectClass->get_property = webkitEditorStateGetProperty;
+
+    /**
+     * WebKitEditorState:typing-attributes:
+     *
+     * Bitmask of #WebKitEditorTypingAttributes flags.
+     * See webkit_editor_state_get_typing_attributes() for more information.
+     *
+     * Since: 2.10
+     */
+    g_object_class_install_property(
+        objectClass,
+        PROP_TYPING_ATTRIBUTES,
+        g_param_spec_uint(
+            "typing-attributes",
+            _("Typing Attributes"),
+            _("Flags with the typing attributes"),
+            0, G_MAXUINT, 0,
+            WEBKIT_PARAM_READABLE));
+}
+
+static void webkitEditorStateSetTypingAttributes(WebKitEditorState* editorState, unsigned typingAttributes)
+{
+    if (typingAttributes == editorState->priv->typingAttributes)
+        return;
+
+    editorState->priv->typingAttributes = typingAttributes;
+    g_object_notify(G_OBJECT(editorState), "typing-attributes");
+}
+
+WebKitEditorState* webkitEditorStateCreate(const EditorState& state)
+{
+    WebKitEditorState* editorState = WEBKIT_EDITOR_STATE(g_object_new(WEBKIT_TYPE_EDITOR_STATE, nullptr));
+    webkitEditorStateChanged(editorState, state);
+    return editorState;
+}
+
+void webkitEditorStateChanged(WebKitEditorState* editorState, const EditorState& newState)
+{
+    unsigned typingAttributes = WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE;
+    const auto& postLayoutData = newState.postLayoutData();
+    if (postLayoutData.typingAttributes & AttributeBold)
+        typingAttributes |= WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD;
+    if (postLayoutData.typingAttributes & AttributeItalics)
+        typingAttributes |= WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC;
+    if (postLayoutData.typingAttributes & AttributeUnderline)
+        typingAttributes |= WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE;
+    if (postLayoutData.typingAttributes & AttributeStrikeThrough)
+        typingAttributes |= WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH;
+    webkitEditorStateSetTypingAttributes(editorState, typingAttributes);
+}
+
+/**
+ * webkit_editor_state_get_typing_attributes:
+ * @editor_state: a #WebKitEditorState
+ *
+ * Gets the typing attributes at the current cursor position.
+ * If there is a selection, this returns the typing attributes
+ * of the the selected text. Note that in case of a selection,
+ * typing attributes are considered active only when they are
+ * present throughout the selection.
+ *
+ * Returns: a bitmask of #WebKitEditorTypingAttributes flags
+ *
+ * Since: 2.10
+ */
+guint webkit_editor_state_get_typing_attributes(WebKitEditorState* editorState)
+{
+    g_return_val_if_fail(WEBKIT_IS_EDITOR_STATE(editorState), WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE);
+
+    return editorState->priv->typingAttributes;
+}
+

Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.h (0 => 187100)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.h	                        (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitEditorState.h	2015-07-21 06:06:18 UTC (rev 187100)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__)
+#error "Only <webkit2/webkit2.h> can be included directly."
+#endif
+
+#ifndef WebKitEditorState_h
+#define WebKitEditorState_h
+
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_EDITOR_STATE            (webkit_editor_state_get_type())
+#define WEBKIT_EDITOR_STATE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_EDITOR_STATE, WebKitEditorState))
+#define WEBKIT_IS_EDITOR_STATE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_EDITOR_STATE))
+#define WEBKIT_EDITOR_STATE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),  WEBKIT_TYPE_EDITOR_STATE, WebKitEditorStateClass))
+#define WEBKIT_IS_EDITOR_STATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),  WEBKIT_TYPE_EDITOR_STATE))
+#define WEBKIT_EDITOR_STATE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),  WEBKIT_TYPE_EDITOR_STATE, WebKitEditorStateClass))
+
+typedef struct _WebKitEditorState        WebKitEditorState;
+typedef struct _WebKitEditorStateClass   WebKitEditorStateClass;
+typedef struct _WebKitEditorStatePrivate WebKitEditorStatePrivate;
+
+/**
+ * WebKitEditorTypingAttributes:
+ * @WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE: No typing attrubutes.
+ * @WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD: Bold typing attribute.
+ * @WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC: Italic typing attribute.
+ * @WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE: Underline typing attribute.
+ * @WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH: Strikethrough typing attribute.
+ *
+ * Enum values with flags representing typing attributes.
+ *
+ * Since: 2.10
+ */
+typedef enum
+{
+    WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE           = 1 << 1,
+    WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD           = 1 << 2,
+    WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC         = 1 << 3,
+    WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE      = 1 << 4,
+    WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH  = 1 << 5
+} WebKitEditorTypingAttributes;
+
+struct _WebKitEditorState {
+    GObject parent;
+
+    WebKitEditorStatePrivate *priv;
+};
+
+struct _WebKitEditorStateClass {
+    GObjectClass parent_class;
+
+    void (*_webkit_reserved0) (void);
+    void (*_webkit_reserved1) (void);
+    void (*_webkit_reserved2) (void);
+    void (*_webkit_reserved3) (void);
+};
+
+WEBKIT_API GType
+webkit_editor_state_get_type              (void);
+
+WEBKIT_API guint
+webkit_editor_state_get_typing_attributes (WebKitEditorState *editor_state);
+
+G_END_DECLS
+
+#endif

Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitEditorStatePrivate.h (0 => 187100)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitEditorStatePrivate.h	                        (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitEditorStatePrivate.h	2015-07-21 06:06:18 UTC (rev 187100)
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef WebKitEditorStatePrivate_h
+#define WebKitEditorStatePrivate_h
+
+#include "WebKitEditorState.h"
+#include "WebKitPrivate.h"
+
+WebKitEditorState* webkitEditorStateCreate(const WebKit::EditorState&);
+void webkitEditorStateChanged(WebKitEditorState*, const WebKit::EditorState&);
+
+#endif // WebKitEditorStatePrivate_h

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp (187099 => 187100)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp	2015-07-21 06:06:18 UTC (rev 187100)
@@ -35,6 +35,7 @@
 #include "WebKitContextMenuItemPrivate.h"
 #include "WebKitContextMenuPrivate.h"
 #include "WebKitDownloadPrivate.h"
+#include "WebKitEditorStatePrivate.h"
 #include "WebKitEnumTypes.h"
 #include "WebKitError.h"
 #include "WebKitFaviconDatabasePrivate.h"
@@ -185,6 +186,7 @@
     GRefPtr<WebKitUserContentManager> userContentManager;
     GRefPtr<WebKitWebContext> context;
     GRefPtr<WebKitWindowProperties> windowProperties;
+    GRefPtr<WebKitEditorState> editorState;
 
     GRefPtr<GMainLoop> modalLoop;
 
@@ -2135,6 +2137,14 @@
     return handled;
 }
 
+void webkitWebViewSelectionDidChange(WebKitWebView* webView)
+{
+    if (!webView->priv->editorState)
+        return;
+
+    webkitEditorStateChanged(webView->priv->editorState.get(), getPage(webView)->editorState());
+}
+
 /**
  * webkit_web_view_new:
  *
@@ -3649,3 +3659,23 @@
 
     g_object_notify(G_OBJECT(webView), "editable");
 }
+
+/**
+ * webkit_web_view_get_editor_state:
+ * @web_view: a #WebKitWebView
+ *
+ * Gets the web editor state of @web_view.
+ *
+ * Returns: (transfer none): the #WebKitEditorState of the view
+ *
+ * Since: 2.10
+ */
+WebKitEditorState* webkit_web_view_get_editor_state(WebKitWebView *webView)
+{
+    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), nullptr);
+
+    if (!webView->priv->editorState)
+        webView->priv->editorState = adoptGRef(webkitEditorStateCreate(getPage(webView)->editorState()));
+
+    return webView->priv->editorState.get();
+}

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h (187099 => 187100)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h	2015-07-21 06:06:18 UTC (rev 187100)
@@ -33,6 +33,7 @@
 #include <webkit2/WebKitBackForwardList.h>
 #include <webkit2/WebKitDefines.h>
 #include <webkit2/WebKitColorChooserRequest.h>
+#include <webkit2/WebKitEditorState.h>
 #include <webkit2/WebKitFileChooserRequest.h>
 #include <webkit2/WebKitFindController.h>
 #include <webkit2/WebKitFormSubmissionRequest.h>
@@ -493,6 +494,9 @@
 webkit_web_view_set_editable                         (WebKitWebView             *web_view,
                                                       gboolean                  editable);
 
+WEBKIT_API WebKitEditorState *
+webkit_web_view_get_editor_state                     (WebKitWebView             *web_view);
+
 G_END_DECLS
 
 #endif

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp (187099 => 187100)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp	2015-07-21 06:06:18 UTC (rev 187100)
@@ -1321,7 +1321,7 @@
 
 void webkitWebViewBaseUpdateTextInputState(WebKitWebViewBase* webkitWebViewBase)
 {
-    webkitWebViewBase->priv->inputMethodFilter.setCursorRect(webkitWebViewBase->priv->pageProxy->editorState().cursorRect);
+    webkitWebViewBase->priv->inputMethodFilter.setCursorRect(webkitWebViewBase->priv->pageProxy->editorState().postLayoutData().caretRectAtStart);
 }
 
 void webkitWebViewBaseResetClickCounter(WebKitWebViewBase* webkitWebViewBase)

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h (187099 => 187100)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewPrivate.h	2015-07-21 06:06:18 UTC (rev 187100)
@@ -62,5 +62,6 @@
 bool webkitWebViewEmitRunColorChooser(WebKitWebView*, WebKitColorChooserRequest*);
 void webkitWebViewWebProcessCrashed(WebKitWebView*);
 void webkitWebViewIsPlayingAudioChanged(WebKitWebView*);
+void webkitWebViewSelectionDidChange(WebKitWebView*);
 
 #endif // WebKitWebViewPrivate_h

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt (187099 => 187100)


--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt	2015-07-21 06:06:18 UTC (rev 187100)
@@ -205,6 +205,7 @@
 webkit_web_view_get_background_color
 webkit_web_view_set_editable
 webkit_web_view_is_editable
+webkit_web_view_get_editor_state
 
 <SUBSECTION WebKitJavascriptResult>
 WebKitJavascriptResult
@@ -763,6 +764,26 @@
 </SECTION>
 
 <SECTION>
+<FILE>WebKitEditorState</FILE>
+WebKitEditorState
+WebKitEditorTypingAttributes
+webkit_editor_state_get_typing_attributes
+
+<SUBSECTION Standard>
+WebKitEditorStateClass
+WEBKIT_TYPE_EDITOR_STATE
+WEBKIT_EDITOR_STATE
+WEBKIT_IS_EDITOR_STATE
+WEBKIT_EDITOR_STATE_CLASS
+WEBKIT_IS_EDITOR_STATE_CLASS
+WEBKIT_EDITOR_STATE_GET_CLASS
+
+<SUBSECTION Private>
+WebKitEditorStatePrivate
+webkit_editor_state_get_type
+</SECTION>
+
+<SECTION>
 <FILE>WebKitPrintOperation</FILE>
 WebKitPrintOperation
 WebKitPrintOperationResponse

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0.types (187099 => 187100)


--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0.types	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0.types	2015-07-21 06:06:18 UTC (rev 187100)
@@ -30,3 +30,4 @@
 webkit_user_content_manager_get_type
 webkit_web_hit_test_result_get_type
 webkit_website_data_manager_get_type
+webkit_editor_state_get_type

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml (187099 => 187100)


--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml	2015-07-21 06:06:18 UTC (rev 187100)
@@ -29,6 +29,7 @@
     <xi:include href=""
     <xi:include href=""
     <xi:include href=""
+    <xi:include href=""
     <xi:include href=""
     <xi:include href=""
     <xi:include href=""

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/webkit2.h (187099 => 187100)


--- trunk/Source/WebKit2/UIProcess/API/gtk/webkit2.h	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/webkit2.h	2015-07-21 06:06:18 UTC (rev 187100)
@@ -38,6 +38,7 @@
 #include <webkit2/WebKitDefines.h>
 #include <webkit2/WebKitDownload.h>
 #include <webkit2/WebKitEditingCommands.h>
+#include <webkit2/WebKitEditorState.h>
 #include <webkit2/WebKitEnumTypes.h>
 #include <webkit2/WebKitError.h>
 #include <webkit2/WebKitFaviconDatabase.h>

Modified: trunk/Source/WebKit2/UIProcess/PageClient.h (187099 => 187100)


--- trunk/Source/WebKit2/UIProcess/PageClient.h	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/UIProcess/PageClient.h	2015-07-21 06:06:18 UTC (rev 187100)
@@ -145,9 +145,9 @@
     virtual void didFindZoomableArea(const WebCore::IntPoint&, const WebCore::IntRect&) = 0;
 #endif
 
-#if PLATFORM(EFL) || PLATFORM(GTK)
+#if PLATFORM(EFL)
     virtual void updateTextInputState() = 0;
-#endif // PLATFORM(EFL) || PLATOFRM(GTK)
+#endif // PLATFORM(EFL)
 
     virtual void handleDownloadRequest(DownloadProxy*) = 0;
 
@@ -179,6 +179,9 @@
     virtual LayerOrView *acceleratedCompositingRootLayer() const = 0;
     virtual PassRefPtr<ViewSnapshot> takeViewSnapshot() = 0;
     virtual void wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent&) = 0;
+#endif
+
+#if PLATFORM(COCOA) || PLATFORM(GTK)
     virtual void selectionDidChange() = 0;
 #endif
 

Modified: trunk/Source/WebKit2/UIProcess/gtk/WebPageProxyGtk.cpp (187099 => 187100)


--- trunk/Source/WebKit2/UIProcess/gtk/WebPageProxyGtk.cpp	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/UIProcess/gtk/WebPageProxyGtk.cpp	2015-07-21 06:06:18 UTC (rev 187100)
@@ -73,7 +73,7 @@
     
     if (editorState.shouldIgnoreCompositionSelectionChange)
         return;
-    m_pageClient.updateTextInputState();
+    m_pageClient.selectionDidChange();
 }
 
 #if PLUGIN_ARCHITECTURE(X11)

Modified: trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp (187099 => 187100)


--- trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp	2015-07-21 06:06:18 UTC (rev 187100)
@@ -68,9 +68,40 @@
 {
 }
 
-void WebPage::platformEditorState(Frame& frame, EditorState& result, IncludePostLayoutDataHint) const
+void WebPage::platformEditorState(Frame& frame, EditorState& result, IncludePostLayoutDataHint shouldIncludePostLayoutData) const
 {
-    result.cursorRect = frame.selection().absoluteCaretBounds();
+    if (shouldIncludePostLayoutData == IncludePostLayoutDataHint::No) {
+        result.isMissingPostLayoutData = true;
+        return;
+    }
+
+    auto& postLayoutData = result.postLayoutData();
+    postLayoutData.caretRectAtStart = frame.selection().absoluteCaretBounds();
+
+    const VisibleSelection& selection = frame.selection().selection();
+    if (selection.isNone())
+        return;
+
+    const Editor& editor = frame.editor();
+    if (selection.isRange()) {
+        if (editor.selectionHasStyle(CSSPropertyFontWeight, "bold") == TrueTriState)
+            postLayoutData.typingAttributes |= AttributeBold;
+        if (editor.selectionHasStyle(CSSPropertyFontStyle, "italic") == TrueTriState)
+            postLayoutData.typingAttributes |= AttributeItalics;
+        if (editor.selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline") == TrueTriState)
+            postLayoutData.typingAttributes |= AttributeUnderline;
+        if (editor.selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "line-through") == TrueTriState)
+            postLayoutData.typingAttributes |= AttributeStrikeThrough;
+    } else if (selection.isCaret()) {
+        if (editor.selectionStartHasStyle(CSSPropertyFontWeight, "bold"))
+            postLayoutData.typingAttributes |= AttributeBold;
+        if (editor.selectionStartHasStyle(CSSPropertyFontStyle, "italic"))
+            postLayoutData.typingAttributes |= AttributeItalics;
+        if (editor.selectionStartHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline"))
+            postLayoutData.typingAttributes |= AttributeUnderline;
+        if (editor.selectionStartHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "line-through"))
+            postLayoutData.typingAttributes |= AttributeStrikeThrough;
+    }
 }
 
 #if HAVE(ACCESSIBILITY)

Modified: trunk/Tools/ChangeLog (187099 => 187100)


--- trunk/Tools/ChangeLog	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Tools/ChangeLog	2015-07-21 06:06:18 UTC (rev 187100)
@@ -1,3 +1,24 @@
+2015-07-20  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Add API to be notified about editor state changes
+        https://bugs.webkit.org/show_bug.cgi?id=145875
+
+        Reviewed by Gustavo Noronha Silva.
+
+        Update the typing attributes toggle buttons state according to the
+        editor state in MiniBrowser, and add a test case to the
+        WebViewEditor unit tests.
+
+        * MiniBrowser/gtk/BrowserWindow.c:
+        (browserWindowEditingCommandToggleButtonSetActive):
+        (typingAttributesChanged):
+        (browserWindowSetupEditorToolbar):
+        (browserWindowConstructed):
+        (browser_window_init):
+        * TestWebKitAPI/Tests/WebKit2Gtk/TestWebViewEditor.cpp:
+        (testWebViewEditorEditorStateTypingAttributes):
+        (beforeAll):
+
 2015-07-20  Tomas Popela  <[email protected]>
 
         [GTK] Add selection-changed signal to the WebKit2 API

Modified: trunk/Tools/MiniBrowser/gtk/BrowserWindow.c (187099 => 187100)


--- trunk/Tools/MiniBrowser/gtk/BrowserWindow.c	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Tools/MiniBrowser/gtk/BrowserWindow.c	2015-07-21 06:06:18 UTC (rev 187100)
@@ -53,6 +53,10 @@
     GtkWidget *forwardItem;
     GtkWidget *zoomInItem;
     GtkWidget *zoomOutItem;
+    GtkWidget *boldItem;
+    GtkWidget *italicItem;
+    GtkWidget *underlineItem;
+    GtkWidget *strikethroughItem;
     GtkWidget *statusLabel;
     GtkWidget *settingsDialog;
     WebKitWebView *webView;
@@ -696,7 +700,22 @@
     webkit_web_view_execute_editing_command(window->webView, gtk_widget_get_name(widget));
 }
 
+static void browserWindowEditingCommandToggleButtonSetActive(BrowserWindow *window, GtkWidget *button, gboolean active)
+{
+    g_signal_handlers_block_by_func(button, G_CALLBACK(editingCommandCallback), window);
+    gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(button), active);
+    g_signal_handlers_unblock_by_func(button, G_CALLBACK(editingCommandCallback), window);
+}
 
+static void typingAttributesChanged(WebKitEditorState *editorState, GParamSpec *spec, BrowserWindow *window)
+{
+    unsigned typingAttributes = webkit_editor_state_get_typing_attributes(editorState);
+    browserWindowEditingCommandToggleButtonSetActive(window, window->boldItem, typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD);
+    browserWindowEditingCommandToggleButtonSetActive(window, window->italicItem, typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC);
+    browserWindowEditingCommandToggleButtonSetActive(window, window->underlineItem, typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE);
+    browserWindowEditingCommandToggleButtonSetActive(window, window->strikethroughItem, typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH);
+}
+
 static void browserWindowFinalize(GObject *gObject)
 {
     BrowserWindow *window = BROWSER_WINDOW(gObject);
@@ -755,18 +774,21 @@
     gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH_HORIZ);
 
     GtkToolItem *item = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_BOLD);
+    window->boldItem = item;
     gtk_widget_set_name(GTK_WIDGET(item), "Bold");
     g_signal_connect(G_OBJECT(item), "toggled", G_CALLBACK(editingCommandCallback), window);
     gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
     gtk_widget_show(GTK_WIDGET(item));
 
     item = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_ITALIC);
+    window->italicItem = item;
     gtk_widget_set_name(GTK_WIDGET(item), "Italic");
     g_signal_connect(G_OBJECT(item), "toggled", G_CALLBACK(editingCommandCallback), window);
     gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
     gtk_widget_show(GTK_WIDGET(item));
 
     item = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_UNDERLINE);
+    window->underlineItem = item;
     gtk_widget_set_name(GTK_WIDGET(item), "Underline");
     g_signal_connect(G_OBJECT(item), "toggled", G_CALLBACK(editingCommandCallback), window);
     gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
@@ -774,6 +796,7 @@
 
     item = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_STRIKETHROUGH);
     gtk_widget_set_name(GTK_WIDGET(item), "Strikethrough");
+    window->strikethroughItem = item;
     g_signal_connect(G_OBJECT(item), "toggled", G_CALLBACK(editingCommandCallback), window);
     gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
     gtk_widget_show(GTK_WIDGET(item));
@@ -1004,8 +1027,10 @@
     BrowserWindow *window = BROWSER_WINDOW(gObject);
 
     browserWindowUpdateZoomActions(window);
-    if (webkit_web_view_is_editable(window->webView))
+    if (webkit_web_view_is_editable(window->webView)) {
         browserWindowSetupEditorToolbar(window);
+        g_signal_connect(webkit_web_view_get_editor_state(window->webView), "notify::typing-attributes", G_CALLBACK(typingAttributesChanged), window);
+    }
 
     g_signal_connect(window->webView, "notify::uri", G_CALLBACK(webViewURIChanged), window);
     g_signal_connect(window->webView, "notify::estimated-load-progress", G_CALLBACK(webViewLoadProgressChanged), window);

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebViewEditor.cpp (187099 => 187100)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebViewEditor.cpp	2015-07-21 05:56:40 UTC (rev 187099)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestWebViewEditor.cpp	2015-07-21 06:06:18 UTC (rev 187100)
@@ -32,6 +32,7 @@
         : m_clipboard(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD))
         , m_canExecuteEditingCommand(false)
         , m_triesCount(0)
+        , m_editorState(nullptr)
     {
         gtk_clipboard_clear(m_clipboard);
     }
@@ -85,12 +86,41 @@
         g_timeout_add(kClipboardWaitTimeout, reinterpret_cast<GSourceFunc>(waitForClipboardText), this);
         g_main_loop_run(m_mainLoop);
 
-        return gtk_clipboard_wait_for_text (m_clipboard);
+        return gtk_clipboard_wait_for_text(m_clipboard);
     }
 
+    WebKitEditorState* editorState()
+    {
+        if (m_editorState)
+            return m_editorState;
+
+        m_editorState = webkit_web_view_get_editor_state(m_webView);
+        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_editorState));
+        return m_editorState;
+    }
+
+    static void quitMainLoopInCallback(EditorTest* test)
+    {
+        g_main_loop_quit(test->m_mainLoop);
+    }
+
+    unsigned typingAttributes()
+    {
+        return webkit_editor_state_get_typing_attributes(editorState());
+    }
+
+    unsigned waitUntilTypingAttributesChanged()
+    {
+        unsigned long handlerID = g_signal_connect_swapped(editorState(), "notify::typing-attributes", G_CALLBACK(quitMainLoopInCallback), this);
+        g_main_loop_run(m_mainLoop);
+        g_signal_handler_disconnect(m_editorState, handlerID);
+        return typingAttributes();
+    }
+
     GtkClipboard* m_clipboard;
     bool m_canExecuteEditingCommand;
     size_t m_triesCount;
+    WebKitEditorState* m_editorState;
 };
 
 static const char* selectedSpanHTMLFormat =
@@ -255,6 +285,122 @@
     loadContentsAndTryToCutSelection(test, false);
 }
 
+static void testWebViewEditorEditorStateTypingAttributes(EditorTest* test, gconstpointer)
+{
+    static const char* typingAttributesHTML =
+        "<html><body>"
+        "normal <b>bold </b><i>italic </i><u>underline </u><strike>strike </strike>"
+        "<b><i>boldanditalic </i></b>"
+        "</body></html>";
+
+    test->loadHtml(typingAttributesHTML, nullptr);
+    test->waitUntilLoadFinished();
+    test->setEditable(true);
+
+    unsigned typingAttributes = test->typingAttributes();
+    g_assert_cmpuint(typingAttributes, ==, WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE);
+
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    typingAttributes = test->waitUntilTypingAttributesChanged();
+    g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD);
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC));
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
+
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    typingAttributes = test->waitUntilTypingAttributesChanged();
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD));
+    g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC);
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
+
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    typingAttributes = test->waitUntilTypingAttributesChanged();
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD));
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC));
+    g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE);
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
+
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    typingAttributes = test->waitUntilTypingAttributesChanged();
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD));
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC));
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
+    g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH);
+
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    typingAttributes = test->waitUntilTypingAttributesChanged();
+    g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD);
+    g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC);
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
+
+    // Selections.
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveToBeginningOfDocument");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection");
+    typingAttributes = test->waitUntilTypingAttributesChanged();
+    g_assert_cmpuint(typingAttributes, ==, WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE);
+
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection");
+    typingAttributes = test->waitUntilTypingAttributesChanged();
+    g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD);
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC));
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
+
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection");
+    typingAttributes = test->waitUntilTypingAttributesChanged();
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD));
+    g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC);
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
+
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection");
+    typingAttributes = test->waitUntilTypingAttributesChanged();
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD));
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC));
+    g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE);
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
+
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection");
+    typingAttributes = test->waitUntilTypingAttributesChanged();
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD));
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC));
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
+    g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH);
+
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
+    webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection");
+    typingAttributes = test->waitUntilTypingAttributesChanged();
+    g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD);
+    g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC);
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
+    g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
+
+    webkit_web_view_execute_editing_command(test->m_webView, "SelectAll");
+    typingAttributes = test->waitUntilTypingAttributesChanged();
+    g_assert_cmpuint(typingAttributes, ==, WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE);
+}
+
 void beforeAll()
 {
     EditorTest::add("WebKitWebView", "editable/editable", testWebViewEditorEditable);
@@ -262,6 +408,7 @@
     EditorTest::add("WebKitWebView", "cut-copy-paste/editable", testWebViewEditorCutCopyPasteEditable);
     EditorTest::add("WebKitWebView", "select-all/non-editable", testWebViewEditorSelectAllNonEditable);
     EditorTest::add("WebKitWebView", "select-all/editable", testWebViewEditorSelectAllEditable);
+    EditorTest::add("WebKitWebView", "editor-state/typing-attributes", testWebViewEditorEditorStateTypingAttributes);
 }
 
 void afterAll()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to