[iOS] Paste is missing from callout bar when pasteboard only contains custom data
[WebKit-https.git] / Source / WebKit / Shared / EditorState.cpp
1 /*
2  * Copyright (C) 2010, 2011 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 "EditorState.h"
28
29 #include "WebCoreArgumentCoders.h"
30 #include <wtf/text/TextStream.h>
31
32 using namespace WebCore;
33
34 namespace WebKit {
35
36 void EditorState::encode(IPC::Encoder& encoder) const
37 {
38     encoder << shouldIgnoreSelectionChanges;
39     encoder << selectionIsNone;
40     encoder << selectionIsRange;
41     encoder << isContentEditable;
42     encoder << isContentRichlyEditable;
43     encoder << isInPasswordField;
44     encoder << isInPlugin;
45     encoder << hasComposition;
46     encoder << isMissingPostLayoutData;
47
48     if (!isMissingPostLayoutData)
49         m_postLayoutData.encode(encoder);
50
51 #if PLATFORM(IOS)
52     encoder << firstMarkedRect;
53     encoder << lastMarkedRect;
54     encoder << markedText;
55 #endif
56
57     encoder << originIdentifierForPasteboard;
58 }
59
60 bool EditorState::decode(IPC::Decoder& decoder, EditorState& result)
61 {
62     if (!decoder.decode(result.shouldIgnoreSelectionChanges))
63         return false;
64
65     if (!decoder.decode(result.selectionIsNone))
66         return false;
67
68     if (!decoder.decode(result.selectionIsRange))
69         return false;
70
71     if (!decoder.decode(result.isContentEditable))
72         return false;
73
74     if (!decoder.decode(result.isContentRichlyEditable))
75         return false;
76
77     if (!decoder.decode(result.isInPasswordField))
78         return false;
79
80     if (!decoder.decode(result.isInPlugin))
81         return false;
82
83     if (!decoder.decode(result.hasComposition))
84         return false;
85
86     if (!decoder.decode(result.isMissingPostLayoutData))
87         return false;
88
89     if (!result.isMissingPostLayoutData) {
90         if (!PostLayoutData::decode(decoder, result.postLayoutData()))
91             return false;
92     }
93
94 #if PLATFORM(IOS)
95     if (!decoder.decode(result.firstMarkedRect))
96         return false;
97     if (!decoder.decode(result.lastMarkedRect))
98         return false;
99     if (!decoder.decode(result.markedText))
100         return false;
101 #endif
102
103     if (!decoder.decode(result.originIdentifierForPasteboard))
104         return false;
105
106     return true;
107 }
108
109 void EditorState::PostLayoutData::encode(IPC::Encoder& encoder) const
110 {
111     encoder << typingAttributes;
112 #if PLATFORM(IOS) || PLATFORM(GTK)
113     encoder << caretRectAtStart;
114 #endif
115 #if PLATFORM(IOS) || PLATFORM(MAC)
116     encoder << selectionClipRect;
117     encoder << selectedTextLength;
118     encoder << textAlignment;
119     encoder << textColor;
120     encoder << enclosingListType;
121 #endif
122 #if PLATFORM(IOS)
123     encoder << caretRectAtEnd;
124     encoder << selectionRects;
125     encoder << wordAtSelection;
126     encoder << characterAfterSelection;
127     encoder << characterBeforeSelection;
128     encoder << twoCharacterBeforeSelection;
129     encoder << isReplaceAllowed;
130     encoder << hasContent;
131     encoder << isStableStateUpdate;
132     encoder << insideFixedPosition;
133     encoder << hasPlainText;
134     encoder << caretColor;
135 #endif
136 #if PLATFORM(MAC)
137     encoder << candidateRequestStartPosition;
138     encoder << paragraphContextForCandidateRequest;
139     encoder << stringForCandidateRequest;
140 #endif
141     encoder << canCut;
142     encoder << canCopy;
143     encoder << canPaste;
144 }
145
146 bool EditorState::PostLayoutData::decode(IPC::Decoder& decoder, PostLayoutData& result)
147 {
148     if (!decoder.decode(result.typingAttributes))
149         return false;
150 #if PLATFORM(IOS) || PLATFORM(GTK)
151     if (!decoder.decode(result.caretRectAtStart))
152         return false;
153 #endif
154 #if PLATFORM(IOS) || PLATFORM(MAC)
155     if (!decoder.decode(result.selectionClipRect))
156         return false;
157     if (!decoder.decode(result.selectedTextLength))
158         return false;
159     if (!decoder.decode(result.textAlignment))
160         return false;
161     if (!decoder.decode(result.textColor))
162         return false;
163     if (!decoder.decode(result.enclosingListType))
164         return false;
165 #endif
166 #if PLATFORM(IOS)
167     if (!decoder.decode(result.caretRectAtEnd))
168         return false;
169     if (!decoder.decode(result.selectionRects))
170         return false;
171     if (!decoder.decode(result.wordAtSelection))
172         return false;
173     if (!decoder.decode(result.characterAfterSelection))
174         return false;
175     if (!decoder.decode(result.characterBeforeSelection))
176         return false;
177     if (!decoder.decode(result.twoCharacterBeforeSelection))
178         return false;
179     if (!decoder.decode(result.isReplaceAllowed))
180         return false;
181     if (!decoder.decode(result.hasContent))
182         return false;
183     if (!decoder.decode(result.isStableStateUpdate))
184         return false;
185     if (!decoder.decode(result.insideFixedPosition))
186         return false;
187     if (!decoder.decode(result.hasPlainText))
188         return false;
189     if (!decoder.decode(result.caretColor))
190         return false;
191 #endif
192 #if PLATFORM(MAC)
193     if (!decoder.decode(result.candidateRequestStartPosition))
194         return false;
195
196     if (!decoder.decode(result.paragraphContextForCandidateRequest))
197         return false;
198
199     if (!decoder.decode(result.stringForCandidateRequest))
200         return false;
201 #endif
202
203     if (!decoder.decode(result.canCut))
204         return false;
205     if (!decoder.decode(result.canCopy))
206         return false;
207     if (!decoder.decode(result.canPaste))
208         return false;
209
210     return true;
211 }
212
213 TextStream& operator<<(TextStream& ts, const EditorState& editorState)
214 {
215 #if PLATFORM(IOS)
216     if (editorState.firstMarkedRect != IntRect())
217         ts.dumpProperty("firstMarkedRect", editorState.firstMarkedRect);
218     if (editorState.lastMarkedRect != IntRect())
219         ts.dumpProperty("lastMarkedRect", editorState.lastMarkedRect);
220     if (editorState.markedText.length())
221         ts.dumpProperty("markedText", editorState.markedText);
222 #endif
223
224     if (editorState.shouldIgnoreSelectionChanges)
225         ts.dumpProperty("shouldIgnoreSelectionChanges", editorState.shouldIgnoreSelectionChanges);
226     if (!editorState.selectionIsNone)
227         ts.dumpProperty("selectionIsNone", editorState.selectionIsNone);
228     if (editorState.selectionIsRange)
229         ts.dumpProperty("selectionIsRange", editorState.selectionIsRange);
230     if (editorState.isContentEditable)
231         ts.dumpProperty("isContentEditable", editorState.isContentEditable);
232     if (editorState.isContentRichlyEditable)
233         ts.dumpProperty("isContentRichlyEditable", editorState.isContentRichlyEditable);
234     if (editorState.isInPasswordField)
235         ts.dumpProperty("isInPasswordField", editorState.isInPasswordField);
236     if (editorState.isInPlugin)
237         ts.dumpProperty("isInPlugin", editorState.isInPlugin);
238     if (editorState.hasComposition)
239         ts.dumpProperty("hasComposition", editorState.hasComposition);
240     if (editorState.isMissingPostLayoutData)
241         ts.dumpProperty("isMissingPostLayoutData", editorState.isMissingPostLayoutData);
242
243     if (editorState.isMissingPostLayoutData)
244         return ts;
245
246     TextStream::GroupScope scope(ts);
247     ts << "postLayoutData";
248     if (editorState.postLayoutData().typingAttributes != AttributeNone)
249         ts.dumpProperty("typingAttributes", editorState.postLayoutData().typingAttributes);
250 #if PLATFORM(IOS) || PLATFORM(GTK)
251     if (editorState.postLayoutData().caretRectAtStart != IntRect())
252         ts.dumpProperty("caretRectAtStart", editorState.postLayoutData().caretRectAtStart);
253 #endif
254 #if PLATFORM(IOS) || PLATFORM(MAC)
255     if (editorState.postLayoutData().selectionClipRect != IntRect())
256         ts.dumpProperty("selectionClipRect", editorState.postLayoutData().selectionClipRect);
257     if (editorState.postLayoutData().selectedTextLength)
258         ts.dumpProperty("selectedTextLength", editorState.postLayoutData().selectedTextLength);
259     if (editorState.postLayoutData().textAlignment != NoAlignment)
260         ts.dumpProperty("textAlignment", editorState.postLayoutData().textAlignment);
261     if (editorState.postLayoutData().textColor.isValid())
262         ts.dumpProperty("textColor", editorState.postLayoutData().textColor);
263     if (editorState.postLayoutData().enclosingListType != NoList)
264         ts.dumpProperty("enclosingListType", editorState.postLayoutData().enclosingListType);
265 #endif
266 #if PLATFORM(IOS)
267     if (editorState.postLayoutData().caretRectAtEnd != IntRect())
268         ts.dumpProperty("caretRectAtEnd", editorState.postLayoutData().caretRectAtEnd);
269     if (editorState.postLayoutData().selectionRects.size())
270         ts.dumpProperty("selectionRects", editorState.postLayoutData().selectionRects);
271     if (editorState.postLayoutData().wordAtSelection.length())
272         ts.dumpProperty("wordAtSelection", editorState.postLayoutData().wordAtSelection);
273     if (editorState.postLayoutData().characterAfterSelection)
274         ts.dumpProperty("characterAfterSelection", editorState.postLayoutData().characterAfterSelection);
275     if (editorState.postLayoutData().characterBeforeSelection)
276         ts.dumpProperty("characterBeforeSelection", editorState.postLayoutData().characterBeforeSelection);
277     if (editorState.postLayoutData().twoCharacterBeforeSelection)
278         ts.dumpProperty("twoCharacterBeforeSelection", editorState.postLayoutData().twoCharacterBeforeSelection);
279
280     if (editorState.postLayoutData().isReplaceAllowed)
281         ts.dumpProperty("isReplaceAllowed", editorState.postLayoutData().isReplaceAllowed);
282     if (editorState.postLayoutData().hasContent)
283         ts.dumpProperty("hasContent", editorState.postLayoutData().hasContent);
284     ts.dumpProperty("isStableStateUpdate", editorState.postLayoutData().isStableStateUpdate);
285     if (editorState.postLayoutData().insideFixedPosition)
286         ts.dumpProperty("insideFixedPosition", editorState.postLayoutData().insideFixedPosition);
287     if (editorState.postLayoutData().caretColor.isValid())
288         ts.dumpProperty("caretColor", editorState.postLayoutData().caretColor);
289 #endif
290 #if PLATFORM(MAC)
291     if (editorState.postLayoutData().candidateRequestStartPosition)
292         ts.dumpProperty("candidateRequestStartPosition", editorState.postLayoutData().candidateRequestStartPosition);
293     if (editorState.postLayoutData().paragraphContextForCandidateRequest.length())
294         ts.dumpProperty("paragraphContextForCandidateRequest", editorState.postLayoutData().paragraphContextForCandidateRequest);
295     if (editorState.postLayoutData().stringForCandidateRequest.length())
296         ts.dumpProperty("stringForCandidateRequest", editorState.postLayoutData().stringForCandidateRequest);
297 #endif
298
299     if (editorState.postLayoutData().canCut)
300         ts.dumpProperty("canCut", editorState.postLayoutData().canCut);
301     if (editorState.postLayoutData().canCopy)
302         ts.dumpProperty("canCopy", editorState.postLayoutData().canCopy);
303     if (editorState.postLayoutData().canPaste)
304         ts.dumpProperty("canPaste", editorState.postLayoutData().canPaste);
305
306     return ts;
307 }
308
309 } // namespace WebKit