2010-05-06 Anders Carlsson <andersca@apple.com>
[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 setPluginsEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1165 {
1166     // Has mac & windows implementation
1167     if (argumentCount < 1)
1168         return JSValueMakeUndefined(context);
1169     
1170     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1171     controller->setPluginsEnabled(JSValueToBoolean(context, arguments[0]));
1172     
1173     return JSValueMakeUndefined(context);
1174 }    
1175
1176 static JSValueRef setSmartInsertDeleteEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1177 {
1178     if (argumentCount < 1)
1179         return JSValueMakeUndefined(context);
1180
1181     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1182     controller->setSmartInsertDeleteEnabled(JSValueToBoolean(context, arguments[0]));
1183     return JSValueMakeUndefined(context);
1184 }
1185
1186 static JSValueRef setSelectTrailingWhitespaceEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1187 {
1188     if (argumentCount < 1)
1189         return JSValueMakeUndefined(context);
1190
1191     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1192     controller->setSelectTrailingWhitespaceEnabled(JSValueToBoolean(context, arguments[0]));
1193     return JSValueMakeUndefined(context);
1194 }
1195
1196 static JSValueRef setStopProvisionalFrameLoadsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1197 {
1198     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1199     controller->setStopProvisionalFrameLoads(true);
1200     return JSValueMakeUndefined(context);
1201 }
1202
1203 static JSValueRef showWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1204 {
1205     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1206     controller->showWebInspector();
1207     return JSValueMakeUndefined(context);
1208 }
1209
1210 static JSValueRef closeWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1211 {
1212     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1213     controller->setTimelineProfilingEnabled(false);
1214     controller->closeWebInspector();
1215     return JSValueMakeUndefined(context);
1216 }
1217
1218 static JSValueRef evaluateInWebInspectorCallback(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 callId = JSValueToNumber(context, arguments[0], exception);
1222     ASSERT(!*exception);
1223     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[1], exception));
1224     ASSERT(!*exception);
1225
1226     controller->evaluateInWebInspector(static_cast<long>(callId), script.get());
1227     return JSValueMakeUndefined(context);
1228 }
1229
1230 static JSValueRef evaluateScriptInIsolatedWorldCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1231 {
1232     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1233     double worldID = JSValueToNumber(context, arguments[0], exception);
1234     ASSERT(!*exception);
1235     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[1], exception));
1236     ASSERT(!*exception);
1237
1238     controller->evaluateScriptInIsolatedWorld(static_cast<unsigned>(worldID), JSContextGetGlobalObject(context), script.get());
1239     return JSValueMakeUndefined(context);
1240 }
1241
1242 static JSValueRef elementDoesAutoCompleteForElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1243 {
1244     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1245     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1246     ASSERT(!*exception);
1247
1248     bool autoCompletes = controller->elementDoesAutoCompleteForElementWithId(elementId.get());
1249
1250     return JSValueMakeBoolean(context, autoCompletes);
1251 }
1252
1253 static JSValueRef pauseAnimationAtTimeOnElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1254 {
1255     if (argumentCount != 3)
1256         return JSValueMakeUndefined(context);
1257
1258     JSRetainPtr<JSStringRef> animationName(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1259     ASSERT(!*exception);
1260     double time = JSValueToNumber(context, arguments[1], exception);
1261     ASSERT(!*exception);
1262     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
1263     ASSERT(!*exception);
1264
1265     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1266     return JSValueMakeBoolean(context, controller->pauseAnimationAtTimeOnElementWithId(animationName.get(), time, elementId.get()));
1267 }
1268
1269 static JSValueRef pauseTransitionAtTimeOnElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1270 {
1271     if (argumentCount != 3)
1272         return JSValueMakeUndefined(context);
1273
1274     JSRetainPtr<JSStringRef> propertyName(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1275     ASSERT(!*exception);
1276     double time = JSValueToNumber(context, arguments[1], exception);
1277     ASSERT(!*exception);
1278     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
1279     ASSERT(!*exception);
1280
1281     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1282     return JSValueMakeBoolean(context, controller->pauseTransitionAtTimeOnElementWithId(propertyName.get(), time, elementId.get()));
1283 }
1284
1285 static JSValueRef sampleSVGAnimationForElementAtTimeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1286 {
1287     if (argumentCount != 3)
1288         return JSValueMakeUndefined(context);
1289
1290     JSRetainPtr<JSStringRef> animationId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1291     ASSERT(!*exception);
1292     double time = JSValueToNumber(context, arguments[1], exception);
1293     ASSERT(!*exception);
1294     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
1295     ASSERT(!*exception);
1296
1297     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1298     return JSValueMakeBoolean(context, controller->sampleSVGAnimationForElementAtTime(animationId.get(), time, elementId.get()));
1299 }
1300
1301 static JSValueRef numberOfActiveAnimationsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1302 {
1303     if (argumentCount != 0)
1304         return JSValueMakeUndefined(context);
1305
1306     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1307     return JSValueMakeNumber(context, controller->numberOfActiveAnimations());
1308 }
1309
1310 static JSValueRef waitForPolicyDelegateCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*)
1311 {
1312     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1313     controller->waitForPolicyDelegate();
1314     return JSValueMakeUndefined(context);
1315 }
1316
1317 static JSValueRef addOriginAccessWhitelistEntryCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1318 {
1319     if (argumentCount != 4)
1320         return JSValueMakeUndefined(context);
1321
1322     JSRetainPtr<JSStringRef> sourceOrigin(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1323     ASSERT(!*exception);
1324     JSRetainPtr<JSStringRef> destinationProtocol(Adopt, JSValueToStringCopy(context, arguments[1], exception));
1325     ASSERT(!*exception);
1326     JSRetainPtr<JSStringRef> destinationHost(Adopt, JSValueToStringCopy(context, arguments[2], exception));
1327     ASSERT(!*exception);
1328     bool allowDestinationSubdomains = JSValueToBoolean(context, arguments[3]);
1329
1330     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1331     controller->addOriginAccessWhitelistEntry(sourceOrigin.get(), destinationProtocol.get(), destinationHost.get(), allowDestinationSubdomains);
1332     return JSValueMakeUndefined(context);
1333 }
1334
1335 static JSValueRef removeOriginAccessWhitelistEntryCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1336 {
1337     if (argumentCount != 4)
1338         return JSValueMakeUndefined(context);
1339
1340     JSRetainPtr<JSStringRef> sourceOrigin(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1341     ASSERT(!*exception);
1342     JSRetainPtr<JSStringRef> destinationProtocol(Adopt, JSValueToStringCopy(context, arguments[1], exception));
1343     ASSERT(!*exception);
1344     JSRetainPtr<JSStringRef> destinationHost(Adopt, JSValueToStringCopy(context, arguments[2], exception));
1345     ASSERT(!*exception);
1346     bool allowDestinationSubdomains = JSValueToBoolean(context, arguments[3]);
1347
1348     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1349     controller->removeOriginAccessWhitelistEntry(sourceOrigin.get(), destinationProtocol.get(), destinationHost.get(), allowDestinationSubdomains);
1350     return JSValueMakeUndefined(context);
1351 }
1352
1353 static JSValueRef setScrollbarPolicyCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1354 {
1355     if (argumentCount != 2)
1356         return JSValueMakeUndefined(context);
1357
1358     JSRetainPtr<JSStringRef> orientation(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1359     ASSERT(!*exception);
1360     JSRetainPtr<JSStringRef> policy(Adopt, JSValueToStringCopy(context, arguments[1], exception));
1361     ASSERT(!*exception);
1362
1363     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1364     controller->setScrollbarPolicy(orientation.get(), policy.get());
1365     return JSValueMakeUndefined(context);
1366 }
1367
1368 static JSValueRef addUserScriptCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1369 {
1370     if (argumentCount != 2)
1371         return JSValueMakeUndefined(context);
1372     
1373     JSRetainPtr<JSStringRef> source(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1374     ASSERT(!*exception);
1375     bool runAtStart = JSValueToBoolean(context, arguments[1]);
1376     
1377     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1378     controller->addUserScript(source.get(), runAtStart);
1379     return JSValueMakeUndefined(context);
1380 }
1381  
1382 static JSValueRef addUserStyleSheetCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1383 {
1384     if (argumentCount != 1)
1385         return JSValueMakeUndefined(context);
1386     
1387     JSRetainPtr<JSStringRef> source(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1388     ASSERT(!*exception);
1389    
1390     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1391     controller->addUserStyleSheet(source.get());
1392     return JSValueMakeUndefined(context);
1393 }
1394
1395 static JSValueRef apiTestNewWindowDataLoadBaseURLCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1396 {
1397     if (argumentCount != 2)
1398         return JSValueMakeUndefined(context);
1399
1400     JSRetainPtr<JSStringRef> utf8Data(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1401     ASSERT(!*exception);
1402
1403     JSRetainPtr<JSStringRef> baseURL(Adopt, JSValueToStringCopy(context, arguments[1], exception));
1404     ASSERT(!*exception);
1405         
1406     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1407     controller->apiTestNewWindowDataLoadBaseURL(utf8Data.get(), baseURL.get());
1408     return JSValueMakeUndefined(context);
1409 }
1410
1411 static JSValueRef apiTestGoToCurrentBackForwardItemCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1412 {
1413     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1414     controller->apiTestGoToCurrentBackForwardItem();
1415     return JSValueMakeUndefined(context);
1416 }
1417
1418 static JSValueRef setWebViewEditableCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1419 {
1420     // Has Mac implementation
1421     if (argumentCount < 1)
1422         return JSValueMakeUndefined(context);
1423
1424     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1425     controller->setWebViewEditable(JSValueToBoolean(context, arguments[0]));
1426
1427     return JSValueMakeUndefined(context);
1428 }
1429
1430 static JSValueRef markerTextForListItemCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1431 {
1432     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1433     if (argumentCount < 1)
1434         return JSValueMakeUndefined(context);
1435     return JSValueMakeString(context, controller->markerTextForListItem(context, arguments[0]).get());
1436 }
1437
1438 static JSValueRef authenticateSessionCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1439 {
1440     // authenticateSession(url, username, password)
1441     if (argumentCount != 3)
1442         return JSValueMakeUndefined(context);
1443
1444     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1445     ASSERT(!*exception);
1446     JSRetainPtr<JSStringRef> username(Adopt, JSValueToStringCopy(context, arguments[1], exception));
1447     ASSERT(!*exception);
1448     JSRetainPtr<JSStringRef> password(Adopt, JSValueToStringCopy(context, arguments[2], exception));
1449     ASSERT(!*exception);
1450
1451     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1452     controller->authenticateSession(url.get(), username.get(), password.get());
1453     return JSValueMakeUndefined(context);
1454 }
1455
1456 // Static Values
1457
1458 static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1459 {
1460     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1461     return JSValueMakeBoolean(context, controller->globalFlag());
1462 }
1463
1464 static JSValueRef getWebHistoryItemCountCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1465 {
1466     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1467     return JSValueMakeNumber(context, controller->webHistoryItemCount());
1468 }
1469
1470 static JSValueRef getWorkerThreadCountCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1471 {
1472     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1473     return JSValueMakeNumber(context, controller->workerThreadCount());
1474 }
1475
1476 static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
1477 {
1478     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1479     controller->setGlobalFlag(JSValueToBoolean(context, value));
1480     return true;
1481 }
1482
1483 static void layoutTestControllerObjectFinalize(JSObjectRef object)
1484 {
1485     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(object));
1486     controller->deref();
1487 }
1488
1489 // Object Creation
1490
1491 void LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
1492 {
1493     JSRetainPtr<JSStringRef> layoutTestContollerStr(Adopt, JSStringCreateWithUTF8CString("layoutTestController"));
1494     ref();
1495
1496     JSClassRef classRef = getJSClass();
1497     JSValueRef layoutTestContollerObject = JSObjectMake(context, classRef, this);
1498     JSClassRelease(classRef);
1499
1500     JSObjectSetProperty(context, windowObject, layoutTestContollerStr.get(), layoutTestContollerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
1501 }
1502
1503 JSClassRef LayoutTestController::getJSClass()
1504 {
1505     static JSStaticValue* staticValues = LayoutTestController::staticValues();
1506     static JSStaticFunction* staticFunctions = LayoutTestController::staticFunctions();
1507     static JSClassDefinition classDefinition = {
1508         0, kJSClassAttributeNone, "LayoutTestController", 0, staticValues, staticFunctions,
1509         0, layoutTestControllerObjectFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
1510     };
1511
1512     return JSClassCreate(&classDefinition);
1513 }
1514
1515 JSStaticValue* LayoutTestController::staticValues()
1516 {
1517     static JSStaticValue staticValues[] = {
1518         { "globalFlag", getGlobalFlagCallback, setGlobalFlagCallback, kJSPropertyAttributeNone },
1519         { "webHistoryItemCount", getWebHistoryItemCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1520         { "workerThreadCount", getWorkerThreadCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1521         { 0, 0, 0, 0 }
1522     };
1523     return staticValues;
1524 }
1525
1526 JSStaticFunction* LayoutTestController::staticFunctions()
1527 {
1528     static JSStaticFunction staticFunctions[] = {
1529         { "addDisallowedURL", addDisallowedURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1530         { "addUserScript", addUserScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1531         { "addUserStyleSheet", addUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1532         { "apiTestNewWindowDataLoadBaseURL", apiTestNewWindowDataLoadBaseURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1533         { "apiTestGoToCurrentBackForwardItem", apiTestGoToCurrentBackForwardItemCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1534         { "callShouldCloseOnWebView", callShouldCloseOnWebViewCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1535         { "clearAllDatabases", clearAllDatabasesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1536         { "clearBackForwardList", clearBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1537         { "clearPersistentUserStyleSheet", clearPersistentUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1538         { "closeWebInspector", closeWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1539         { "computedStyleIncludingVisitedInfo", computedStyleIncludingVisitedInfoCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1540         { "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1541         { "disableImageLoading", disableImageLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1542         { "dispatchPendingLoadRequests", dispatchPendingLoadRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1543         { "display", displayCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1544         { "dumpAsText", dumpAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1545         { "dumpBackForwardList", dumpBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1546         { "dumpChildFrameScrollPositions", dumpChildFrameScrollPositionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1547         { "dumpChildFramesAsText", dumpChildFramesAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1548         { "dumpDOMAsWebArchive", dumpDOMAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1549         { "dumpDatabaseCallbacks", dumpDatabaseCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1550         { "dumpEditingCallbacks", dumpEditingCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1551         { "dumpFrameLoadCallbacks", dumpFrameLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1552         { "dumpResourceLoadCallbacks", dumpResourceLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1553         { "dumpResourceResponseMIMETypes", dumpResourceResponseMIMETypesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1554         { "dumpSelectionRect", dumpSelectionRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1555         { "dumpSourceAsWebArchive", dumpSourceAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1556         { "dumpStatusCallbacks", dumpStatusCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1557         { "dumpTitleChanges", dumpTitleChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1558         { "dumpIconChanges", dumpIconChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1559         { "dumpWillCacheResponse", dumpWillCacheResponseCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1560         { "elementDoesAutoCompleteForElementWithId", elementDoesAutoCompleteForElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1561         { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1562         { "evaluateInWebInspector", evaluateInWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1563         { "evaluateScriptInIsolatedWorld", evaluateScriptInIsolatedWorldCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1564         { "execCommand", execCommandCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1565         { "counterValueForElementById", counterValueForElementByIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1566         { "grantDesktopNotificationPermission", grantDesktopNotificationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
1567         { "isCommandEnabled", isCommandEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1568         { "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1569         { "layerTreeAsText", layerTreeAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1570         { "numberOfPages", numberOfPagesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1571         { "markerTextForListItem", markerTextForListItemCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1572         { "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1573         { "numberOfActiveAnimations", numberOfActiveAnimationsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1574         { "overridePreference", overridePreferenceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1575         { "pageNumberForElementById", pageNumberForElementByIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1576         { "pathToLocalResource", pathToLocalResourceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1577         { "pauseAnimationAtTimeOnElementWithId", pauseAnimationAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1578         { "pauseTransitionAtTimeOnElementWithId", pauseTransitionAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1579         { "sampleSVGAnimationForElementAtTime", sampleSVGAnimationForElementAtTimeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1580         { "printToPDF", dumpAsPDFCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1581         { "queueBackNavigation", queueBackNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1582         { "queueForwardNavigation", queueForwardNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1583         { "queueLoad", queueLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1584         { "queueLoadingScript", queueLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1585         { "queueNonLoadingScript", queueNonLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1586         { "queueReload", queueReloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1587         { "removeAllVisitedLinks", removeAllVisitedLinksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1588         { "removeOriginAccessWhitelistEntry", removeOriginAccessWhitelistEntryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1589         { "repaintSweepHorizontally", repaintSweepHorizontallyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1590         { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1591         { "setAllowUniversalAccessFromFileURLs", setAllowUniversalAccessFromFileURLsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1592         { "setAllowFileAccessFromFileURLs", setAllowFileAccessFromFileURLsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1593         { "setAlwaysAcceptCookies", setAlwaysAcceptCookiesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1594         { "setAppCacheMaximumSize", setAppCacheMaximumSizeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
1595         { "setAuthenticationPassword", setAuthenticationPasswordCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1596         { "setAuthenticationUsername", setAuthenticationUsernameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1597         { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1598         { "setCacheModel", setCacheModelCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1599         { "setCallCloseOnWebViews", setCallCloseOnWebViewsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1600         { "setCanOpenWindows", setCanOpenWindowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1601         { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1602         { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1603         { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
1604         { "setDomainRelaxationForbiddenForURLScheme", setDomainRelaxationForbiddenForURLSchemeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1605         { "setFrameFlatteningEnabled", setFrameFlatteningEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1606         { "setGeolocationPermission", setGeolocationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1607         { "setHandlesAuthenticationChallenges", setHandlesAuthenticationChallengesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1608         { "setIconDatabaseEnabled", setIconDatabaseEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1609         { "setJavaScriptProfilingEnabled", setJavaScriptProfilingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1610         { "setMainFrameIsFirstResponder", setMainFrameIsFirstResponderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1611         { "setMockGeolocationError", setMockGeolocationErrorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1612         { "setMockGeolocationPosition", setMockGeolocationPositionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1613         { "setNewWindowsCopyBackForwardList", setNewWindowsCopyBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1614         { "setPOSIXLocale", setPOSIXLocaleCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1615         { "setPersistentUserStyleSheetLocation", setPersistentUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1616         { "setPopupBlockingEnabled", setPopupBlockingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1617         { "setPluginsEnabled", setPluginsEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1618         { "setPrinting", setPrintingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1619         { "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1620         { "setSelectTrailingWhitespaceEnabled", setSelectTrailingWhitespaceEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1621         { "setSmartInsertDeleteEnabled", setSmartInsertDeleteEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1622         { "setSpatialNavigationEnabled", setSpatialNavigationEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1623         { "setStopProvisionalFrameLoads", setStopProvisionalFrameLoadsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1624         { "setTabKeyCyclesThroughElements", setTabKeyCyclesThroughElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1625         { "setTimelineProfilingEnabled", setTimelineProfilingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1626         { "setUseDashboardCompatibilityMode", setUseDashboardCompatibilityModeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1627         { "setUserStyleSheetEnabled", setUserStyleSheetEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1628         { "setUserStyleSheetLocation", setUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1629         { "setWebViewEditable", setWebViewEditableCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1630         { "setWillSendRequestClearHeader", setWillSendRequestClearHeaderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1631         { "setWillSendRequestReturnsNull", setWillSendRequestReturnsNullCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1632         { "setWillSendRequestReturnsNullOnRedirect", setWillSendRequestReturnsNullOnRedirectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1633         { "setWindowIsKey", setWindowIsKeyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1634         { "setJavaScriptCanAccessClipboard", setJavaScriptCanAccessClipboardCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1635         { "setXSSAuditorEnabled", setXSSAuditorEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1636         { "showWebInspector", showWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1637         { "testOnscreen", testOnscreenCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1638         { "testRepaint", testRepaintCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1639         { "waitForPolicyDelegate", waitForPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1640         { "waitUntilDone", waitUntilDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1641         { "windowCount", windowCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1642         { "addOriginAccessWhitelistEntry", addOriginAccessWhitelistEntryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1643         { "setScrollbarPolicy", setScrollbarPolicyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1644         { "authenticateSession", authenticateSessionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1645         { 0, 0, 0 }
1646     };
1647
1648     return staticFunctions;
1649 }
1650
1651 void LayoutTestController::queueBackNavigation(int howFarBack)
1652 {
1653     WorkQueue::shared()->queue(new BackItem(howFarBack));
1654 }
1655
1656 void LayoutTestController::queueForwardNavigation(int howFarForward)
1657 {
1658     WorkQueue::shared()->queue(new ForwardItem(howFarForward));
1659 }
1660
1661 void LayoutTestController::queueLoadingScript(JSStringRef script)
1662 {
1663     WorkQueue::shared()->queue(new LoadingScriptItem(script));
1664 }
1665
1666 void LayoutTestController::queueNonLoadingScript(JSStringRef script)
1667 {
1668     WorkQueue::shared()->queue(new NonLoadingScriptItem(script));
1669 }
1670
1671 void LayoutTestController::queueReload()
1672 {
1673     WorkQueue::shared()->queue(new ReloadItem);
1674 }
1675
1676 void LayoutTestController::grantDesktopNotificationPermission(JSStringRef origin)
1677 {
1678     m_desktopNotificationAllowedOrigins.push_back(JSStringRetain(origin));
1679 }
1680
1681 bool LayoutTestController::checkDesktopNotificationPermission(JSStringRef origin)
1682 {
1683     std::vector<JSStringRef>::iterator i;
1684     for (i = m_desktopNotificationAllowedOrigins.begin();
1685          i != m_desktopNotificationAllowedOrigins.end();
1686          ++i) {
1687         if (JSStringIsEqual(*i, origin))
1688             return true;
1689     }
1690     return false;
1691 }
1692
1693 void LayoutTestController::waitToDumpWatchdogTimerFired()
1694 {
1695     const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
1696     fprintf(stderr, "%s", message);
1697     fprintf(stdout, "%s", message);
1698     notifyDone();
1699 }
1700
1701 void LayoutTestController::setGeolocationPermission(bool allow)
1702 {
1703     m_isGeolocationPermissionSet = true;
1704     m_geolocationPermission = allow;
1705 }
1706
1707 void LayoutTestController::setPOSIXLocale(JSStringRef locale)
1708 {
1709     char localeBuf[32];
1710     JSStringGetUTF8CString(locale, localeBuf, sizeof(localeBuf));
1711     setlocale(LC_ALL, localeBuf);
1712 }
1713
1714 const unsigned LayoutTestController::maxViewWidth = 800;
1715 const unsigned LayoutTestController::maxViewHeight = 600;