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