• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007, 2008, 2009 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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "config.h"
30 #include "LayoutTestController.h"
31 
32 #include "WorkQueue.h"
33 #include "WorkQueueItem.h"
34 #include <JavaScriptCore/JSObjectRef.h>
35 #include <JavaScriptCore/JSRetainPtr.h>
36 #include <wtf/Assertions.h>
37 #include <wtf/MathExtras.h>
38 
LayoutTestController(const std::string & testPathOrURL,const std::string & expectedPixelHash)39 LayoutTestController::LayoutTestController(const std::string& testPathOrURL, const std::string& expectedPixelHash)
40     : m_dumpAsText(false)
41     , m_dumpAsPDF(false)
42     , m_dumpBackForwardList(false)
43     , m_dumpChildFrameScrollPositions(false)
44     , m_dumpChildFramesAsText(false)
45     , m_dumpDatabaseCallbacks(false)
46     , m_dumpDOMAsWebArchive(false)
47     , m_dumpSelectionRect(false)
48     , m_dumpSourceAsWebArchive(false)
49     , m_dumpStatusCallbacks(false)
50     , m_dumpTitleChanges(false)
51     , m_dumpEditingCallbacks(false)
52     , m_dumpResourceLoadCallbacks(false)
53     , m_dumpResourceResponseMIMETypes(false)
54     , m_dumpWillCacheResponse(false)
55     , m_dumpFrameLoadCallbacks(false)
56     , m_callCloseOnWebViews(true)
57     , m_canOpenWindows(false)
58     , m_closeRemainingWindowsWhenComplete(true)
59     , m_stopProvisionalFrameLoads(false)
60     , m_testOnscreen(false)
61     , m_testRepaint(false)
62     , m_testRepaintSweepHorizontally(false)
63     , m_waitToDump(false)
64     , m_willSendRequestReturnsNullOnRedirect(false)
65     , m_windowIsKey(true)
66     , m_globalFlag(false)
67     , m_testPathOrURL(testPathOrURL)
68     , m_expectedPixelHash(expectedPixelHash)
69 {
70 }
71 
72 // Static Functions
73 
dumpAsTextCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)74 static JSValueRef dumpAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
75 {
76     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
77     controller->setDumpAsText(true);
78     return JSValueMakeUndefined(context);
79 }
80 
dumpAsPDFCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)81 static JSValueRef dumpAsPDFCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
82 {
83     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
84     controller->setDumpAsPDF(true);
85     return JSValueMakeUndefined(context);
86 }
87 
dumpBackForwardListCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)88 static JSValueRef dumpBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
89 {
90     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
91     controller->setDumpBackForwardList(true);
92     return JSValueMakeUndefined(context);
93 }
94 
dumpChildFramesAsTextCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)95 static JSValueRef dumpChildFramesAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
96 {
97     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
98     controller->setDumpChildFramesAsText(true);
99     return JSValueMakeUndefined(context);
100 }
101 
dumpChildFrameScrollPositionsCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)102 static JSValueRef dumpChildFrameScrollPositionsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
103 {
104     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
105     controller->setDumpChildFrameScrollPositions(true);
106     return JSValueMakeUndefined(context);
107 }
108 
dumpDatabaseCallbacksCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)109 static JSValueRef dumpDatabaseCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
110 {
111     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
112     controller->setDumpDatabaseCallbacks(true);
113     return JSValueMakeUndefined(context);
114 }
115 
dumpDOMAsWebArchiveCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)116 static JSValueRef dumpDOMAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
117 {
118     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
119     controller->setDumpDOMAsWebArchive(true);
120     return JSValueMakeUndefined(context);
121 }
122 
dumpEditingCallbacksCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)123 static JSValueRef dumpEditingCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
124 {
125     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
126     controller->setDumpEditingCallbacks(true);
127     return JSValueMakeUndefined(context);
128 }
129 
dumpResourceLoadCallbacksCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)130 static JSValueRef dumpResourceLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
131 {
132     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
133     controller->setDumpResourceLoadCallbacks(true);
134     return JSValueMakeUndefined(context);
135 }
136 
dumpResourceResponseMIMETypesCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)137 static JSValueRef dumpResourceResponseMIMETypesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
138 {
139     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
140     controller->setDumpResourceResponseMIMETypes(true);
141     return JSValueMakeUndefined(context);
142 }
143 
dumpSelectionRectCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)144 static JSValueRef dumpSelectionRectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
145 {
146     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
147     controller->setDumpSelectionRect(true);
148     return JSValueMakeUndefined(context);
149 }
150 
dumpSourceAsWebArchiveCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)151 static JSValueRef dumpSourceAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
152 {
153     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
154     controller->setDumpSourceAsWebArchive(true);
155     return JSValueMakeUndefined(context);
156 }
157 
dumpStatusCallbacksCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)158 static JSValueRef dumpStatusCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
159 {
160     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
161     controller->setDumpStatusCallbacks(true);
162     return JSValueMakeUndefined(context);
163 }
164 
dumpTitleChangesCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)165 static JSValueRef dumpTitleChangesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
166 {
167     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
168     controller->setDumpTitleChanges(true);
169     return JSValueMakeUndefined(context);
170 }
171 
dumpWillCacheResponseCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)172 static JSValueRef dumpWillCacheResponseCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
173 {
174     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
175     controller->setDumpWillCacheResponse(true);
176     return JSValueMakeUndefined(context);
177 }
178 
pathToLocalResourceCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)179 static JSValueRef pathToLocalResourceCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
180 {
181     if (argumentCount < 1)
182         return JSValueMakeUndefined(context);
183 
184     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
185     JSRetainPtr<JSStringRef> localPath(Adopt, JSValueToStringCopy(context, arguments[0], exception));
186     ASSERT(!*exception);
187 
188     JSRetainPtr<JSStringRef> convertedPath(Adopt, controller->pathToLocalResource(context, localPath.get()));
189     if (!convertedPath)
190         return JSValueMakeUndefined(context);
191 
192     return JSValueMakeString(context, convertedPath.get());
193 }
194 
repaintSweepHorizontallyCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)195 static JSValueRef repaintSweepHorizontallyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
196 {
197     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
198     controller->setTestRepaintSweepHorizontally(true);
199     return JSValueMakeUndefined(context);
200 }
201 
setCallCloseOnWebViewsCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)202 static JSValueRef setCallCloseOnWebViewsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
203 {
204     if (argumentCount < 1)
205         return JSValueMakeUndefined(context);
206 
207     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
208     controller->setCallCloseOnWebViews(JSValueToBoolean(context, arguments[0]));
209     return JSValueMakeUndefined(context);
210 }
211 
setCanOpenWindowsCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)212 static JSValueRef setCanOpenWindowsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
213 {
214     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
215     controller->setCanOpenWindows(true);
216     return JSValueMakeUndefined(context);
217 }
218 
setCloseRemainingWindowsWhenCompleteCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)219 static JSValueRef setCloseRemainingWindowsWhenCompleteCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
220 {
221     if (argumentCount < 1)
222         return JSValueMakeUndefined(context);
223 
224     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
225     controller->setCloseRemainingWindowsWhenComplete(JSValueToBoolean(context, arguments[0]));
226     return JSValueMakeUndefined(context);
227 }
228 
testOnscreenCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)229 static JSValueRef testOnscreenCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
230 {
231     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
232     controller->setTestOnscreen(true);
233     return JSValueMakeUndefined(context);
234 }
235 
testRepaintCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)236 static JSValueRef testRepaintCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
237 {
238     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
239     controller->setTestRepaint(true);
240     return JSValueMakeUndefined(context);
241 }
242 
addDisallowedURLCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)243 static JSValueRef addDisallowedURLCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
244 {
245     // Has mac implementation
246     if (argumentCount < 1)
247         return JSValueMakeUndefined(context);
248 
249     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
250     ASSERT(!*exception);
251 
252     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
253     controller->addDisallowedURL(url.get());
254 
255     return JSValueMakeUndefined(context);
256 }
257 
clearAllDatabasesCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)258 static JSValueRef clearAllDatabasesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
259 {
260     // Has mac & windows implementation
261     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
262     controller->clearAllDatabases();
263 
264     return JSValueMakeUndefined(context);
265 }
266 
clearBackForwardListCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)267 static JSValueRef clearBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
268 {
269     // Has mac & windows implementation
270     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
271     controller->clearBackForwardList();
272 
273     return JSValueMakeUndefined(context);
274 }
275 
clearPersistentUserStyleSheetCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)276 static JSValueRef clearPersistentUserStyleSheetCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
277 {
278     // Has mac & windows implementation
279     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
280     controller->clearPersistentUserStyleSheet();
281 
282     return JSValueMakeUndefined(context);
283 }
284 
decodeHostNameCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)285 static JSValueRef decodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
286 {
287     // Has mac implementation
288     if (argumentCount < 1)
289         return JSValueMakeUndefined(context);
290 
291     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
292     ASSERT(!*exception);
293 
294     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
295     JSRetainPtr<JSStringRef> decodedHostName(Adopt, controller->copyDecodedHostName(name.get()));
296     return JSValueMakeString(context, decodedHostName.get());
297 }
298 
disableImageLoadingCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)299 static JSValueRef disableImageLoadingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
300 {
301     // Has mac implementation, needs windows implementation
302     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
303     controller->disableImageLoading();
304 
305     return JSValueMakeUndefined(context);
306 }
307 
dispatchPendingLoadRequestsCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)308 static JSValueRef dispatchPendingLoadRequestsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
309 {
310     // Has mac implementation, needs windows implementation
311     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
312     controller->dispatchPendingLoadRequests();
313 
314     return JSValueMakeUndefined(context);
315 }
316 
displayCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)317 static JSValueRef displayCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
318 {
319     // Has mac & windows implementation
320     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
321     controller->display();
322 
323     return JSValueMakeUndefined(context);
324 }
325 
encodeHostNameCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)326 static JSValueRef encodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
327 {
328     // Has mac implementation
329     if (argumentCount < 1)
330         return JSValueMakeUndefined(context);
331 
332     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
333     ASSERT(!*exception);
334 
335     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
336     JSRetainPtr<JSStringRef> encodedHostName(Adopt, controller->copyEncodedHostName(name.get()));
337     return JSValueMakeString(context, encodedHostName.get());
338 }
339 
execCommandCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)340 static JSValueRef execCommandCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
341 {
342     // Has Mac & Windows implementations.
343     if (argumentCount < 1)
344         return JSValueMakeUndefined(context);
345 
346     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
347     ASSERT(!*exception);
348 
349     // Ignoring the second parameter (userInterface), as this command emulates a manual action.
350 
351     JSRetainPtr<JSStringRef> value;
352     if (argumentCount >= 3) {
353         value.adopt(JSValueToStringCopy(context, arguments[2], exception));
354         ASSERT(!*exception);
355     } else
356         value.adopt(JSStringCreateWithUTF8CString(""));
357 
358 
359     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
360     controller->execCommand(name.get(), value.get());
361 
362     return JSValueMakeUndefined(context);
363 }
364 
isCommandEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)365 static JSValueRef isCommandEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
366 {
367     // Has Mac implementation.
368 
369     if (argumentCount < 1)
370         return JSValueMakeUndefined(context);
371 
372     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
373     ASSERT(!*exception);
374 
375     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
376 
377     return JSValueMakeBoolean(context, controller->isCommandEnabled(name.get()));
378 }
379 
keepWebHistoryCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)380 static JSValueRef keepWebHistoryCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
381 {
382     // Has mac implementation
383     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
384     controller->keepWebHistory();
385 
386     return JSValueMakeUndefined(context);
387 }
388 
notifyDoneCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)389 static JSValueRef notifyDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
390 {
391     // Has mac & windows implementation
392     // May be able to be made platform independant by using shared WorkQueue
393     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
394     controller->notifyDone();
395     return JSValueMakeUndefined(context);
396 }
397 
queueBackNavigationCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)398 static JSValueRef queueBackNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
399 {
400     // Has mac & windows implementation
401     // May be able to be made platform independant by using shared WorkQueue
402     if (argumentCount < 1)
403         return JSValueMakeUndefined(context);
404 
405     double howFarBackDouble = JSValueToNumber(context, arguments[0], exception);
406     ASSERT(!*exception);
407 
408     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
409     controller->queueBackNavigation(static_cast<int>(howFarBackDouble));
410 
411     return JSValueMakeUndefined(context);
412 }
413 
queueForwardNavigationCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)414 static JSValueRef queueForwardNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
415 {
416     // Has mac & windows implementation
417     // May be able to be made platform independant by using shared WorkQueue
418     if (argumentCount < 1)
419         return JSValueMakeUndefined(context);
420 
421     double howFarForwardDouble = JSValueToNumber(context, arguments[0], exception);
422     ASSERT(!*exception);
423 
424     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
425     controller->queueForwardNavigation(static_cast<int>(howFarForwardDouble));
426 
427     return JSValueMakeUndefined(context);
428 }
429 
queueLoadCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)430 static JSValueRef queueLoadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
431 {
432     // Has mac & windows implementation
433     // May be able to be made platform independant by using shared WorkQueue
434     if (argumentCount < 1)
435         return JSValueMakeUndefined(context);
436 
437     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
438     ASSERT(!*exception);
439 
440     JSRetainPtr<JSStringRef> target;
441     if (argumentCount >= 2) {
442         target.adopt(JSValueToStringCopy(context, arguments[1], exception));
443         ASSERT(!*exception);
444     } else
445         target.adopt(JSStringCreateWithUTF8CString(""));
446 
447     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
448     controller->queueLoad(url.get(), target.get());
449 
450     return JSValueMakeUndefined(context);
451 }
452 
queueReloadCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)453 static JSValueRef queueReloadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
454 {
455     // Has mac & windows implementation
456     // May be able to be made platform independant by using shared WorkQueue
457 
458     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
459     controller->queueReload();
460 
461     return JSValueMakeUndefined(context);
462 }
463 
queueLoadingScriptCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)464 static JSValueRef queueLoadingScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
465 {
466     // Has mac & windows implementation
467     // May be able to be made platform independant by using shared WorkQueue
468     if (argumentCount < 1)
469         return JSValueMakeUndefined(context);
470 
471     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
472     ASSERT(!*exception);
473 
474     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
475     controller->queueLoadingScript(script.get());
476 
477     return JSValueMakeUndefined(context);
478 }
479 
queueNonLoadingScriptCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)480 static JSValueRef queueNonLoadingScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
481 {
482     // Has mac & windows implementation
483     // May be able to be made platform independant by using shared WorkQueue
484     if (argumentCount < 1)
485         return JSValueMakeUndefined(context);
486 
487     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
488     ASSERT(!*exception);
489 
490     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
491     controller->queueNonLoadingScript(script.get());
492 
493     return JSValueMakeUndefined(context);
494 }
495 
setAcceptsEditingCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)496 static JSValueRef setAcceptsEditingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
497 {
498     // Has mac & windows implementation
499     if (argumentCount < 1)
500         return JSValueMakeUndefined(context);
501 
502     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
503     controller->setAcceptsEditing(JSValueToBoolean(context, arguments[0]));
504 
505     return JSValueMakeUndefined(context);
506 }
507 
setAppCacheMaximumSizeCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)508 static JSValueRef setAppCacheMaximumSizeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
509 {
510     // Has mac implementation
511     if (argumentCount < 1)
512         return JSValueMakeUndefined(context);
513 
514     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
515 
516     double size = JSValueToNumber(context, arguments[0], NULL);
517     if (!isnan(size))
518         controller->setAppCacheMaximumSize(static_cast<unsigned long long>(size));
519 
520     return JSValueMakeUndefined(context);
521 
522 }
523 
setAuthorAndUserStylesEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)524 static JSValueRef setAuthorAndUserStylesEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
525 {
526     // Has mac & windows implementation
527     if (argumentCount < 1)
528         return JSValueMakeUndefined(context);
529 
530     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
531     controller->setAuthorAndUserStylesEnabled(JSValueToBoolean(context, arguments[0]));
532 
533     return JSValueMakeUndefined(context);
534 }
535 
setCacheModelCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)536 static JSValueRef setCacheModelCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
537 {
538     // Has Mac implementation.
539     if (argumentCount < 1)
540         return JSValueMakeUndefined(context);
541 
542     int cacheModel = JSValueToNumber(context, arguments[0], exception);
543     ASSERT(!*exception);
544 
545     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
546     controller->setCacheModel(cacheModel);
547 
548     return JSValueMakeUndefined(context);
549 }
550 
setCustomPolicyDelegateCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)551 static JSValueRef setCustomPolicyDelegateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
552 {
553     // Has mac implementation
554     if (argumentCount < 1)
555         return JSValueMakeUndefined(context);
556 
557     bool permissive = false;
558     if (argumentCount >= 2)
559         permissive = JSValueToBoolean(context, arguments[1]);
560 
561     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
562     controller->setCustomPolicyDelegate(JSValueToBoolean(context, arguments[0]), permissive);
563 
564     return JSValueMakeUndefined(context);
565 }
566 
setDatabaseQuotaCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)567 static JSValueRef setDatabaseQuotaCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
568 {
569     // Has mac implementation
570     if (argumentCount < 1)
571         return JSValueMakeUndefined(context);
572 
573     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
574 
575     double quota = JSValueToNumber(context, arguments[0], NULL);
576     if (!isnan(quota))
577         controller->setDatabaseQuota(static_cast<unsigned long long>(quota));
578 
579     return JSValueMakeUndefined(context);
580 
581 }
582 
setIconDatabaseEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)583 static JSValueRef setIconDatabaseEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
584 {
585     // Has mac & windows implementation
586     if (argumentCount < 1)
587         return JSValueMakeUndefined(context);
588 
589     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
590     controller->setIconDatabaseEnabled(JSValueToBoolean(context, arguments[0]));
591 
592     return JSValueMakeUndefined(context);
593 }
594 
setJavaScriptProfilingEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)595 static JSValueRef setJavaScriptProfilingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
596 {
597     if (argumentCount < 1)
598         return JSValueMakeUndefined(context);
599 
600     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
601     controller->setJavaScriptProfilingEnabled(JSValueToBoolean(context, arguments[0]));
602 
603     return JSValueMakeUndefined(context);
604 }
605 
setMainFrameIsFirstResponderCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)606 static JSValueRef setMainFrameIsFirstResponderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
607 {
608     // Has mac implementation
609     if (argumentCount < 1)
610         return JSValueMakeUndefined(context);
611 
612     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
613     controller->setMainFrameIsFirstResponder(JSValueToBoolean(context, arguments[0]));
614 
615     return JSValueMakeUndefined(context);
616 }
617 
setPersistentUserStyleSheetLocationCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)618 static JSValueRef setPersistentUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
619 {
620     // Has mac implementation
621     if (argumentCount < 1)
622         return JSValueMakeUndefined(context);
623 
624     JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
625     ASSERT(!*exception);
626 
627     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
628     controller->setPersistentUserStyleSheetLocation(path.get());
629 
630     return JSValueMakeUndefined(context);
631 }
632 
setPrivateBrowsingEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)633 static JSValueRef setPrivateBrowsingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
634 {
635     // Has mac & windows implementation
636     if (argumentCount < 1)
637         return JSValueMakeUndefined(context);
638 
639     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
640     controller->setPrivateBrowsingEnabled(JSValueToBoolean(context, arguments[0]));
641 
642     return JSValueMakeUndefined(context);
643 }
644 
setXSSAuditorEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)645 static JSValueRef setXSSAuditorEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
646 {
647     // Has mac & windows implementation
648     if (argumentCount < 1)
649         return JSValueMakeUndefined(context);
650 
651     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
652     controller->setXSSAuditorEnabled(JSValueToBoolean(context, arguments[0]));
653 
654     return JSValueMakeUndefined(context);
655 }
656 
setTabKeyCyclesThroughElementsCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)657 static JSValueRef setTabKeyCyclesThroughElementsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
658 {
659     // Has mac & windows implementation
660     if (argumentCount < 1)
661         return JSValueMakeUndefined(context);
662 
663     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
664     controller->setTabKeyCyclesThroughElements(JSValueToBoolean(context, arguments[0]));
665 
666     return JSValueMakeUndefined(context);
667 }
668 
setUseDashboardCompatibilityModeCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)669 static JSValueRef setUseDashboardCompatibilityModeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
670 {
671     // Has mac implementation
672     if (argumentCount < 1)
673         return JSValueMakeUndefined(context);
674 
675     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
676     controller->setUseDashboardCompatibilityMode(JSValueToBoolean(context, arguments[0]));
677 
678     return JSValueMakeUndefined(context);
679 }
680 
setUserStyleSheetEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)681 static JSValueRef setUserStyleSheetEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
682 {
683     // Has mac implementation
684     if (argumentCount < 1)
685         return JSValueMakeUndefined(context);
686 
687     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
688     controller->setUserStyleSheetEnabled(JSValueToBoolean(context, arguments[0]));
689 
690     return JSValueMakeUndefined(context);
691 }
692 
setUserStyleSheetLocationCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)693 static JSValueRef setUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
694 {
695     // Has mac implementation
696     if (argumentCount < 1)
697         return JSValueMakeUndefined(context);
698 
699     JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
700     ASSERT(!*exception);
701 
702     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
703     controller->setUserStyleSheetLocation(path.get());
704 
705     return JSValueMakeUndefined(context);
706 }
707 
setWillSendRequestReturnsNullOnRedirectCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)708 static JSValueRef setWillSendRequestReturnsNullOnRedirectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
709 {
710     // Has cross-platform implementation
711     if (argumentCount < 1)
712         return JSValueMakeUndefined(context);
713 
714     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
715     controller->setWillSendRequestReturnsNullOnRedirect(JSValueToBoolean(context, arguments[0]));
716 
717     return JSValueMakeUndefined(context);
718 }
719 
setWindowIsKeyCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)720 static JSValueRef setWindowIsKeyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
721 {
722     // Has mac implementation
723     if (argumentCount < 1)
724         return JSValueMakeUndefined(context);
725 
726     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
727     controller->setWindowIsKey(JSValueToBoolean(context, arguments[0]));
728 
729     return JSValueMakeUndefined(context);
730 }
731 
waitUntilDoneCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)732 static JSValueRef waitUntilDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
733 {
734     // Has mac & windows implementation
735     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
736     controller->setWaitToDump(true);
737 
738     return JSValueMakeUndefined(context);
739 }
740 
windowCountCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)741 static JSValueRef windowCountCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
742 {
743     // Has mac implementation
744     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
745     int windows = controller->windowCount();
746     return JSValueMakeNumber(context, windows);
747 }
748 
setPopupBlockingEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)749 static JSValueRef setPopupBlockingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
750 {
751     // Has mac & windows implementation
752     if (argumentCount < 1)
753         return JSValueMakeUndefined(context);
754 
755     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
756     controller->setPopupBlockingEnabled(JSValueToBoolean(context, arguments[0]));
757 
758     return JSValueMakeUndefined(context);
759 }
760 
setSmartInsertDeleteEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)761 static JSValueRef setSmartInsertDeleteEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
762 {
763     if (argumentCount < 1)
764         return JSValueMakeUndefined(context);
765 
766     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
767     controller->setSmartInsertDeleteEnabled(JSValueToBoolean(context, arguments[0]));
768     return JSValueMakeUndefined(context);
769 }
770 
setSelectTrailingWhitespaceEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)771 static JSValueRef setSelectTrailingWhitespaceEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
772 {
773     if (argumentCount < 1)
774         return JSValueMakeUndefined(context);
775 
776     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
777     controller->setSelectTrailingWhitespaceEnabled(JSValueToBoolean(context, arguments[0]));
778     return JSValueMakeUndefined(context);
779 }
780 
setStopProvisionalFrameLoadsCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)781 static JSValueRef setStopProvisionalFrameLoadsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
782 {
783     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
784     controller->setStopProvisionalFrameLoads(true);
785     return JSValueMakeUndefined(context);
786 }
787 
elementDoesAutoCompleteForElementWithIdCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)788 static JSValueRef elementDoesAutoCompleteForElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
789 {
790     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
791     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
792     ASSERT(!*exception);
793 
794     bool autoCompletes = controller->elementDoesAutoCompleteForElementWithId(elementId.get());
795 
796     return JSValueMakeBoolean(context, autoCompletes);
797 }
798 
pauseAnimationAtTimeOnElementWithIdCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)799 static JSValueRef pauseAnimationAtTimeOnElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
800 {
801     if (argumentCount != 3)
802         return JSValueMakeUndefined(context);
803 
804     JSRetainPtr<JSStringRef> animationName(Adopt, JSValueToStringCopy(context, arguments[0], exception));
805     ASSERT(!*exception);
806     double time = JSValueToNumber(context, arguments[1], exception);
807     ASSERT(!*exception);
808     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
809     ASSERT(!*exception);
810 
811     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
812     return JSValueMakeBoolean(context, controller->pauseAnimationAtTimeOnElementWithId(animationName.get(), time, elementId.get()));
813 }
814 
pauseTransitionAtTimeOnElementWithIdCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)815 static JSValueRef pauseTransitionAtTimeOnElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
816 {
817     if (argumentCount != 3)
818         return JSValueMakeUndefined(context);
819 
820     JSRetainPtr<JSStringRef> propertyName(Adopt, JSValueToStringCopy(context, arguments[0], exception));
821     ASSERT(!*exception);
822     double time = JSValueToNumber(context, arguments[1], exception);
823     ASSERT(!*exception);
824     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
825     ASSERT(!*exception);
826 
827     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
828     return JSValueMakeBoolean(context, controller->pauseTransitionAtTimeOnElementWithId(propertyName.get(), time, elementId.get()));
829 }
830 
numberOfActiveAnimationsCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)831 static JSValueRef numberOfActiveAnimationsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
832 {
833     if (argumentCount != 0)
834         return JSValueMakeUndefined(context);
835 
836     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
837     return JSValueMakeNumber(context, controller->numberOfActiveAnimations());
838 }
839 
waitForPolicyDelegateCallback(JSContextRef context,JSObjectRef,JSObjectRef thisObject,size_t,const JSValueRef[],JSValueRef *)840 static JSValueRef waitForPolicyDelegateCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*)
841 {
842     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
843     controller->waitForPolicyDelegate();
844     return JSValueMakeUndefined(context);
845 }
846 
847 // Static Values
848 
getGlobalFlagCallback(JSContextRef context,JSObjectRef thisObject,JSStringRef propertyName,JSValueRef * exception)849 static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
850 {
851     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
852     return JSValueMakeBoolean(context, controller->globalFlag());
853 }
854 
getWebHistoryItemCountCallback(JSContextRef context,JSObjectRef thisObject,JSStringRef propertyName,JSValueRef * exception)855 static JSValueRef getWebHistoryItemCountCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
856 {
857     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
858     return JSValueMakeNumber(context, controller->webHistoryItemCount());
859 }
860 
setGlobalFlagCallback(JSContextRef context,JSObjectRef thisObject,JSStringRef propertyName,JSValueRef value,JSValueRef * exception)861 static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
862 {
863     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
864     controller->setGlobalFlag(JSValueToBoolean(context, value));
865     return true;
866 }
867 
layoutTestControllerObjectFinalize(JSObjectRef object)868 static void layoutTestControllerObjectFinalize(JSObjectRef object)
869 {
870     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(object));
871     controller->deref();
872 }
873 
874 // Object Creation
875 
makeWindowObject(JSContextRef context,JSObjectRef windowObject,JSValueRef * exception)876 void LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
877 {
878     JSRetainPtr<JSStringRef> layoutTestContollerStr(Adopt, JSStringCreateWithUTF8CString("layoutTestController"));
879     ref();
880     JSValueRef layoutTestContollerObject = JSObjectMake(context, getJSClass(), this);
881     JSObjectSetProperty(context, windowObject, layoutTestContollerStr.get(), layoutTestContollerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
882 }
883 
getJSClass()884 JSClassRef LayoutTestController::getJSClass()
885 {
886     static JSClassRef layoutTestControllerClass;
887 
888     if (!layoutTestControllerClass) {
889         JSStaticValue* staticValues = LayoutTestController::staticValues();
890         JSStaticFunction* staticFunctions = LayoutTestController::staticFunctions();
891         JSClassDefinition classDefinition = {
892             0, kJSClassAttributeNone, "LayoutTestController", 0, staticValues, staticFunctions,
893             0, layoutTestControllerObjectFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
894         };
895 
896         layoutTestControllerClass = JSClassCreate(&classDefinition);
897     }
898 
899     return layoutTestControllerClass;
900 }
901 
staticValues()902 JSStaticValue* LayoutTestController::staticValues()
903 {
904     static JSStaticValue staticValues[] = {
905         { "globalFlag", getGlobalFlagCallback, setGlobalFlagCallback, kJSPropertyAttributeNone },
906         { "webHistoryItemCount", getWebHistoryItemCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
907         { 0, 0, 0, 0 }
908     };
909     return staticValues;
910 }
911 
staticFunctions()912 JSStaticFunction* LayoutTestController::staticFunctions()
913 {
914     static JSStaticFunction staticFunctions[] = {
915         { "addDisallowedURL", addDisallowedURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
916         { "clearAllDatabases", clearAllDatabasesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
917         { "clearBackForwardList", clearBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
918         { "clearPersistentUserStyleSheet", clearPersistentUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
919         { "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
920         { "disableImageLoading", disableImageLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
921         { "dispatchPendingLoadRequests", dispatchPendingLoadRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
922         { "display", displayCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
923         { "dumpAsText", dumpAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
924         { "dumpBackForwardList", dumpBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
925         { "dumpChildFrameScrollPositions", dumpChildFrameScrollPositionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
926         { "dumpChildFramesAsText", dumpChildFramesAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
927         { "dumpDOMAsWebArchive", dumpDOMAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
928         { "dumpDatabaseCallbacks", dumpDatabaseCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
929         { "dumpEditingCallbacks", dumpEditingCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
930         { "dumpResourceLoadCallbacks", dumpResourceLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
931         { "dumpResourceResponseMIMETypes", dumpResourceResponseMIMETypesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
932         { "dumpSelectionRect", dumpSelectionRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
933         { "dumpSourceAsWebArchive", dumpSourceAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
934         { "dumpStatusCallbacks", dumpStatusCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
935         { "dumpTitleChanges", dumpTitleChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
936         { "dumpWillCacheResponse", dumpWillCacheResponseCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
937         { "elementDoesAutoCompleteForElementWithId", elementDoesAutoCompleteForElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
938         { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
939         { "execCommand", execCommandCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
940         { "isCommandEnabled", isCommandEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
941         { "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
942         { "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
943         { "numberOfActiveAnimations", numberOfActiveAnimationsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
944         { "pathToLocalResource", pathToLocalResourceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
945         { "pauseAnimationAtTimeOnElementWithId", pauseAnimationAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
946         { "pauseTransitionAtTimeOnElementWithId", pauseTransitionAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
947         { "printToPDF", dumpAsPDFCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
948         { "queueBackNavigation", queueBackNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
949         { "queueForwardNavigation", queueForwardNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
950         { "queueLoad", queueLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
951         { "queueLoadingScript", queueLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
952         { "queueNonLoadingScript", queueNonLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
953         { "queueReload", queueReloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
954         { "repaintSweepHorizontally", repaintSweepHorizontallyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
955         { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
956         { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
957         { "setAppCacheMaximumSize", setAppCacheMaximumSizeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
958         { "setCallCloseOnWebViews", setCallCloseOnWebViewsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
959         { "setCanOpenWindows", setCanOpenWindowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
960         { "setCacheModel", setCacheModelCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
961         { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
962         { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
963         { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
964         { "setIconDatabaseEnabled", setIconDatabaseEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
965         { "setJavaScriptProfilingEnabled", setJavaScriptProfilingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
966         { "setMainFrameIsFirstResponder", setMainFrameIsFirstResponderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
967         { "setPersistentUserStyleSheetLocation", setPersistentUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
968         { "setPopupBlockingEnabled", setPopupBlockingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
969         { "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
970         { "setXSSAuditorEnabled", setXSSAuditorEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
971         { "setSelectTrailingWhitespaceEnabled", setSelectTrailingWhitespaceEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
972         { "setSmartInsertDeleteEnabled", setSmartInsertDeleteEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
973         { "setStopProvisionalFrameLoads", setStopProvisionalFrameLoadsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
974         { "setTabKeyCyclesThroughElements", setTabKeyCyclesThroughElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
975         { "setUseDashboardCompatibilityMode", setUseDashboardCompatibilityModeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
976         { "setUserStyleSheetEnabled", setUserStyleSheetEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
977         { "setUserStyleSheetLocation", setUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
978         { "setWillSendRequestReturnsNullOnRedirect", setWillSendRequestReturnsNullOnRedirectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
979         { "setWindowIsKey", setWindowIsKeyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
980         { "testOnscreen", testOnscreenCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
981         { "testRepaint", testRepaintCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
982         { "waitForPolicyDelegate", waitForPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
983         { "waitUntilDone", waitUntilDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
984         { "windowCount", windowCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
985         { 0, 0, 0 }
986     };
987 
988     return staticFunctions;
989 }
990 
queueBackNavigation(int howFarBack)991 void LayoutTestController::queueBackNavigation(int howFarBack)
992 {
993     WorkQueue::shared()->queue(new BackItem(howFarBack));
994 }
995 
queueForwardNavigation(int howFarForward)996 void LayoutTestController::queueForwardNavigation(int howFarForward)
997 {
998     WorkQueue::shared()->queue(new ForwardItem(howFarForward));
999 }
1000 
queueLoadingScript(JSStringRef script)1001 void LayoutTestController::queueLoadingScript(JSStringRef script)
1002 {
1003     WorkQueue::shared()->queue(new LoadingScriptItem(script));
1004 }
1005 
queueNonLoadingScript(JSStringRef script)1006 void LayoutTestController::queueNonLoadingScript(JSStringRef script)
1007 {
1008     WorkQueue::shared()->queue(new NonLoadingScriptItem(script));
1009 }
1010 
queueReload()1011 void LayoutTestController::queueReload()
1012 {
1013     WorkQueue::shared()->queue(new ReloadItem);
1014 }
1015