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