[Mac] WebInspectorUI.framework does not need to be soft-linked anymore
[WebKit-https.git] / Tools / DumpRenderTree / TestRunner.cpp
1 /*
2  * Copyright (C) 2007-2016 Apple Inc. All rights reserved.
3  * Copyright (C) 2010 Joone Hur <joone@kldp.org>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer. 
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution. 
14  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission. 
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "TestRunner.h"
32
33 #include "WebCoreTestSupport.h"
34 #include "WorkQueue.h"
35 #include "WorkQueueItem.h"
36 #include <JavaScriptCore/APICast.h>
37 #include <JavaScriptCore/ArrayBufferView.h>
38 #include <JavaScriptCore/HeapInlines.h>
39 #include <JavaScriptCore/JSArrayBufferView.h>
40 #include <JavaScriptCore/JSCTestRunnerUtils.h>
41 #include <JavaScriptCore/JSContextRef.h>
42 #include <JavaScriptCore/JSObjectRef.h>
43 #include <JavaScriptCore/JSRetainPtr.h>
44 #include <JavaScriptCore/TypedArrayInlines.h>
45 #include <JavaScriptCore/VMInlines.h>
46 #include <WebCore/LogInitialization.h>
47 #include <cstring>
48 #include <locale.h>
49 #include <stdio.h>
50 #include <wtf/Assertions.h>
51 #include <wtf/LoggingAccumulator.h>
52 #include <wtf/MathExtras.h>
53 #include <wtf/RefPtr.h>
54 #include <wtf/RunLoop.h>
55 #include <wtf/StdLibExtras.h>
56 #include <wtf/WallTime.h>
57 #include <wtf/text/WTFString.h>
58
59 #if PLATFORM(IOS_FAMILY)
60 #include <WebCore/WebCoreThreadRun.h>
61 #include <wtf/BlockPtr.h>
62 #endif
63
64 #if PLATFORM(MAC) && !PLATFORM(IOS_FAMILY)
65 #include <Carbon/Carbon.h>
66 #endif
67
68 FILE* testResult = stdout;
69
70 const unsigned TestRunner::viewWidth = 800;
71 const unsigned TestRunner::viewHeight = 600;
72
73 const unsigned TestRunner::w3cSVGViewWidth = 480;
74 const unsigned TestRunner::w3cSVGViewHeight = 360;
75
76 TestRunner::TestRunner(const std::string& testURL, const std::string& expectedPixelHash)
77     : m_disallowIncreaseForApplicationCacheQuota(false)
78     , m_dumpApplicationCacheDelegateCallbacks(false)
79     , m_dumpAsAudio(false)
80     , m_dumpAsPDF(false)
81     , m_dumpAsText(false)
82     , m_dumpBackForwardList(false)
83     , m_dumpChildFrameScrollPositions(false)
84     , m_dumpChildFramesAsText(false)
85     , m_dumpDOMAsWebArchive(false)
86     , m_dumpDatabaseCallbacks(false)
87     , m_dumpEditingCallbacks(false)
88     , m_dumpFrameLoadCallbacks(false)
89     , m_dumpProgressFinishedCallback(false)
90     , m_dumpUserGestureInFrameLoadCallbacks(false)
91     , m_dumpHistoryDelegateCallbacks(false)
92     , m_dumpResourceLoadCallbacks(false)
93     , m_dumpResourceResponseMIMETypes(false)
94     , m_dumpSelectionRect(false)
95     , m_dumpSourceAsWebArchive(false)
96     , m_dumpStatusCallbacks(false)
97     , m_dumpTitleChanges(false)
98     , m_dumpVisitedLinksCallback(false)
99     , m_dumpWillCacheResponse(false)
100     , m_generatePixelResults(true)
101     , m_callCloseOnWebViews(true)
102     , m_canOpenWindows(false)
103     , m_closeRemainingWindowsWhenComplete(true)
104     , m_newWindowsCopyBackForwardList(false)
105     , m_stopProvisionalFrameLoads(false)
106     , m_testOnscreen(false)
107     , m_testRepaint(false)
108     , m_testRepaintSweepHorizontally(false)
109     , m_waitToDump(false)
110     , m_willSendRequestReturnsNull(false)
111     , m_willSendRequestReturnsNullOnRedirect(false)
112     , m_windowIsKey(true)
113     , m_alwaysAcceptCookies(false)
114     , m_globalFlag(false)
115     , m_isGeolocationPermissionSet(false)
116     , m_geolocationPermission(false)
117     , m_rejectsProtectionSpaceAndContinueForAuthenticationChallenges(false)
118     , m_handlesAuthenticationChallenges(false)
119     , m_isPrinting(false)
120     , m_useDeferredFrameLoading(false)
121     , m_shouldPaintBrokenImage(true)
122     , m_shouldStayOnPageAfterHandlingBeforeUnload(false)
123     , m_areLegacyWebNotificationPermissionRequestsIgnored(false)
124     , m_customFullScreenBehavior(false) 
125     , m_hasPendingWebNotificationClick(false)
126     , m_databaseDefaultQuota(-1)
127     , m_databaseMaxQuota(-1)
128     , m_testURL(testURL)
129     , m_expectedPixelHash(expectedPixelHash)
130     , m_titleTextDirection("ltr")
131     , m_timeout(0)
132 {
133 }
134
135 Ref<TestRunner> TestRunner::create(const std::string& testURL, const std::string& expectedPixelHash)
136 {
137     return adoptRef(*new TestRunner(testURL, expectedPixelHash));
138 }
139
140 // Static Functions
141
142 static JSValueRef disallowIncreaseForApplicationCacheQuotaCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
143 {
144     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
145     controller->setDisallowIncreaseForApplicationCacheQuota(true);
146     return JSValueMakeUndefined(context);
147 }
148
149 static JSValueRef dumpApplicationCacheDelegateCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
150 {
151     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
152     controller->setDumpApplicationCacheDelegateCallbacks(true);
153     return JSValueMakeUndefined(context);
154 }
155
156 static JSValueRef dumpAsPDFCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
157 {
158     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
159     controller->setDumpAsPDF(true);
160     return JSValueMakeUndefined(context);
161 }
162
163 static JSValueRef dumpAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
164 {
165     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
166     controller->setDumpAsText(true);
167
168     // Optional paramater, describing whether it's allowed to dump pixel results in dumpAsText mode.
169     controller->setGeneratePixelResults(argumentCount > 0 ? JSValueToBoolean(context, arguments[0]) : false);
170
171     return JSValueMakeUndefined(context);
172 }
173
174 static JSValueRef dumpBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
175 {
176     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
177     controller->setDumpBackForwardList(true);
178     return JSValueMakeUndefined(context);
179 }
180
181 static JSValueRef dumpChildFramesAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
182 {
183     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
184     controller->setDumpChildFramesAsText(true);
185     return JSValueMakeUndefined(context);
186 }
187
188 static JSValueRef dumpChildFrameScrollPositionsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
189 {
190     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
191     controller->setDumpChildFrameScrollPositions(true);
192     return JSValueMakeUndefined(context);
193 }
194
195 static JSValueRef dumpDatabaseCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
196 {
197     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
198     controller->setDumpDatabaseCallbacks(true);
199     return JSValueMakeUndefined(context);
200 }
201
202 static JSValueRef dumpDOMAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
203 {
204     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
205     controller->setDumpDOMAsWebArchive(true);
206     return JSValueMakeUndefined(context);
207 }
208
209 static JSValueRef dumpEditingCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
210 {
211     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
212     controller->setDumpEditingCallbacks(true);
213     return JSValueMakeUndefined(context);
214 }
215
216 static JSValueRef dumpFrameLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
217 {
218     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
219     controller->setDumpFrameLoadCallbacks(true);
220     return JSValueMakeUndefined(context);
221 }
222
223 static JSValueRef dumpProgressFinishedCallbackCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
224 {
225     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
226     controller->setDumpProgressFinishedCallback(true);
227     return JSValueMakeUndefined(context);
228 }
229
230 static JSValueRef dumpUserGestureInFrameLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
231 {
232     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
233     controller->setDumpUserGestureInFrameLoadCallbacks(true);
234     return JSValueMakeUndefined(context);
235 }
236
237 static JSValueRef dumpResourceLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
238 {
239     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
240     controller->setDumpResourceLoadCallbacks(true);
241     return JSValueMakeUndefined(context);
242 }
243
244 static JSValueRef dumpResourceResponseMIMETypesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
245 {
246     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
247     controller->setDumpResourceResponseMIMETypes(true);
248     return JSValueMakeUndefined(context);
249 }
250
251 static JSValueRef dumpSelectionRectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
252 {
253     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
254     controller->setDumpSelectionRect(true);
255     return JSValueMakeUndefined(context);
256 }
257
258 static JSValueRef dumpSourceAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
259 {
260     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
261     controller->setDumpSourceAsWebArchive(true);
262     return JSValueMakeUndefined(context);
263 }
264
265 static JSValueRef dumpStatusCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
266 {
267     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
268     controller->setDumpStatusCallbacks(true);
269     return JSValueMakeUndefined(context);
270 }
271
272 static JSValueRef dumpTitleChangesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
273 {
274     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
275     controller->setDumpTitleChanges(true);
276     return JSValueMakeUndefined(context);
277 }
278
279 static JSValueRef dumpWillCacheResponseCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
280 {
281     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
282     controller->setDumpWillCacheResponse(true);
283     return JSValueMakeUndefined(context);
284 }
285
286 static JSValueRef pathToLocalResourceCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
287 {
288     if (argumentCount < 1)
289         return JSValueMakeUndefined(context);
290
291     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
292     auto localPath = adopt(JSValueToStringCopy(context, arguments[0], exception));
293     ASSERT(!*exception);
294
295     auto convertedPath = controller->pathToLocalResource(context, localPath.get());
296     if (!convertedPath)
297         return JSValueMakeUndefined(context);
298
299     return JSValueMakeString(context, convertedPath.get());
300 }
301
302 static JSValueRef removeAllVisitedLinksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
303 {
304     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
305     controller->setDumpVisitedLinksCallback(true);
306     controller->removeAllVisitedLinks();
307     return JSValueMakeUndefined(context);
308 }
309
310 static JSValueRef repaintSweepHorizontallyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
311 {
312     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
313     controller->setTestRepaintSweepHorizontally(true);
314     return JSValueMakeUndefined(context);
315 }
316
317 static JSValueRef setCallCloseOnWebViewsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
318 {
319     if (argumentCount < 1)
320         return JSValueMakeUndefined(context);
321
322     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
323     controller->setCallCloseOnWebViews(JSValueToBoolean(context, arguments[0]));
324     return JSValueMakeUndefined(context);
325 }
326
327 static JSValueRef setCanOpenWindowsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
328 {
329     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
330     controller->setCanOpenWindows(true);
331     return JSValueMakeUndefined(context);
332 }
333
334 static JSValueRef setCloseRemainingWindowsWhenCompleteCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
335 {
336     if (argumentCount < 1)
337         return JSValueMakeUndefined(context);
338
339     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
340     controller->setCloseRemainingWindowsWhenComplete(JSValueToBoolean(context, arguments[0]));
341     return JSValueMakeUndefined(context);
342 }
343
344 static JSValueRef setAudioResultCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
345 {
346     if (argumentCount < 1)
347         return JSValueMakeUndefined(context);
348
349     // FIXME (123058): Use a JSC API to get buffer contents once such is exposed.
350     JSC::VM& vm = toJS(context)->vm();
351     JSC::JSLockHolder lock(vm);
352
353     JSC::JSArrayBufferView* jsBufferView = JSC::jsDynamicCast<JSC::JSArrayBufferView*>(vm, toJS(toJS(context), arguments[0]));
354     ASSERT(jsBufferView);
355     RefPtr<JSC::ArrayBufferView> bufferView = jsBufferView->unsharedImpl();
356     const char* buffer = static_cast<const char*>(bufferView->baseAddress());
357     std::vector<char> audioData(buffer, buffer + bufferView->byteLength());
358
359     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
360     controller->setAudioResult(audioData);
361     controller->setDumpAsAudio(true);
362
363     return JSValueMakeUndefined(context);
364 }
365
366 static JSValueRef testOnscreenCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
367 {
368     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
369     controller->setTestOnscreen(true);
370     return JSValueMakeUndefined(context);
371 }
372
373 static JSValueRef testRepaintCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
374 {
375     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
376     controller->setTestRepaint(true);
377     return JSValueMakeUndefined(context);
378 }
379
380 static JSValueRef addDisallowedURLCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
381 {
382     // Has mac implementation
383     if (argumentCount < 1)
384         return JSValueMakeUndefined(context);
385
386     auto url = adopt(JSValueToStringCopy(context, arguments[0], exception));
387     ASSERT(!*exception);
388
389     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
390     controller->addDisallowedURL(url.get());
391
392     return JSValueMakeUndefined(context);
393 }
394
395 static JSValueRef addURLToRedirectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
396 {
397     if (argumentCount < 2)
398         return JSValueMakeUndefined(context);
399
400     auto origin = adopt(JSValueToStringCopy(context, arguments[0], exception));
401     ASSERT(!*exception);
402
403     auto destination = adopt(JSValueToStringCopy(context, arguments[1], exception));
404     ASSERT(!*exception);
405
406     size_t maxLength = JSStringGetMaximumUTF8CStringSize(origin.get());
407     auto originBuffer = std::make_unique<char[]>(maxLength + 1);
408     JSStringGetUTF8CString(origin.get(), originBuffer.get(), maxLength + 1);
409
410     maxLength = JSStringGetMaximumUTF8CStringSize(destination.get());
411     auto destinationBuffer = std::make_unique<char[]>(maxLength + 1);
412     JSStringGetUTF8CString(destination.get(), destinationBuffer.get(), maxLength + 1);
413
414     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
415     controller->addURLToRedirect(originBuffer.get(), destinationBuffer.get());
416
417     return JSValueMakeUndefined(context);
418 }
419
420 static JSValueRef callShouldCloseOnWebViewCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
421 {
422     // Has mac & windows implementation
423     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
424
425     return JSValueMakeBoolean(context, controller->callShouldCloseOnWebView());
426 }
427
428 static JSValueRef clearAllApplicationCachesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
429 {
430     // Has mac implementation
431     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
432     controller->clearAllApplicationCaches();
433
434     return JSValueMakeUndefined(context);
435 }
436
437 static JSValueRef clearApplicationCacheForOriginCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
438 {
439     if (argumentCount < 1)
440         return JSValueMakeUndefined(context);
441
442     auto originURL = adopt(JSValueToStringCopy(context, arguments[0], exception));
443     ASSERT(!*exception);
444
445     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
446     controller->clearApplicationCacheForOrigin(originURL.get());
447     
448     return JSValueMakeUndefined(context);
449 }
450
451 static JSValueRef applicationCacheDiskUsageForOriginCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
452 {
453     if (argumentCount < 1)
454         return JSValueMakeUndefined(context);
455
456     auto originURL = adopt(JSValueToStringCopy(context, arguments[0], exception));
457     ASSERT(!*exception);
458     
459     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
460
461     return JSValueMakeNumber(context, controller->applicationCacheDiskUsageForOrigin(originURL.get()));
462 }
463
464 static JSValueRef originsWithApplicationCacheCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
465 {
466     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
467     return controller->originsWithApplicationCache(context);
468 }
469
470 static JSValueRef clearAllDatabasesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
471 {
472     // Has mac & windows implementation
473     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
474     controller->clearAllDatabases();
475
476     return JSValueMakeUndefined(context);
477 }
478
479 static JSValueRef clearBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
480 {
481     // Has mac & windows implementation
482     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
483     controller->clearBackForwardList();
484
485     return JSValueMakeUndefined(context);
486 }
487
488 static JSValueRef clearPersistentUserStyleSheetCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
489 {
490     // Has mac & windows implementation
491     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
492     controller->clearPersistentUserStyleSheet();
493
494     return JSValueMakeUndefined(context);
495 }
496
497 static JSValueRef decodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
498 {
499     // Has mac implementation
500     if (argumentCount < 1)
501         return JSValueMakeUndefined(context);
502
503     auto name = adopt(JSValueToStringCopy(context, arguments[0], exception));
504     ASSERT(!*exception);
505
506     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
507     auto decodedHostName = controller->copyDecodedHostName(name.get());
508     return JSValueMakeString(context, decodedHostName.get());
509 }
510
511 static JSValueRef dispatchPendingLoadRequestsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
512 {
513     // Has mac implementation, needs windows implementation
514     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
515     controller->dispatchPendingLoadRequests();
516     
517     return JSValueMakeUndefined(context);
518 }
519
520 static JSValueRef displayCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
521 {
522     // Has mac & windows implementation
523     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
524     controller->display();
525
526     return JSValueMakeUndefined(context);
527 }
528
529 static JSValueRef displayAndTrackRepaintsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
530 {
531     // Has mac & windows implementation
532     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
533     controller->displayAndTrackRepaints();
534
535     return JSValueMakeUndefined(context);
536 }
537
538 static JSValueRef encodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
539 {
540     // Has mac implementation
541     if (argumentCount < 1)
542         return JSValueMakeUndefined(context);
543
544     auto name = adopt(JSValueToStringCopy(context, arguments[0], exception));
545     ASSERT(!*exception);
546
547     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
548     auto encodedHostName = controller->copyEncodedHostName(name.get());
549     return JSValueMakeString(context, encodedHostName.get());
550 }
551
552 static JSValueRef execCommandCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
553 {
554     // Has Mac & Windows implementations.
555     if (argumentCount < 1)
556         return JSValueMakeUndefined(context);
557
558     auto name = adopt(JSValueToStringCopy(context, arguments[0], exception));
559     ASSERT(!*exception);
560
561     // Ignoring the second parameter (userInterface), as this command emulates a manual action.
562
563     JSRetainPtr<JSStringRef> value;
564     if (argumentCount >= 3) {
565         value = adopt(JSValueToStringCopy(context, arguments[2], exception));
566         ASSERT(!*exception);
567     } else
568         value = adopt(JSStringCreateWithUTF8CString(""));
569
570
571     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
572     controller->execCommand(name.get(), value.get());
573
574     return JSValueMakeUndefined(context);
575 }
576
577 static JSValueRef findStringCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
578 {
579     // Has Mac implementation.
580     if (argumentCount < 2)
581         return JSValueMakeUndefined(context);
582
583     auto target = adopt(JSValueToStringCopy(context, arguments[0], exception));
584     ASSERT(!*exception);
585
586     JSObjectRef options = JSValueToObject(context, arguments[1], exception);
587     ASSERT(!*exception);
588
589     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
590     return JSValueMakeBoolean(context, controller->findString(context, target.get(), options));
591 }
592
593 static JSValueRef goBackCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
594 {
595     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
596     controller->goBack();
597     
598     return JSValueMakeUndefined(context);
599 }
600
601 static JSValueRef isCommandEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
602 {
603     // Has Mac implementation.
604
605     if (argumentCount < 1)
606         return JSValueMakeUndefined(context);
607
608     auto name = adopt(JSValueToStringCopy(context, arguments[0], exception));
609     ASSERT(!*exception);
610
611     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
612
613     return JSValueMakeBoolean(context, controller->isCommandEnabled(name.get()));
614 }
615
616 static JSValueRef overridePreferenceCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
617 {
618     if (argumentCount < 2)
619         return JSValueMakeUndefined(context);
620
621     auto key = adopt(JSValueToStringCopy(context, arguments[0], exception));
622     ASSERT(!*exception);
623     auto value = adopt(JSValueToStringCopy(context, arguments[1], exception));
624     ASSERT(!*exception);
625
626     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
627     controller->overridePreference(key.get(), value.get());
628
629     return JSValueMakeUndefined(context);
630 }
631
632 static JSValueRef keepWebHistoryCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
633 {
634     // Has mac implementation
635     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
636     controller->keepWebHistory();
637
638     return JSValueMakeUndefined(context);
639 }
640
641 static JSValueRef notifyDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
642 {
643     // Has mac & windows implementation
644     // May be able to be made platform independant by using shared WorkQueue
645     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
646     controller->notifyDone();
647     return JSValueMakeUndefined(context);
648 }
649
650 static JSValueRef numberOfPendingGeolocationPermissionRequestsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
651 {
652     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
653     return JSValueMakeNumber(context, controller->numberOfPendingGeolocationPermissionRequests());
654 }
655
656 static JSValueRef isGeolocationProviderActiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
657 {
658     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
659     return JSValueMakeBoolean(context, controller->isGeolocationProviderActive());
660 }
661
662 static JSValueRef queueBackNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
663 {
664     // Has mac & windows implementation
665     // May be able to be made platform independant by using shared WorkQueue
666     if (argumentCount < 1)
667         return JSValueMakeUndefined(context);
668
669     double howFarBackDouble = JSValueToNumber(context, arguments[0], exception);
670     ASSERT(!*exception);
671
672     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
673     controller->queueBackNavigation(static_cast<int>(howFarBackDouble));
674
675     return JSValueMakeUndefined(context);
676 }
677
678 static JSValueRef queueForwardNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
679 {
680     // Has mac & windows implementation
681     // May be able to be made platform independant by using shared WorkQueue
682     if (argumentCount < 1)
683         return JSValueMakeUndefined(context);
684
685     double howFarForwardDouble = JSValueToNumber(context, arguments[0], exception);
686     ASSERT(!*exception);
687
688     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
689     controller->queueForwardNavigation(static_cast<int>(howFarForwardDouble));
690
691     return JSValueMakeUndefined(context);
692 }
693
694 static JSValueRef queueLoadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
695 {
696     // Has mac & windows implementation
697     // May be able to be made platform independant by using shared WorkQueue
698     if (argumentCount < 1)
699         return JSValueMakeUndefined(context);
700
701     auto url = adopt(JSValueToStringCopy(context, arguments[0], exception));
702     ASSERT(!*exception);
703
704     JSRetainPtr<JSStringRef> target;
705     if (argumentCount >= 2) {
706         target = adopt(JSValueToStringCopy(context, arguments[1], exception));
707         ASSERT(!*exception);
708     } else
709         target = adopt(JSStringCreateWithUTF8CString(""));
710
711     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
712     controller->queueLoad(url.get(), target.get());
713
714     return JSValueMakeUndefined(context);
715 }
716
717 static JSValueRef queueLoadHTMLStringCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
718 {
719     // Has Mac & Windows implementation
720     if (argumentCount < 1)
721         return JSValueMakeUndefined(context);
722
723     auto content = adopt(JSValueToStringCopy(context, arguments[0], exception));
724     ASSERT(!*exception);
725
726     JSRetainPtr<JSStringRef> baseURL;
727     if (argumentCount >= 2) {
728         baseURL = adopt(JSValueToStringCopy(context, arguments[1], exception));
729         ASSERT(!*exception);
730     } else
731         baseURL = adopt(JSStringCreateWithUTF8CString(""));
732
733     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
734
735     if (argumentCount >= 3) {
736         auto unreachableURL = adopt(JSValueToStringCopy(context, arguments[2], exception));
737         ASSERT(!*exception);
738         controller->queueLoadAlternateHTMLString(content.get(), baseURL.get(), unreachableURL.get());
739         return JSValueMakeUndefined(context);
740     }
741
742     controller->queueLoadHTMLString(content.get(), baseURL.get());
743     return JSValueMakeUndefined(context);
744 }
745
746 static JSValueRef queueReloadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
747 {
748     // Has mac & windows implementation
749     // May be able to be made platform independant by using shared WorkQueue
750
751     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
752     controller->queueReload();
753
754     return JSValueMakeUndefined(context);
755 }
756
757 static JSValueRef queueLoadingScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
758 {
759     // Has mac & windows implementation
760     // May be able to be made platform independant by using shared WorkQueue
761     if (argumentCount < 1)
762         return JSValueMakeUndefined(context);
763
764     auto script = adopt(JSValueToStringCopy(context, arguments[0], exception));
765     ASSERT(!*exception);
766
767     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
768     controller->queueLoadingScript(script.get());
769
770     return JSValueMakeUndefined(context);
771 }
772
773 static JSValueRef queueNonLoadingScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
774 {
775     // Has mac & windows implementation
776     // May be able to be made platform independant by using shared WorkQueue
777     if (argumentCount < 1)
778         return JSValueMakeUndefined(context);
779
780     auto script = adopt(JSValueToStringCopy(context, arguments[0], exception));
781     ASSERT(!*exception);
782
783     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
784     controller->queueNonLoadingScript(script.get());
785
786     return JSValueMakeUndefined(context);
787 }
788
789 static JSValueRef setAcceptsEditingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
790 {
791     // Has mac & windows implementation
792     if (argumentCount < 1)
793         return JSValueMakeUndefined(context);
794
795     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
796     controller->setAcceptsEditing(JSValueToBoolean(context, arguments[0]));
797
798     return JSValueMakeUndefined(context);
799 }
800
801 static JSValueRef setAlwaysAcceptCookiesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
802 {
803     // Has mac & windows implementation
804     if (argumentCount < 1)
805         return JSValueMakeUndefined(context);
806
807     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
808     controller->setAlwaysAcceptCookies(JSValueToBoolean(context, arguments[0]));
809
810     return JSValueMakeUndefined(context);
811 }
812
813 static JSValueRef setOnlyAcceptFirstPartyCookiesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
814 {
815     if (argumentCount < 1)
816         return JSValueMakeUndefined(context);
817
818     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
819     controller->setOnlyAcceptFirstPartyCookies(JSValueToBoolean(context, arguments[0]));
820
821     return JSValueMakeUndefined(context);
822 }
823
824 static JSValueRef setAppCacheMaximumSizeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
825 {
826     // Has mac implementation
827     if (argumentCount < 1)
828         return JSValueMakeUndefined(context);
829
830     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
831
832     double size = JSValueToNumber(context, arguments[0], NULL);
833     if (!std::isnan(size))
834         controller->setAppCacheMaximumSize(static_cast<unsigned long long>(size));
835         
836     return JSValueMakeUndefined(context);
837 }
838
839 static JSValueRef setAuthenticationPasswordCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
840 {
841     // Has mac & windows implementation
842     if (argumentCount < 1)
843         return JSValueMakeUndefined(context);
844
845     auto password = adopt(JSValueToStringCopy(context, arguments[0], exception));
846     ASSERT(!*exception);
847
848     size_t maxLength = JSStringGetMaximumUTF8CStringSize(password.get());
849     char* passwordBuffer = new char[maxLength + 1];
850     JSStringGetUTF8CString(password.get(), passwordBuffer, maxLength + 1);
851     
852     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
853     controller->setAuthenticationPassword(passwordBuffer);
854     delete[] passwordBuffer;
855
856     return JSValueMakeUndefined(context);
857 }
858
859 static JSValueRef setAuthenticationUsernameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
860 {
861     // Has mac & windows implementation
862     if (argumentCount < 1)
863         return JSValueMakeUndefined(context);
864
865     auto username = adopt(JSValueToStringCopy(context, arguments[0], exception));
866     ASSERT(!*exception);
867
868     size_t maxLength = JSStringGetMaximumUTF8CStringSize(username.get());
869     char* usernameBuffer = new char[maxLength + 1];
870     JSStringGetUTF8CString(username.get(), usernameBuffer, maxLength + 1);
871     
872     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
873     controller->setAuthenticationUsername(usernameBuffer);
874     delete[] usernameBuffer;
875
876     return JSValueMakeUndefined(context);
877 }
878
879 static JSValueRef setAuthorAndUserStylesEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
880 {
881     // Has mac & windows implementation
882     if (argumentCount < 1)
883         return JSValueMakeUndefined(context);
884
885     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
886     controller->setAuthorAndUserStylesEnabled(JSValueToBoolean(context, arguments[0]));
887
888     return JSValueMakeUndefined(context);
889 }
890
891 static JSValueRef setCacheModelCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
892 {
893     // Has Mac implementation.
894     if (argumentCount < 1)
895         return JSValueMakeUndefined(context);
896
897     int cacheModel = JSValueToNumber(context, arguments[0], exception);
898     ASSERT(!*exception);
899
900     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
901     controller->setCacheModel(cacheModel);
902
903     return JSValueMakeUndefined(context);
904 }
905
906 static JSValueRef setCustomPolicyDelegateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
907 {
908     // Has mac implementation
909     if (argumentCount < 1)
910         return JSValueMakeUndefined(context);
911     
912     bool permissive = false;
913     if (argumentCount >= 2)
914         permissive = JSValueToBoolean(context, arguments[1]);
915
916     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
917     controller->setCustomPolicyDelegate(JSValueToBoolean(context, arguments[0]), permissive);
918
919     return JSValueMakeUndefined(context);
920 }
921
922 static JSValueRef setDatabaseQuotaCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
923 {
924     // Has mac implementation
925     if (argumentCount < 1)
926         return JSValueMakeUndefined(context);
927
928     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
929
930     double quota = JSValueToNumber(context, arguments[0], NULL);
931     if (!std::isnan(quota))
932         controller->setDatabaseQuota(static_cast<unsigned long long>(quota));
933         
934     return JSValueMakeUndefined(context);
935 }
936
937 static JSValueRef setIDBPerOriginQuotaCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
938 {
939     if (argumentCount < 1)
940         return JSValueMakeUndefined(context);
941     
942     auto* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
943     
944     double quota = JSValueToNumber(context, arguments[0], nullptr);
945     if (!std::isnan(quota))
946         controller->setIDBPerOriginQuota(static_cast<uint64_t>(quota));
947     
948     return JSValueMakeUndefined(context);
949 }
950
951 static JSValueRef setDefersLoadingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
952 {
953     if (argumentCount < 1)
954         return JSValueMakeUndefined(context);
955
956     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
957     controller->setDefersLoading(JSValueToBoolean(context, arguments[0]));
958
959     return JSValueMakeUndefined(context);
960 }
961
962 static JSValueRef setUseDeferredFrameLoadingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
963 {
964     if (argumentCount < 1)
965         return JSValueMakeUndefined(context);
966
967     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
968     controller->setUseDeferredFrameLoading(JSValueToBoolean(context, arguments[0]));
969
970     return JSValueMakeUndefined(context);
971 }
972
973 static JSValueRef setDomainRelaxationForbiddenForURLSchemeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
974 {
975     // Has Mac and Windows implementation
976     if (argumentCount < 2)
977         return JSValueMakeUndefined(context);
978
979     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
980
981     bool forbidden = JSValueToBoolean(context, arguments[0]);
982     auto scheme = adopt(JSValueToStringCopy(context, arguments[1], 0));
983     controller->setDomainRelaxationForbiddenForURLScheme(forbidden, scheme.get());
984
985     return JSValueMakeUndefined(context);
986 }
987
988 static JSValueRef setMockDeviceOrientationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
989 {
990     if (argumentCount < 6)
991         return JSValueMakeUndefined(context);
992
993     bool canProvideAlpha = JSValueToBoolean(context, arguments[0]);
994     double alpha = JSValueToNumber(context, arguments[1], exception);
995     ASSERT(!*exception);
996     bool canProvideBeta = JSValueToBoolean(context, arguments[2]);
997     double beta = JSValueToNumber(context, arguments[3], exception);
998     ASSERT(!*exception);
999     bool canProvideGamma = JSValueToBoolean(context, arguments[4]);
1000     double gamma = JSValueToNumber(context, arguments[5], exception);
1001     ASSERT(!*exception);
1002
1003     TestRunner* controller = reinterpret_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1004     controller->setMockDeviceOrientation(canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma);
1005
1006     return JSValueMakeUndefined(context);
1007 }
1008
1009 static JSValueRef setMockGeolocationPositionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1010 {
1011     if (argumentCount < 3)
1012         return JSValueMakeUndefined(context);
1013
1014     double latitude = JSValueToNumber(context, arguments[0], 0);
1015     double longitude = JSValueToNumber(context, arguments[1], 0);
1016     double accuracy = JSValueToNumber(context, arguments[2], 0);
1017
1018     bool canProvideAltitude = false;
1019     double altitude = 0.;
1020     if (argumentCount > 3 && !JSValueIsUndefined(context, arguments[3])) {
1021         canProvideAltitude = true;
1022         altitude = JSValueToNumber(context, arguments[3], 0);
1023     }
1024
1025     bool canProvideAltitudeAccuracy = false;
1026     double altitudeAccuracy = 0.;
1027     if (argumentCount > 4 && !JSValueIsUndefined(context, arguments[4])) {
1028         canProvideAltitudeAccuracy = true;
1029         altitudeAccuracy = JSValueToNumber(context, arguments[4], 0);
1030     }
1031
1032     bool canProvideHeading = false;
1033     double heading = 0.;
1034     if (argumentCount > 5 && !JSValueIsUndefined(context, arguments[5])) {
1035         canProvideHeading = true;
1036         heading = JSValueToNumber(context, arguments[5], 0);
1037     }
1038
1039     bool canProvideSpeed = false;
1040     double speed = 0.;
1041     if (argumentCount > 6 && !JSValueIsUndefined(context, arguments[6])) {
1042         canProvideSpeed = true;
1043         speed = JSValueToNumber(context, arguments[6], 0);
1044     }
1045
1046     bool canProvideFloorLevel = false;
1047     double floorLevel = 0.;
1048     if (argumentCount > 7 && !JSValueIsUndefined(context, arguments[7])) {
1049         canProvideFloorLevel = true;
1050         floorLevel = JSValueToNumber(context, arguments[7], 0);
1051     }
1052
1053     TestRunner* controller = reinterpret_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1054     controller->setMockGeolocationPosition(latitude, longitude, accuracy, canProvideAltitude, altitude, canProvideAltitudeAccuracy, altitudeAccuracy, canProvideHeading, heading, canProvideSpeed, speed, canProvideFloorLevel, floorLevel);
1055
1056     return JSValueMakeUndefined(context);
1057 }
1058
1059 static JSValueRef setMockGeolocationPositionUnavailableErrorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1060 {
1061     if (argumentCount != 1)
1062         return JSValueMakeUndefined(context);
1063
1064     auto message = adopt(JSValueToStringCopy(context, arguments[0], exception));
1065     ASSERT(!*exception);
1066
1067     TestRunner* controller = reinterpret_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1068     controller->setMockGeolocationPositionUnavailableError(message.get());
1069
1070     return JSValueMakeUndefined(context);
1071 }
1072
1073 static JSValueRef setNewWindowsCopyBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1074 {
1075     // Has mac implementation
1076     if (argumentCount < 1)
1077         return JSValueMakeUndefined(context);
1078     
1079     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1080     controller->setNewWindowsCopyBackForwardList(JSValueToBoolean(context, arguments[0]));
1081
1082     return JSValueMakeUndefined(context);
1083 }
1084
1085 static JSValueRef setGeolocationPermissionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1086 {
1087     // Has mac implementation
1088     if (argumentCount < 1)
1089         return JSValueMakeUndefined(context);
1090
1091     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1092     controller->setGeolocationPermission(JSValueToBoolean(context, arguments[0]));
1093
1094     return JSValueMakeUndefined(context);
1095 }
1096
1097 static JSValueRef setRejectsProtectionSpaceAndContinueForAuthenticationChallengesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1098 {
1099     // Has mac & windows implementation
1100     if (argumentCount < 1)
1101         return JSValueMakeUndefined(context);
1102     
1103     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1104     controller->setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(JSValueToBoolean(context, arguments[0]));
1105     
1106     return JSValueMakeUndefined(context);
1107 }
1108
1109 static JSValueRef setHandlesAuthenticationChallengesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1110 {
1111     // Has mac & windows implementation
1112     if (argumentCount < 1)
1113         return JSValueMakeUndefined(context);
1114
1115     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1116     controller->setHandlesAuthenticationChallenges(JSValueToBoolean(context, arguments[0]));
1117
1118     return JSValueMakeUndefined(context);
1119 }
1120
1121 static JSValueRef setPOSIXLocaleCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1122 {
1123     if (argumentCount < 1)
1124         return JSValueMakeUndefined(context);
1125
1126     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1127     auto locale = adopt(JSValueToStringCopy(context, arguments[0], exception));
1128     ASSERT(!*exception);
1129     controller->setPOSIXLocale(locale.get());
1130
1131     return JSValueMakeUndefined(context);
1132 }
1133
1134 static JSValueRef setIconDatabaseEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1135 {
1136     // Has mac & windows implementation
1137     if (argumentCount < 1)
1138         return JSValueMakeUndefined(context);
1139
1140     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1141     controller->setIconDatabaseEnabled(JSValueToBoolean(context, arguments[0]));
1142
1143     return JSValueMakeUndefined(context);
1144 }
1145
1146 static JSValueRef setMainFrameIsFirstResponderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1147 {
1148     // Has mac implementation
1149     if (argumentCount < 1)
1150         return JSValueMakeUndefined(context);
1151
1152     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1153     controller->setMainFrameIsFirstResponder(JSValueToBoolean(context, arguments[0]));
1154
1155     return JSValueMakeUndefined(context);
1156 }
1157
1158 static JSValueRef setPersistentUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1159 {
1160     // Has mac implementation
1161     if (argumentCount < 1)
1162         return JSValueMakeUndefined(context);
1163
1164     auto path = adopt(JSValueToStringCopy(context, arguments[0], exception));
1165     ASSERT(!*exception);
1166
1167     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1168     controller->setPersistentUserStyleSheetLocation(path.get());
1169
1170     return JSValueMakeUndefined(context);
1171 }
1172
1173 static JSValueRef setPrivateBrowsingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1174 {
1175     // Has mac & windows implementation
1176     if (argumentCount < 1)
1177         return JSValueMakeUndefined(context);
1178
1179     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1180     controller->setPrivateBrowsingEnabled(JSValueToBoolean(context, arguments[0]));
1181
1182     return JSValueMakeUndefined(context);
1183 }
1184
1185 static JSValueRef setJavaScriptCanAccessClipboardCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1186 {
1187     // Has mac & windows implementation
1188     if (argumentCount < 1)
1189         return JSValueMakeUndefined(context);
1190
1191     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1192     controller->setJavaScriptCanAccessClipboard(JSValueToBoolean(context, arguments[0]));
1193
1194     return JSValueMakeUndefined(context);
1195 }
1196
1197 static JSValueRef setXSSAuditorEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1198 {
1199     // Has mac & windows implementation
1200     if (argumentCount < 1)
1201         return JSValueMakeUndefined(context);
1202
1203     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1204     controller->setXSSAuditorEnabled(JSValueToBoolean(context, arguments[0]));
1205
1206     return JSValueMakeUndefined(context);
1207 }
1208
1209 static JSValueRef setSpatialNavigationEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1210 {
1211     // Has mac & windows implementation.
1212     if (argumentCount < 1)
1213         return JSValueMakeUndefined(context);
1214
1215     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1216     controller->setSpatialNavigationEnabled(JSValueToBoolean(context, arguments[0]));
1217
1218     return JSValueMakeUndefined(context);
1219 }
1220
1221 static JSValueRef setPrintingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1222 {
1223     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1224     controller->setIsPrinting(true);
1225     return JSValueMakeUndefined(context);
1226 }
1227
1228 static JSValueRef setAllowsAnySSLCertificateCallback(JSContextRef context, JSObjectRef, JSObjectRef, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1229 {
1230     bool allowAnyCertificate = false;
1231     if (argumentCount == 1)
1232         allowAnyCertificate = JSValueToBoolean(context, arguments[0]);
1233     
1234     TestRunner::setAllowsAnySSLCertificate(allowAnyCertificate);
1235     return JSValueMakeUndefined(context);
1236 }
1237
1238 static JSValueRef setAllowUniversalAccessFromFileURLsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1239 {
1240     // Has mac & windows implementation
1241     if (argumentCount < 1)
1242         return JSValueMakeUndefined(context);
1243
1244     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1245     controller->setAllowUniversalAccessFromFileURLs(JSValueToBoolean(context, arguments[0]));
1246
1247     return JSValueMakeUndefined(context);
1248 }
1249
1250 static JSValueRef setAllowFileAccessFromFileURLsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1251 {
1252     // Has mac & windows implementation
1253     if (argumentCount < 1)
1254         return JSValueMakeUndefined(context);
1255
1256     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1257     controller->setAllowFileAccessFromFileURLs(JSValueToBoolean(context, arguments[0]));
1258
1259     return JSValueMakeUndefined(context);
1260 }
1261
1262 static JSValueRef setNeedsStorageAccessFromFileURLsQuirkCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1263 {
1264     // Has mac & windows implementation
1265     if (argumentCount < 1)
1266         return JSValueMakeUndefined(context);
1267     
1268     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1269     controller->setNeedsStorageAccessFromFileURLsQuirk(JSValueToBoolean(context, arguments[0]));
1270     
1271     return JSValueMakeUndefined(context);
1272 }
1273
1274 static JSValueRef setTabKeyCyclesThroughElementsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1275 {
1276     // Has mac & windows implementation
1277     if (argumentCount < 1)
1278         return JSValueMakeUndefined(context);
1279
1280     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1281     controller->setTabKeyCyclesThroughElements(JSValueToBoolean(context, arguments[0]));
1282
1283     return JSValueMakeUndefined(context);
1284 }
1285
1286 #if PLATFORM(IOS_FAMILY)
1287 static JSValueRef setTelephoneNumberParsingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1288 {
1289     if (argumentCount < 1)
1290         return JSValueMakeUndefined(context);
1291
1292     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1293     controller->setTelephoneNumberParsingEnabled(JSValueToBoolean(context, arguments[0]));
1294
1295     return JSValueMakeUndefined(context);
1296 }
1297
1298 static JSValueRef setPagePausedCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1299 {
1300     if (argumentCount < 1)
1301         return JSValueMakeUndefined(context);
1302
1303     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1304     controller->setPagePaused(JSValueToBoolean(context, arguments[0]));
1305
1306     return JSValueMakeUndefined(context);
1307 }
1308 #endif
1309
1310 static JSValueRef setUseDashboardCompatibilityModeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1311 {
1312     // Has mac implementation
1313     if (argumentCount < 1)
1314         return JSValueMakeUndefined(context);
1315
1316     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1317     controller->setUseDashboardCompatibilityMode(JSValueToBoolean(context, arguments[0]));
1318
1319     return JSValueMakeUndefined(context);
1320 }
1321
1322 static JSValueRef setUserStyleSheetEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1323 {
1324     // Has mac implementation
1325     if (argumentCount < 1)
1326         return JSValueMakeUndefined(context);
1327
1328     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1329     controller->setUserStyleSheetEnabled(JSValueToBoolean(context, arguments[0]));
1330
1331     return JSValueMakeUndefined(context);
1332 }
1333
1334 static JSValueRef setUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1335 {
1336     // Has mac implementation
1337     if (argumentCount < 1)
1338         return JSValueMakeUndefined(context);
1339
1340     auto path = adopt(JSValueToStringCopy(context, arguments[0], exception));
1341     ASSERT(!*exception);
1342
1343     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1344     controller->setUserStyleSheetLocation(path.get());
1345
1346     return JSValueMakeUndefined(context);
1347 }
1348
1349 static JSValueRef setValueForUserCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1350 {
1351     // Has mac implementation
1352     if (argumentCount != 2)
1353         return JSValueMakeUndefined(context);
1354
1355     auto value = adopt(JSValueToStringCopy(context, arguments[1], exception));
1356     ASSERT(!*exception);
1357
1358     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1359     controller->setValueForUser(context, arguments[0], value.get());
1360
1361     return JSValueMakeUndefined(context);
1362 }
1363
1364 static JSValueRef setWillSendRequestClearHeaderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1365 {
1366     // Has mac & windows implementation
1367     if (argumentCount < 1)
1368         return JSValueMakeUndefined(context);
1369
1370     auto header = adopt(JSValueToStringCopy(context, arguments[0], exception));
1371     ASSERT(!*exception);
1372
1373     size_t maxLength = JSStringGetMaximumUTF8CStringSize(header.get());
1374     auto headerBuffer = std::make_unique<char[]>(maxLength + 1);
1375     JSStringGetUTF8CString(header.get(), headerBuffer.get(), maxLength + 1);
1376
1377     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1378     controller->setWillSendRequestClearHeader(headerBuffer.get());
1379
1380     return JSValueMakeUndefined(context);
1381 }
1382
1383 static JSValueRef setWillSendRequestReturnsNullCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1384 {
1385     // Has cross-platform implementation
1386     if (argumentCount < 1)
1387         return JSValueMakeUndefined(context);
1388
1389     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1390     controller->setWillSendRequestReturnsNull(JSValueToBoolean(context, arguments[0]));
1391
1392     return JSValueMakeUndefined(context);
1393 }
1394
1395 static JSValueRef setWillSendRequestReturnsNullOnRedirectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1396 {
1397     // Has cross-platform implementation
1398     if (argumentCount < 1)
1399         return JSValueMakeUndefined(context);
1400
1401     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1402     controller->setWillSendRequestReturnsNullOnRedirect(JSValueToBoolean(context, arguments[0]));
1403
1404     return JSValueMakeUndefined(context);
1405 }
1406
1407 static JSValueRef setWindowIsKeyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1408 {
1409     // Has mac implementation
1410     if (argumentCount < 1)
1411         return JSValueMakeUndefined(context);
1412
1413     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1414     controller->setWindowIsKey(JSValueToBoolean(context, arguments[0]));
1415
1416     return JSValueMakeUndefined(context);
1417 }
1418
1419 static JSValueRef setViewSizeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1420 {
1421     if (argumentCount < 2)
1422         return JSValueMakeUndefined(context);
1423
1424     double width = JSValueToNumber(context, arguments[0], exception);
1425     ASSERT(!*exception);
1426     double height = JSValueToNumber(context, arguments[1], exception);
1427     ASSERT(!*exception);
1428
1429     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1430     controller->setViewSize(width, height);
1431
1432     return JSValueMakeUndefined(context);
1433 }
1434
1435 static JSValueRef waitUntilDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1436 {
1437     // Has mac & windows implementation
1438     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1439     controller->setWaitToDump(true);
1440
1441     return JSValueMakeUndefined(context);
1442 }
1443
1444 static JSValueRef windowCountCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1445 {
1446     // Has mac implementation
1447     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1448     int windows = controller->windowCount();
1449     return JSValueMakeNumber(context, windows);
1450 }
1451
1452 static JSValueRef setPopupBlockingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1453 {
1454     // Has mac & windows implementation
1455     if (argumentCount < 1)
1456         return JSValueMakeUndefined(context);
1457
1458     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1459     controller->setPopupBlockingEnabled(JSValueToBoolean(context, arguments[0]));
1460
1461     return JSValueMakeUndefined(context);
1462 }
1463
1464 static JSValueRef setPluginsEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1465 {
1466     // Has mac & windows implementation
1467     if (argumentCount < 1)
1468         return JSValueMakeUndefined(context);
1469     
1470     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1471     controller->setPluginsEnabled(JSValueToBoolean(context, arguments[0]));
1472     
1473     return JSValueMakeUndefined(context);
1474 }    
1475
1476 static JSValueRef setPageVisibilityCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1477 {
1478     // Has mac & windows implementation
1479     if (argumentCount < 1)
1480         return JSValueMakeUndefined(context);
1481
1482     auto visibility = adopt(JSValueToStringCopy(context, arguments[0], exception));
1483     ASSERT(!*exception);
1484
1485     size_t maxLength = JSStringGetMaximumUTF8CStringSize(visibility.get());
1486     char* visibilityBuffer = new char[maxLength + 1];
1487     JSStringGetUTF8CString(visibility.get(), visibilityBuffer, maxLength + 1);
1488     
1489     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1490     controller->setPageVisibility(visibilityBuffer);
1491     delete[] visibilityBuffer;
1492     
1493     return JSValueMakeUndefined(context);
1494 }    
1495
1496 static JSValueRef resetPageVisibilityCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1497 {
1498     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1499     controller->resetPageVisibility();
1500     return JSValueMakeUndefined(context);
1501 }    
1502
1503 static JSValueRef setAutomaticLinkDetectionEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1504 {
1505     if (argumentCount < 1)
1506         return JSValueMakeUndefined(context);
1507
1508     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1509     controller->setAutomaticLinkDetectionEnabled(JSValueToBoolean(context, arguments[0]));
1510     return JSValueMakeUndefined(context);
1511 }
1512
1513 static JSValueRef setStopProvisionalFrameLoadsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1514 {
1515     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1516     controller->setStopProvisionalFrameLoads(true);
1517     return JSValueMakeUndefined(context);
1518 }
1519
1520 static JSValueRef showWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1521 {
1522     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1523     controller->showWebInspector();
1524     return JSValueMakeUndefined(context);
1525 }
1526
1527 static JSValueRef closeWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1528 {
1529     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1530     controller->closeWebInspector();
1531     return JSValueMakeUndefined(context);
1532 }
1533
1534 static JSValueRef evaluateInWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1535 {
1536     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1537     auto script = adopt(JSValueToStringCopy(context, arguments[0], exception));
1538     ASSERT(!*exception);
1539
1540     controller->evaluateInWebInspector(script.get());
1541     return JSValueMakeUndefined(context);
1542 }
1543
1544 static JSValueRef evaluateScriptInIsolatedWorldCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1545 {
1546     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1547     double worldID = JSValueToNumber(context, arguments[0], exception);
1548     ASSERT(!*exception);
1549     auto script = adopt(JSValueToStringCopy(context, arguments[1], exception));
1550     ASSERT(!*exception);
1551
1552     controller->evaluateScriptInIsolatedWorld(static_cast<unsigned>(worldID), JSContextGetGlobalObject(context), script.get());
1553     return JSValueMakeUndefined(context);
1554 }
1555
1556 static JSValueRef evaluateScriptInIsolatedWorldAndReturnValueCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1557 {
1558     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1559     double worldID = JSValueToNumber(context, arguments[0], exception);
1560     ASSERT(!*exception);
1561     auto script = adopt(JSValueToStringCopy(context, arguments[1], exception));
1562     ASSERT(!*exception);
1563
1564     controller->evaluateScriptInIsolatedWorldAndReturnValue(static_cast<unsigned>(worldID), JSContextGetGlobalObject(context), script.get());
1565     return JSValueMakeUndefined(context);
1566 }
1567
1568 static JSValueRef waitForPolicyDelegateCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*)
1569 {
1570     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1571     controller->waitForPolicyDelegate();
1572     return JSValueMakeUndefined(context);
1573 }
1574
1575 static JSValueRef addOriginAccessWhitelistEntryCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1576 {
1577     if (argumentCount != 4)
1578         return JSValueMakeUndefined(context);
1579
1580     auto sourceOrigin = adopt(JSValueToStringCopy(context, arguments[0], exception));
1581     ASSERT(!*exception);
1582     auto destinationProtocol = adopt(JSValueToStringCopy(context, arguments[1], exception));
1583     ASSERT(!*exception);
1584     auto destinationHost = adopt(JSValueToStringCopy(context, arguments[2], exception));
1585     ASSERT(!*exception);
1586     bool allowDestinationSubdomains = JSValueToBoolean(context, arguments[3]);
1587
1588     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1589     controller->addOriginAccessWhitelistEntry(sourceOrigin.get(), destinationProtocol.get(), destinationHost.get(), allowDestinationSubdomains);
1590     return JSValueMakeUndefined(context);
1591 }
1592
1593 static JSValueRef removeOriginAccessWhitelistEntryCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1594 {
1595     if (argumentCount != 4)
1596         return JSValueMakeUndefined(context);
1597
1598     auto sourceOrigin = adopt(JSValueToStringCopy(context, arguments[0], exception));
1599     ASSERT(!*exception);
1600     auto destinationProtocol = adopt(JSValueToStringCopy(context, arguments[1], exception));
1601     ASSERT(!*exception);
1602     auto destinationHost = adopt(JSValueToStringCopy(context, arguments[2], exception));
1603     ASSERT(!*exception);
1604     bool allowDestinationSubdomains = JSValueToBoolean(context, arguments[3]);
1605
1606     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1607     controller->removeOriginAccessWhitelistEntry(sourceOrigin.get(), destinationProtocol.get(), destinationHost.get(), allowDestinationSubdomains);
1608     return JSValueMakeUndefined(context);
1609 }
1610
1611 static JSValueRef setScrollbarPolicyCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1612 {
1613     if (argumentCount != 2)
1614         return JSValueMakeUndefined(context);
1615
1616     auto orientation = adopt(JSValueToStringCopy(context, arguments[0], exception));
1617     ASSERT(!*exception);
1618     auto policy = adopt(JSValueToStringCopy(context, arguments[1], exception));
1619     ASSERT(!*exception);
1620
1621     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1622     controller->setScrollbarPolicy(orientation.get(), policy.get());
1623     return JSValueMakeUndefined(context);
1624 }
1625
1626 static JSValueRef addUserScriptCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1627 {
1628     if (argumentCount != 3)
1629         return JSValueMakeUndefined(context);
1630     
1631     auto source = adopt(JSValueToStringCopy(context, arguments[0], exception));
1632     ASSERT(!*exception);
1633     bool runAtStart = JSValueToBoolean(context, arguments[1]);
1634     bool allFrames = JSValueToBoolean(context, arguments[2]);
1635     
1636     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1637     controller->addUserScript(source.get(), runAtStart, allFrames);
1638     return JSValueMakeUndefined(context);
1639 }
1640  
1641 static JSValueRef addUserStyleSheetCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1642 {
1643     if (argumentCount != 2)
1644         return JSValueMakeUndefined(context);
1645     
1646     auto source = adopt(JSValueToStringCopy(context, arguments[0], exception));
1647     ASSERT(!*exception);
1648     bool allFrames = JSValueToBoolean(context, arguments[1]);
1649    
1650     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1651     controller->addUserStyleSheet(source.get(), allFrames);
1652     return JSValueMakeUndefined(context);
1653 }
1654
1655 static JSValueRef setShouldPaintBrokenImageCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1656 {
1657     // Has Mac implementation
1658     if (argumentCount < 1)
1659         return JSValueMakeUndefined(context);
1660
1661     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1662     controller->setShouldPaintBrokenImage(JSValueToBoolean(context, arguments[0]));
1663
1664     return JSValueMakeUndefined(context);
1665 }
1666
1667 static JSValueRef apiTestNewWindowDataLoadBaseURLCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1668 {
1669     if (argumentCount != 2)
1670         return JSValueMakeUndefined(context);
1671
1672     auto utf8Data = adopt(JSValueToStringCopy(context, arguments[0], exception));
1673     ASSERT(!*exception);
1674
1675     auto baseURL = adopt(JSValueToStringCopy(context, arguments[1], exception));
1676     ASSERT(!*exception);
1677         
1678     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1679     controller->apiTestNewWindowDataLoadBaseURL(utf8Data.get(), baseURL.get());
1680     return JSValueMakeUndefined(context);
1681 }
1682
1683 static JSValueRef apiTestGoToCurrentBackForwardItemCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1684 {
1685     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1686     controller->apiTestGoToCurrentBackForwardItem();
1687     return JSValueMakeUndefined(context);
1688 }
1689
1690 static JSValueRef setWebViewEditableCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1691 {
1692     // Has Mac implementation
1693     if (argumentCount < 1)
1694         return JSValueMakeUndefined(context);
1695
1696     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1697     controller->setWebViewEditable(JSValueToBoolean(context, arguments[0]));
1698
1699     return JSValueMakeUndefined(context);
1700 }
1701
1702 static JSValueRef abortModalCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1703 {
1704     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1705     controller->abortModal();
1706     return JSValueMakeUndefined(context);
1707 }
1708
1709 static JSValueRef authenticateSessionCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1710 {
1711     // authenticateSession(url, username, password)
1712     if (argumentCount != 3)
1713         return JSValueMakeUndefined(context);
1714
1715     auto url = adopt(JSValueToStringCopy(context, arguments[0], exception));
1716     ASSERT(!*exception);
1717     auto username = adopt(JSValueToStringCopy(context, arguments[1], exception));
1718     ASSERT(!*exception);
1719     auto password = adopt(JSValueToStringCopy(context, arguments[2], exception));
1720     ASSERT(!*exception);
1721
1722     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1723     controller->authenticateSession(url.get(), username.get(), password.get());
1724     return JSValueMakeUndefined(context);
1725 }
1726
1727 static JSValueRef setSerializeHTTPLoadsCallback(JSContextRef context, JSObjectRef, JSObjectRef, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1728 {
1729     bool serialize = true;
1730     if (argumentCount == 1)
1731         serialize = JSValueToBoolean(context, arguments[0]);
1732
1733     TestRunner::setSerializeHTTPLoads(serialize);
1734     return JSValueMakeUndefined(context);
1735 }
1736
1737 static JSValueRef setShouldStayOnPageAfterHandlingBeforeUnloadCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1738 {
1739     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1740     
1741     if (argumentCount == 1)
1742         controller->setShouldStayOnPageAfterHandlingBeforeUnload(JSValueToBoolean(context, arguments[0]));
1743
1744     return JSValueMakeUndefined(context);
1745 }
1746
1747 static JSValueRef addChromeInputFieldCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1748 {
1749     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1750     controller->addChromeInputField();
1751     // the first argument is a callback that is called once the input field has been added
1752     if (argumentCount == 1)
1753         JSObjectCallAsFunction(context, JSValueToObject(context, arguments[0], 0), thisObject, 0, 0, 0);
1754     return JSValueMakeUndefined(context);
1755 }
1756
1757 static JSValueRef removeChromeInputFieldCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1758 {
1759     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1760     controller->removeChromeInputField();
1761     // the first argument is a callback that is called once the input field has been added
1762     if (argumentCount == 1)
1763         JSObjectCallAsFunction(context, JSValueToObject(context, arguments[0], 0), thisObject, 0, 0, 0);
1764     return JSValueMakeUndefined(context);
1765 }
1766
1767 static JSValueRef focusWebViewCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1768 {
1769     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1770     controller->focusWebView();
1771     // the first argument is a callback that is called once the input field has been added
1772     if (argumentCount == 1)
1773         JSObjectCallAsFunction(context, JSValueToObject(context, arguments[0], 0), thisObject, 0, 0, 0);
1774     return JSValueMakeUndefined(context);
1775 }
1776
1777 static JSValueRef setBackingScaleFactorCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1778 {
1779     if (argumentCount != 2)
1780         return JSValueMakeUndefined(context);
1781
1782     double backingScaleFactor = JSValueToNumber(context, arguments[0], exception);
1783     ASSERT(!*exception);
1784
1785     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1786     controller->setBackingScaleFactor(backingScaleFactor);
1787
1788     // The second argument is a callback that is called once the backing scale factor has been set.
1789     JSObjectCallAsFunction(context, JSValueToObject(context, arguments[1], 0), thisObject, 0, 0, 0);
1790     return JSValueMakeUndefined(context);
1791 }
1792
1793 static JSValueRef preciseTimeCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1794 {
1795     return JSValueMakeNumber(context, WallTime::now().secondsSinceEpoch().seconds());
1796 }
1797
1798 static JSValueRef imageCountInGeneralPasteboardCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1799 {
1800     // Has mac & windows implementation
1801     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1802     
1803     return JSValueMakeNumber(context, controller->imageCountInGeneralPasteboard());
1804 }
1805
1806 static JSValueRef setSpellCheckerLoggingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1807 {
1808     if (argumentCount < 1)
1809         return JSValueMakeUndefined(context);
1810     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1811     controller->setSpellCheckerLoggingEnabled(JSValueToBoolean(context, arguments[0]));
1812     return JSValueMakeUndefined(context);
1813 }
1814
1815 static JSValueRef setSpellCheckerResultsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1816 {
1817     if (argumentCount < 1)
1818         return JSValueMakeUndefined(context);
1819
1820     auto* runner = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1821     runner->setSpellCheckerResults(context, JSValueToObject(context, arguments[0], nullptr));
1822     return JSValueMakeUndefined(context);
1823 }
1824
1825 static JSValueRef setOpenPanelFilesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1826 {
1827     if (argumentCount == 1)
1828         static_cast<TestRunner*>(JSObjectGetPrivate(thisObject))->setOpenPanelFiles(context, arguments[0]);
1829     return JSValueMakeUndefined(context);
1830 }
1831
1832 // Static Values
1833
1834 static JSValueRef getTimeoutCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1835 {
1836     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1837     return JSValueMakeNumber(context, controller->timeout());
1838 }
1839
1840 static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1841 {
1842     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1843     return JSValueMakeBoolean(context, controller->globalFlag());
1844 }
1845
1846 static JSValueRef getDidCancelClientRedirect(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1847 {
1848     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1849     return JSValueMakeBoolean(context, controller->didCancelClientRedirect());
1850 }
1851
1852 static JSValueRef getDatabaseDefaultQuotaCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1853 {
1854     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1855     return JSValueMakeNumber(context, controller->databaseDefaultQuota());
1856 }
1857
1858 static JSValueRef getDatabaseMaxQuotaCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1859 {
1860     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1861     return JSValueMakeNumber(context, controller->databaseMaxQuota());
1862 }
1863
1864 static JSValueRef getWebHistoryItemCountCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1865 {
1866     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1867     return JSValueMakeNumber(context, controller->webHistoryItemCount());
1868 }
1869
1870 static JSValueRef getSecureEventInputIsEnabledCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1871 {
1872 #if PLATFORM(MAC) && !PLATFORM(IOS_FAMILY)
1873     return JSValueMakeBoolean(context, IsSecureEventInputEnabled());
1874 #else
1875     return JSValueMakeBoolean(context, false);
1876 #endif
1877 }
1878
1879 static JSValueRef getTitleTextDirectionCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1880 {
1881     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1882     auto titleDirection = adopt(JSStringCreateWithUTF8CString(controller->titleTextDirection().c_str()));
1883     return JSValueMakeString(context, titleDirection.get());
1884 }
1885
1886 static JSValueRef getInspectorTestStubURLCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1887 {
1888     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1889     auto url = controller->inspectorTestStubURL();
1890     return JSValueMakeString(context, url.get());
1891 }
1892
1893 static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
1894 {
1895     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1896     controller->setGlobalFlag(JSValueToBoolean(context, value));
1897     return true;
1898 }
1899
1900 static bool setDatabaseDefaultQuotaCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
1901 {
1902     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1903     controller->setDatabaseDefaultQuota(JSValueToNumber(context, value, exception));
1904     ASSERT(!*exception);
1905     return true;
1906 }
1907
1908 static bool setDatabaseMaxQuotaCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
1909 {
1910     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1911     controller->setDatabaseMaxQuota(JSValueToNumber(context, value, exception));
1912     ASSERT(!*exception);
1913     return true;
1914 }
1915
1916 static JSValueRef ignoreLegacyWebNotificationPermissionRequestsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1917 {
1918     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1919     controller->ignoreLegacyWebNotificationPermissionRequests();
1920     return JSValueMakeUndefined(context);
1921 }
1922
1923 static JSValueRef simulateLegacyWebNotificationClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1924 {
1925     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject)); 
1926     auto title = adopt(JSValueToStringCopy(context, arguments[0], exception));
1927     controller->simulateLegacyWebNotificationClick(title.get());
1928     return JSValueMakeUndefined(context);
1929 }
1930
1931 static JSValueRef setTextDirectionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1932 {
1933     if (argumentCount == 1) {
1934         auto direction = adopt(JSValueToStringCopy(context, arguments[0], exception));
1935         TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1936         controller->setTextDirection(direction.get());
1937     }
1938
1939     return JSValueMakeUndefined(context);
1940
1941 }
1942
1943 static JSValueRef setHasCustomFullScreenBehaviorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1944 {
1945     if (argumentCount == 1) {
1946         bool hasCustomBehavior = JSValueToBoolean(context, arguments[0]);
1947         TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1948         controller->setHasCustomFullScreenBehavior(hasCustomBehavior);
1949     }
1950
1951     return JSValueMakeUndefined(context);
1952 }
1953
1954 static JSValueRef setStorageDatabaseIdleIntervalCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1955 {
1956     if (argumentCount != 1)
1957         return JSValueMakeUndefined(context);
1958
1959     double interval = JSValueToNumber(context, arguments[0], exception);
1960     ASSERT(!*exception);
1961
1962     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1963     controller->setStorageDatabaseIdleInterval(interval);
1964
1965     return JSValueMakeUndefined(context);
1966 }
1967
1968 static JSValueRef closeIdleLocalStorageDatabasesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1969 {
1970     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1971     controller->closeIdleLocalStorageDatabases();
1972
1973     return JSValueMakeUndefined(context);
1974 }
1975
1976 static JSValueRef grantWebNotificationPermissionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1977 {
1978     if (argumentCount < 1)
1979         return JSValueMakeUndefined(context);
1980
1981     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1982
1983     auto origin = adopt(JSValueToStringCopy(context, arguments[0], exception));
1984     ASSERT(!*exception);
1985     controller->grantWebNotificationPermission(origin.get());
1986
1987     return JSValueMakeUndefined(context);
1988 }
1989
1990
1991 static JSValueRef denyWebNotificationPermissionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1992 {
1993     if (argumentCount < 1)
1994         return JSValueMakeUndefined(context);
1995
1996     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
1997
1998     auto origin = adopt(JSValueToStringCopy(context, arguments[0], exception));
1999     ASSERT(!*exception);
2000     controller->denyWebNotificationPermission(origin.get());
2001
2002     return JSValueMakeUndefined(context);
2003 }
2004
2005
2006 static JSValueRef removeAllWebNotificationPermissionsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
2007 {
2008     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
2009
2010     controller->removeAllWebNotificationPermissions();
2011
2012     return JSValueMakeUndefined(context);
2013 }
2014
2015
2016 static JSValueRef simulateWebNotificationClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
2017 {
2018     // Has Windows implementation
2019     if (argumentCount < 1)
2020         return JSValueMakeUndefined(context);
2021
2022     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
2023
2024     controller->simulateWebNotificationClick(arguments[0]);
2025
2026     return JSValueMakeUndefined(context);
2027 }
2028
2029 static JSValueRef forceImmediateCompletionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
2030 {
2031     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
2032     controller->forceImmediateCompletion();
2033     return JSValueMakeUndefined(context);
2034 }
2035
2036 static JSValueRef failNextNewCodeBlock(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
2037 {
2038     if (argumentCount < 1)
2039         return JSValueMakeUndefined(context);
2040     
2041     return JSC::failNextNewCodeBlock(context);
2042 }
2043
2044 static JSValueRef numberOfDFGCompiles(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
2045 {
2046     return JSC::numberOfDFGCompiles(context, arguments[0]);
2047 }
2048
2049 static JSValueRef neverInlineFunction(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
2050 {
2051     if (argumentCount < 1)
2052         return JSValueMakeUndefined(context);
2053     
2054     return JSC::setNeverInline(context, arguments[0]);
2055 }
2056
2057 static JSValueRef accummulateLogsForChannel(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
2058 {
2059     if (argumentCount < 1)
2060         return JSValueMakeUndefined(context);
2061
2062     auto channel = adopt(JSValueToStringCopy(context, arguments[0], exception));
2063     ASSERT(!*exception);
2064
2065     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
2066     controller->setAccummulateLogsForChannel(channel.get());
2067
2068     return JSValueMakeUndefined(context);
2069 }
2070
2071 static JSValueRef runUIScriptCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
2072 {
2073     if (argumentCount < 1)
2074         return JSValueMakeUndefined(context);
2075
2076     auto script = argumentCount > 0 ? adopt(JSValueToStringCopy(context, arguments[0], 0)) : JSRetainPtr<JSStringRef>();
2077     JSValueRef callback = argumentCount > 1 ? arguments[1] : JSValueMakeUndefined(context);
2078
2079     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
2080     controller->runUIScript(context, script.get(), callback);
2081
2082     return JSValueMakeUndefined(context);
2083 }
2084
2085 static void testRunnerObjectFinalize(JSObjectRef object)
2086 {
2087     TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(object));
2088     controller->deref();
2089 }
2090
2091 // Object Creation
2092
2093 void TestRunner::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
2094 {
2095     auto testRunnerStr = adopt(JSStringCreateWithUTF8CString("testRunner"));
2096     ref();
2097
2098     JSClassRef classRef = getJSClass();
2099     JSValueRef layoutTestContollerObject = JSObjectMake(context, classRef, this);
2100     JSClassRelease(classRef);
2101
2102     JSObjectSetProperty(context, windowObject, testRunnerStr.get(), layoutTestContollerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
2103 }
2104
2105 JSClassRef TestRunner::getJSClass()
2106 {
2107     static JSStaticValue* staticValues = TestRunner::staticValues();
2108     static JSStaticFunction* staticFunctions = TestRunner::staticFunctions();
2109     static JSClassDefinition classDefinition = {
2110         0, kJSClassAttributeNone, "TestRunner", 0, staticValues, staticFunctions,
2111         0, testRunnerObjectFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
2112     };
2113
2114     return JSClassCreate(&classDefinition);
2115 }
2116
2117 JSStaticValue* TestRunner::staticValues()
2118 {
2119     static JSStaticValue staticValues[] = {
2120         { "didCancelClientRedirect", getDidCancelClientRedirect, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2121         { "timeout", getTimeoutCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2122         { "globalFlag", getGlobalFlagCallback, setGlobalFlagCallback, kJSPropertyAttributeNone },
2123         { "webHistoryItemCount", getWebHistoryItemCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2124         { "secureEventInputIsEnabled", getSecureEventInputIsEnabledCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2125         { "titleTextDirection", getTitleTextDirectionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2126         { "databaseDefaultQuota", getDatabaseDefaultQuotaCallback, setDatabaseDefaultQuotaCallback, kJSPropertyAttributeNone },
2127         { "databaseMaxQuota", getDatabaseMaxQuotaCallback, setDatabaseMaxQuotaCallback, kJSPropertyAttributeNone },
2128         { "inspectorTestStubURL", getInspectorTestStubURLCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2129         { 0, 0, 0, 0 }
2130     };
2131     return staticValues;
2132 }
2133
2134 JSStaticFunction* TestRunner::staticFunctions()
2135 {
2136     static JSStaticFunction staticFunctions[] = {
2137         { "abortModal", abortModalCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2138         { "addDisallowedURL", addDisallowedURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2139         { "addURLToRedirect", addURLToRedirectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2140         { "addUserScript", addUserScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2141         { "addUserStyleSheet", addUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2142         { "apiTestNewWindowDataLoadBaseURL", apiTestNewWindowDataLoadBaseURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2143         { "apiTestGoToCurrentBackForwardItem", apiTestGoToCurrentBackForwardItemCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2144         { "applicationCacheDiskUsageForOrigin", applicationCacheDiskUsageForOriginCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2145         { "callShouldCloseOnWebView", callShouldCloseOnWebViewCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2146         { "clearAllApplicationCaches", clearAllApplicationCachesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2147         { "clearAllDatabases", clearAllDatabasesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2148         { "clearApplicationCacheForOrigin", clearApplicationCacheForOriginCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2149         { "clearBackForwardList", clearBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2150         { "clearPersistentUserStyleSheet", clearPersistentUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2151         { "closeWebInspector", closeWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2152         { "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2153         { "disallowIncreaseForApplicationCacheQuota", disallowIncreaseForApplicationCacheQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2154         { "dispatchPendingLoadRequests", dispatchPendingLoadRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2155         { "display", displayCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2156         { "displayAndTrackRepaints", displayAndTrackRepaintsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2157         { "dumpApplicationCacheDelegateCallbacks", dumpApplicationCacheDelegateCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2158         { "dumpAsText", dumpAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2159         { "dumpBackForwardList", dumpBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2160         { "dumpChildFrameScrollPositions", dumpChildFrameScrollPositionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2161         { "dumpChildFramesAsText", dumpChildFramesAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2162         { "dumpDOMAsWebArchive", dumpDOMAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2163         { "dumpDatabaseCallbacks", dumpDatabaseCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2164         { "dumpEditingCallbacks", dumpEditingCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2165         { "dumpFrameLoadCallbacks", dumpFrameLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2166         { "dumpProgressFinishedCallback", dumpProgressFinishedCallbackCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2167         { "dumpUserGestureInFrameLoadCallbacks", dumpUserGestureInFrameLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },        
2168         { "dumpResourceLoadCallbacks", dumpResourceLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2169         { "dumpResourceResponseMIMETypes", dumpResourceResponseMIMETypesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2170         { "dumpSelectionRect", dumpSelectionRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2171         { "dumpSourceAsWebArchive", dumpSourceAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2172         { "dumpStatusCallbacks", dumpStatusCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2173         { "dumpTitleChanges", dumpTitleChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2174         { "dumpWillCacheResponse", dumpWillCacheResponseCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2175         { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2176         { "evaluateInWebInspector", evaluateInWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2177         { "evaluateScriptInIsolatedWorldAndReturnValue", evaluateScriptInIsolatedWorldAndReturnValueCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2178         { "evaluateScriptInIsolatedWorld", evaluateScriptInIsolatedWorldCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2179         { "execCommand", execCommandCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2180         { "findString", findStringCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2181         { "originsWithApplicationCache", originsWithApplicationCacheCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2182         { "goBack", goBackCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
2183         { "ignoreLegacyWebNotificationPermissionRequests", ignoreLegacyWebNotificationPermissionRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2184         { "isGeolocationProviderActive", isGeolocationProviderActiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2185         { "isCommandEnabled", isCommandEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2186         { "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2187         { "numberOfPendingGeolocationPermissionRequests", numberOfPendingGeolocationPermissionRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2188         { "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2189         { "overridePreference", overridePreferenceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2190         { "pathToLocalResource", pathToLocalResourceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2191         { "printToPDF", dumpAsPDFCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2192         { "queueBackNavigation", queueBackNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2193         { "queueForwardNavigation", queueForwardNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2194         { "queueLoad", queueLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2195         { "queueLoadHTMLString", queueLoadHTMLStringCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2196         { "queueLoadingScript", queueLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2197         { "queueNonLoadingScript", queueNonLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2198         { "queueReload", queueReloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2199         { "removeAllVisitedLinks", removeAllVisitedLinksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2200         { "removeOriginAccessWhitelistEntry", removeOriginAccessWhitelistEntryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2201         { "repaintSweepHorizontally", repaintSweepHorizontallyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2202         { "resetPageVisibility", resetPageVisibilityCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2203         { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2204         { "setAllowUniversalAccessFromFileURLs", setAllowUniversalAccessFromFileURLsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2205         { "setAllowFileAccessFromFileURLs", setAllowFileAccessFromFileURLsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2206         { "setNeedsStorageAccessFromFileURLsQuirk", setNeedsStorageAccessFromFileURLsQuirkCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2207         { "setAllowsAnySSLCertificate", setAllowsAnySSLCertificateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2208         { "setAlwaysAcceptCookies", setAlwaysAcceptCookiesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2209         { "setOnlyAcceptFirstPartyCookies", setOnlyAcceptFirstPartyCookiesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2210         { "setAppCacheMaximumSize", setAppCacheMaximumSizeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2211         { "setAudioResult", setAudioResultCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2212         { "setAuthenticationPassword", setAuthenticationPasswordCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2213         { "setAuthenticationUsername", setAuthenticationUsernameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2214         { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2215         { "setCacheModel", setCacheModelCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2216         { "setCallCloseOnWebViews", setCallCloseOnWebViewsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2217         { "setCanOpenWindows", setCanOpenWindowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2218         { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2219         { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2220         { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
2221         { "setDefersLoading", setDefersLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2222         { "setUseDeferredFrameLoading", setUseDeferredFrameLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2223         { "setDomainRelaxationForbiddenForURLScheme", setDomainRelaxationForbiddenForURLSchemeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2224         { "setGeolocationPermission", setGeolocationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2225         { "setRejectsProtectionSpaceAndContinueForAuthenticationChallenges", setRejectsProtectionSpaceAndContinueForAuthenticationChallengesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2226         { "setHandlesAuthenticationChallenges", setHandlesAuthenticationChallengesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2227         { "setIconDatabaseEnabled", setIconDatabaseEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2228         { "setIDBPerOriginQuota", setIDBPerOriginQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2229         { "setAutomaticLinkDetectionEnabled", setAutomaticLinkDetectionEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2230         { "setMainFrameIsFirstResponder", setMainFrameIsFirstResponderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2231         { "setMockDeviceOrientation", setMockDeviceOrientationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2232         { "setMockGeolocationPositionUnavailableError", setMockGeolocationPositionUnavailableErrorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2233         { "setMockGeolocationPosition", setMockGeolocationPositionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2234         { "setNewWindowsCopyBackForwardList", setNewWindowsCopyBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2235         { "setPageVisibility", setPageVisibilityCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2236         { "setPOSIXLocale", setPOSIXLocaleCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2237         { "setPersistentUserStyleSheetLocation", setPersistentUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2238         { "setPopupBlockingEnabled", setPopupBlockingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2239         { "setPluginsEnabled", setPluginsEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2240         { "setPrinting", setPrintingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2241         { "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2242         { "setSerializeHTTPLoads", setSerializeHTTPLoadsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2243         { "setSpatialNavigationEnabled", setSpatialNavigationEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2244         { "setStopProvisionalFrameLoads", setStopProvisionalFrameLoadsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2245         { "setTabKeyCyclesThroughElements", setTabKeyCyclesThroughElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2246 #if PLATFORM(IOS_FAMILY)
2247         { "setTelephoneNumberParsingEnabled", setTelephoneNumberParsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2248         { "setPagePaused", setPagePausedCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2249 #endif
2250         { "setUseDashboardCompatibilityMode", setUseDashboardCompatibilityModeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2251         { "setUserStyleSheetEnabled", setUserStyleSheetEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2252         { "setUserStyleSheetLocation", setUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2253         { "setValueForUser", setValueForUserCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2254         { "setWebViewEditable", setWebViewEditableCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2255         { "setWillSendRequestClearHeader", setWillSendRequestClearHeaderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2256         { "setWillSendRequestReturnsNull", setWillSendRequestReturnsNullCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2257         { "setWillSendRequestReturnsNullOnRedirect", setWillSendRequestReturnsNullOnRedirectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2258         { "setWindowIsKey", setWindowIsKeyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2259         { "setViewSize", setViewSizeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2260         { "setJavaScriptCanAccessClipboard", setJavaScriptCanAccessClipboardCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2261         { "setXSSAuditorEnabled", setXSSAuditorEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2262         { "showWebInspector", showWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2263         { "simulateLegacyWebNotificationClick", simulateLegacyWebNotificationClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2264         { "testOnscreen", testOnscreenCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2265         { "testRepaint", testRepaintCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2266         { "waitForPolicyDelegate", waitForPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2267         { "waitUntilDone", waitUntilDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2268         { "windowCount", windowCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2269         { "addOriginAccessWhitelistEntry", addOriginAccessWhitelistEntryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2270         { "setScrollbarPolicy", setScrollbarPolicyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2271         { "authenticateSession", authenticateSessionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2272         { "setShouldPaintBrokenImage", setShouldPaintBrokenImageCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2273         { "setTextDirection", setTextDirectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2274         { "setShouldStayOnPageAfterHandlingBeforeUnload", setShouldStayOnPageAfterHandlingBeforeUnloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2275         { "addChromeInputField", addChromeInputFieldCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2276         { "removeChromeInputField", removeChromeInputFieldCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2277         { "focusWebView", focusWebViewCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2278         { "setBackingScaleFactor", setBackingScaleFactorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2279         { "preciseTime", preciseTimeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2280         { "setHasCustomFullScreenBehavior", setHasCustomFullScreenBehaviorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2281         { "setStorageDatabaseIdleInterval", setStorageDatabaseIdleIntervalCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2282         { "closeIdleLocalStorageDatabases", closeIdleLocalStorageDatabasesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2283         { "grantWebNotificationPermission", grantWebNotificationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2284         { "denyWebNotificationPermission", denyWebNotificationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2285         { "removeAllWebNotificationPermissions", removeAllWebNotificationPermissionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2286         { "simulateWebNotificationClick", simulateWebNotificationClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2287         { "failNextNewCodeBlock", failNextNewCodeBlock, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2288         { "numberOfDFGCompiles", numberOfDFGCompiles, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2289         { "neverInlineFunction", neverInlineFunction, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2290         { "accummulateLogsForChannel", accummulateLogsForChannel, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2291         { "runUIScript", runUIScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2292         { "imageCountInGeneralPasteboard", imageCountInGeneralPasteboardCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2293         { "setSpellCheckerLoggingEnabled", setSpellCheckerLoggingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2294         { "setSpellCheckerResults", setSpellCheckerResultsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2295         { "setOpenPanelFiles", setOpenPanelFilesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2296         { "forceImmediateCompletion", forceImmediateCompletionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
2297         { 0, 0, 0 }
2298     };
2299
2300     return staticFunctions;
2301 }
2302
2303 void TestRunner::queueLoadHTMLString(JSStringRef content, JSStringRef baseURL)
2304 {
2305     DRT::WorkQueue::singleton().queue(new LoadHTMLStringItem(content, baseURL));
2306 }
2307
2308 void TestRunner::queueLoadAlternateHTMLString(JSStringRef content, JSStringRef baseURL, JSStringRef unreachableURL)
2309 {
2310     DRT::WorkQueue::singleton().queue(new LoadHTMLStringItem(content, baseURL, unreachableURL));
2311 }
2312
2313 void TestRunner::queueBackNavigation(int howFarBack)
2314 {
2315     DRT::WorkQueue::singleton().queue(new BackItem(howFarBack));
2316 }
2317
2318 void TestRunner::queueForwardNavigation(int howFarForward)
2319 {
2320     DRT::WorkQueue::singleton().queue(new ForwardItem(howFarForward));
2321 }
2322
2323 void TestRunner::queueLoadingScript(JSStringRef script)
2324 {
2325     DRT::WorkQueue::singleton().queue(new LoadingScriptItem(script));
2326 }
2327
2328 void TestRunner::queueNonLoadingScript(JSStringRef script)
2329 {
2330     DRT::WorkQueue::singleton().queue(new NonLoadingScriptItem(script));
2331 }
2332
2333 void TestRunner::queueReload()
2334 {
2335     DRT::WorkQueue::singleton().queue(new ReloadItem);
2336 }
2337
2338 void TestRunner::ignoreLegacyWebNotificationPermissionRequests()
2339 {
2340     m_areLegacyWebNotificationPermissionRequestsIgnored = false;
2341 }
2342
2343 void TestRunner::waitToDumpWatchdogTimerFired()
2344 {
2345     const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
2346     fprintf(testResult, "%s", message);
2347
2348     auto accumulatedLogs = getAndResetAccumulatedLogs();
2349     if (!accumulatedLogs.isEmpty()) {
2350         const char* message = "Logs accumulated during test run:\n";
2351         fprintf(testResult, "%s%s\n", message, accumulatedLogs.utf8().data());
2352     }
2353
2354     notifyDone();
2355 }
2356
2357 void TestRunner::setGeolocationPermissionCommon(bool allow)
2358 {
2359     m_isGeolocationPermissionSet = true;
2360     m_geolocationPermission = allow;
2361 }
2362
2363 void TestRunner::setPOSIXLocale(JSStringRef locale)
2364 {
2365     char localeBuf[32];
2366     JSStringGetUTF8CString(locale, localeBuf, sizeof(localeBuf));
2367     setlocale(LC_ALL, localeBuf);
2368 }
2369
2370 void TestRunner::addURLToRedirect(std::string origin, std::string destination)
2371 {
2372     m_URLsToRedirect[origin] = destination;
2373 }
2374
2375 const char* TestRunner::redirectionDestinationForURL(const char* origin)
2376 {
2377     if (!origin)
2378         return nullptr;
2379
2380     auto iterator = m_URLsToRedirect.find(origin);
2381     if (iterator == m_URLsToRedirect.end())
2382         return nullptr;
2383
2384     return iterator->second.data();
2385 }
2386
2387 void TestRunner::setShouldPaintBrokenImage(bool shouldPaintBrokenImage)
2388 {
2389     m_shouldPaintBrokenImage = shouldPaintBrokenImage;
2390 }
2391
2392 void TestRunner::setAccummulateLogsForChannel(JSStringRef channel)
2393 {
2394     size_t maxLength = JSStringGetMaximumUTF8CStringSize(channel);
2395     auto buffer = std::make_unique<char[]>(maxLength + 1);
2396     JSStringGetUTF8CString(channel, buffer.get(), maxLength + 1);
2397
2398     WebCoreTestSupport::setLogChannelToAccumulate({ buffer.get() });
2399 }
2400
2401 typedef WTF::HashMap<unsigned, JSValueRef> CallbackMap;
2402 static CallbackMap& callbackMap()
2403 {
2404     static CallbackMap& map = *new CallbackMap;
2405     return map;
2406 }
2407
2408 void TestRunner::cacheTestRunnerCallback(unsigned index, JSValueRef callback)
2409 {
2410     if (!callback)
2411         return;
2412
2413     if (callbackMap().contains(index)) {
2414         fprintf(stderr, "FAIL: Tried to install a second TestRunner callback for the same event (id %d)\n", index);
2415         return;
2416     }
2417
2418     JSContextRef context = mainFrameJSContext();
2419     JSValueProtect(context, callback);
2420     callbackMap().add(index, callback);
2421 }
2422
2423 void TestRunner::callTestRunnerCallback(unsigned index, size_t argumentCount, const JSValueRef arguments[])
2424 {
2425     if (!callbackMap().contains(index))
2426         return;
2427
2428     JSContextRef context = mainFrameJSContext();
2429     if (JSObjectRef callback = JSValueToObject(context, callbackMap().take(index), 0)) {
2430         JSObjectCallAsFunction(context, callback, JSContextGetGlobalObject(context), argumentCount, arguments, 0);
2431         JSValueUnprotect(context, callback);
2432     }
2433 }
2434
2435 void TestRunner::clearTestRunnerCallbacks()
2436 {
2437     JSContextRef context = mainFrameJSContext();
2438
2439     for (auto& iter : callbackMap()) {
2440         if (JSObjectRef callback = JSValueToObject(context, iter.value, 0))
2441             JSValueUnprotect(context, callback);
2442     }
2443
2444     callbackMap().clear();
2445 }
2446
2447 enum {
2448     FirstUIScriptCallbackID = 100
2449 };
2450
2451 static unsigned nextUIScriptCallbackID()
2452 {
2453     static unsigned callbackID = FirstUIScriptCallbackID;
2454     return callbackID++;
2455 }
2456
2457 void TestRunner::runUIScript(JSContextRef context, JSStringRef script, JSValueRef callback)
2458 {
2459     m_pendingUIScriptInvocationData = nullptr;
2460
2461     unsigned callbackID = nextUIScriptCallbackID();
2462     cacheTestRunnerCallback(callbackID, callback);
2463
2464     if (!m_UIScriptContext)
2465         m_UIScriptContext = std::make_unique<WTR::UIScriptContext>(*this);
2466
2467     String scriptString(JSStringGetCharactersPtr(script), JSStringGetLength(script));
2468     m_UIScriptContext->runUIScript(scriptString, callbackID);
2469 }
2470
2471 void TestRunner::callUIScriptCallback(unsigned callbackID, JSStringRef result)
2472 {
2473     JSRetainPtr<JSStringRef> protectedResult(result);
2474 #if !PLATFORM(IOS_FAMILY)
2475     RunLoop::main().dispatch([protectedThis = makeRef(*this), callbackID, protectedResult]() mutable {
2476         JSContextRef context = protectedThis->mainFrameJSContext();
2477         JSValueRef resultValue = JSValueMakeString(context, protectedResult.get());
2478         protectedThis->callTestRunnerCallback(callbackID, 1, &resultValue);
2479     });
2480 #else
2481     WebThreadRun(
2482         makeBlockPtr([protectedThis = makeRef(*this), callbackID, protectedResult] {
2483             JSContextRef context = protectedThis->mainFrameJSContext();
2484             JSValueRef resultValue = JSValueMakeString(context, protectedResult.get());
2485             protectedThis->callTestRunnerCallback(callbackID, 1, &resultValue);
2486         }).get()
2487     );
2488 #endif
2489 }
2490
2491 void TestRunner::uiScriptDidComplete(const String& result, unsigned callbackID)
2492 {
2493     auto stringRef = adopt(JSStringCreateWithUTF8CString(result.utf8().data()));
2494     callUIScriptCallback(callbackID, stringRef.get());
2495 }
2496
2497 void TestRunner::setAllowsAnySSLCertificate(bool allowsAnySSLCertificate)
2498 {
2499     WebCoreTestSupport::setAllowsAnySSLCertificate(allowsAnySSLCertificate);
2500 }
2501
2502 void TestRunner::setOpenPanelFiles(JSContextRef context, JSValueRef filesValue)
2503 {
2504     if (!JSValueIsArray(context, filesValue))
2505         return;
2506
2507     JSObjectRef files = JSValueToObject(context, filesValue, nullptr);
2508     static auto lengthProperty = adopt(JSStringCreateWithUTF8CString("length"));
2509     JSValueRef filesLengthValue = JSObjectGetProperty(context, files, lengthProperty.get(), nullptr);
2510     if (!JSValueIsNumber(context, filesLengthValue))
2511         return;
2512
2513     m_openPanelFiles.clear();
2514     auto filesLength = static_cast<size_t>(JSValueToNumber(context, filesLengthValue, nullptr));
2515     for (size_t i = 0; i < filesLength; ++i) {
2516         JSValueRef fileValue = JSObjectGetPropertyAtIndex(context, files, i, nullptr);
2517         if (!JSValueIsString(context, fileValue))
2518             continue;
2519
2520         auto file = adopt(JSValueToStringCopy(context, fileValue, nullptr));
2521         size_t fileBufferSize = JSStringGetMaximumUTF8CStringSize(file.get()) + 1;
2522         auto fileBuffer = std::make_unique<char[]>(fileBufferSize);
2523         JSStringGetUTF8CString(file.get(), fileBuffer.get(), fileBufferSize);
2524
2525         m_openPanelFiles.push_back(fileBuffer.get());
2526     }
2527 }
2528
2529 void TestRunner::cleanup()
2530 {
2531     clearTestRunnerCallbacks();
2532 }