248f99d7e09dada45f4d0391274a46caeed53080
[WebKit.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 <WebKit2/WKBundleFrame.h>
30 #include <WebKit2/WKBundlePagePrivate.h>
31 #include <WebKit2/WKRetainPtr.h>
32 #include <WebKit2/WKString.h>
33 #include <WebKit2/WKStringCF.h>
34 #include <wtf/RetainPtr.h>
35 #include <wtf/Vector.h>
36
37 namespace WTR {
38
39 InjectedBundlePage::InjectedBundlePage(WKBundlePageRef page)
40     : m_page(page)
41 {
42     WKBundlePageLoaderClient loaderClient = {
43         0,
44         this,
45         _didStartProvisionalLoadForFrame,
46         _didReceiveServerRedirectForProvisionalLoadForFrame,
47         _didFailProvisionalLoadWithErrorForFrame,
48         _didCommitLoadForFrame,
49         _didFinishLoadForFrame,
50         _didFailLoadWithErrorForFrame,
51         _didReceiveTitleForFrame,
52         _didClearWindowForFrame
53     };
54     WKBundlePageSetLoaderClient(m_page, &loaderClient);
55
56     WKBundlePageUIClient uiClient = {
57         0,
58         this,
59         _addMessageToConsole
60     };
61     WKBundlePageSetUIClient(m_page, &uiClient);
62
63 }
64
65 InjectedBundlePage::~InjectedBundlePage()
66 {
67 }
68
69 // Loader Client Callbacks
70
71 void InjectedBundlePage::_didStartProvisionalLoadForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void *clientInfo)
72 {
73     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didStartProvisionalLoadForFrame(frame);
74 }
75
76 void InjectedBundlePage::_didReceiveServerRedirectForProvisionalLoadForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void *clientInfo)
77 {
78     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didReceiveServerRedirectForProvisionalLoadForFrame(frame);
79 }
80
81 void InjectedBundlePage::_didFailProvisionalLoadWithErrorForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void *clientInfo)
82 {
83     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didFailProvisionalLoadWithErrorForFrame(frame);
84 }
85
86 void InjectedBundlePage::_didCommitLoadForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void *clientInfo)
87 {
88     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didCommitLoadForFrame(frame);
89 }
90
91 void InjectedBundlePage::_didFinishLoadForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void *clientInfo)
92 {
93     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didFinishLoadForFrame(frame);
94 }
95
96 void InjectedBundlePage::_didFailLoadWithErrorForFrame(WKBundlePageRef page, WKBundleFrameRef frame, const void *clientInfo)
97 {
98     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didFailLoadWithErrorForFrame(frame);
99 }
100
101 void InjectedBundlePage::_didReceiveTitleForFrame(WKBundlePageRef page, WKStringRef title, WKBundleFrameRef frame, const void *clientInfo)
102 {
103     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didReceiveTitleForFrame(title, frame);
104 }
105
106 void InjectedBundlePage::_didClearWindowForFrame(WKBundlePageRef page, WKBundleFrameRef frame, JSContextRef ctx, JSObjectRef window, const void *clientInfo)
107 {
108     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->didClearWindowForFrame(frame, ctx, window);
109 }
110
111 void InjectedBundlePage::didStartProvisionalLoadForFrame(WKBundleFrameRef frame)
112 {
113 }
114
115 void InjectedBundlePage::didReceiveServerRedirectForProvisionalLoadForFrame(WKBundleFrameRef frame)
116 {
117 }
118
119 void InjectedBundlePage::didFailProvisionalLoadWithErrorForFrame(WKBundleFrameRef frame)
120 {
121 }
122
123 void InjectedBundlePage::didCommitLoadForFrame(WKBundleFrameRef frame)
124 {
125 }
126
127 static std::auto_ptr<Vector<char> > WKStringToUTF8(WKStringRef wkStringRef)
128 {
129     RetainPtr<CFStringRef> cfString(AdoptCF, WKStringCopyCFString(0, wkStringRef));
130     CFIndex bufferLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfString.get()), kCFStringEncodingUTF8) + 1;
131     std::auto_ptr<Vector<char> > buffer(new Vector<char>(bufferLength));
132     if (!CFStringGetCString(cfString.get(), buffer->data(), bufferLength, kCFStringEncodingUTF8)) {
133         buffer->shrink(1);
134         (*buffer)[0] = 0;
135     } else
136         buffer->shrink(strlen(buffer->data()) + 1);
137     return buffer;
138 }
139
140 void InjectedBundlePage::didFinishLoadForFrame(WKBundleFrameRef frame)
141 {
142     if (!WKBundleFrameIsMainFrame(frame))
143         return;
144
145     if (InjectedBundle::shared().layoutTestController()->dumpAsText()) {
146         // FIXME: Support dumping subframes when layoutTestController()->dumpChildFramesAsText() is true.
147         WKRetainPtr<WKStringRef> innerText(AdoptWK, WKBundleFrameCopyInnerText(frame));
148         std::auto_ptr<Vector<char> > utf8InnerText = WKStringToUTF8(innerText.get());
149         InjectedBundle::shared().os() << utf8InnerText->data() << "\n";
150     } else {
151         WKRetainPtr<WKStringRef> externalRepresentation(AdoptWK, WKBundlePageCopyRenderTreeExternalRepresentation(m_page));
152         std::auto_ptr<Vector<char> > utf8externalRepresentation = WKStringToUTF8(externalRepresentation.get());
153         InjectedBundle::shared().os() << utf8externalRepresentation->data();
154     }
155     InjectedBundle::shared().done();
156 }
157
158 void InjectedBundlePage::didFailLoadWithErrorForFrame(WKBundleFrameRef frame)
159 {
160     if (!WKBundleFrameIsMainFrame(frame))
161         return;
162
163     InjectedBundle::shared().done();
164 }
165
166 void InjectedBundlePage::didReceiveTitleForFrame(WKStringRef title, WKBundleFrameRef frame)
167 {
168 }
169
170 void InjectedBundlePage::didClearWindowForFrame(WKBundleFrameRef frame, JSContextRef ctx, JSObjectRef window)
171 {
172     JSValueRef exception = 0;
173     InjectedBundle::shared().layoutTestController()->makeWindowObject(ctx, window, &exception);
174 }
175
176 // UI Client Callbacks
177
178 void InjectedBundlePage::_addMessageToConsole(WKBundlePageRef page, WKStringRef message, uint32_t lineNumber, const void *clientInfo)
179 {
180     static_cast<InjectedBundlePage*>(const_cast<void*>(clientInfo))->addMessageToConsole(message, lineNumber);
181 }
182
183 void InjectedBundlePage::addMessageToConsole(WKStringRef message, uint32_t lineNumber)
184 {
185     // FIXME: Strip file: urls.
186     std::auto_ptr<Vector<char> > utf8Message = WKStringToUTF8(message);
187     InjectedBundle::shared().os() << "CONSOLE MESSAGE: line " << lineNumber << ": " << utf8Message->data() << "\n";
188 }
189
190 } // namespace WTR