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