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
43namespace WebKit {
44using namespace WebCore;
45
46InjectedBundlePageEditorClient::InjectedBundlePageEditorClient(const WKBundlePageEditorClientBase& client)
47{
48 initialize(&client);
49}
50
51bool 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
60bool 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
69bool 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
79bool 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
88bool 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
97bool 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
107bool 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
117void 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
123void 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
129void 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
135void 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
141void 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
149void 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
177bool 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
187void 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