b4b5bf2eca382ddeca500cfbe3f4c1ba4bd96c79
[WebKit.git] / WebKitTools / DumpRenderTree / LayoutTestController.cpp
1 /*
2  * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer. 
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution. 
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "LayoutTestController.h"
31
32 #include "WorkQueue.h"
33 #include "WorkQueueItem.h"
34 #include <JavaScriptCore/JSContextRef.h>
35 #include <JavaScriptCore/JSObjectRef.h>
36 #include <JavaScriptCore/JSRetainPtr.h>
37 #include <stdio.h>
38 #include <wtf/Assertions.h>
39 #include <wtf/MathExtras.h>
40 #include <wtf/RefPtr.h>
41
42 LayoutTestController::LayoutTestController(const std::string& testPathOrURL, const std::string& expectedPixelHash)
43     : m_dumpAsPDF(false)
44     , m_dumpAsText(false)
45     , m_dumpBackForwardList(false)
46     , m_dumpChildFrameScrollPositions(false)
47     , m_dumpChildFramesAsText(false)
48     , m_dumpDOMAsWebArchive(false)
49     , m_dumpDatabaseCallbacks(false)
50     , m_dumpEditingCallbacks(false)
51     , m_dumpFrameLoadCallbacks(false)
52     , m_dumpHistoryDelegateCallbacks(false)
53     , m_dumpResourceLoadCallbacks(false)
54     , m_dumpResourceResponseMIMETypes(false)
55     , m_dumpSelectionRect(false)
56     , m_dumpSourceAsWebArchive(false)
57     , m_dumpStatusCallbacks(false)
58     , m_dumpTitleChanges(false)
59     , m_dumpIconChanges(false)
60     , m_dumpVisitedLinksCallback(false)
61     , m_dumpWillCacheResponse(false)
62     , m_callCloseOnWebViews(true)
63     , m_canOpenWindows(false)
64     , m_closeRemainingWindowsWhenComplete(true)
65     , m_newWindowsCopyBackForwardList(false)
66     , m_stopProvisionalFrameLoads(false)
67     , m_testOnscreen(false)
68     , m_testRepaint(false)
69     , m_testRepaintSweepHorizontally(false)
70     , m_waitToDump(false)
71     , m_willSendRequestReturnsNull(false)
72     , m_willSendRequestReturnsNullOnRedirect(false)
73     , m_windowIsKey(true)
74     , m_alwaysAcceptCookies(false)
75     , m_globalFlag(false)
76     , m_isGeolocationPermissionSet(false)
77     , m_geolocationPermission(false)
78     , m_handlesAuthenticationChallenges(false)
79     , m_isPrinting(false)
80     , m_testPathOrURL(testPathOrURL)
81     , m_expectedPixelHash(expectedPixelHash)
82 {
83 }
84
85 // Static Functions
86
87 static JSValueRef dumpAsPDFCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
88 {
89     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
90     controller->setDumpAsPDF(true);
91     return JSValueMakeUndefined(context);
92 }
93
94 static JSValueRef dumpAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
95 {
96     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
97     controller->setDumpAsText(true);
98     return JSValueMakeUndefined(context);
99 }
100
101 static JSValueRef dumpBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
102 {
103     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
104     controller->setDumpBackForwardList(true);
105     return JSValueMakeUndefined(context);
106 }
107
108 static JSValueRef dumpChildFramesAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
109 {
110     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
111     controller->setDumpChildFramesAsText(true);
112     return JSValueMakeUndefined(context);
113 }
114
115 static JSValueRef dumpChildFrameScrollPositionsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
116 {
117     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
118     controller->setDumpChildFrameScrollPositions(true);
119     return JSValueMakeUndefined(context);
120 }
121
122 static JSValueRef dumpDatabaseCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
123 {
124     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
125     controller->setDumpDatabaseCallbacks(true);
126     return JSValueMakeUndefined(context);
127 }
128
129 static JSValueRef dumpDOMAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
130 {
131     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
132     controller->setDumpDOMAsWebArchive(true);
133     return JSValueMakeUndefined(context);
134 }
135
136 static JSValueRef dumpEditingCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
137 {
138     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
139     controller->setDumpEditingCallbacks(true);
140     return JSValueMakeUndefined(context);
141 }
142
143 static JSValueRef dumpFrameLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
144 {
145     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
146     controller->setDumpFrameLoadCallbacks(true);
147     return JSValueMakeUndefined(context);
148 }
149
150 static JSValueRef dumpResourceLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
151 {
152     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
153     controller->setDumpResourceLoadCallbacks(true);
154     return JSValueMakeUndefined(context);
155 }
156
157 static JSValueRef dumpResourceResponseMIMETypesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
158 {
159     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
160     controller->setDumpResourceResponseMIMETypes(true);
161     return JSValueMakeUndefined(context);
162 }
163
164 static JSValueRef dumpSelectionRectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
165 {
166     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
167     controller->setDumpSelectionRect(true);
168     return JSValueMakeUndefined(context);
169 }
170
171 static JSValueRef dumpSourceAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
172 {
173     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
174     controller->setDumpSourceAsWebArchive(true);
175     return JSValueMakeUndefined(context);
176 }
177
178 static JSValueRef dumpStatusCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
179 {
180     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
181     controller->setDumpStatusCallbacks(true);
182     return JSValueMakeUndefined(context);
183 }
184
185 static JSValueRef dumpTitleChangesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
186 {
187     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
188     controller->setDumpTitleChanges(true);
189     return JSValueMakeUndefined(context);
190 }
191
192 static JSValueRef dumpIconChangesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
193 {
194     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
195     controller->setDumpIconChanges(true);
196     return JSValueMakeUndefined(context);
197 }
198
199 static JSValueRef dumpWillCacheResponseCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
200 {
201     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
202     controller->setDumpWillCacheResponse(true);
203     return JSValueMakeUndefined(context);
204 }
205
206 static JSValueRef pathToLocalResourceCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
207 {
208     if (argumentCount < 1)
209         return JSValueMakeUndefined(context);
210
211     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
212     JSRetainPtr<JSStringRef> localPath(Adopt, JSValueToStringCopy(context, arguments[0], exception));
213     ASSERT(!*exception);
214
215     JSRetainPtr<JSStringRef> convertedPath(Adopt, controller->pathToLocalResource(context, localPath.get()));
216     if (!convertedPath)
217         return JSValueMakeUndefined(context);
218
219     return JSValueMakeString(context, convertedPath.get());
220 }
221
222 static JSValueRef removeAllVisitedLinksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
223 {
224     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
225     controller->setDumpVisitedLinksCallback(true);
226     controller->removeAllVisitedLinks();
227     return JSValueMakeUndefined(context);
228 }
229
230 static JSValueRef repaintSweepHorizontallyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
231 {
232     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
233     controller->setTestRepaintSweepHorizontally(true);
234     return JSValueMakeUndefined(context);
235 }
236
237 static JSValueRef setCallCloseOnWebViewsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
238 {
239     if (argumentCount < 1)
240         return JSValueMakeUndefined(context);
241
242     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
243     controller->setCallCloseOnWebViews(JSValueToBoolean(context, arguments[0]));
244     return JSValueMakeUndefined(context);
245 }
246
247 static JSValueRef setCanOpenWindowsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
248 {
249     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
250     controller->setCanOpenWindows(true);
251     return JSValueMakeUndefined(context);
252 }
253
254 static JSValueRef setCloseRemainingWindowsWhenCompleteCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
255 {
256     if (argumentCount < 1)
257         return JSValueMakeUndefined(context);
258
259     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
260     controller->setCloseRemainingWindowsWhenComplete(JSValueToBoolean(context, arguments[0]));
261     return JSValueMakeUndefined(context);
262 }
263
264 static JSValueRef testOnscreenCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
265 {
266     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
267     controller->setTestOnscreen(true);
268     return JSValueMakeUndefined(context);
269 }
270
271 static JSValueRef testRepaintCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
272 {
273     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
274     controller->setTestRepaint(true);
275     return JSValueMakeUndefined(context);
276 }
277
278 static JSValueRef addDisallowedURLCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
279 {
280     // Has mac implementation
281     if (argumentCount < 1)
282         return JSValueMakeUndefined(context);
283
284     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
285     ASSERT(!*exception);
286
287     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
288     controller->addDisallowedURL(url.get());
289
290     return JSValueMakeUndefined(context);
291 }
292
293 static JSValueRef callShouldCloseOnWebViewCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
294 {
295     // Has mac & windows implementation
296     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
297
298     return JSValueMakeBoolean(context, controller->callShouldCloseOnWebView());
299 }
300
301 static JSValueRef clearAllDatabasesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
302 {
303     // Has mac & windows implementation
304     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
305     controller->clearAllDatabases();
306
307     return JSValueMakeUndefined(context);
308 }
309
310 static JSValueRef clearBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
311 {
312     // Has mac & windows implementation
313     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
314     controller->clearBackForwardList();
315
316     return JSValueMakeUndefined(context);
317 }
318
319 static JSValueRef clearPersistentUserStyleSheetCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
320 {
321     // Has mac & windows implementation
322     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
323     controller->clearPersistentUserStyleSheet();
324
325     return JSValueMakeUndefined(context);
326 }
327
328 static JSValueRef decodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
329 {
330     // Has mac implementation
331     if (argumentCount < 1)
332         return JSValueMakeUndefined(context);
333
334     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
335     ASSERT(!*exception);
336
337     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
338     JSRetainPtr<JSStringRef> decodedHostName(Adopt, controller->copyDecodedHostName(name.get()));
339     return JSValueMakeString(context, decodedHostName.get());
340 }
341
342 static JSValueRef disableImageLoadingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
343 {
344     // Has mac implementation, needs windows implementation
345     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
346     controller->disableImageLoading();
347     
348     return JSValueMakeUndefined(context);
349 }
350
351 static JSValueRef dispatchPendingLoadRequestsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
352 {
353     // Has mac implementation, needs windows implementation
354     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
355     controller->dispatchPendingLoadRequests();
356     
357     return JSValueMakeUndefined(context);
358 }
359
360 static JSValueRef displayCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
361 {
362     // Has mac & windows implementation
363     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
364     controller->display();
365
366     return JSValueMakeUndefined(context);
367 }
368
369 static JSValueRef encodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
370 {
371     // Has mac implementation
372     if (argumentCount < 1)
373         return JSValueMakeUndefined(context);
374
375     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
376     ASSERT(!*exception);
377
378     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
379     JSRetainPtr<JSStringRef> encodedHostName(Adopt, controller->copyEncodedHostName(name.get()));
380     return JSValueMakeString(context, encodedHostName.get());
381 }
382
383 static JSValueRef execCommandCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
384 {
385     // Has Mac & Windows implementations.
386     if (argumentCount < 1)
387         return JSValueMakeUndefined(context);
388
389     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
390     ASSERT(!*exception);
391
392     // Ignoring the second parameter (userInterface), as this command emulates a manual action.
393
394     JSRetainPtr<JSStringRef> value;
395     if (argumentCount >= 3) {
396         value.adopt(JSValueToStringCopy(context, arguments[2], exception));
397         ASSERT(!*exception);
398     } else
399         value.adopt(JSStringCreateWithUTF8CString(""));
400
401
402     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
403     controller->execCommand(name.get(), value.get());
404
405     return JSValueMakeUndefined(context);
406 }
407
408 static JSValueRef counterValueForElementByIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
409 {
410     if (argumentCount < 1)
411         return JSValueMakeUndefined(context);
412
413     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
414     if (*exception)
415         return JSValueMakeUndefined(context);
416
417     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
418     JSRetainPtr<JSStringRef> counterValue(controller->counterValueForElementById(elementId.get()));
419     if (!counterValue.get())
420         return JSValueMakeUndefined(context);
421     return JSValueMakeString(context, counterValue.get());
422 }
423
424 static JSValueRef grantDesktopNotificationPermissionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
425 {
426     // Has Windows implementation
427     if (argumentCount < 1)
428         return JSValueMakeUndefined(context);
429
430     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
431
432     controller->grantDesktopNotificationPermission(JSValueToStringCopy(context, arguments[0], NULL));
433         
434     return JSValueMakeUndefined(context);
435 }
436
437 static JSValueRef isCommandEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
438 {
439     // Has Mac implementation.
440
441     if (argumentCount < 1)
442         return JSValueMakeUndefined(context);
443
444     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
445     ASSERT(!*exception);
446
447     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
448
449     return JSValueMakeBoolean(context, controller->isCommandEnabled(name.get()));
450 }
451
452 static JSValueRef overridePreferenceCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
453 {
454     if (argumentCount < 2)
455         return JSValueMakeUndefined(context);
456
457     JSRetainPtr<JSStringRef> key(Adopt, JSValueToStringCopy(context, arguments[0], exception));
458     ASSERT(!*exception);
459     JSRetainPtr<JSStringRef> value(Adopt, JSValueToStringCopy(context, arguments[1], exception));
460     ASSERT(!*exception);
461
462     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
463     controller->overridePreference(key.get(), value.get());
464
465     return JSValueMakeUndefined(context);
466 }
467
468 static JSValueRef keepWebHistoryCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
469 {
470     // Has mac implementation
471     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
472     controller->keepWebHistory();
473
474     return JSValueMakeUndefined(context);
475 }
476
477 static JSValueRef computedStyleIncludingVisitedInfoCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
478 {
479     if (argumentCount != 1)
480         return JSValueMakeUndefined(context);
481     
482     // Has mac implementation
483     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
484     return controller->computedStyleIncludingVisitedInfo(context, arguments[0]);
485 }
486
487 static JSValueRef layerTreeAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
488 {
489     // Has mac & windows implementation
490     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
491     return JSValueMakeString(context, controller->layerTreeAsText().get());
492 }
493
494 static JSValueRef notifyDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
495 {
496     // Has mac & windows implementation
497     // May be able to be made platform independant by using shared WorkQueue
498     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
499     controller->notifyDone();
500     return JSValueMakeUndefined(context);
501 }
502
503 static bool parsePageParameters(JSContextRef context, int argumentCount, const JSValueRef* arguments, JSValueRef* exception, float& pageWidthInPixels, float& pageHeightInPixels)
504 {
505     pageWidthInPixels = LayoutTestController::maxViewWidth;
506     pageHeightInPixels = LayoutTestController::maxViewHeight;
507     switch (argumentCount) {
508     case 2:
509         pageWidthInPixels = static_cast<float>(JSValueToNumber(context, arguments[0], exception));
510         if (*exception)
511             return false;
512         pageHeightInPixels = static_cast<float>(JSValueToNumber(context, arguments[1], exception));
513         if (*exception)
514             return false;
515     case 0: // Fall through.
516         break;
517     default:
518         return false;
519     }
520     return true;
521 }
522
523 static JSValueRef pageNumberForElementByIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
524 {
525     float pageWidthInPixels = 0;
526     float pageHeightInPixels = 0;
527     if (!parsePageParameters(context, argumentCount - 1, arguments + 1, exception, pageWidthInPixels, pageHeightInPixels))
528         return JSValueMakeUndefined(context);
529
530     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
531     if (*exception)
532         return JSValueMakeUndefined(context);
533
534     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
535     int pageNumber = controller->pageNumberForElementById(elementId.get(), pageWidthInPixels, pageHeightInPixels);
536     return JSValueMakeNumber(context, pageNumber);
537 }
538
539 static JSValueRef numberOfPagesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
540 {
541     float pageWidthInPixels = 0;
542     float pageHeightInPixels = 0;
543     if (!parsePageParameters(context, argumentCount, arguments, exception, pageWidthInPixels, pageHeightInPixels))
544         return JSValueMakeUndefined(context);
545
546     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
547     return JSValueMakeNumber(context, controller->numberOfPages(pageWidthInPixels, pageHeightInPixels));
548 }
549
550 static JSValueRef queueBackNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
551 {
552     // Has mac & windows implementation
553     // May be able to be made platform independant by using shared WorkQueue
554     if (argumentCount < 1)
555         return JSValueMakeUndefined(context);
556
557     double howFarBackDouble = JSValueToNumber(context, arguments[0], exception);
558     ASSERT(!*exception);
559
560     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
561     controller->queueBackNavigation(static_cast<int>(howFarBackDouble));
562
563     return JSValueMakeUndefined(context);
564 }
565
566 static JSValueRef queueForwardNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
567 {
568     // Has mac & windows implementation
569     // May be able to be made platform independant by using shared WorkQueue
570     if (argumentCount < 1)
571         return JSValueMakeUndefined(context);
572
573     double howFarForwardDouble = JSValueToNumber(context, arguments[0], exception);
574     ASSERT(!*exception);
575
576     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
577     controller->queueForwardNavigation(static_cast<int>(howFarForwardDouble));
578
579     return JSValueMakeUndefined(context);
580 }
581
582 static JSValueRef queueLoadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
583 {
584     // Has mac & windows implementation
585     // May be able to be made platform independant by using shared WorkQueue
586     if (argumentCount < 1)
587         return JSValueMakeUndefined(context);
588
589     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
590     ASSERT(!*exception);
591
592     JSRetainPtr<JSStringRef> target;
593     if (argumentCount >= 2) {
594         target.adopt(JSValueToStringCopy(context, arguments[1], exception));
595         ASSERT(!*exception);
596     } else
597         target.adopt(JSStringCreateWithUTF8CString(""));
598
599     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
600     controller->queueLoad(url.get(), target.get());
601
602     return JSValueMakeUndefined(context);
603 }
604
605 static JSValueRef queueReloadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
606 {
607     // Has mac & windows implementation
608     // May be able to be made platform independant by using shared WorkQueue
609
610     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
611     controller->queueReload();
612
613     return JSValueMakeUndefined(context);
614 }
615
616 static JSValueRef queueLoadingScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
617 {
618     // Has mac & windows implementation
619     // May be able to be made platform independant by using shared WorkQueue
620     if (argumentCount < 1)
621         return JSValueMakeUndefined(context);
622
623     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
624     ASSERT(!*exception);
625
626     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
627     controller->queueLoadingScript(script.get());
628
629     return JSValueMakeUndefined(context);
630 }
631
632 static JSValueRef queueNonLoadingScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
633 {
634     // Has mac & windows implementation
635     // May be able to be made platform independant by using shared WorkQueue
636     if (argumentCount < 1)
637         return JSValueMakeUndefined(context);
638
639     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
640     ASSERT(!*exception);
641
642     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
643     controller->queueNonLoadingScript(script.get());
644
645     return JSValueMakeUndefined(context);
646 }
647
648 static JSValueRef setAcceptsEditingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
649 {
650     // Has mac & windows implementation
651     if (argumentCount < 1)
652         return JSValueMakeUndefined(context);
653
654     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
655     controller->setAcceptsEditing(JSValueToBoolean(context, arguments[0]));
656
657     return JSValueMakeUndefined(context);
658 }
659
660 static JSValueRef setAlwaysAcceptCookiesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
661 {
662     // Has mac & windows implementation
663     if (argumentCount < 1)
664         return JSValueMakeUndefined(context);
665
666     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
667     controller->setAlwaysAcceptCookies(JSValueToBoolean(context, arguments[0]));
668
669     return JSValueMakeUndefined(context);
670 }
671
672 static JSValueRef setAppCacheMaximumSizeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
673 {
674     // Has mac implementation
675     if (argumentCount < 1)
676         return JSValueMakeUndefined(context);
677
678     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
679
680     double size = JSValueToNumber(context, arguments[0], NULL);
681     if (!isnan(size))
682         controller->setAppCacheMaximumSize(static_cast<unsigned long long>(size));
683         
684     return JSValueMakeUndefined(context);
685
686 }
687
688 static JSValueRef setAuthenticationPasswordCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
689 {
690     // Has mac & windows implementation
691     if (argumentCount < 1)
692         return JSValueMakeUndefined(context);
693
694     JSRetainPtr<JSStringRef> password(Adopt, JSValueToStringCopy(context, arguments[0], exception));
695     ASSERT(!*exception);
696
697     size_t maxLength = JSStringGetMaximumUTF8CStringSize(password.get());
698     char* passwordBuffer = new char[maxLength + 1];
699     JSStringGetUTF8CString(password.get(), passwordBuffer, maxLength + 1);
700     
701     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
702     controller->setAuthenticationPassword(passwordBuffer);
703     delete[] passwordBuffer;
704
705     return JSValueMakeUndefined(context);
706 }
707
708 static JSValueRef setAuthenticationUsernameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
709 {
710     // Has mac & windows implementation
711     if (argumentCount < 1)
712         return JSValueMakeUndefined(context);
713
714     JSRetainPtr<JSStringRef> username(Adopt, JSValueToStringCopy(context, arguments[0], exception));
715     ASSERT(!*exception);
716
717     size_t maxLength = JSStringGetMaximumUTF8CStringSize(username.get());
718     char* usernameBuffer = new char[maxLength + 1];
719     JSStringGetUTF8CString(username.get(), usernameBuffer, maxLength + 1);
720     
721     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
722     controller->setAuthenticationUsername(usernameBuffer);
723     delete[] usernameBuffer;
724
725     return JSValueMakeUndefined(context);
726 }
727
728 static JSValueRef setAuthorAndUserStylesEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
729 {
730     // Has mac & windows implementation
731     if (argumentCount < 1)
732         return JSValueMakeUndefined(context);
733
734     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
735     controller->setAuthorAndUserStylesEnabled(JSValueToBoolean(context, arguments[0]));
736
737     return JSValueMakeUndefined(context);
738 }
739
740 static JSValueRef setCacheModelCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
741 {
742     // Has Mac implementation.
743     if (argumentCount < 1)
744         return JSValueMakeUndefined(context);
745
746     int cacheModel = JSValueToNumber(context, arguments[0], exception);
747     ASSERT(!*exception);
748
749     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
750     controller->setCacheModel(cacheModel);
751
752     return JSValueMakeUndefined(context);
753 }
754
755 static JSValueRef setCustomPolicyDelegateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
756 {
757     // Has mac implementation
758     if (argumentCount < 1)
759         return JSValueMakeUndefined(context);
760     
761     bool permissive = false;
762     if (argumentCount >= 2)
763         permissive = JSValueToBoolean(context, arguments[1]);
764
765     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
766     controller->setCustomPolicyDelegate(JSValueToBoolean(context, arguments[0]), permissive);
767
768     return JSValueMakeUndefined(context);
769 }
770
771 static JSValueRef setDatabaseQuotaCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
772 {
773     // Has mac implementation
774     if (argumentCount < 1)
775         return JSValueMakeUndefined(context);
776
777     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
778
779     double quota = JSValueToNumber(context, arguments[0], NULL);
780     if (!isnan(quota))
781         controller->setDatabaseQuota(static_cast<unsigned long long>(quota));
782         
783     return JSValueMakeUndefined(context);
784 }
785
786 static JSValueRef setDomainRelaxationForbiddenForURLSchemeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
787 {
788     // Has Mac and Windows implementation
789     if (argumentCount < 2)
790         return JSValueMakeUndefined(context);
791
792     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
793
794     bool forbidden = JSValueToBoolean(context, arguments[0]);
795     JSRetainPtr<JSStringRef> scheme(Adopt, JSValueToStringCopy(context, arguments[1], 0));
796     controller->setDomainRelaxationForbiddenForURLScheme(forbidden, scheme.get());
797
798     return JSValueMakeUndefined(context);
799 }
800
801 static JSValueRef setMockGeolocationPositionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
802 {
803     if (argumentCount < 3)
804         return JSValueMakeUndefined(context);
805
806     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
807     controller->setMockGeolocationPosition(JSValueToNumber(context, arguments[0], NULL),  // latitude
808                                            JSValueToNumber(context, arguments[1], NULL),  // longitude
809                                            JSValueToNumber(context, arguments[2], NULL));  // accuracy
810
811     return JSValueMakeUndefined(context);
812 }
813
814 static JSValueRef setMockGeolocationErrorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
815 {
816     if (argumentCount < 2)
817         return JSValueMakeUndefined(context);
818
819     int code = JSValueToNumber(context, arguments[0], NULL);
820     JSRetainPtr<JSStringRef> message(Adopt, JSValueToStringCopy(context, arguments[1], exception));
821     ASSERT(!*exception);
822
823     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
824     controller->setMockGeolocationError(code, message.get());
825
826     return JSValueMakeUndefined(context);
827 }
828
829 static JSValueRef setNewWindowsCopyBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
830 {
831     // Has mac implementation
832     if (argumentCount < 1)
833         return JSValueMakeUndefined(context);
834     
835     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
836     controller->setNewWindowsCopyBackForwardList(JSValueToBoolean(context, arguments[0]));
837
838     return JSValueMakeUndefined(context);
839 }
840
841 static JSValueRef setGeolocationPermissionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
842 {
843     // Has mac implementation
844     if (argumentCount < 1)
845         return JSValueMakeUndefined(context);
846
847     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
848     controller->setGeolocationPermission(JSValueToBoolean(context, arguments[0]));
849
850     return JSValueMakeUndefined(context);
851 }
852
853 static JSValueRef setHandlesAuthenticationChallengesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
854 {
855     // Has mac & windows implementation
856     if (argumentCount < 1)
857         return JSValueMakeUndefined(context);
858
859     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
860     controller->setHandlesAuthenticationChallenges(JSValueToBoolean(context, arguments[0]));
861
862     return JSValueMakeUndefined(context);
863 }
864
865 static JSValueRef setPOSIXLocaleCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
866 {
867     if (argumentCount < 1)
868         return JSValueMakeUndefined(context);
869
870     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
871     JSRetainPtr<JSStringRef> locale(Adopt, JSValueToStringCopy(context, arguments[0], exception));
872     ASSERT(!*exception);
873     controller->setPOSIXLocale(locale.get());
874
875     return JSValueMakeUndefined(context);
876 }
877
878 static JSValueRef setIconDatabaseEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
879 {
880     // Has mac & windows implementation
881     if (argumentCount < 1)
882         return JSValueMakeUndefined(context);
883
884     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
885     controller->setIconDatabaseEnabled(JSValueToBoolean(context, arguments[0]));
886
887     return JSValueMakeUndefined(context);
888 }
889
890 static JSValueRef setJavaScriptProfilingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
891 {
892     if (argumentCount < 1)
893         return JSValueMakeUndefined(context);
894
895     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
896     controller->setJavaScriptProfilingEnabled(JSValueToBoolean(context, arguments[0]));
897
898     return JSValueMakeUndefined(context);
899 }
900
901 static JSValueRef setMainFrameIsFirstResponderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
902 {
903     // Has mac implementation
904     if (argumentCount < 1)
905         return JSValueMakeUndefined(context);
906
907     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
908     controller->setMainFrameIsFirstResponder(JSValueToBoolean(context, arguments[0]));
909
910     return JSValueMakeUndefined(context);
911 }
912
913 static JSValueRef setPersistentUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
914 {
915     // Has mac implementation
916     if (argumentCount < 1)
917         return JSValueMakeUndefined(context);
918
919     JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
920     ASSERT(!*exception);
921
922     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
923     controller->setPersistentUserStyleSheetLocation(path.get());
924
925     return JSValueMakeUndefined(context);
926 }
927
928 static JSValueRef setPrivateBrowsingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
929 {
930     // Has mac & windows implementation
931     if (argumentCount < 1)
932         return JSValueMakeUndefined(context);
933
934     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
935     controller->setPrivateBrowsingEnabled(JSValueToBoolean(context, arguments[0]));
936
937     return JSValueMakeUndefined(context);
938 }
939
940 static JSValueRef setJavaScriptCanAccessClipboardCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
941 {
942     // Has mac & windows implementation
943     if (argumentCount < 1)
944         return JSValueMakeUndefined(context);
945
946     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
947     controller->setJavaScriptCanAccessClipboard(JSValueToBoolean(context, arguments[0]));
948
949     return JSValueMakeUndefined(context);
950 }
951
952 static JSValueRef setXSSAuditorEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
953 {
954     // Has mac & windows implementation
955     if (argumentCount < 1)
956         return JSValueMakeUndefined(context);
957
958     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
959     controller->setXSSAuditorEnabled(JSValueToBoolean(context, arguments[0]));
960
961     return JSValueMakeUndefined(context);
962 }
963
964 static JSValueRef setSpatialNavigationEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
965 {
966     if (argumentCount < 1)
967         return JSValueMakeUndefined(context);
968
969     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
970     controller->setSpatialNavigationEnabled(JSValueToBoolean(context, arguments[0]));
971
972     return JSValueMakeUndefined(context);
973 }
974
975 static JSValueRef setPrintingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
976 {
977     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
978     controller->setIsPrinting(true);
979     return JSValueMakeUndefined(context);
980 }
981
982
983 static JSValueRef setFrameFlatteningEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
984 {
985     // Has mac & windows implementation
986     if (argumentCount < 1)
987         return JSValueMakeUndefined(context);
988
989     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
990     controller->setFrameFlatteningEnabled(JSValueToBoolean(context, arguments[0]));
991
992     return JSValueMakeUndefined(context);
993 }
994
995 static JSValueRef setAllowUniversalAccessFromFileURLsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
996 {
997     // Has mac & windows implementation
998     if (argumentCount < 1)
999         return JSValueMakeUndefined(context);
1000
1001     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1002     controller->setAllowUniversalAccessFromFileURLs(JSValueToBoolean(context, arguments[0]));
1003
1004     return JSValueMakeUndefined(context);
1005 }
1006
1007 static JSValueRef setAllowFileAccessFromFileURLsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1008 {
1009     // Has mac & windows implementation
1010     if (argumentCount < 1)
1011         return JSValueMakeUndefined(context);
1012
1013     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1014     controller->setAllowFileAccessFromFileURLs(JSValueToBoolean(context, arguments[0]));
1015
1016     return JSValueMakeUndefined(context);
1017 }
1018
1019 static JSValueRef setTabKeyCyclesThroughElementsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1020 {
1021     // Has mac & windows implementation
1022     if (argumentCount < 1)
1023         return JSValueMakeUndefined(context);
1024
1025     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1026     controller->setTabKeyCyclesThroughElements(JSValueToBoolean(context, arguments[0]));
1027
1028     return JSValueMakeUndefined(context);
1029 }
1030
1031 static JSValueRef setTimelineProfilingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1032 {
1033     if (argumentCount < 1)
1034         return JSValueMakeUndefined(context);
1035
1036     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1037     controller->setTimelineProfilingEnabled(JSValueToBoolean(context, arguments[0]));
1038     return JSValueMakeUndefined(context);
1039 }
1040
1041 static JSValueRef setUseDashboardCompatibilityModeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1042 {
1043     // Has mac implementation
1044     if (argumentCount < 1)
1045         return JSValueMakeUndefined(context);
1046
1047     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1048     controller->setUseDashboardCompatibilityMode(JSValueToBoolean(context, arguments[0]));
1049
1050     return JSValueMakeUndefined(context);
1051 }
1052
1053 static JSValueRef setUserStyleSheetEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1054 {
1055     // Has mac implementation
1056     if (argumentCount < 1)
1057         return JSValueMakeUndefined(context);
1058
1059     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1060     controller->setUserStyleSheetEnabled(JSValueToBoolean(context, arguments[0]));
1061
1062     return JSValueMakeUndefined(context);
1063 }
1064
1065 static JSValueRef setUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1066 {
1067     // Has mac implementation
1068     if (argumentCount < 1)
1069         return JSValueMakeUndefined(context);
1070
1071     JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1072     ASSERT(!*exception);
1073
1074     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1075     controller->setUserStyleSheetLocation(path.get());
1076
1077     return JSValueMakeUndefined(context);
1078 }
1079
1080 static JSValueRef setWillSendRequestClearHeaderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1081 {
1082     // Has mac & windows implementation
1083     if (argumentCount < 1)
1084         return JSValueMakeUndefined(context);
1085
1086     JSRetainPtr<JSStringRef> header(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1087     ASSERT(!*exception);
1088
1089     size_t maxLength = JSStringGetMaximumUTF8CStringSize(header.get());
1090     char* headerBuffer = new char[maxLength + 1];
1091     JSStringGetUTF8CString(header.get(), headerBuffer, maxLength + 1);
1092
1093     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1094     controller->setWillSendRequestClearHeader(headerBuffer);
1095
1096     return JSValueMakeUndefined(context);
1097 }
1098
1099 static JSValueRef setWillSendRequestReturnsNullCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1100 {
1101     // Has cross-platform implementation
1102     if (argumentCount < 1)
1103         return JSValueMakeUndefined(context);
1104
1105     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1106     controller->setWillSendRequestReturnsNull(JSValueToBoolean(context, arguments[0]));
1107
1108     return JSValueMakeUndefined(context);
1109 }
1110
1111 static JSValueRef setWillSendRequestReturnsNullOnRedirectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1112 {
1113     // Has cross-platform implementation
1114     if (argumentCount < 1)
1115         return JSValueMakeUndefined(context);
1116
1117     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1118     controller->setWillSendRequestReturnsNullOnRedirect(JSValueToBoolean(context, arguments[0]));
1119
1120     return JSValueMakeUndefined(context);
1121 }
1122
1123 static JSValueRef setWindowIsKeyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1124 {
1125     // Has mac implementation
1126     if (argumentCount < 1)
1127         return JSValueMakeUndefined(context);
1128
1129     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1130     controller->setWindowIsKey(JSValueToBoolean(context, arguments[0]));
1131
1132     return JSValueMakeUndefined(context);
1133 }
1134
1135 static JSValueRef waitUntilDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1136 {
1137     // Has mac & windows implementation
1138     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1139     controller->setWaitToDump(true);
1140
1141     return JSValueMakeUndefined(context);
1142 }
1143
1144 static JSValueRef windowCountCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1145 {
1146     // Has mac implementation
1147     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1148     int windows = controller->windowCount();
1149     return JSValueMakeNumber(context, windows);
1150 }
1151
1152 static JSValueRef setPopupBlockingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1153 {
1154     // Has mac & windows implementation
1155     if (argumentCount < 1)
1156         return JSValueMakeUndefined(context);
1157
1158     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1159     controller->setPopupBlockingEnabled(JSValueToBoolean(context, arguments[0]));
1160
1161     return JSValueMakeUndefined(context);
1162 }
1163
1164 static JSValueRef setSmartInsertDeleteEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1165 {
1166     if (argumentCount < 1)
1167         return JSValueMakeUndefined(context);
1168
1169     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1170     controller->setSmartInsertDeleteEnabled(JSValueToBoolean(context, arguments[0]));
1171     return JSValueMakeUndefined(context);
1172 }
1173
1174 static JSValueRef setSelectTrailingWhitespaceEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1175 {
1176     if (argumentCount < 1)
1177         return JSValueMakeUndefined(context);
1178
1179     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1180     controller->setSelectTrailingWhitespaceEnabled(JSValueToBoolean(context, arguments[0]));
1181     return JSValueMakeUndefined(context);
1182 }
1183
1184 static JSValueRef setStopProvisionalFrameLoadsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1185 {
1186     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1187     controller->setStopProvisionalFrameLoads(true);
1188     return JSValueMakeUndefined(context);
1189 }
1190
1191 static JSValueRef showWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1192 {
1193     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1194     controller->showWebInspector();
1195     return JSValueMakeUndefined(context);
1196 }
1197
1198 static JSValueRef closeWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1199 {
1200     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1201     controller->setTimelineProfilingEnabled(false);
1202     controller->closeWebInspector();
1203     return JSValueMakeUndefined(context);
1204 }
1205
1206 static JSValueRef evaluateInWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1207 {
1208     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1209     double callId = JSValueToNumber(context, arguments[0], exception);
1210     ASSERT(!*exception);
1211     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[1], exception));
1212     ASSERT(!*exception);
1213
1214     controller->evaluateInWebInspector(static_cast<long>(callId), script.get());
1215     return JSValueMakeUndefined(context);
1216 }
1217
1218 static JSValueRef evaluateScriptInIsolatedWorldCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1219 {
1220     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1221     double worldID = JSValueToNumber(context, arguments[0], exception);
1222     ASSERT(!*exception);
1223     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[1], exception));
1224     ASSERT(!*exception);
1225
1226     controller->evaluateScriptInIsolatedWorld(static_cast<unsigned>(worldID), JSContextGetGlobalObject(context), script.get());
1227     return JSValueMakeUndefined(context);
1228 }
1229
1230 static JSValueRef elementDoesAutoCompleteForElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1231 {
1232     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1233     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1234     ASSERT(!*exception);
1235
1236     bool autoCompletes = controller->elementDoesAutoCompleteForElementWithId(elementId.get());
1237
1238     return JSValueMakeBoolean(context, autoCompletes);
1239 }
1240
1241 static JSValueRef pauseAnimationAtTimeOnElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1242 {
1243     if (argumentCount != 3)
1244         return JSValueMakeUndefined(context);
1245
1246     JSRetainPtr<JSStringRef> animationName(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1247     ASSERT(!*exception);
1248     double time = JSValueToNumber(context, arguments[1], exception);
1249     ASSERT(!*exception);
1250     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
1251     ASSERT(!*exception);
1252
1253     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1254     return JSValueMakeBoolean(context, controller->pauseAnimationAtTimeOnElementWithId(animationName.get(), time, elementId.get()));
1255 }
1256
1257 static JSValueRef pauseTransitionAtTimeOnElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1258 {
1259     if (argumentCount != 3)
1260         return JSValueMakeUndefined(context);
1261
1262     JSRetainPtr<JSStringRef> propertyName(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1263     ASSERT(!*exception);
1264     double time = JSValueToNumber(context, arguments[1], exception);
1265     ASSERT(!*exception);
1266     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
1267     ASSERT(!*exception);
1268
1269     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1270     return JSValueMakeBoolean(context, controller->pauseTransitionAtTimeOnElementWithId(propertyName.get(), time, elementId.get()));
1271 }
1272
1273 static JSValueRef sampleSVGAnimationForElementAtTimeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1274 {
1275     if (argumentCount != 3)
1276         return JSValueMakeUndefined(context);
1277
1278     JSRetainPtr<JSStringRef> animationId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1279     ASSERT(!*exception);
1280     double time = JSValueToNumber(context, arguments[1], exception);
1281     ASSERT(!*exception);
1282     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
1283     ASSERT(!*exception);
1284
1285     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1286     return JSValueMakeBoolean(context, controller->sampleSVGAnimationForElementAtTime(animationId.get(), time, elementId.get()));
1287 }
1288
1289 static JSValueRef numberOfActiveAnimationsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1290 {
1291     if (argumentCount != 0)
1292         return JSValueMakeUndefined(context);
1293
1294     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1295     return JSValueMakeNumber(context, controller->numberOfActiveAnimations());
1296 }
1297
1298 static JSValueRef waitForPolicyDelegateCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*)
1299 {
1300     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1301     controller->waitForPolicyDelegate();
1302     return JSValueMakeUndefined(context);
1303 }
1304
1305 static JSValueRef addOriginAccessWhitelistEntryCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1306 {
1307     if (argumentCount != 4)
1308         return JSValueMakeUndefined(context);
1309
1310     JSRetainPtr<JSStringRef> sourceOrigin(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1311     ASSERT(!*exception);
1312     JSRetainPtr<JSStringRef> destinationProtocol(Adopt, JSValueToStringCopy(context, arguments[1], exception));
1313     ASSERT(!*exception);
1314     JSRetainPtr<JSStringRef> destinationHost(Adopt, JSValueToStringCopy(context, arguments[2], exception));
1315     ASSERT(!*exception);
1316     bool allowDestinationSubdomains = JSValueToBoolean(context, arguments[3]);
1317
1318     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1319     controller->addOriginAccessWhitelistEntry(sourceOrigin.get(), destinationProtocol.get(), destinationHost.get(), allowDestinationSubdomains);
1320     return JSValueMakeUndefined(context);
1321 }
1322
1323 static JSValueRef removeOriginAccessWhitelistEntryCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1324 {
1325     if (argumentCount != 4)
1326         return JSValueMakeUndefined(context);
1327
1328     JSRetainPtr<JSStringRef> sourceOrigin(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1329     ASSERT(!*exception);
1330     JSRetainPtr<JSStringRef> destinationProtocol(Adopt, JSValueToStringCopy(context, arguments[1], exception));
1331     ASSERT(!*exception);
1332     JSRetainPtr<JSStringRef> destinationHost(Adopt, JSValueToStringCopy(context, arguments[2], exception));
1333     ASSERT(!*exception);
1334     bool allowDestinationSubdomains = JSValueToBoolean(context, arguments[3]);
1335
1336     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1337     controller->removeOriginAccessWhitelistEntry(sourceOrigin.get(), destinationProtocol.get(), destinationHost.get(), allowDestinationSubdomains);
1338     return JSValueMakeUndefined(context);
1339 }
1340
1341 static JSValueRef setScrollbarPolicyCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1342 {
1343     if (argumentCount != 2)
1344         return JSValueMakeUndefined(context);
1345
1346     JSRetainPtr<JSStringRef> orientation(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1347     ASSERT(!*exception);
1348     JSRetainPtr<JSStringRef> policy(Adopt, JSValueToStringCopy(context, arguments[1], exception));
1349     ASSERT(!*exception);
1350
1351     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1352     controller->setScrollbarPolicy(orientation.get(), policy.get());
1353     return JSValueMakeUndefined(context);
1354 }
1355
1356 static JSValueRef addUserScriptCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1357 {
1358     if (argumentCount != 2)
1359         return JSValueMakeUndefined(context);
1360     
1361     JSRetainPtr<JSStringRef> source(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1362     ASSERT(!*exception);
1363     bool runAtStart = JSValueToBoolean(context, arguments[1]);
1364     
1365     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1366     controller->addUserScript(source.get(), runAtStart);
1367     return JSValueMakeUndefined(context);
1368 }
1369  
1370 static JSValueRef addUserStyleSheetCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1371 {
1372     if (argumentCount != 1)
1373         return JSValueMakeUndefined(context);
1374     
1375     JSRetainPtr<JSStringRef> source(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1376     ASSERT(!*exception);
1377    
1378     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1379     controller->addUserStyleSheet(source.get());
1380     return JSValueMakeUndefined(context);
1381 }
1382
1383 static JSValueRef apiTestNewWindowDataLoadBaseURLCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1384 {
1385     if (argumentCount != 2)
1386         return JSValueMakeUndefined(context);
1387
1388     JSRetainPtr<JSStringRef> utf8Data(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1389     ASSERT(!*exception);
1390
1391     JSRetainPtr<JSStringRef> baseURL(Adopt, JSValueToStringCopy(context, arguments[1], exception));
1392     ASSERT(!*exception);
1393         
1394     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1395     controller->apiTestNewWindowDataLoadBaseURL(utf8Data.get(), baseURL.get());
1396     return JSValueMakeUndefined(context);
1397 }
1398
1399 static JSValueRef apiTestGoToCurrentBackForwardItemCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1400 {
1401     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1402     controller->apiTestGoToCurrentBackForwardItem();
1403     return JSValueMakeUndefined(context);
1404 }
1405
1406 static JSValueRef setWebViewEditableCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1407 {
1408     // Has Mac implementation
1409     if (argumentCount < 1)
1410         return JSValueMakeUndefined(context);
1411
1412     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1413     controller->setWebViewEditable(JSValueToBoolean(context, arguments[0]));
1414
1415     return JSValueMakeUndefined(context);
1416 }
1417
1418 static JSValueRef markerTextForListItemCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1419 {
1420     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1421     if (argumentCount < 1)
1422         return JSValueMakeUndefined(context);
1423     return JSValueMakeString(context, controller->markerTextForListItem(context, arguments[0]).get());
1424 }
1425
1426 static JSValueRef authenticateSessionCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1427 {
1428     // authenticateSession(url, username, password)
1429     if (argumentCount != 3)
1430         return JSValueMakeUndefined(context);
1431
1432     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1433     ASSERT(!*exception);
1434     JSRetainPtr<JSStringRef> username(Adopt, JSValueToStringCopy(context, arguments[1], exception));
1435     ASSERT(!*exception);
1436     JSRetainPtr<JSStringRef> password(Adopt, JSValueToStringCopy(context, arguments[2], exception));
1437     ASSERT(!*exception);
1438
1439     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1440     controller->authenticateSession(url.get(), username.get(), password.get());
1441     return JSValueMakeUndefined(context);
1442 }
1443
1444 // Static Values
1445
1446 static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1447 {
1448     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1449     return JSValueMakeBoolean(context, controller->globalFlag());
1450 }
1451
1452 static JSValueRef getWebHistoryItemCountCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1453 {
1454     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1455     return JSValueMakeNumber(context, controller->webHistoryItemCount());
1456 }
1457
1458 static JSValueRef getWorkerThreadCountCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1459 {
1460     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1461     return JSValueMakeNumber(context, controller->workerThreadCount());
1462 }
1463
1464 static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
1465 {
1466     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1467     controller->setGlobalFlag(JSValueToBoolean(context, value));
1468     return true;
1469 }
1470
1471 static void layoutTestControllerObjectFinalize(JSObjectRef object)
1472 {
1473     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(object));
1474     controller->deref();
1475 }
1476
1477 // Object Creation
1478
1479 void LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
1480 {
1481     JSRetainPtr<JSStringRef> layoutTestContollerStr(Adopt, JSStringCreateWithUTF8CString("layoutTestController"));
1482     ref();
1483
1484     JSClassRef classRef = getJSClass();
1485     JSValueRef layoutTestContollerObject = JSObjectMake(context, classRef, this);
1486     JSClassRelease(classRef);
1487
1488     JSObjectSetProperty(context, windowObject, layoutTestContollerStr.get(), layoutTestContollerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
1489 }
1490
1491 JSClassRef LayoutTestController::getJSClass()
1492 {
1493     static JSStaticValue* staticValues = LayoutTestController::staticValues();
1494     static JSStaticFunction* staticFunctions = LayoutTestController::staticFunctions();
1495     static JSClassDefinition classDefinition = {
1496         0, kJSClassAttributeNone, "LayoutTestController", 0, staticValues, staticFunctions,
1497         0, layoutTestControllerObjectFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
1498     };
1499
1500     return JSClassCreate(&classDefinition);
1501 }
1502
1503 JSStaticValue* LayoutTestController::staticValues()
1504 {
1505     static JSStaticValue staticValues[] = {
1506         { "globalFlag", getGlobalFlagCallback, setGlobalFlagCallback, kJSPropertyAttributeNone },
1507         { "webHistoryItemCount", getWebHistoryItemCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1508         { "workerThreadCount", getWorkerThreadCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1509         { 0, 0, 0, 0 }
1510     };
1511     return staticValues;
1512 }
1513
1514 JSStaticFunction* LayoutTestController::staticFunctions()
1515 {
1516     static JSStaticFunction staticFunctions[] = {
1517         { "addDisallowedURL", addDisallowedURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1518         { "addUserScript", addUserScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1519         { "addUserStyleSheet", addUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1520         { "apiTestNewWindowDataLoadBaseURL", apiTestNewWindowDataLoadBaseURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1521         { "apiTestGoToCurrentBackForwardItem", apiTestGoToCurrentBackForwardItemCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1522         { "callShouldCloseOnWebView", callShouldCloseOnWebViewCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1523         { "clearAllDatabases", clearAllDatabasesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1524         { "clearBackForwardList", clearBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1525         { "clearPersistentUserStyleSheet", clearPersistentUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1526         { "closeWebInspector", closeWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1527         { "computedStyleIncludingVisitedInfo", computedStyleIncludingVisitedInfoCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1528         { "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1529         { "disableImageLoading", disableImageLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1530         { "dispatchPendingLoadRequests", dispatchPendingLoadRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1531         { "display", displayCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1532         { "dumpAsText", dumpAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1533         { "dumpBackForwardList", dumpBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1534         { "dumpChildFrameScrollPositions", dumpChildFrameScrollPositionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1535         { "dumpChildFramesAsText", dumpChildFramesAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1536         { "dumpDOMAsWebArchive", dumpDOMAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1537         { "dumpDatabaseCallbacks", dumpDatabaseCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1538         { "dumpEditingCallbacks", dumpEditingCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1539         { "dumpFrameLoadCallbacks", dumpFrameLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1540         { "dumpResourceLoadCallbacks", dumpResourceLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1541         { "dumpResourceResponseMIMETypes", dumpResourceResponseMIMETypesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1542         { "dumpSelectionRect", dumpSelectionRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1543         { "dumpSourceAsWebArchive", dumpSourceAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1544         { "dumpStatusCallbacks", dumpStatusCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1545         { "dumpTitleChanges", dumpTitleChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1546         { "dumpIconChanges", dumpIconChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1547         { "dumpWillCacheResponse", dumpWillCacheResponseCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1548         { "elementDoesAutoCompleteForElementWithId", elementDoesAutoCompleteForElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1549         { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1550         { "evaluateInWebInspector", evaluateInWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1551         { "evaluateScriptInIsolatedWorld", evaluateScriptInIsolatedWorldCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1552         { "execCommand", execCommandCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1553         { "counterValueForElementById", counterValueForElementByIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1554         { "grantDesktopNotificationPermission", grantDesktopNotificationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
1555         { "isCommandEnabled", isCommandEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1556         { "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1557         { "layerTreeAsText", layerTreeAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1558         { "numberOfPages", numberOfPagesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1559         { "markerTextForListItem", markerTextForListItemCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1560         { "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1561         { "numberOfActiveAnimations", numberOfActiveAnimationsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1562         { "overridePreference", overridePreferenceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1563         { "pageNumberForElementById", pageNumberForElementByIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1564         { "pathToLocalResource", pathToLocalResourceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1565         { "pauseAnimationAtTimeOnElementWithId", pauseAnimationAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1566         { "pauseTransitionAtTimeOnElementWithId", pauseTransitionAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1567         { "sampleSVGAnimationForElementAtTime", sampleSVGAnimationForElementAtTimeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1568         { "printToPDF", dumpAsPDFCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1569         { "queueBackNavigation", queueBackNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1570         { "queueForwardNavigation", queueForwardNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1571         { "queueLoad", queueLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1572         { "queueLoadingScript", queueLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1573         { "queueNonLoadingScript", queueNonLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1574         { "queueReload", queueReloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1575         { "removeAllVisitedLinks", removeAllVisitedLinksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1576         { "removeOriginAccessWhitelistEntry", removeOriginAccessWhitelistEntryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1577         { "repaintSweepHorizontally", repaintSweepHorizontallyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1578         { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1579         { "setAllowUniversalAccessFromFileURLs", setAllowUniversalAccessFromFileURLsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1580         { "setAllowFileAccessFromFileURLs", setAllowFileAccessFromFileURLsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1581         { "setAlwaysAcceptCookies", setAlwaysAcceptCookiesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1582         { "setAppCacheMaximumSize", setAppCacheMaximumSizeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
1583         { "setAuthenticationPassword", setAuthenticationPasswordCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1584         { "setAuthenticationUsername", setAuthenticationUsernameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1585         { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1586         { "setCacheModel", setCacheModelCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1587         { "setCallCloseOnWebViews", setCallCloseOnWebViewsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1588         { "setCanOpenWindows", setCanOpenWindowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1589         { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1590         { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1591         { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
1592         { "setDomainRelaxationForbiddenForURLScheme", setDomainRelaxationForbiddenForURLSchemeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1593         { "setFrameFlatteningEnabled", setFrameFlatteningEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1594         { "setGeolocationPermission", setGeolocationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1595         { "setHandlesAuthenticationChallenges", setHandlesAuthenticationChallengesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1596         { "setIconDatabaseEnabled", setIconDatabaseEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1597         { "setJavaScriptProfilingEnabled", setJavaScriptProfilingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1598         { "setMainFrameIsFirstResponder", setMainFrameIsFirstResponderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1599         { "setMockGeolocationError", setMockGeolocationErrorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1600         { "setMockGeolocationPosition", setMockGeolocationPositionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1601         { "setNewWindowsCopyBackForwardList", setNewWindowsCopyBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1602         { "setPOSIXLocale", setPOSIXLocaleCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1603         { "setPersistentUserStyleSheetLocation", setPersistentUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1604         { "setPopupBlockingEnabled", setPopupBlockingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1605         { "setPrinting", setPrintingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1606         { "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1607         { "setSelectTrailingWhitespaceEnabled", setSelectTrailingWhitespaceEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1608         { "setSmartInsertDeleteEnabled", setSmartInsertDeleteEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1609         { "setSpatialNavigationEnabled", setSpatialNavigationEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1610         { "setStopProvisionalFrameLoads", setStopProvisionalFrameLoadsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1611         { "setTabKeyCyclesThroughElements", setTabKeyCyclesThroughElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1612         { "setTimelineProfilingEnabled", setTimelineProfilingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1613         { "setUseDashboardCompatibilityMode", setUseDashboardCompatibilityModeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1614         { "setUserStyleSheetEnabled", setUserStyleSheetEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1615         { "setUserStyleSheetLocation", setUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1616         { "setWebViewEditable", setWebViewEditableCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1617         { "setWillSendRequestClearHeader", setWillSendRequestClearHeaderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1618         { "setWillSendRequestReturnsNull", setWillSendRequestReturnsNullCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1619         { "setWillSendRequestReturnsNullOnRedirect", setWillSendRequestReturnsNullOnRedirectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1620         { "setWindowIsKey", setWindowIsKeyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1621         { "setJavaScriptCanAccessClipboard", setJavaScriptCanAccessClipboardCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1622         { "setXSSAuditorEnabled", setXSSAuditorEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1623         { "showWebInspector", showWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1624         { "testOnscreen", testOnscreenCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1625         { "testRepaint", testRepaintCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1626         { "waitForPolicyDelegate", waitForPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1627         { "waitUntilDone", waitUntilDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1628         { "windowCount", windowCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1629         { "addOriginAccessWhitelistEntry", addOriginAccessWhitelistEntryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1630         { "setScrollbarPolicy", setScrollbarPolicyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1631         { "authenticateSession", authenticateSessionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1632         { 0, 0, 0 }
1633     };
1634
1635     return staticFunctions;
1636 }
1637
1638 void LayoutTestController::queueBackNavigation(int howFarBack)
1639 {
1640     WorkQueue::shared()->queue(new BackItem(howFarBack));
1641 }
1642
1643 void LayoutTestController::queueForwardNavigation(int howFarForward)
1644 {
1645     WorkQueue::shared()->queue(new ForwardItem(howFarForward));
1646 }
1647
1648 void LayoutTestController::queueLoadingScript(JSStringRef script)
1649 {
1650     WorkQueue::shared()->queue(new LoadingScriptItem(script));
1651 }
1652
1653 void LayoutTestController::queueNonLoadingScript(JSStringRef script)
1654 {
1655     WorkQueue::shared()->queue(new NonLoadingScriptItem(script));
1656 }
1657
1658 void LayoutTestController::queueReload()
1659 {
1660     WorkQueue::shared()->queue(new ReloadItem);
1661 }
1662
1663 void LayoutTestController::grantDesktopNotificationPermission(JSStringRef origin)
1664 {
1665     m_desktopNotificationAllowedOrigins.push_back(JSStringRetain(origin));
1666 }
1667
1668 bool LayoutTestController::checkDesktopNotificationPermission(JSStringRef origin)
1669 {
1670     std::vector<JSStringRef>::iterator i;
1671     for (i = m_desktopNotificationAllowedOrigins.begin();
1672          i != m_desktopNotificationAllowedOrigins.end();
1673          ++i) {
1674         if (JSStringIsEqual(*i, origin))
1675             return true;
1676     }
1677     return false;
1678 }
1679
1680 void LayoutTestController::waitToDumpWatchdogTimerFired()
1681 {
1682     const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
1683     fprintf(stderr, "%s", message);
1684     fprintf(stdout, "%s", message);
1685     notifyDone();
1686 }
1687
1688 void LayoutTestController::setGeolocationPermission(bool allow)
1689 {
1690     m_isGeolocationPermissionSet = true;
1691     m_geolocationPermission = allow;
1692 }
1693
1694 void LayoutTestController::setPOSIXLocale(JSStringRef locale)
1695 {
1696     char localeBuf[32];
1697     JSStringGetUTF8CString(locale, localeBuf, sizeof(localeBuf));
1698     setlocale(LC_ALL, localeBuf);
1699 }
1700
1701 const unsigned LayoutTestController::maxViewWidth = 800;
1702 const unsigned LayoutTestController::maxViewHeight = 600;