~mmach/netext73/webkit2gtk

« back to all changes in this revision

Viewing changes to Source/WebKit/WebProcess/WebPage/glib/WebPageGLib.cpp

  • Committer: mmach
  • Date: 2023-06-16 17:21:37 UTC
  • Revision ID: netbit73@gmail.com-20230616172137-2rqx6yr96ga9g3kp
1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2019 Igalia S.L.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions
 
6
 * are met:
 
7
 * 1. Redistributions of source code must retain the above copyright
 
8
 *    notice, this list of conditions and the following disclaimer.
 
9
 * 2. Redistributions in binary form must reproduce the above copyright
 
10
 *    notice, this list of conditions and the following disclaimer in the
 
11
 *    documentation and/or other materials provided with the distribution.
 
12
 *
 
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 
14
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 
15
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
16
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 
17
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
19
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
20
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
21
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
22
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 
23
 * THE POSSIBILITY OF SUCH DAMAGE.
 
24
 */
 
25
 
 
26
#include "config.h"
 
27
#include "WebPage.h"
 
28
 
 
29
#include "EditorState.h"
 
30
#include "InputMethodState.h"
 
31
#include "UserMessage.h"
 
32
#include "WebKitExtensionManager.h"
 
33
#include "WebKitUserMessage.h"
 
34
#include "WebKitWebExtension.h"
 
35
#include "WebKitWebPagePrivate.h"
 
36
#include "WebPageProxyMessages.h"
 
37
#include <WebCore/Editor.h>
 
38
#include <WebCore/Frame.h>
 
39
#include <WebCore/FrameView.h>
 
40
#include <WebCore/HTMLInputElement.h>
 
41
#include <WebCore/HTMLTextAreaElement.h>
 
42
#include <WebCore/TextIterator.h>
 
43
#include <WebCore/VisiblePosition.h>
 
44
#include <WebCore/VisibleUnits.h>
 
