1 | /* |
2 | * Copyright (C) 2010 Apple Inc. All rights reserved. |
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 "InjectedBundlePageEditorClient.h" |
28 | |
29 | #include "APIArray.h" |
30 | #include "APIData.h" |
31 | #include "InjectedBundleCSSStyleDeclarationHandle.h" |
32 | #include "InjectedBundleNodeHandle.h" |
33 | #include "InjectedBundleRangeHandle.h" |
34 | #include "WKAPICast.h" |
35 | #include "WKBundleAPICast.h" |
36 | #include "WKData.h" |
37 | #include "WKRetainPtr.h" |
38 | #include "WKString.h" |
39 | #include "WebPage.h" |
40 | #include <WebCore/DocumentFragment.h> |
41 | #include <wtf/text/WTFString.h> |
42 | |
43 | namespace WebKit { |
44 | using namespace WebCore; |
45 | |
46 | InjectedBundlePageEditorClient::InjectedBundlePageEditorClient(const WKBundlePageEditorClientBase& client) |
47 | { |
48 | initialize(&client); |
49 | } |
50 | |
51 | bool InjectedBundlePageEditorClient::shouldBeginEditing(WebPage& page, Range* range) |
52 | { |
53 | if (m_client.shouldBeginEditing) { |
54 | RefPtr<InjectedBundleRangeHandle> rangeHandle = InjectedBundleRangeHandle::getOrCreate(range); |
55 | return m_client.shouldBeginEditing(toAPI(&page), toAPI(rangeHandle.get()), m_client.base.clientInfo); |
56 | } |
57 | return true; |
58 | } |
59 | |
60 | bool InjectedBundlePageEditorClient::shouldEndEditing(WebPage& page, Range* range) |
61 | { |
62 | if (m_client.shouldEndEditing) { |
63 | RefPtr<InjectedBundleRangeHandle> rangeHandle = InjectedBundleRangeHandle::getOrCreate(range); |
64 | return m_client.shouldEndEditing(toAPI(&page), toAPI(rangeHandle.get()), m_client.base.clientInfo); |
65 | } |
66 | return true; |
67 | } |
68 | |
69 | bool InjectedBundlePageEditorClient::shouldInsertNode(WebPage& page, Node* node, Range* rangeToReplace, EditorInsertAction action) |
70 | { |
71 | if (m_client.shouldInsertNode) { |
72 | RefPtr<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::getOrCreate(node); |
73 | RefPtr<InjectedBundleRangeHandle> rangeToReplaceHandle = InjectedBundleRangeHandle::getOrCreate(rangeToReplace); |
74 | return m_client.shouldInsertNode(toAPI(&page), toAPI(nodeHandle.get()), toAPI(rangeToReplaceHandle.get()), toAPI(action), m_client.base.clientInfo); |
75 | } |
76 | return true; |
77 | } |
78 | |
79 | bool InjectedBundlePageEditorClient::shouldInsertText(WebPage& page, StringImpl* text, Range* rangeToReplace, EditorInsertAction action) |
80 | { |
81 | if (m_client.shouldInsertText) { |
82 | RefPtr<InjectedBundleRangeHandle> rangeToReplaceHandle = InjectedBundleRangeHandle::getOrCreate(rangeToReplace); |
83 | return m_client.shouldInsertText(toAPI(&page), toAPI(text), toAPI(rangeToReplaceHandle.get()), toAPI(action), m_client.base.clientInfo); |
84 | } |
85 | return true; |
86 | } |
87 | |
88 | bool InjectedBundlePageEditorClient::shouldDeleteRange(WebPage& page, Range* range) |
89 | { |
90 | if (m_client.shouldDeleteRange) { |
91 | RefPtr<InjectedBundleRangeHandle> rangeHandle = InjectedBundleRangeHandle::getOrCreate(range); |
92 | return m_client.shouldDeleteRange(toAPI(&page), toAPI(rangeHandle.get()), m_client.base.clientInfo); |
93 | } |
94 | return true; |
95 | } |
96 | |
97 | bool InjectedBundlePageEditorClient::shouldChangeSelectedRange(WebPage& page, Range* fromRange, Range* toRange, EAffinity affinity, bool stillSelecting) |
98 | { |
99 | if (m_client.shouldChangeSelectedRange) { |
100 | RefPtr<InjectedBundleRangeHandle> fromRangeHandle = InjectedBundleRangeHandle::getOrCreate(fromRange); |
101 | RefPtr<InjectedBundleRangeHandle> toRangeHandle = InjectedBundleRangeHandle::getOrCreate(toRange); |
102 | return m_client.shouldChangeSelectedRange(toAPI(&page), toAPI(fromRangeHandle.get()), toAPI(toRangeHandle.get()), toAPI(affinity), stillSelecting, m_client.base.clientInfo); |
103 | } |
104 | return true; |
105 | } |
106 | |
107 | bool InjectedBundlePageEditorClient::shouldApplyStyle(WebPage& page, CSSStyleDeclaration* style, Range* range) |
108 | { |
109 | if (m_client.shouldApplyStyle) { |
110 | RefPtr<InjectedBundleCSSStyleDeclarationHandle> styleHandle = InjectedBundleCSSStyleDeclarationHandle::getOrCreate(style); |
111 | RefPtr<InjectedBundleRangeHandle> rangeHandle = InjectedBundleRangeHandle::getOrCreate(range); |
112 | return m_client.shouldApplyStyle(toAPI(&page), toAPI(styleHandle.get()), toAPI(rangeHandle.get()), m_client.base.clientInfo); |
113 | } |
114 | return true; |
115 | } |
116 | |
117 | void InjectedBundlePageEditorClient::didBeginEditing(WebPage& page, StringImpl* notificationName) |
118 | { |
119 | if (m_client.didBeginEditing) |
120 | m_client.didBeginEditing(toAPI(&page), toAPI(notificationName), m_client.base.clientInfo); |
121 | } |
122 | |
123 | void InjectedBundlePageEditorClient::didEndEditing(WebPage& page, StringImpl* notificationName) |
124 | { |
125 | if (m_client.didEndEditing) |
126 | m_client.didEndEditing(toAPI(&page), toAPI(notificationName), m_client.base.clientInfo); |
127 | } |
128 | |
129 | void InjectedBundlePageEditorClient::didChange(WebPage& page, StringImpl* notificationName) |
130 | { |
131 | if (m_client.didChange) |
132 | m_client.didChange(toAPI(&page), toAPI(notificationName), m_client.base.clientInfo); |
133 | } |
134 | |
135 | void InjectedBundlePageEditorClient::didChangeSelection(WebPage& page, StringImpl* notificationName) |
136 | { |
137 | if (m_client.didChangeSelection) |
138 | m_client.didChangeSelection(toAPI(&page), toAPI(notificationName), m_client.base.clientInfo); |
139 | } |
140 | |
141 | void InjectedBundlePageEditorClient::willWriteToPasteboard(WebPage& page, Range* range) |
142 | { |
143 | if (m_client.willWriteToPasteboard) { |
144 | RefPtr<InjectedBundleRangeHandle> rangeHandle = InjectedBundleRangeHandle::getOrCreate(range); |
145 | m_client.willWriteToPasteboard(toAPI(&page), toAPI(rangeHandle.get()), m_client.base.clientInfo); |
146 | } |
147 | } |
148 | |
149 | void InjectedBundlePageEditorClient::getPasteboardDataForRange(WebPage& page, Range* range, Vector<String>& pasteboardTypes, Vector<RefPtr<SharedBuffer>>& pasteboardData) |
150 | { |
151 | if (m_client.getPasteboardDataForRange) { |
152 | RefPtr<InjectedBundleRangeHandle> rangeHandle = InjectedBundleRangeHandle::getOrCreate(range); |
153 | WKArrayRef types = 0; |
154 | WKArrayRef data = 0; |
155 | m_client.getPasteboardDataForRange(toAPI(&page), toAPI(rangeHandle.get()), &types, &data, m_client.base.clientInfo); |
156 | RefPtr<API::Array> typesArray = adoptRef(toImpl(types)); |
157 | RefPtr<API::Array> dataArray = adoptRef(toImpl(data)); |
158 | |
159 | pasteboardTypes.clear(); |
160 | pasteboardData.clear(); |
161 | |
162 | if (!typesArray || !dataArray) |
163 | return; |
164 | |
165 | ASSERT(typesArray->size() == dataArray->size()); |
166 | |
167 | for (auto type : typesArray->elementsOfType<API::String>()) |
168 | pasteboardTypes.append(type->string()); |
169 | |
170 | for (auto item : dataArray->elementsOfType<API::Data>()) { |
171 | auto buffer = SharedBuffer::create(item->bytes(), item->size()); |
172 | pasteboardData.append(WTFMove(buffer)); |
173 | } |
174 | } |
175 | } |
176 | |
177 | bool InjectedBundlePageEditorClient::performTwoStepDrop(WebPage& page, DocumentFragment& fragment, Range& destination, bool isMove) |
178 | { |
179 | if (!m_client.performTwoStepDrop) |
180 | return false; |
181 | |
182 | auto rangeHandle = InjectedBundleRangeHandle::getOrCreate(&destination); |
183 | auto nodeHandle = InjectedBundleNodeHandle::getOrCreate(&fragment); |
184 | return m_client.performTwoStepDrop(toAPI(&page), toAPI(nodeHandle.get()), toAPI(rangeHandle.get()), isMove, m_client.base.clientInfo); |
185 | } |
186 | |
187 | void InjectedBundlePageEditorClient::didWriteToPasteboard(WebPage& page) |
188 | { |
189 | if (m_client.didWriteToPasteboard) |
190 | m_client.didWriteToPasteboard(toAPI(&page), m_client.base.clientInfo); |
191 | } |
192 | |
193 | } // namespace WebKit |
194 | |