Fix the build.
[WebKit-https.git] / WebKitTools / DumpRenderTree / LayoutTestController.cpp
1 /*
2  * Copyright (C) 2007 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 "DumpRenderTree.h"
30 #include "LayoutTestController.h"
31
32 #include <JavaScriptCore/JSObjectRef.h>
33 #include <JavaScriptCore/JSRetainPtr.h>
34 #include <wtf/Assertions.h>
35 #include <wtf/MathExtras.h>
36
37 LayoutTestController::LayoutTestController(bool testRepaintDefault, bool testRepaintSweepHorizontallyDefault)
38     : m_dumpAsText(false)
39     , m_dumpAsPDF(false)
40     , m_dumpBackForwardList(false)
41     , m_dumpChildFrameScrollPositions(false)
42     , m_dumpChildFramesAsText(false)
43     , m_dumpDatabaseCallbacks(false)
44     , m_dumpDOMAsWebArchive(false)
45     , m_dumpSelectionRect(false)
46     , m_dumpSourceAsWebArchive(false)
47     , m_dumpStatusCallbacks(false)
48     , m_dumpTitleChanges(false)
49     , m_dumpEditingCallbacks(false)
50     , m_dumpResourceLoadCallbacks(false)
51     , m_dumpFrameLoadCallbacks(false)
52     , m_addFileToPasteboardOnDrag(false)
53     , m_callCloseOnWebViews(true)
54     , m_canOpenWindows(false)
55     , m_closeRemainingWindowsWhenComplete(true)
56     , m_stopProvisionalFrameLoads(false)
57     , m_testRepaint(testRepaintDefault)
58     , m_testRepaintSweepHorizontally(testRepaintSweepHorizontallyDefault)
59     , m_waitToDump(false)
60     , m_windowIsKey(true)
61     , m_globalFlag(false)
62     , m_selfJSObject(0)
63 {
64 }
65
66 // Static Functions
67
68 static JSValueRef dumpAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
69 {
70     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
71     controller->setDumpAsText(true);
72     return JSValueMakeUndefined(context);
73 }
74
75 static JSValueRef dumpAsPDFCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
76 {
77     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
78     controller->setDumpAsPDF(true);
79     return JSValueMakeUndefined(context);
80 }
81
82 static JSValueRef dumpBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
83 {
84     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
85     controller->setDumpBackForwardList(true);
86     return JSValueMakeUndefined(context);
87 }
88
89 static JSValueRef dumpChildFramesAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
90 {
91     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
92     controller->setDumpChildFramesAsText(true);
93     return JSValueMakeUndefined(context);
94 }
95
96 static JSValueRef dumpChildFrameScrollPositionsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
97 {
98     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
99     controller->setDumpChildFrameScrollPositions(true);
100     return JSValueMakeUndefined(context);
101 }
102
103 static JSValueRef dumpDatabaseCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
104 {
105     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
106     controller->setDumpDatabaseCallbacks(true);
107     return JSValueMakeUndefined(context);
108 }
109
110 static JSValueRef dumpDOMAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
111 {
112     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
113     controller->setDumpDOMAsWebArchive(true);
114     return JSValueMakeUndefined(context);
115 }
116
117 static JSValueRef dumpEditingCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
118 {
119     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
120     controller->setDumpEditingCallbacks(true);
121     return JSValueMakeUndefined(context);
122 }
123
124 static JSValueRef dumpResourceLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
125 {
126     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
127     controller->setDumpResourceLoadCallbacks(true);
128     return JSValueMakeUndefined(context);
129 }
130
131 static JSValueRef dumpSelectionRectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
132 {
133     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
134     controller->setDumpSelectionRect(true);
135     return JSValueMakeUndefined(context);
136 }
137
138 static JSValueRef dumpSourceAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
139 {
140     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
141     controller->setDumpSourceAsWebArchive(true);
142     return JSValueMakeUndefined(context);
143 }
144
145 static JSValueRef dumpStatusCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
146 {
147     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
148     controller->setDumpStatusCallbacks(true);
149     return JSValueMakeUndefined(context);
150 }
151
152 static JSValueRef dumpTitleChangesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
153 {
154     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
155     controller->setDumpTitleChanges(true);
156     return JSValueMakeUndefined(context);
157 }
158
159 static JSValueRef pathToLocalResourceCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
160 {
161     if (argumentCount < 1)
162         return JSValueMakeUndefined(context);
163
164     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
165     JSRetainPtr<JSStringRef> localPath(Adopt, JSValueToStringCopy(context, arguments[0], exception));
166     ASSERT(!*exception);
167
168     JSRetainPtr<JSStringRef> convertedPath(Adopt, controller->pathToLocalResource(context, localPath.get()));
169     if (!convertedPath)
170         return JSValueMakeUndefined(context);
171
172     return JSValueMakeString(context, convertedPath.get());
173 }
174
175 static JSValueRef repaintSweepHorizontallyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
176 {
177     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
178     controller->setTestRepaintSweepHorizontally(true);
179     return JSValueMakeUndefined(context);
180 }
181
182 static JSValueRef setCallCloseOnWebViewsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
183 {
184     if (argumentCount < 1)
185         return JSValueMakeUndefined(context);
186
187     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
188     controller->setCallCloseOnWebViews(JSValueToBoolean(context, arguments[0]));
189     return JSValueMakeUndefined(context);
190 }
191
192 static JSValueRef setCanOpenWindowsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
193 {
194     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
195     controller->setCanOpenWindows(true);
196     return JSValueMakeUndefined(context);
197 }
198
199 static JSValueRef setCloseRemainingWindowsWhenCompleteCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
200 {
201     if (argumentCount < 1)
202         return JSValueMakeUndefined(context);
203
204     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
205     controller->setCloseRemainingWindowsWhenComplete(JSValueToBoolean(context, arguments[0]));
206     return JSValueMakeUndefined(context);
207 }
208
209 static JSValueRef testRepaintCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
210 {
211     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
212     controller->setTestRepaint(true);
213     return JSValueMakeUndefined(context);
214 }
215
216 static JSValueRef addFileToPasteboardOnDragCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
217 {
218     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
219     controller->setAddFileToPasteboardOnDrag(true);
220     return JSValueMakeUndefined(context);
221 }
222
223 static JSValueRef addDisallowedURLCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
224 {
225     // Has mac implementation
226     if (argumentCount < 1)
227         return JSValueMakeUndefined(context);
228
229     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
230     ASSERT(!*exception);
231
232     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
233     controller->addDisallowedURL(url.get());
234
235     return JSValueMakeUndefined(context);
236 }
237
238 static JSValueRef clearAllDatabasesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
239 {
240     // Has mac & windows implementation
241     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
242     controller->clearAllDatabases();
243
244     return JSValueMakeUndefined(context);
245 }
246
247 static JSValueRef clearBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
248 {
249     // Has mac & windows implementation
250     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
251     controller->clearBackForwardList();
252
253     return JSValueMakeUndefined(context);
254 }
255
256 static JSValueRef clearPersistentUserStyleSheetCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
257 {
258     // Has mac & windows implementation
259     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
260     controller->clearPersistentUserStyleSheet();
261
262     return JSValueMakeUndefined(context);
263 }
264
265 static JSValueRef decodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
266 {
267     // Has mac implementation
268     if (argumentCount < 1)
269         return JSValueMakeUndefined(context);
270
271     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
272     ASSERT(!*exception);
273
274     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
275     JSRetainPtr<JSStringRef> decodedHostName(Adopt, controller->copyDecodedHostName(name.get()));
276     return JSValueMakeString(context, decodedHostName.get());
277 }
278
279 static JSValueRef displayCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
280 {
281     // Has mac & windows implementation
282     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
283     controller->display();
284
285     return JSValueMakeUndefined(context);
286 }
287
288 static JSValueRef encodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
289 {
290     // Has mac implementation
291     if (argumentCount < 1)
292         return JSValueMakeUndefined(context);
293
294     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
295     ASSERT(!*exception);
296
297     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
298     JSRetainPtr<JSStringRef> encodedHostName(Adopt, controller->copyEncodedHostName(name.get()));
299     return JSValueMakeString(context, encodedHostName.get());
300 }
301
302 static JSValueRef execCommandCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
303 {
304     // Has Mac & Windows implementations.
305     if (argumentCount < 1)
306         return JSValueMakeUndefined(context);
307
308     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
309     ASSERT(!*exception);
310
311     // Ignoring the second parameter (userInterface), as this command emulates a manual action.
312
313     JSRetainPtr<JSStringRef> value;
314     if (argumentCount >= 3) {
315         value.adopt(JSValueToStringCopy(context, arguments[2], exception));
316         ASSERT(!*exception);
317     } else
318         value.adopt(JSStringCreateWithUTF8CString(""));
319
320
321     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
322     controller->execCommand(name.get(), value.get());
323
324     return JSValueMakeUndefined(context);
325 }
326
327 static JSValueRef keepWebHistoryCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
328 {
329     // Has mac implementation
330     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
331     controller->keepWebHistory();
332
333     return JSValueMakeUndefined(context);
334 }
335
336 static JSValueRef notifyDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
337 {
338     // Has mac & windows implementation
339     // May be able to be made platform independant by using shared WorkQueue
340     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
341     if (controller)
342         controller->notifyDone();
343     else {
344         const char* msg = "FAIL: Null layoutTestController in notifyDone(). Did a test call notifyDone() twice?\n";
345         fprintf(stderr, "%s", msg);
346         fprintf(stdout, "%s", msg);
347     }
348     return JSValueMakeUndefined(context);
349 }
350
351 static JSValueRef queueBackNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
352 {
353     // Has mac & windows implementation
354     // May be able to be made platform independant by using shared WorkQueue
355     if (argumentCount < 1)
356         return JSValueMakeUndefined(context);
357
358     double howFarBackDouble = JSValueToNumber(context, arguments[0], exception);
359     ASSERT(!*exception);
360
361     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
362     controller->queueBackNavigation(static_cast<int>(howFarBackDouble));
363
364     return JSValueMakeUndefined(context);
365 }
366
367 static JSValueRef queueForwardNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
368 {
369     // Has mac & windows implementation
370     // May be able to be made platform independant by using shared WorkQueue
371     if (argumentCount < 1)
372         return JSValueMakeUndefined(context);
373
374     double howFarForwardDouble = JSValueToNumber(context, arguments[0], exception);
375     ASSERT(!*exception);
376
377     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
378     controller->queueForwardNavigation(static_cast<int>(howFarForwardDouble));
379
380     return JSValueMakeUndefined(context);
381 }
382
383 static JSValueRef queueLoadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
384 {
385     // Has mac & windows implementation
386     // May be able to be made platform independant by using shared WorkQueue
387     if (argumentCount < 1)
388         return JSValueMakeUndefined(context);
389
390     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
391     ASSERT(!*exception);
392
393     JSRetainPtr<JSStringRef> target;
394     if (argumentCount >= 2) {
395         target.adopt(JSValueToStringCopy(context, arguments[1], exception));
396         ASSERT(!*exception);
397     } else
398         target.adopt(JSStringCreateWithUTF8CString(""));
399
400     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
401     controller->queueLoad(url.get(), target.get());
402
403     return JSValueMakeUndefined(context);
404 }
405
406 static JSValueRef queueReloadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
407 {
408     // Has mac & windows implementation
409     // May be able to be made platform independant by using shared WorkQueue
410
411     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
412     controller->queueReload();
413
414     return JSValueMakeUndefined(context);
415 }
416
417 static JSValueRef queueScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
418 {
419     // Has mac & windows implementation
420     // May be able to be made platform independant by using shared WorkQueue
421     if (argumentCount < 1)
422         return JSValueMakeUndefined(context);
423
424     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
425     ASSERT(!*exception);
426
427     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
428     controller->queueScript(script.get());
429
430     return JSValueMakeUndefined(context);
431 }
432
433 static JSValueRef setAcceptsEditingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
434 {
435     // Has mac & windows implementation
436     if (argumentCount < 1)
437         return JSValueMakeUndefined(context);
438
439     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
440     controller->setAcceptsEditing(JSValueToBoolean(context, arguments[0]));
441
442     return JSValueMakeUndefined(context);
443 }
444
445 static JSValueRef setAuthorAndUserStylesEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
446 {
447     // Has mac & windows implementation
448     if (argumentCount < 1)
449         return JSValueMakeUndefined(context);
450
451     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
452     controller->setAuthorAndUserStylesEnabled(JSValueToBoolean(context, arguments[0]));
453
454     return JSValueMakeUndefined(context);
455 }
456
457 static JSValueRef setCustomPolicyDelegateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
458 {
459     // Has mac implementation
460     if (argumentCount < 1)
461         return JSValueMakeUndefined(context);
462
463     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
464     controller->setCustomPolicyDelegate(JSValueToBoolean(context, arguments[0]));
465
466     return JSValueMakeUndefined(context);
467 }
468
469 static JSValueRef setDatabaseQuotaCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
470 {
471     // Has mac implementation
472     if (argumentCount < 1)
473         return JSValueMakeUndefined(context);
474
475     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
476
477     double quota = JSValueToNumber(context, arguments[0], NULL);
478     if (!isnan(quota))
479         controller->setDatabaseQuota(static_cast<unsigned long long>(quota));
480         
481     return JSValueMakeUndefined(context);
482
483 }
484
485 static JSValueRef setMainFrameIsFirstResponderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
486 {
487     // Has mac implementation
488     if (argumentCount < 1)
489         return JSValueMakeUndefined(context);
490
491     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
492     controller->setMainFrameIsFirstResponder(JSValueToBoolean(context, arguments[0]));
493
494     return JSValueMakeUndefined(context);
495 }
496
497 static JSValueRef setPersistentUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
498 {
499     // Has mac implementation
500     if (argumentCount < 1)
501         return JSValueMakeUndefined(context);
502
503     JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
504     ASSERT(!*exception);
505
506     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
507     controller->setPersistentUserStyleSheetLocation(path.get());
508
509     return JSValueMakeUndefined(context);
510 }
511
512 static JSValueRef setPrivateBrowsingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
513 {
514     // Has mac & windows implementation
515     if (argumentCount < 1)
516         return JSValueMakeUndefined(context);
517
518     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
519     controller->setPrivateBrowsingEnabled(JSValueToBoolean(context, arguments[0]));
520
521     return JSValueMakeUndefined(context);
522 }
523
524 static JSValueRef setTabKeyCyclesThroughElementsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
525 {
526     // Has mac & windows implementation
527     if (argumentCount < 1)
528         return JSValueMakeUndefined(context);
529
530     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
531     controller->setTabKeyCyclesThroughElements(JSValueToBoolean(context, arguments[0]));
532
533     return JSValueMakeUndefined(context);
534 }
535
536 static JSValueRef setUseDashboardCompatibilityModeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
537 {
538     // Has mac implementation
539     if (argumentCount < 1)
540         return JSValueMakeUndefined(context);
541
542     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
543     controller->setUseDashboardCompatibilityMode(JSValueToBoolean(context, arguments[0]));
544
545     return JSValueMakeUndefined(context);
546 }
547
548 static JSValueRef setUserStyleSheetEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
549 {
550     // Has mac implementation
551     if (argumentCount < 1)
552         return JSValueMakeUndefined(context);
553
554     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
555     controller->setUserStyleSheetEnabled(JSValueToBoolean(context, arguments[0]));
556
557     return JSValueMakeUndefined(context);
558 }
559
560 static JSValueRef setUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
561 {
562     // Has mac implementation
563     if (argumentCount < 1)
564         return JSValueMakeUndefined(context);
565
566     JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
567     ASSERT(!*exception);
568
569     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
570     controller->setUserStyleSheetLocation(path.get());
571
572     return JSValueMakeUndefined(context);
573 }
574
575 static JSValueRef setWindowIsKeyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
576 {
577     // Has mac implementation
578     if (argumentCount < 1)
579         return JSValueMakeUndefined(context);
580
581     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
582     controller->setWindowIsKey(JSValueToBoolean(context, arguments[0]));
583
584     return JSValueMakeUndefined(context);
585 }
586
587 static JSValueRef waitUntilDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
588 {
589     // Has mac & windows implementation
590     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
591     controller->setWaitToDump(true);
592
593     return JSValueMakeUndefined(context);
594 }
595
596 static JSValueRef windowCountCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
597 {
598     // Has mac implementation
599     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
600     int windows = controller->windowCount();
601     return JSValueMakeNumber(context, windows);
602 }
603
604 static JSValueRef setPopupBlockingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
605 {
606     // Has mac & windows implementation
607     if (argumentCount < 1)
608         return JSValueMakeUndefined(context);
609
610     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
611     controller->setPopupBlockingEnabled(JSValueToBoolean(context, arguments[0]));
612
613     return JSValueMakeUndefined(context);
614 }
615
616 static JSValueRef setStopProvisionalFrameLoadsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
617 {
618     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
619     controller->setStopProvisionalFrameLoads(true);
620     return JSValueMakeUndefined(context);
621 }
622
623 static JSValueRef elementDoesAutoCompleteForElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
624 {
625     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
626     JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
627     ASSERT(!*exception);
628
629     bool autoCompletes = controller->elementDoesAutoCompleteForElementWithId(elementId.get());
630
631     return JSValueMakeBoolean(context, autoCompletes);
632 }
633
634 // Static Values
635
636 static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
637 {
638     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
639     return JSValueMakeBoolean(context, controller->globalFlag());
640 }
641
642 static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
643 {
644     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
645     controller->setGlobalFlag(JSValueToBoolean(context, value));
646     return true;
647 }
648
649 static void layoutTestControllerObjectFinalize(JSObjectRef object)
650 {
651     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(object));
652     if (controller)
653         controller->setJSObject(0);
654 }
655
656 // Object Creation
657
658 void LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
659 {
660     JSRetainPtr<JSStringRef> layoutTestContollerStr(Adopt, JSStringCreateWithUTF8CString("layoutTestController"));
661     setJSObject(JSObjectMake(context, getJSClass(), this));
662     JSObjectSetProperty(context, windowObject, layoutTestContollerStr.get(), jsObject(), kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
663 }
664
665 JSClassRef LayoutTestController::getJSClass()
666 {
667     static JSClassRef layoutTestControllerClass;
668
669     if (!layoutTestControllerClass) {
670         JSStaticValue* staticValues = LayoutTestController::staticValues();
671         JSStaticFunction* staticFunctions = LayoutTestController::staticFunctions();
672         JSClassDefinition classDefinition = {
673             0, kJSClassAttributeNone, "LayoutTestController", 0, staticValues, staticFunctions,
674             0, layoutTestControllerObjectFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
675         };
676
677         layoutTestControllerClass = JSClassCreate(&classDefinition);
678     }
679
680     return layoutTestControllerClass;
681 }
682
683 JSStaticValue* LayoutTestController::staticValues()
684 {
685     static JSStaticValue staticValues[] = {
686         { "globalFlag", getGlobalFlagCallback, setGlobalFlagCallback, kJSPropertyAttributeNone },
687         { 0, 0, 0, 0 }
688     };
689     return staticValues;
690
691 }
692
693 JSStaticFunction* LayoutTestController::staticFunctions()
694 {
695     static JSStaticFunction staticFunctions[] = {
696         { "addDisallowedURL", addDisallowedURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
697         { "addFileToPasteboardOnDrag", addFileToPasteboardOnDragCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
698         { "clearAllDatabases", clearAllDatabasesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
699         { "clearBackForwardList", clearBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
700         { "clearPersistentUserStyleSheet", clearPersistentUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
701         { "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
702         { "display", displayCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
703         { "dumpAsText", dumpAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
704         { "printToPDF", dumpAsPDFCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
705         { "dumpBackForwardList", dumpBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
706         { "dumpChildFramesAsText", dumpChildFramesAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
707         { "dumpChildFrameScrollPositions", dumpChildFrameScrollPositionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
708         { "dumpDatabaseCallbacks", dumpDatabaseCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
709         { "dumpDOMAsWebArchive", dumpDOMAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
710         { "dumpEditingCallbacks", dumpEditingCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
711         { "dumpResourceLoadCallbacks", dumpResourceLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
712         { "dumpSelectionRect", dumpSelectionRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
713         { "dumpSourceAsWebArchive", dumpSourceAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
714         { "dumpStatusCallbacks", dumpStatusCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
715         { "dumpTitleChanges", dumpTitleChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
716         { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
717         { "execCommand", execCommandCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
718         { "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
719         { "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
720         { "pathToLocalResource", pathToLocalResourceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
721         { "queueBackNavigation", queueBackNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
722         { "queueForwardNavigation", queueForwardNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
723         { "queueLoad", queueLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
724         { "queueReload", queueReloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
725         { "queueScript", queueScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
726         { "repaintSweepHorizontally", repaintSweepHorizontallyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
727         { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
728         { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
729         { "setCallCloseOnWebViews", setCallCloseOnWebViewsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
730         { "setCanOpenWindows", setCanOpenWindowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
731         { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
732         { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
733         { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, 
734         { "setMainFrameIsFirstResponder", setMainFrameIsFirstResponderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
735         { "setPersistentUserStyleSheetLocation", setPersistentUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
736         { "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
737         { "setPopupBlockingEnabled", setPopupBlockingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
738         { "setStopProvisionalFrameLoads", setStopProvisionalFrameLoadsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
739         { "setTabKeyCyclesThroughElements", setTabKeyCyclesThroughElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
740         { "setUseDashboardCompatibilityMode", setUseDashboardCompatibilityModeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
741         { "setUserStyleSheetEnabled", setUserStyleSheetEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
742         { "setUserStyleSheetLocation", setUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
743         { "setWindowIsKey", setWindowIsKeyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
744         { "testRepaint", testRepaintCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
745         { "waitUntilDone", waitUntilDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
746         { "windowCount", windowCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
747         { "elementDoesAutoCompleteForElementWithId", elementDoesAutoCompleteForElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
748         { 0, 0, 0 }
749     };
750
751     return staticFunctions;
752 }
753
754