45
 
 
46
namespace WebKit {
 
47
using namespace WebCore;
 
48
 
 
49
void WebPage::sendMessageToWebExtensionWithReply(UserMessage&& message, CompletionHandler<void(UserMessage&&)>&& completionHandler)
 
50
{
 
51
    auto* extension = WebKitExtensionManager::singleton().extension();
 
52
    if (!extension) {
 
53
        completionHandler(UserMessage(message.name, WEBKIT_USER_MESSAGE_UNHANDLED_MESSAGE));
 
54
        return;
 
55
    }
 
56
 
 
57
    auto* page = webkit_web_extension_get_page(extension, m_identifier.toUInt64());
 
58
    if (!page) {
 
59
        completionHandler(UserMessage(message.name, WEBKIT_USER_MESSAGE_UNHANDLED_MESSAGE));
 
60
        return;
 
61
    }
 
62
 
 
63
    webkitWebPageDidReceiveUserMessage(page, WTFMove(message), WTFMove(completionHandler));
 
64
}
 
65
 
 
66
void WebPage::sendMessageToWebExtension(UserMessage&& message)
 
67
{
 
68
    sendMessageToWebExtensionWithReply(WTFMove(message), [](UserMessage&&) { });
 
69
}
 
70
 
 
71
void WebPage::platformEditorState(Frame& frame, EditorState& result, IncludePostLayoutDataHint shouldIncludePostLayoutData) const
 
72
{
 
73
    if (shouldIncludePostLayoutData == IncludePostLayoutDataHint::No || !frame.view() || frame.view()->needsLayout()) {
 
74
        result.isMissingPostLayoutData = true;
 
75
        return;
 
76
    }
 
77
 
 
78
    auto& postLayoutData = result.postLayoutData();
 
79
    postLayoutData.caretRectAtStart = frame.selection().absoluteCaretBounds();
 
80
 
 
81
    const VisibleSelection& selection = frame.selection().selection();
 
82
    if (selection.isNone())
 
83
        return;
 
84
 
 
85
#if PLATFORM(GTK)
 
86
    const Editor& editor = frame.editor();
 
87
    if (selection.isRange()) {
 
88
        if (editor.selectionHasStyle(CSSPropertyFontWeight, "bold") == TrueTriState)
 
89
            postLayoutData.typingAttributes |= AttributeBold;
 
90
        if (editor.selectionHasStyle(CSSPropertyFontStyle, "italic") == TrueTriState)
 
91
            postLayoutData.typingAttributes |= AttributeItalics;
 
92
        if (editor.selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline") == TrueTriState)
 
93
            postLayoutData.typingAttributes |= AttributeUnderline;
 
94
        if (editor.selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "line-through") == TrueTriState)
 
95
            postLayoutData.typingAttributes |= AttributeStrikeThrough;
 
96
    } else if (selection.isCaret()) {
 
97
        if (editor.selectionStartHasStyle(CSSPropertyFontWeight, "bold"))
 
98
            postLayoutData.typingAttributes |= AttributeBold;
 
99
        if (editor.selectionStartHasStyle(CSSPropertyFontStyle, "italic"))
 
100
            postLayoutData.typingAttributes |= AttributeItalics;
 
101
        if (editor.selectionStartHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline"))
 
102
            postLayoutData.typingAttributes |= AttributeUnderline;
 
103
        if (editor.selectionStartHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "line-through"))
 
104
            postLayoutData.typingAttributes |= AttributeStrikeThrough;
 
105
    }
 
106
#endif
 
107
 
 
108
    if (selection.isContentEditable()) {
 
109
        auto selectionStart = selection.visibleStart();
 
110
        auto surroundingStart = startOfEditableContent(selectionStart);
 
111
        auto surroundingEnd = endOfEditableContent(selectionStart);
 
112
        auto surroundingRange = makeRange(surroundingStart, surroundingEnd);
 
113
        auto compositionRange = frame.editor().compositionRange();
 
114
        if (compositionRange && surroundingRange->contains(*compositionRange)) {
 
115
            auto clonedRange = surroundingRange->cloneRange();
 
116
            surroundingRange->setEnd(compositionRange->startPosition());
 
117
            clonedRange->setStart(compositionRange->endPosition());
 
118
            postLayoutData.surroundingContext = plainText(surroundingRange.get()) + plainText(clonedRange.ptr());
 
119
            postLayoutData.surroundingContextCursorPosition = TextIterator::rangeLength(surroundingRange.get());
 
120
            postLayoutData.surroundingContextSelectionPosition = postLayoutData.surroundingContextCursorPosition;
 
121
        } else {
 
122
            postLayoutData.surroundingContext = plainText(surroundingRange.get());
 
123
            postLayoutData.surroundingContextCursorPosition = TextIterator::rangeLength(makeRange(surroundingStart, selectionStart).get());
 
124
            postLayoutData.surroundingContextSelectionPosition = TextIterator::rangeLength(makeRange(surroundingStart, selection.visibleEnd()).get());
 
125
        }
 
126
    }
 
127
}
 
128
 
 
129
static Optional<InputMethodState> inputMethodSateForElement(Element* element)
 
130
{
 
131
    if (!element || !element->shouldUseInputMethod())
 
132
        return WTF::nullopt;
 
133
 
 
134
    InputMethodState state;
 
135
    if (is<HTMLInputElement>(*element)) {
 
136
        auto& inputElement = downcast<HTMLInputElement>(*element);
 
137
        state.setPurposeForInputElement(inputElement);
 
138
        state.addHintsForAutocapitalizeType(inputElement.autocapitalizeType());
 
139
    } else if (is<HTMLTextAreaElement>(*element) || (element->hasEditableStyle() && is<HTMLElement>(*element))) {
 
140
        auto& htmlElement = downcast<HTMLElement>(*element);
 
141
        state.setPurposeOrHintForInputMode(htmlElement.canonicalInputMode());
 
142
        state.addHintsForAutocapitalizeType(htmlElement.autocapitalizeType());
 
143
    }
 
144
 
 
145
    if (element->isSpellCheckingEnabled())
 
146
        state.hints.add(InputMethodState::Hint::Spellcheck);
 
147
 
 
148
    return state;
 
149
}
 
150
 
 
151
void WebPage::setInputMethodState(Element* element)
 
152
{
 
153
    auto state = inputMethodSateForElement(element);
 
154
    if (m_inputMethodState == state)
 
155
        return;
 
156
 
 
157
    m_inputMethodState = state;
 
158
    send(Messages::WebPageProxy::SetInputMethodState(state));
 
159
}
 
160
 
 
161
} // namespace WebKit