ca01c144ee3bdde22a0537d3b260fcc7ba744310
[WebKit-https.git] / WebKitTools / WebKitTestRunner / InjectedBundle / InjectedBundlePage.cpp
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 "InjectedBundlePage.h"
27
28 #include "InjectedBundle.h"
29 #include <JavaScriptCore/JSRetainPtr.h>
30 #include <WebKit2/WKArray.h>
31 #include <WebKit2/WKBundleFrame.h>
32 #include <WebKit2/WKBundleNode.h>
33 #include <WebKit2/WKBundlePagePrivate.h>
34 #include <WebKit2/WKRetainPtr.h>
35 #include <WebKit2/WKBundleRange.h>
36 #include <WebKit2/WKString.h>
37 #include <WebKit2/WKStringCF.h>
38 #include <wtf/PassOwnPtr.h>
39 #include <wtf/RetainPtr.h>
40 #include <wtf/Vector.h>
41
42 using namespace std;
43
44 namespace WTR {
45
46 static ostream& operator<<(ostream& out, CFStringRef stringRef)
47 {
48     if (!stringRef)
49         return out;
50     CFIndex bufferLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(stringRef), kCFStringEncodingUTF8) + 1;
51     Vector<char> buffer(bufferLength);
52     if (!CFStringGetCString(stringRef, buffer.data(), bufferLength, kCFStringEncodingUTF8))
53         return out;
54     return out << buffer.data();
55 }
56
57 static ostream& operator<<(ostream& out, const RetainPtr<CFStringRef>& stringRef)
58 {
59     return out << stringRef.get();
60 }
61
62 static ostream& operator<<(ostream& out, WKStringRef stringRef)
63 {
64     if (!stringRef)
65         return out;
66     RetainPtr<CFStringRef> cfString(AdoptCF, WKStringCopyCFString(0, stringRef));
67     return out << cfString;
68 }
69
70 static ostream& operator<<(ostream& out, const WKRetainPtr<WKStringRef>& stringRef)
71 {
72     return out << stringRef.get();
73 }
74
75 static ostream& operator<<(ostream& out, JSStringRef stringRef)
76 {
77     if (!stringRef)
78         return out;
79     CFIndex bufferLength = JSStringGetMaximumUTF8CStringSize(stringRef) + 1;
80     Vector<char> buffer(bufferLength);
81     JSStringGetUTF8CString(stringRef, buffer.data(), bufferLength);
82     return out << buffer.data();
83 }
84
85 static ostream& operator<<(ostream& out, const JSRetainPtr<JSStringRef>& stringRef)
86 {
87     return out << stringRef.get();
88 }
89
90 static string dumpPath(WKBundleNodeRef node)
91 {
92     if (!node)
93         return "(null)";
94     WKRetainPtr<WKStringRef> nodeName(AdoptWK, WKBundleNodeCopyNodeName(node));
95     ostringstream out;
96     out << nodeName;
97     if (WKBundleNodeRef parent = WKBundleNodeGetParent(node))
98         out << " > " << dumpPath(parent);
99     return out.str();
100 }
101
102 static ostream& operator<<(ostream& out, WKBundleRangeRef rangeRef)
103 {
104     if (rangeRef)
105         out << "range from " << WKBundleRangeGetStartOffset(rangeRef) << " of " << dumpPath(WKBundleRangeGetStartContainer(rangeRef)) << " to " << WKBundleRangeGetEndOffset(rangeRef) << " of " << dumpPath(WKBundleRangeGetEndContainer(rangeRef));
106     else
107         out << "(null)";
108
109     return out;
110 }
111
112 static ostream& operator<<(ostream& out, WKBundleCSSStyleDeclarationRef style)
113 {
114     // DumpRenderTree calls -[DOMCSSStyleDeclaration description], which just dumps class name and object address.
115     // No existing tests actually hit this code path at the time of this writing, because WebCore doesn't call
116     // the editing client if the styling operation source is CommandFromDOM or CommandFromDOMWithUserInterface.
117     out << "<DOMCSSStyleDeclaration ADDRESS>";
118     return out;
119 }
120
121 InjectedBundlePage::InjectedBundlePage(WKBundlePageRef page)
122     : m_page(page)
123     , m_isLoading(false)
124 {
125     WKBundlePageLoaderClient loaderClient = {
126         0,
127         this,
128         _didStartProvisionalLoadForFrame,
129         _didReceiveServerRedirectForProvisionalLoadForFrame,
130         _didFailProvisionalLoadWithErrorForFrame,
131         _didCommitLoadForFrame,
132         _didFinishLoadForFrame,
133         _didFailLoadWithErrorForFrame,
134         _didReceiveTitleForFrame,
135         _didClearWindowForFrame
136     };
137     WKBundlePageSetLoaderClient(m_page, &loaderClient);
138
139     WKBundlePageUIClient uiClient = {
140         0,
141         this,
142         _willAddMessageToConsole,
143         _willSetStatusbarText,
144         _willRunJavaScriptAlert,
145         _willRunJavaScriptConfirm,
146         _willRunJavaScriptPrompt
147     };
148     WKBundlePageSetUIClient(m_page, &uiClient);
149
150     WKBundlePageEditorClient editorClient = {
151         0,
152         this,
153         _shouldBeginEditing,
154         _shouldEndEditing,
155         _shouldInsertNode,
156         _shouldInsertText,
157         _shouldDeleteRange,
158         _shouldChangeSelectedRange,
159         _shouldApplyStyle,
160         _didBeginEditing,
161         _didEndEditing,
162         _didChange,
163         _didChangeSelection
164     };
165     WKBundlePageSetEditorClient(m_page, &editorClient);
166 }
167
168 InjectedBundlePage::~InjectedBundlePage()
169 {
170 }
171
172 // Loader Client Callbacks
173
174 void InjectedBundlePage::_didStartProvisionalLoadForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void *clientInfo)
175 {
176     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didStartProvisionalLoadForFrame(frame);
177 }
178
179 void InjectedBundlePage::_didReceiveServerRedirectForProvisionalLoadForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void *clientInfo)
180 {
181     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didReceiveServerRedirectForProvisionalLoadForFrame(frame);
182 }
183
184 void InjectedBundlePage::_didFailProvisionalLoadWithErrorForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void *clientInfo)
185 {
186     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didFailProvisionalLoadWithErrorForFrame(frame);
187 }
188
189 void InjectedBundlePage::_didCommitLoadForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void *clientInfo)
190 {
191     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didCommitLoadForFrame(frame);
192 }
193
194 void InjectedBundlePage::_didFinishLoadForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void *clientInfo)
195 {
196     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didFinishLoadForFrame(frame);
197 }
198
199 void InjectedBundlePage::_didFailLoadWithErrorForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void *clientInfo)
200 {
201     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didFailLoadWithErrorForFrame(frame);
202 }
203
204 void InjectedBundlePage::_didReceiveTitleForFrame(WKBundlePageRef page, WKStringRef title, WKBundleFrameRef frame, const void *clientInfo)
205 {
206     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didReceiveTitleForFrame(title, frame);
207 }
208
209 void InjectedBundlePage::_didClearWindowForFrame(WKBundlePageRef page, WKBundleFrameRef frame, JSGlobalContextRef context, JSObjectRef window, const void *clientInfo)
210 {
211     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didClearWindowForFrame(frame, context, window);
212 }
213
214 void InjectedBundlePage::didStartProvisionalLoadForFrame(WKBundleFrameRef frame)
215 {
216     if (frame == WKBundlePageGetMainFrame(m_page))
217         m_isLoading = true;
218 }
219
220 void InjectedBundlePage::didReceiveServerRedirectForProvisionalLoadForFrame(WKBundleFrameRef frame)
221 {
222 }
223
224 void InjectedBundlePage::didFailProvisionalLoadWithErrorForFrame(WKBundleFrameRef frame)
225 {
226 }
227
228 void InjectedBundlePage::didCommitLoadForFrame(WKBundleFrameRef frame)
229 {
230 }
231
232 static JSValueRef propertyValue(JSContextRef context, JSObjectRef object, const char* propertyName)
233 {
234     if (!object)
235         return 0;
236     JSRetainPtr<JSStringRef> propertyNameString(Adopt, JSStringCreateWithUTF8CString(propertyName));
237     JSValueRef exception;
238     return JSObjectGetProperty(context, object, propertyNameString.get(), &exception);
239 }
240
241 static JSObjectRef propertyObject(JSContextRef context, JSObjectRef object, const char* propertyName)
242 {
243     JSValueRef value = propertyValue(context, object, propertyName);
244     if (!value || !JSValueIsObject(context, value))
245         return 0;
246     return const_cast<JSObjectRef>(value);
247 }
248
249 static JSRetainPtr<JSStringRef> propertyString(JSContextRef context, JSObjectRef object, const char* propertyName)
250 {
251     JSValueRef value = propertyValue(context, object, propertyName);
252     if (!value)
253         return 0;
254     JSValueRef exception;
255     return JSRetainPtr<JSStringRef>(Adopt, JSValueToStringCopy(context, value, &exception));
256 }
257
258 static double numericWindowPropertyValue(WKBundleFrameRef frame, const char* propertyName)
259 {
260     JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame);
261     JSValueRef value = propertyValue(context, JSContextGetGlobalObject(context), propertyName);
262     if (!value)
263         return 0;
264     JSValueRef exception;
265     return JSValueToNumber(context, value, &exception);
266 }
267
268 enum FrameNamePolicy { ShouldNotIncludeFrameName, ShouldIncludeFrameName };
269
270 static void dumpFrameScrollPosition(WKBundleFrameRef frame, FrameNamePolicy shouldIncludeFrameName = ShouldNotIncludeFrameName)
271 {
272     double x = numericWindowPropertyValue(frame, "pageXOffset");
273     double y = numericWindowPropertyValue(frame, "pageYOffset");
274     if (fabs(x) > 0.00000001 || fabs(y) > 0.00000001) {
275         if (shouldIncludeFrameName) {
276             WKRetainPtr<WKStringRef> name(AdoptWK, WKBundleFrameCopyName(frame));
277             InjectedBundle::shared().os() << "frame '" << name << "' ";
278         }
279         InjectedBundle::shared().os() << "scrolled to " << x << "," << y << "\n";
280     }
281 }
282
283 static void dumpDescendantFrameScrollPositions(WKBundleFrameRef frame)
284 {
285     WKRetainPtr<WKArrayRef> childFrames(AdoptWK, WKBundleFrameCopyChildFrames(frame));
286     size_t size = WKArrayGetSize(childFrames.get());
287     for (size_t i = 0; i < size; ++i) {
288         WKBundleFrameRef subframe = static_cast<WKBundleFrameRef>(WKArrayGetItemAtIndex(childFrames.get(), i));
289         dumpFrameScrollPosition(subframe, ShouldIncludeFrameName);
290         dumpDescendantFrameScrollPositions(subframe);
291     }
292 }
293
294 void InjectedBundlePage::dumpAllFrameScrollPositions()
295 {
296     WKBundleFrameRef frame = WKBundlePageGetMainFrame(m_page);
297     dumpFrameScrollPosition(frame);
298     dumpDescendantFrameScrollPositions(frame);
299 }
300
301 static void dumpFrameText(WKBundleFrameRef frame)
302 {
303     JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame);
304     JSObjectRef document = propertyObject(context, JSContextGetGlobalObject(context), "document");
305     JSObjectRef documentElement = propertyObject(context, document, "documentElement");
306     InjectedBundle::shared().os() << propertyString(context, documentElement, "innerText") << "\n";
307 }
308
309 static void dumpDescendantFramesText(WKBundleFrameRef frame)
310 {
311     WKRetainPtr<WKArrayRef> childFrames(AdoptWK, WKBundleFrameCopyChildFrames(frame));
312     size_t size = WKArrayGetSize(childFrames.get());
313     for (size_t i = 0; i < size; ++i) {
314         WKBundleFrameRef subframe = static_cast<WKBundleFrameRef>(WKArrayGetItemAtIndex(childFrames.get(), i));
315         WKRetainPtr<WKStringRef> subframeName(AdoptWK, WKBundleFrameCopyName(subframe));
316         InjectedBundle::shared().os() << "\n--------\nFrame: '" << subframeName << "'\n--------\n";
317         dumpFrameText(subframe);
318         dumpDescendantFramesText(subframe);
319     }
320 }
321
322 void InjectedBundlePage::dumpAllFramesText()
323 {
324     WKBundleFrameRef frame = WKBundlePageGetMainFrame(m_page);
325     dumpFrameText(frame);
326     dumpDescendantFramesText(frame);
327 }
328
329 void InjectedBundlePage::dump()
330 {
331     InjectedBundle::shared().layoutTestController()->invalidateWaitToDumpWatchdog();
332
333     switch (InjectedBundle::shared().layoutTestController()->whatToDump()) {
334     case LayoutTestController::RenderTree: {
335         WKRetainPtr<WKStringRef> text(AdoptWK, WKBundlePageCopyRenderTreeExternalRepresentation(m_page));
336         InjectedBundle::shared().os() << text;
337         break;
338     }
339     case LayoutTestController::MainFrameText:
340         dumpFrameText(WKBundlePageGetMainFrame(m_page));
341         break;
342     case LayoutTestController::AllFramesText:
343         dumpAllFramesText();
344         break;
345     }
346
347     if (InjectedBundle::shared().layoutTestController()->shouldDumpAllFrameScrollPositions())
348         dumpAllFrameScrollPositions();
349     else if (InjectedBundle::shared().layoutTestController()->shouldDumpMainFrameScrollPosition())
350         dumpFrameScrollPosition(WKBundlePageGetMainFrame(m_page));
351
352     InjectedBundle::shared().done();
353 }
354
355 void InjectedBundlePage::didFinishLoadForFrame(WKBundleFrameRef frame)
356 {
357     if (!WKBundleFrameIsMainFrame(frame))
358         return;
359
360     m_isLoading = false;
361
362     if (InjectedBundle::shared().layoutTestController()->waitToDump())
363         return;
364
365     dump();
366 }
367
368 void InjectedBundlePage::didFailLoadWithErrorForFrame(WKBundleFrameRef frame)
369 {
370     if (!WKBundleFrameIsMainFrame(frame))
371         return;
372
373     m_isLoading = false;
374
375     InjectedBundle::shared().done();
376 }
377
378 void InjectedBundlePage::didReceiveTitleForFrame(WKStringRef title, WKBundleFrameRef frame)
379 {
380 }
381
382 void InjectedBundlePage::didClearWindowForFrame(WKBundleFrameRef frame, JSGlobalContextRef context, JSObjectRef window)
383 {
384     JSValueRef exception = 0;
385     InjectedBundle::shared().layoutTestController()->makeWindowObject(context, window, &exception);
386 }
387
388 // UI Client Callbacks
389
390 void InjectedBundlePage::_willAddMessageToConsole(WKBundlePageRef page, WKStringRef message, uint32_t lineNumber, const void *clientInfo)
391 {
392     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->willAddMessageToConsole(message, lineNumber);
393 }
394
395 void InjectedBundlePage::_willSetStatusbarText(WKBundlePageRef page, WKStringRef statusbarText, const void *clientInfo)
396 {
397     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->willSetStatusbarText(statusbarText);
398 }
399
400 void InjectedBundlePage::_willRunJavaScriptAlert(WKBundlePageRef page, WKStringRef message, WKBundleFrameRef frame, const void *clientInfo)
401 {
402     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->willRunJavaScriptAlert(message, frame);
403 }
404
405 void InjectedBundlePage::_willRunJavaScriptConfirm(WKBundlePageRef page, WKStringRef message, WKBundleFrameRef frame, const void *clientInfo)
406 {
407     return static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->willRunJavaScriptConfirm(message, frame);
408 }
409
410 void InjectedBundlePage::_willRunJavaScriptPrompt(WKBundlePageRef page, WKStringRef message, WKStringRef defaultValue, WKBundleFrameRef frame, const void *clientInfo)
411 {
412     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->willRunJavaScriptPrompt(message, defaultValue, frame);
413 }
414
415 void InjectedBundlePage::willAddMessageToConsole(WKStringRef message, uint32_t lineNumber)
416 {
417     // FIXME: Strip file: urls.
418     InjectedBundle::shared().os() << "CONSOLE MESSAGE: line " << lineNumber << ": " << message << "\n";
419 }
420
421 void InjectedBundlePage::willSetStatusbarText(WKStringRef statusbarText)
422 {
423     if (!InjectedBundle::shared().layoutTestController()->shouldDumpStatusCallbacks())
424         return;
425
426     InjectedBundle::shared().os() << "UI DELEGATE STATUS CALLBACK: setStatusText:" << statusbarText << "\n";
427 }
428
429 void InjectedBundlePage::willRunJavaScriptAlert(WKStringRef message, WKBundleFrameRef)
430 {
431     InjectedBundle::shared().os() << "ALERT: " << message << "\n";
432 }
433
434 void InjectedBundlePage::willRunJavaScriptConfirm(WKStringRef message, WKBundleFrameRef)
435 {
436     InjectedBundle::shared().os() << "CONFIRM: " << message << "\n";
437 }
438
439 void InjectedBundlePage::willRunJavaScriptPrompt(WKStringRef message, WKStringRef defaultValue, WKBundleFrameRef)
440 {
441     InjectedBundle::shared().os() << "PROMPT: " << message << ", default text: " << defaultValue <<  "\n";
442 }
443
444 // Editor Client Callbacks
445
446 bool InjectedBundlePage::_shouldBeginEditing(WKBundlePageRef page, WKBundleRangeRef range, const void* clientInfo)
447 {
448     return static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->shouldBeginEditing(range);
449 }
450
451 bool InjectedBundlePage::_shouldEndEditing(WKBundlePageRef page, WKBundleRangeRef range, const void* clientInfo)
452 {
453     return static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->shouldEndEditing(range);
454 }
455
456 bool InjectedBundlePage::_shouldInsertNode(WKBundlePageRef page, WKBundleNodeRef node, WKBundleRangeRef rangeToReplace, WKInsertActionType action, const void* clientInfo)
457 {
458     return static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->shouldInsertNode(node, rangeToReplace, action);
459 }
460
461 bool InjectedBundlePage::_shouldInsertText(WKBundlePageRef page, WKStringRef text, WKBundleRangeRef rangeToReplace, WKInsertActionType action, const void* clientInfo)
462 {
463     return static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->shouldInsertText(text, rangeToReplace, action);
464 }
465
466 bool InjectedBundlePage::_shouldDeleteRange(WKBundlePageRef page, WKBundleRangeRef range, const void* clientInfo)
467 {
468     return static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->shouldDeleteRange(range);
469 }
470
471 bool InjectedBundlePage::_shouldChangeSelectedRange(WKBundlePageRef page, WKBundleRangeRef fromRange, WKBundleRangeRef toRange, WKAffinityType affinity, bool stillSelecting, const void* clientInfo)
472 {
473     return static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->shouldChangeSelectedRange(fromRange, toRange, affinity, stillSelecting);
474 }
475
476 bool InjectedBundlePage::_shouldApplyStyle(WKBundlePageRef page, WKBundleCSSStyleDeclarationRef style, WKBundleRangeRef range, const void* clientInfo)
477 {
478     return static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->shouldApplyStyle(style, range);
479 }
480
481 void InjectedBundlePage::_didBeginEditing(WKBundlePageRef page, WKStringRef notificationName, const void* clientInfo)
482 {
483     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didBeginEditing(notificationName);
484 }
485
486 void InjectedBundlePage::_didEndEditing(WKBundlePageRef page, WKStringRef notificationName, const void* clientInfo)
487 {
488     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didEndEditing(notificationName);
489 }
490
491 void InjectedBundlePage::_didChange(WKBundlePageRef page, WKStringRef notificationName, const void* clientInfo)
492 {
493     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didChange(notificationName);
494 }
495
496 void InjectedBundlePage::_didChangeSelection(WKBundlePageRef page, WKStringRef notificationName, const void* clientInfo)
497 {
498     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didChangeSelection(notificationName);
499 }
500
501 bool InjectedBundlePage::shouldBeginEditing(WKBundleRangeRef range)
502 {
503     if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
504         InjectedBundle::shared().os() << "EDITING DELEGATE: shouldBeginEditingInDOMRange:" << range << "\n";
505     return InjectedBundle::shared().layoutTestController()->shouldAllowEditing();
506 }
507
508 bool InjectedBundlePage::shouldEndEditing(WKBundleRangeRef range)
509 {
510     if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
511         InjectedBundle::shared().os() << "EDITING DELEGATE: shouldEndEditingInDOMRange:" << range << "\n";
512     return InjectedBundle::shared().layoutTestController()->shouldAllowEditing();
513 }
514
515 bool InjectedBundlePage::shouldInsertNode(WKBundleNodeRef node, WKBundleRangeRef rangeToReplace, WKInsertActionType action)
516 {
517     static const char *insertactionstring[] = {
518         "WebViewInsertActionTyped",
519         "WebViewInsertActionPasted",
520         "WebViewInsertActionDropped",
521     };
522
523     if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
524         InjectedBundle::shared().os() << "EDITING DELEGATE: shouldInsertNode:" << dumpPath(node) << " replacingDOMRange:" << rangeToReplace << " givenAction:" << insertactionstring[action] << "\n";
525     return InjectedBundle::shared().layoutTestController()->shouldAllowEditing();
526 }
527
528 bool InjectedBundlePage::shouldInsertText(WKStringRef text, WKBundleRangeRef rangeToReplace, WKInsertActionType action)
529 {
530     static const char *insertactionstring[] = {
531         "WebViewInsertActionTyped",
532         "WebViewInsertActionPasted",
533         "WebViewInsertActionDropped",
534     };
535
536     if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
537         InjectedBundle::shared().os() << "EDITING DELEGATE: shouldInsertText:" << text << " replacingDOMRange:" << rangeToReplace << " givenAction:" << insertactionstring[action] << "\n";
538     return InjectedBundle::shared().layoutTestController()->shouldAllowEditing();
539 }
540
541 bool InjectedBundlePage::shouldDeleteRange(WKBundleRangeRef range)
542 {
543     if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
544         InjectedBundle::shared().os() << "EDITING DELEGATE: shouldDeleteDOMRange:" << range << "\n";
545     return InjectedBundle::shared().layoutTestController()->shouldAllowEditing();
546 }
547
548 bool InjectedBundlePage::shouldChangeSelectedRange(WKBundleRangeRef fromRange, WKBundleRangeRef toRange, WKAffinityType affinity, bool stillSelecting)
549 {
550     static const char *affinitystring[] = {
551         "NSSelectionAffinityUpstream",
552         "NSSelectionAffinityDownstream"
553     };
554     static const char *boolstring[] = {
555         "FALSE",
556         "TRUE"
557     };
558
559     if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
560         InjectedBundle::shared().os() << "EDITING DELEGATE: shouldChangeSelectedDOMRange:" << fromRange << " toDOMRange:" << toRange << " affinity:" << affinitystring[affinity] << " stillSelecting:" << boolstring[stillSelecting] << "\n";
561     return InjectedBundle::shared().layoutTestController()->shouldAllowEditing();
562 }
563
564 bool InjectedBundlePage::shouldApplyStyle(WKBundleCSSStyleDeclarationRef style, WKBundleRangeRef range)
565 {
566     if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
567         InjectedBundle::shared().os() << "EDITING DELEGATE: shouldApplyStyle:" << style << " toElementsInDOMRange:" << range << "\n";
568     return InjectedBundle::shared().layoutTestController()->shouldAllowEditing();
569 }
570
571 void InjectedBundlePage::didBeginEditing(WKStringRef notificationName)
572 {
573     if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
574         InjectedBundle::shared().os() << "EDITING DELEGATE: webViewDidBeginEditing:" << notificationName << "\n";
575 }
576
577 void InjectedBundlePage::didEndEditing(WKStringRef notificationName)
578 {
579     if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
580         InjectedBundle::shared().os() << "EDITING DELEGATE: webViewDidEndEditing:" << notificationName << "\n";
581 }
582
583 void InjectedBundlePage::didChange(WKStringRef notificationName)
584 {
585     if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
586         InjectedBundle::shared().os() << "EDITING DELEGATE: webViewDidChange:" << notificationName << "\n";
587 }
588
589 void InjectedBundlePage::didChangeSelection(WKStringRef notificationName)
590 {
591     if (InjectedBundle::shared().layoutTestController()->shouldDumpEditingCallbacks())
592         InjectedBundle::shared().os() << "EDITING DELEGATE: webViewDidChangeSelection:" << notificationName << "\n";
593 }
594
595
596 } // namespace WTR