Safari 4 cannot be used to update firmware on Linksys routers.
[WebKit-https.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/JSObjectRef.h>
35 #include <JavaScriptCore/JSRetainPtr.h>
36 #include <stdio.h>
37 #include <wtf/Assertions.h>
38 #include <wtf/MathExtras.h>
39 #include <wtf/RefPtr.h>
40
41 LayoutTestController::LayoutTestController(const std::string& testPathOrURL, const std::string& expectedPixelHash)
42     : m_dumpAsText(false)
43     , m_dumpAsPDF(false)
44     , m_dumpBackForwardList(false)
45     , m_dumpChildFrameScrollPositions(false)
46     , m_dumpChildFramesAsText(false)
47     , m_dumpDatabaseCallbacks(false)
48     , m_dumpDOMAsWebArchive(false)
49     , m_dumpSelectionRect(false)
50     , m_dumpSourceAsWebArchive(false)
51     , m_dumpStatusCallbacks(false)
52     , m_dumpTitleChanges(false)
53     , m_dumpEditingCallbacks(false)
54     , m_dumpResourceLoadCallbacks(false)
55     , m_dumpResourceResponseMIMETypes(false)
56     , m_dumpWillCacheResponse(false)
57     , m_dumpFrameLoadCallbacks(false)
58     , m_callCloseOnWebViews(true)
59     , m_canOpenWindows(false)
60     , m_closeRemainingWindowsWhenComplete(true)
61     , m_stopProvisionalFrameLoads(false)
62     , m_testOnscreen(false)
63     , m_testRepaint(false)
64     , m_testRepaintSweepHorizontally(false)
65     , m_waitToDump(false)
66     , m_willSendRequestReturnsNullOnRedirect(false)
67     , m_windowIsKey(true)
68     , m_alwaysAcceptCookies(false)
69     , m_globalFlag(false)
70     , m_isGeolocationPermissionSet(false)
71     , m_geolocationPermission(false)
72     , m_testPathOrURL(testPathOrURL)
73     , m_expectedPixelHash(expectedPixelHash)
74 {
75 }
76
77 // Static Functions
78
79 static JSValueRef dumpAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
80 {
81     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
82     controller->setDumpAsText(true);
83     return JSValueMakeUndefined(context);
84 }
85
86 static JSValueRef dumpAsPDFCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
87 {
88     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
89     controller->setDumpAsPDF(true);
90     return JSValueMakeUndefined(context);
91 }
92
93 static JSValueRef dumpBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
94 {
95     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
96     controller->setDumpBackForwardList(true);
97     return JSValueMakeUndefined(context);
98 }
99
100 static JSValueRef dumpChildFramesAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
101 {
102     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
103     controller->setDumpChildFramesAsText(true);
104     return JSValueMakeUndefined(context);
105 }
106
107 static JSValueRef dumpChildFrameScrollPositionsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
108 {
109     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
110     controller->setDumpChildFrameScrollPositions(true);
111     return JSValueMakeUndefined(context);
112 }
113
114 static JSValueRef dumpDatabaseCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
115 {
116     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
117     controller->setDumpDatabaseCallbacks(true);
118     return JSValueMakeUndefined(context);
119 }
120
121 static JSValueRef dumpDOMAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
122 {
123     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
124     controller->setDumpDOMAsWebArchive(true);
125     return JSValueMakeUndefined(context);
126 }
127
128 static JSValueRef dumpEditingCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
129 {
130     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
131     controller->setDumpEditingCallbacks(true);
132     return JSValueMakeUndefined(context);
133 }
134
135 static JSValueRef dumpResourceLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
136 {
137     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
138     controller->setDumpResourceLoadCallbacks(true);
139     return JSValueMakeUndefined(context);
140 }
141
142 static JSValueRef dumpFrameLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
143 {
144     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
145     controller->setDumpFrameLoadCallbacks(true);
146     return JSValueMakeUndefined(context);
147 }
148
149 static JSValueRef dumpResourceResponseMIMETypesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
150 {
151     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
152     controller->setDumpResourceResponseMIMETypes(true);
153     return JSValueMakeUndefined(context);
154 }
155
156 static JSValueRef dumpSelectionRectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
157 {
158     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
159     controller->setDumpSelectionRect(true);
160     return JSValueMakeUndefined(context);
161 }
162
163 static JSValueRef dumpSourceAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
164 {
165     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
166     controller->setDumpSourceAsWebArchive(true);
167     return JSValueMakeUndefined(context);
168 }
169
170 static JSValueRef dumpStatusCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
171 {
172     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
173     controller->setDumpStatusCallbacks(true);
174     return JSValueMakeUndefined(context);
175 }
176
177 static JSValueRef dumpTitleChangesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
178 {
179     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
180     controller->setDumpTitleChanges(true);
181     return JSValueMakeUndefined(context);
182 }
183
184 static JSValueRef dumpWillCacheResponseCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
185 {
186     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
187     controller->setDumpWillCacheResponse(true);
188     return JSValueMakeUndefined(context);
189 }
190
191 static JSValueRef pathToLocalResourceCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
192 {
193     if (argumentCount < 1)
194         return JSValueMakeUndefined(context);
195
196     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
197     JSRetainPtr<JSStringRef> localPath(Adopt, JSValueToStringCopy(context, arguments[0], exception));
198     ASSERT(!*exception);
199
200     JSRetainPtr<JSStringRef> convertedPath(Adopt, controller->pathToLocalResource(context, localPath.get()));
201     if (!convertedPath)
202         return JSValueMakeUndefined(context);
203
204     return JSValueMakeString(context, convertedPath.get());
205 }
206
207 static JSValueRef repaintSweepHorizontallyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
208 {
209     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
210     controller->setTestRepaintSweepHorizontally(true);
211     return JSValueMakeUndefined(context);
212 }
213
214 static JSValueRef setCallCloseOnWebViewsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
215 {
216     if (argumentCount < 1)
217         return JSValueMakeUndefined(context);
218
219     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
220     controller->setCallCloseOnWebViews(JSValueToBoolean(context, arguments[0]));
221     return JSValueMakeUndefined(context);
222 }
223
224 static JSValueRef setCanOpenWindowsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
225 {
226     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
227     controller->setCanOpenWindows(true);
228     return JSValueMakeUndefined(context);
229 }
230
231 static JSValueRef setCloseRemainingWindowsWhenCompleteCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
232 {
233     if (argumentCount < 1)
234         return JSValueMakeUndefined(context);
235
236     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
237     controller->setCloseRemainingWindowsWhenComplete(JSValueToBoolean(context, arguments[0]));
238     return JSValueMakeUndefined(context);
239 }
240
241 static JSValueRef testOnscreenCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
242 {
243     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
244     controller->setTestOnscreen(true);
245     return JSValueMakeUndefined(context);
246 }
247
248 static JSValueRef testRepaintCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
249 {
250     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
251     controller->setTestRepaint(true);
252     return JSValueMakeUndefined(context);
253 }
254
255 static JSValueRef addDisallowedURLCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
256 {
257     // Has mac implementation
258     if (argumentCount < 1)
259         return JSValueMakeUndefined(context);
260
261     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
262     ASSERT(!*exception);
263
264     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
265     controller->addDisallowedURL(url.get());
266
267     return JSValueMakeUndefined(context);
268 }
269
270 static JSValueRef clearAllDatabasesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
271 {
272     // Has mac & windows implementation
273     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
274     controller->clearAllDatabases();
275
276     return JSValueMakeUndefined(context);
277 }
278
279 static JSValueRef clearBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
280 {
281     // Has mac & windows implementation
282     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
283     controller->clearBackForwardList();
284
285     return JSValueMakeUndefined(context);
286 }
287
288 static JSValueRef clearPersistentUserStyleSheetCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
289 {
290     // Has mac & windows implementation
291     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
292     controller->clearPersistentUserStyleSheet();
293
294     return JSValueMakeUndefined(context);
295 }
296
297 static JSValueRef decodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
298 {
299     // Has mac implementation
300     if (argumentCount < 1)
301         return JSValueMakeUndefined(context);
302
303     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
304     ASSERT(!*exception);
305
306     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
307     JSRetainPtr<JSStringRef> decodedHostName(Adopt, controller->copyDecodedHostName(name.get()));
308     return JSValueMakeString(context, decodedHostName.get());
309 }
310
311 static JSValueRef disableImageLoadingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
312 {
313     // Has mac implementation, needs windows implementation
314     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
315     controller->disableImageLoading();
316     
317     return JSValueMakeUndefined(context);
318 }
319
320 static JSValueRef dispatchPendingLoadRequestsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
321 {
322     // Has mac implementation, needs windows implementation
323     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
324     controller->dispatchPendingLoadRequests();
325     
326     return JSValueMakeUndefined(context);
327 }
328
329 static JSValueRef displayCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
330 {
331     // Has mac & windows implementation
332     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
333     controller->display();
334
335     return JSValueMakeUndefined(context);
336 }
337
338 static JSValueRef encodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
339 {
340     // Has mac implementation
341     if (argumentCount < 1)
342         return JSValueMakeUndefined(context);
343
344     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
345     ASSERT(!*exception);
346
347     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
348     JSRetainPtr<JSStringRef> encodedHostName(Adopt, controller->copyEncodedHostName(name.get()));
349     return JSValueMakeString(context, encodedHostName.get());
350 }
351
352 static JSValueRef execCommandCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
353 {
354     // Has Mac & Windows implementations.
355     if (argumentCount < 1)
356         return JSValueMakeUndefined(context);
357
358     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
359     ASSERT(!*exception);
360
361     // Ignoring the second parameter (userInterface), as this command emulates a manual action.
362
363     JSRetainPtr<JSStringRef> value;
364     if (argumentCount >= 3) {
365         value.adopt(JSValueToStringCopy(context, arguments[2], exception));
366         ASSERT(!*exception);
367     } else
368         value.adopt(JSStringCreateWithUTF8CString(""));
369
370
371     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
372     controller->execCommand(name.get(), value.get());
373
374     return JSValueMakeUndefined(context);
375 }
376
377 static JSValueRef grantDesktopNotificationPermissionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
378 {
379     // Has Windows implementation
380     if (argumentCount < 1)
381         return JSValueMakeUndefined(context);
382
383     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
384
385     controller->grantDesktopNotificationPermission(JSValueToStringCopy(context, arguments[0], NULL));
386         
387     return JSValueMakeUndefined(context);
388 }
389
390 static JSValueRef isCommandEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
391 {
392     // Has Mac implementation.
393
394     if (argumentCount < 1)
395         return JSValueMakeUndefined(context);
396
397     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
398     ASSERT(!*exception);
399
400     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
401
402     return JSValueMakeBoolean(context, controller->isCommandEnabled(name.get()));
403 }
404
405 static JSValueRef overridePreferenceCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
406 {
407     if (argumentCount < 2)
408         return JSValueMakeUndefined(context);
409
410     JSRetainPtr<JSStringRef> key(Adopt, JSValueToStringCopy(context, arguments[0], exception));
411     ASSERT(!*exception);
412     JSRetainPtr<JSStringRef> value(Adopt, JSValueToStringCopy(context, arguments[1], exception));
413     ASSERT(!*exception);
414
415     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
416     controller->overridePreference(key.get(), value.get());
417
418     return JSValueMakeUndefined(context);
419 }
420
421 static JSValueRef keepWebHistoryCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
422 {
423     // Has mac implementation
424     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
425     controller->keepWebHistory();
426
427     return JSValueMakeUndefined(context);
428 }
429
430 static JSValueRef notifyDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
431 {
432     // Has mac & windows implementation
433     // May be able to be made platform independant by using shared WorkQueue
434     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
435     controller->notifyDone();
436     return JSValueMakeUndefined(context);
437 }
438
439 static JSValueRef queueBackNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
440 {
441     // Has mac & windows implementation
442     // May be able to be made platform independant by using shared WorkQueue
443     if (argumentCount < 1)
444         return JSValueMakeUndefined(context);
445
446     double howFarBackDouble = JSValueToNumber(context, arguments[0], exception);
447     ASSERT(!*exception);
448
449     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
450     controller->queueBackNavigation(static_cast<int>(howFarBackDouble));
451
452     return JSValueMakeUndefined(context);
453 }
454
455 static JSValueRef queueForwardNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
456 {
457     // Has mac & windows implementation
458     // May be able to be made platform independant by using shared WorkQueue
459     if (argumentCount < 1)
460         return JSValueMakeUndefined(context);
461
462     double howFarForwardDouble = JSValueToNumber(context, arguments[0], exception);
463     ASSERT(!*exception);
464
465     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
466     controller->queueForwardNavigation(static_cast<int>(howFarForwardDouble));
467
468     return JSValueMakeUndefined(context);
469 }
470
471 static JSValueRef queueLoadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
472 {
473     // Has mac & windows implementation
474     // May be able to be made platform independant by using shared WorkQueue
475     if (argumentCount < 1)
476         return JSValueMakeUndefined(context);
477
478     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
479     ASSERT(!*exception);
480
481     JSRetainPtr<JSStringRef> target;
482     if (argumentCount >= 2) {
483         target.adopt(JSValueToStringCopy(context, arguments[1], exception));
484         ASSERT(!*exception);
485     } else
486         target.adopt(JSStringCreateWithUTF8CString(""));
487
488     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
489     controller->queueLoad(url.get(), target.get());
490
491     return JSValueMakeUndefined(context);
492 }
493
494 static JSValueRef queueReloadCallback(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
499     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
500     controller->queueReload();
501
502     return JSValueMakeUndefined(context);
503 }
504
505 static JSValueRef queueLoadingScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
506 {
507     // Has mac & windows implementation
508     // May be able to be made platform independant by using shared WorkQueue
509     if (argumentCount < 1)
510         return JSValueMakeUndefined(context);
511
512     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
513     ASSERT(!*exception);
514
515     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
516     controller->queueLoadingScript(script.get());
517
518     return JSValueMakeUndefined(context);
519 }
520
521 static JSValueRef queueNonLoadingScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
522 {
523     // Has mac & windows implementation
524     // May be able to be made platform independant by using shared WorkQueue
525     if (argumentCount < 1)
526         return JSValueMakeUndefined(context);
527
528     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
529     ASSERT(!*exception);
530
531     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
532     controller->queueNonLoadingScript(script.get());
533
534     return JSValueMakeUndefined(context);
535 }
536
537 static JSValueRef setAcceptsEditingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
538 {
539     // Has mac & windows implementation
540     if (argumentCount < 1)
541         return JSValueMakeUndefined(context);
542
543     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
544     controller->setAcceptsEditing(JSValueToBoolean(context, arguments[0]));
545
546     return JSValueMakeUndefined(context);
547 }
548
549 static JSValueRef setAlwaysAcceptCookiesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
550 {
551     // Has mac & windows implementation
552     if (argumentCount < 1)
553         return JSValueMakeUndefined(context);
554
555     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
556     controller->setAlwaysAcceptCookies(JSValueToBoolean(context, arguments[0]));
557
558     return JSValueMakeUndefined(context);
559 }
560
561 static JSValueRef setAppCacheMaximumSizeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
562 {
563     // Has mac implementation
564     if (argumentCount < 1)
565         return JSValueMakeUndefined(context);
566
567     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
568
569     double size = JSValueToNumber(context, arguments[0], NULL);
570     if (!isnan(size))
571         controller->setAppCacheMaximumSize(static_cast<unsigned long long>(size));
572         
573     return JSValueMakeUndefined(context);
574
575 }
576
577 static JSValueRef setAuthenticationPasswordCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
578 {
579     // Has mac & windows implementation
580     if (argumentCount < 1)
581         return JSValueMakeUndefined(context);
582
583     JSRetainPtr<JSStringRef> password(Adopt, JSValueToStringCopy(context, arguments[0], exception));
584     ASSERT(!*exception);
585
586     size_t maxLength = JSStringGetMaximumUTF8CStringSize(password.get());
587     char passwordBuffer[maxLength + 1];
588     JSStringGetUTF8CString(password.get(), passwordBuffer, maxLength + 1);
589     
590     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
591     controller->setAuthenticationPassword(passwordBuffer);
592
593     return JSValueMakeUndefined(context);
594 }
595
596 static JSValueRef setAuthenticationUsernameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
597 {
598     // Has mac & windows implementation
599     if (argumentCount < 1)
600         return JSValueMakeUndefined(context);
601
602     JSRetainPtr<JSStringRef> username(Adopt, JSValueToStringCopy(context, arguments[0], exception));
603     ASSERT(!*exception);
604
605     size_t maxLength = JSStringGetMaximumUTF8CStringSize(username.get());
606     char usernameBuffer[maxLength + 1];
607     JSStringGetUTF8CString(username.get(), usernameBuffer, maxLength + 1);
608     
609     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
610     controller->setAuthenticationUsername(usernameBuffer);
611
612     return JSValueMakeUndefined(context);
613 }
614
615 static JSValueRef setAuthorAndUserStylesEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
616 {
617     // Has mac & windows implementation
618     if (argumentCount < 1)
619         return JSValueMakeUndefined(context);
620
621     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
622     controller->setAuthorAndUserStylesEnabled(JSValueToBoolean(context, arguments[0]));
623
624     return JSValueMakeUndefined(context);
625 }
626
627 static JSValueRef setCacheModelCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
628 {
629     // Has Mac implementation.
630     if (argumentCount < 1)
631         return JSValueMakeUndefined(context);
632
633     int cacheModel = JSValueToNumber(context, arguments[0], exception);
634     ASSERT(!*exception);
635
636     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
637     controller->setCacheModel(cacheModel);
638
639     return JSValueMakeUndefined(context);
640 }
641
642 static JSValueRef setCustomPolicyDelegateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
643 {
644     // Has mac implementation
645     if (argumentCount < 1)
646         return JSValueMakeUndefined(context);
647     
648     bool permissive = false;
649     if (argumentCount >= 2)
650         permissive = JSValueToBoolean(context, arguments[1]);
651
652     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
653     controller->setCustomPolicyDelegate(JSValueToBoolean(context, arguments[0]), permissive);
654
655     return JSValueMakeUndefined(context);
656 }
657
658 static JSValueRef setDatabaseQuotaCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
659 {
660     // Has mac implementation
661     if (argumentCount < 1)
662         return JSValueMakeUndefined(context);
663
664     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
665
666     double quota = JSValueToNumber(context, arguments[0], NULL);
667     if (!isnan(quota))
668         controller->setDatabaseQuota(static_cast<unsigned long long>(quota));
669         
670     return JSValueMakeUndefined(context);
671 }
672
673 static JSValueRef setMockGeolocationPositionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
674 {
675     if (argumentCount < 3)
676         return JSValueMakeUndefined(context);
677
678     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
679     controller->setMockGeolocationPosition(JSValueToNumber(context, arguments[0], NULL),  // latitude
680                                            JSValueToNumber(context, arguments[1], NULL),  // longitude
681                                            JSValueToNumber(context, arguments[2], NULL));  // accuracy
682
683     return JSValueMakeUndefined(context);
684 }
685
686 static JSValueRef setMockGeolocationErrorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
687 {
688     if (argumentCount < 2)
689         return JSValueMakeUndefined(context);
690
691     int code = JSValueToNumber(context, arguments[0], NULL);
692     JSRetainPtr<JSStringRef> message(Adopt, JSValueToStringCopy(context, arguments[1], exception));
693     ASSERT(!*exception);
694
695     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
696     controller->setMockGeolocationError(code, message.get());
697
698     return JSValueMakeUndefined(context);
699 }
700
701 static JSValueRef setGeolocationPermissionCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
702 {
703     // Has mac implementation
704     if (argumentCount < 1)
705         return JSValueMakeUndefined(context);
706
707     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
708     controller->setGeolocationPermission(JSValueToBoolean(context, arguments[0]));
709
710     return JSValueMakeUndefined(context);
711 }
712
713 static JSValueRef setHandlesAuthenticationChallengesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
714 {
715     // Has mac & windows implementation
716     if (argumentCount < 1)
717         return JSValueMakeUndefined(context);
718
719     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
720     controller->setHandlesAuthenticationChallenges(JSValueToBoolean(context, arguments[0]));
721
722     return JSValueMakeUndefined(context);
723 }
724
725 static JSValueRef setIconDatabaseEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
726 {
727     // Has mac & windows implementation
728     if (argumentCount < 1)
729         return JSValueMakeUndefined(context);
730
731     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
732     controller->setIconDatabaseEnabled(JSValueToBoolean(context, arguments[0]));
733
734     return JSValueMakeUndefined(context);
735 }
736
737 static JSValueRef setJavaScriptProfilingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
738 {
739     if (argumentCount < 1)
740         return JSValueMakeUndefined(context);
741
742     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
743     controller->setJavaScriptProfilingEnabled(JSValueToBoolean(context, arguments[0]));
744
745     return JSValueMakeUndefined(context);
746 }
747
748 static JSValueRef setMainFrameIsFirstResponderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
749 {
750     // Has mac implementation
751     if (argumentCount < 1)
752         return JSValueMakeUndefined(context);
753
754     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
755     controller->setMainFrameIsFirstResponder(JSValueToBoolean(context, arguments[0]));
756
757     return JSValueMakeUndefined(context);
758 }
759
760 static JSValueRef setPersistentUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
761 {
762     // Has mac implementation
763     if (argumentCount < 1)
764         return JSValueMakeUndefined(context);
765
766     JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
767     ASSERT(!*exception);
768
769     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
770     controller->setPersistentUserStyleSheetLocation(path.get());
771
772     return JSValueMakeUndefined(context);
773 }
774
775 static JSValueRef setPrivateBrowsingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
776 {
777     // Has mac & windows implementation
778     if (argumentCount < 1)
779         return JSValueMakeUndefined(context);
780
781     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
782     controller->setPrivateBrowsingEnabled(JSValueToBoolean(context, arguments[0]));
783
784     return JSValueMakeUndefined(context);
785 }
786
787 static JSValueRef setXSSAuditorEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
788 {
789     // Has mac & windows implementation
790     if (argumentCount < 1)
791         return JSValueMakeUndefined(context);
792
793     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
794     controller->setXSSAuditorEnabled(JSValueToBoolean(context, arguments[0]));
795
796     return JSValueMakeUndefined(context);
797 }
798
799 static JSValueRef setTabKeyCyclesThroughElementsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
800 {
801     // Has mac & windows implementation
802     if (argumentCount < 1)
803         return JSValueMakeUndefined(context);
804
805     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
806     controller->setTabKeyCyclesThroughElements(JSValueToBoolean(context, arguments[0]));
807
808     return JSValueMakeUndefined(context);
809 }
810
811 static JSValueRef setUseDashboardCompatibilityModeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
812 {
813     // Has mac implementation
814     if (argumentCount < 1)
815         return JSValueMakeUndefined(context);
816
817     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
818     controller->setUseDashboardCompatibilityMode(JSValueToBoolean(context, arguments[0]));
819
820     return JSValueMakeUndefined(context);
821 }
822
823 static JSValueRef setUserStyleSheetEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
824 {
825     // Has mac implementation
826     if (argumentCount < 1)
827         return JSValueMakeUndefined(context);
828
829     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
830     controller->setUserStyleSheetEnabled(JSValueToBoolean(context, arguments[0]));
831
832     return JSValueMakeUndefined(context);
833 }
834
835 static JSValueRef setUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
836 {
837     // Has mac implementation
838     if (argumentCount < 1)
839         return JSValueMakeUndefined(context);
840
841     JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
842     ASSERT(!*exception);
843
844     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
845     controller->setUserStyleSheetLocation(path.get());
846
847     return JSValueMakeUndefined(context);
848 }
849
850 static JSValueRef setWillSendRequestReturnsNullOnRedirectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
851 {
852     // Has cross-platform implementation
853     if (argumentCount < 1)
854         return JSValueMakeUndefined(context);
855
856     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
857     controller->setWillSendRequestReturnsNullOnRedirect(JSValueToBoolean(context, arguments[0]));
858
859     return JSValueMakeUndefined(context);
860 }
861
862 static JSValueRef setWindowIsKeyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
863 {
864     // Has mac implementation
865     if (argumentCount < 1)
866         return JSValueMakeUndefined(context);
867
868     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
869     controller->setWindowIsKey(JSValueToBoolean(context, arguments[0]));
870
871     return JSValueMakeUndefined(context);
872 }
873
874 static JSValueRef waitUntilDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
875 {
876     // Has mac & windows implementation
877     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
878     controller->setWaitToDump(true);
879
880     return JSValueMakeUndefined(context);
881 }
882
883 static JSValueRef windowCountCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
884 {
885     // Has mac implementation
886     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
887     int windows = controller->windowCount();
888     return JSValueMakeNumber(context, windows);
889 }
890
891 static JSValueRef setPopupBlockingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
892 {
893     // Has mac & windows implementation
894     if (argumentCount < 1)
895         return JSValueMakeUndefined(context);
896
897     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
898     controller->setPopupBlockingEnabled(JSValueToBoolean(context, arguments[0]));
899
900     return JSValueMakeUndefined(context);
901 }
902
903 static JSValueRef setSmartInsertDeleteEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
904 {
905     if (argumentCount < 1)
906         return JSValueMakeUndefined(context);
907
908     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
909     controller->setSmartInsertDeleteEnabled(JSValueToBoolean(context, arguments[0]));
910     return JSValueMakeUndefined(context);
911 }
912
913 static JSValueRef setSelectTrailingWhitespaceEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
914 {
915     if (argumentCount < 1)
916         return JSValueMakeUndefined(context);
917
918     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
919     controller->setSelectTrailingWhitespaceEnabled(JSValueToBoolean(context, arguments[0]));
920     return JSValueMakeUndefined(context);
921 }
922
923 static JSValueRef setStopProvisionalFrameLoadsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
924 {
925     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
926     controller->setStopProvisionalFrameLoads(true);
927     return JSValueMakeUndefined(context);
928 }
929
930 static JSValueRef elementDoesAutoCompleteForElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
931 {
932     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
933     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
934     ASSERT(!*exception);
935
936     bool autoCompletes = controller->elementDoesAutoCompleteForElementWithId(elementId.get());
937
938     return JSValueMakeBoolean(context, autoCompletes);
939 }
940
941 static JSValueRef pauseAnimationAtTimeOnElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
942 {
943     if (argumentCount != 3)
944         return JSValueMakeUndefined(context);
945
946     JSRetainPtr<JSStringRef> animationName(Adopt, JSValueToStringCopy(context, arguments[0], exception));
947     ASSERT(!*exception);
948     double time = JSValueToNumber(context, arguments[1], exception);
949     ASSERT(!*exception);
950     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
951     ASSERT(!*exception);
952
953     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
954     return JSValueMakeBoolean(context, controller->pauseAnimationAtTimeOnElementWithId(animationName.get(), time, elementId.get()));
955 }
956
957 static JSValueRef pauseTransitionAtTimeOnElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
958 {
959     if (argumentCount != 3)
960         return JSValueMakeUndefined(context);
961
962     JSRetainPtr<JSStringRef> propertyName(Adopt, JSValueToStringCopy(context, arguments[0], exception));
963     ASSERT(!*exception);
964     double time = JSValueToNumber(context, arguments[1], exception);
965     ASSERT(!*exception);
966     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
967     ASSERT(!*exception);
968
969     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
970     return JSValueMakeBoolean(context, controller->pauseTransitionAtTimeOnElementWithId(propertyName.get(), time, elementId.get()));
971 }
972
973 static JSValueRef numberOfActiveAnimationsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
974 {
975     if (argumentCount != 0)
976         return JSValueMakeUndefined(context);
977
978     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
979     return JSValueMakeNumber(context, controller->numberOfActiveAnimations());
980 }
981
982 static JSValueRef waitForPolicyDelegateCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*)
983 {
984     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
985     controller->waitForPolicyDelegate();
986     return JSValueMakeUndefined(context);
987 }
988
989 static JSValueRef whiteListAccessFromOriginCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
990 {
991     if (argumentCount != 4)
992         return JSValueMakeUndefined(context);
993
994     JSRetainPtr<JSStringRef> sourceOrigin(Adopt, JSValueToStringCopy(context, arguments[0], exception));
995     ASSERT(!*exception);
996     JSRetainPtr<JSStringRef> destinationProtocol(Adopt, JSValueToStringCopy(context, arguments[1], exception));
997     ASSERT(!*exception);
998     JSRetainPtr<JSStringRef> destinationHost(Adopt, JSValueToStringCopy(context, arguments[2], exception));
999     ASSERT(!*exception);
1000     bool allowDestinationSubdomains = JSValueToBoolean(context, arguments[3]);
1001
1002     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1003     controller->whiteListAccessFromOrigin(sourceOrigin.get(), destinationProtocol.get(), destinationHost.get(), allowDestinationSubdomains);
1004     return JSValueMakeUndefined(context);
1005 }
1006
1007 static JSValueRef addUserScriptCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1008 {
1009     if (argumentCount != 2)
1010         return JSValueMakeUndefined(context);
1011     
1012     JSRetainPtr<JSStringRef> source(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1013     ASSERT(!*exception);
1014     bool runAtStart = JSValueToBoolean(context, arguments[1]);
1015     
1016     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1017     controller->addUserScript(source.get(), runAtStart);
1018     return JSValueMakeUndefined(context);
1019 }
1020  
1021 static JSValueRef addUserStyleSheetCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
1022 {
1023     if (argumentCount != 1)
1024         return JSValueMakeUndefined(context);
1025     
1026     JSRetainPtr<JSStringRef> source(Adopt, JSValueToStringCopy(context, arguments[0], exception));
1027     ASSERT(!*exception);
1028    
1029     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1030     controller->addUserStyleSheet(source.get());
1031     return JSValueMakeUndefined(context);
1032 }
1033
1034 // Static Values
1035
1036 static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1037 {
1038     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1039     return JSValueMakeBoolean(context, controller->globalFlag());
1040 }
1041
1042 static JSValueRef getWebHistoryItemCountCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1043 {
1044     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1045     return JSValueMakeNumber(context, controller->webHistoryItemCount());
1046 }
1047
1048 static JSValueRef getWorkerThreadCountCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
1049 {
1050     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1051     return JSValueMakeNumber(context, controller->workerThreadCount());
1052 }
1053
1054 static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
1055 {
1056     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
1057     controller->setGlobalFlag(JSValueToBoolean(context, value));
1058     return true;
1059 }
1060
1061 static void layoutTestControllerObjectFinalize(JSObjectRef object)
1062 {
1063     LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(object));
1064     controller->deref();
1065 }
1066
1067 // Object Creation
1068
1069 void LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
1070 {
1071     JSRetainPtr<JSStringRef> layoutTestContollerStr(Adopt, JSStringCreateWithUTF8CString("layoutTestController"));
1072     ref();
1073     JSValueRef layoutTestContollerObject = JSObjectMake(context, getJSClass(), this);
1074     JSObjectSetProperty(context, windowObject, layoutTestContollerStr.get(), layoutTestContollerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
1075 }
1076
1077 JSClassRef LayoutTestController::getJSClass()
1078 {
1079     static JSClassRef layoutTestControllerClass;
1080
1081     if (!layoutTestControllerClass) {
1082         JSStaticValue* staticValues = LayoutTestController::staticValues();
1083         JSStaticFunction* staticFunctions = LayoutTestController::staticFunctions();
1084         JSClassDefinition classDefinition = {
1085             0, kJSClassAttributeNone, "LayoutTestController", 0, staticValues, staticFunctions,
1086             0, layoutTestControllerObjectFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
1087         };
1088
1089         layoutTestControllerClass = JSClassCreate(&classDefinition);
1090     }
1091
1092     return layoutTestControllerClass;
1093 }
1094
1095 JSStaticValue* LayoutTestController::staticValues()
1096 {
1097     static JSStaticValue staticValues[] = {
1098         { "globalFlag", getGlobalFlagCallback, setGlobalFlagCallback, kJSPropertyAttributeNone },
1099         { "webHistoryItemCount", getWebHistoryItemCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1100         { "workerThreadCount", getWorkerThreadCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1101         { 0, 0, 0, 0 }
1102     };
1103     return staticValues;
1104 }
1105
1106 JSStaticFunction* LayoutTestController::staticFunctions()
1107 {
1108     static JSStaticFunction staticFunctions[] = {
1109         { "addDisallowedURL", addDisallowedURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1110         { "addUserScript", addUserScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1111         { "addUserStyleSheet", addUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1112         { "clearAllDatabases", clearAllDatabasesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1113         { "clearBackForwardList", clearBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1114         { "clearPersistentUserStyleSheet", clearPersistentUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1115         { "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1116         { "disableImageLoading", disableImageLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1117         { "dispatchPendingLoadRequests", dispatchPendingLoadRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1118         { "display", displayCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1119         { "dumpAsText", dumpAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1120         { "dumpBackForwardList", dumpBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1121         { "dumpChildFrameScrollPositions", dumpChildFrameScrollPositionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1122         { "dumpChildFramesAsText", dumpChildFramesAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1123         { "dumpDOMAsWebArchive", dumpDOMAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1124         { "dumpDatabaseCallbacks", dumpDatabaseCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1125         { "dumpEditingCallbacks", dumpEditingCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1126         { "dumpResourceLoadCallbacks", dumpResourceLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1127         { "dumpFrameLoadCallbacks", dumpFrameLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1128         { "dumpResourceResponseMIMETypes", dumpResourceResponseMIMETypesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1129         { "dumpSelectionRect", dumpSelectionRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1130         { "dumpSourceAsWebArchive", dumpSourceAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1131         { "dumpStatusCallbacks", dumpStatusCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1132         { "dumpTitleChanges", dumpTitleChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1133         { "dumpWillCacheResponse", dumpWillCacheResponseCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1134         { "elementDoesAutoCompleteForElementWithId", elementDoesAutoCompleteForElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1135         { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1136         { "execCommand", execCommandCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1137         { "grantDesktopNotificationPermission", grantDesktopNotificationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
1138         { "isCommandEnabled", isCommandEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1139         { "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1140         { "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1141         { "numberOfActiveAnimations", numberOfActiveAnimationsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1142         { "overridePreference", overridePreferenceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1143         { "pathToLocalResource", pathToLocalResourceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1144         { "pauseAnimationAtTimeOnElementWithId", pauseAnimationAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1145         { "pauseTransitionAtTimeOnElementWithId", pauseTransitionAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1146         { "printToPDF", dumpAsPDFCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1147         { "queueBackNavigation", queueBackNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1148         { "queueForwardNavigation", queueForwardNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1149         { "queueLoad", queueLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1150         { "queueLoadingScript", queueLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1151         { "queueNonLoadingScript", queueNonLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1152         { "queueReload", queueReloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1153         { "repaintSweepHorizontally", repaintSweepHorizontallyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1154         { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1155         { "setAlwaysAcceptCookies", setAlwaysAcceptCookiesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1156         { "setAppCacheMaximumSize", setAppCacheMaximumSizeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
1157         { "setAuthenticationPassword", setAuthenticationPasswordCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1158         { "setAuthenticationUsername", setAuthenticationUsernameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1159         { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1160         { "setCallCloseOnWebViews", setCallCloseOnWebViewsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1161         { "setCanOpenWindows", setCanOpenWindowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1162         { "setCacheModel", setCacheModelCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1163         { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1164         { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1165         { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
1166         { "setGeolocationPermission", setGeolocationPermissionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1167         { "setHandlesAuthenticationChallenges", setHandlesAuthenticationChallengesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1168         { "setIconDatabaseEnabled", setIconDatabaseEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1169         { "setJavaScriptProfilingEnabled", setJavaScriptProfilingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1170         { "setMainFrameIsFirstResponder", setMainFrameIsFirstResponderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1171         { "setMockGeolocationPosition", setMockGeolocationPositionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1172         { "setMockGeolocationError", setMockGeolocationErrorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1173         { "setPersistentUserStyleSheetLocation", setPersistentUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1174         { "setPopupBlockingEnabled", setPopupBlockingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1175         { "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1176         { "setXSSAuditorEnabled", setXSSAuditorEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1177         { "setSelectTrailingWhitespaceEnabled", setSelectTrailingWhitespaceEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1178         { "setSmartInsertDeleteEnabled", setSmartInsertDeleteEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1179         { "setStopProvisionalFrameLoads", setStopProvisionalFrameLoadsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1180         { "setTabKeyCyclesThroughElements", setTabKeyCyclesThroughElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1181         { "setUseDashboardCompatibilityMode", setUseDashboardCompatibilityModeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1182         { "setUserStyleSheetEnabled", setUserStyleSheetEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1183         { "setUserStyleSheetLocation", setUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1184         { "setWillSendRequestReturnsNullOnRedirect", setWillSendRequestReturnsNullOnRedirectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1185         { "setWindowIsKey", setWindowIsKeyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1186         { "testOnscreen", testOnscreenCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1187         { "testRepaint", testRepaintCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1188         { "waitForPolicyDelegate", waitForPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1189         { "waitUntilDone", waitUntilDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1190         { "windowCount", windowCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1191         { "whiteListAccessFromOrigin", whiteListAccessFromOriginCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
1192         { 0, 0, 0 }
1193     };
1194
1195     return staticFunctions;
1196 }
1197
1198 void LayoutTestController::queueBackNavigation(int howFarBack)
1199 {
1200     WorkQueue::shared()->queue(new BackItem(howFarBack));
1201 }
1202
1203 void LayoutTestController::queueForwardNavigation(int howFarForward)
1204 {
1205     WorkQueue::shared()->queue(new ForwardItem(howFarForward));
1206 }
1207
1208 void LayoutTestController::queueLoadingScript(JSStringRef script)
1209 {
1210     WorkQueue::shared()->queue(new LoadingScriptItem(script));
1211 }
1212
1213 void LayoutTestController::queueNonLoadingScript(JSStringRef script)
1214 {
1215     WorkQueue::shared()->queue(new NonLoadingScriptItem(script));
1216 }
1217
1218 void LayoutTestController::queueReload()
1219 {
1220     WorkQueue::shared()->queue(new ReloadItem);
1221 }
1222
1223 void LayoutTestController::grantDesktopNotificationPermission(JSStringRef origin)
1224 {
1225     m_desktopNotificationAllowedOrigins.push_back(JSStringRetain(origin));
1226 }
1227
1228 bool LayoutTestController::checkDesktopNotificationPermission(JSStringRef origin)
1229 {
1230     std::vector<JSStringRef>::iterator i;
1231     for (i = m_desktopNotificationAllowedOrigins.begin();
1232          i != m_desktopNotificationAllowedOrigins.end();
1233          ++i) {
1234         if (JSStringIsEqual(*i, origin))
1235             return true;
1236     }
1237     return false;
1238 }
1239
1240 void LayoutTestController::waitToDumpWatchdogTimerFired()
1241 {
1242     const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
1243     fprintf(stderr, "%s", message);
1244     fprintf(stdout, "%s", message);
1245     notifyDone();
1246 }
1247
1248 void LayoutTestController::setGeolocationPermission(bool allow)
1249 {
1250     m_isGeolocationPermissionSet = true;
1251     m_geolocationPermission = allow;
1252 }