Reviewed by Darin.
[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
36 LayoutTestController::LayoutTestController(bool testRepaintDefault, bool testRepaintSweepHorizontallyDefault)
37     : m_dumpAsText(false)
38     , m_dumpBackForwardList(false)
39     , m_dumpChildFrameScrollPositions(false)
40     , m_dumpChildFramesAsText(false)
41     , m_dumpDOMAsWebArchive(false)
42     , m_dumpSelectionRect(false)
43     , m_dumpSourceAsWebArchive(false)
44     , m_dumpTitleChanges(false)
45     , m_dumpEditingCallbacks(false)
46     , m_dumpResourceLoadCallbacks(false)
47     , m_dumpFrameLoadCallbacks(false)
48     , m_addFileToPasteboardOnDrag(false)
49     , m_callCloseOnWebViews(true)
50     , m_canOpenWindows(false)
51     , m_closeRemainingWindowsWhenComplete(true)
52     , m_testRepaint(testRepaintDefault)
53     , m_testRepaintSweepHorizontally(testRepaintSweepHorizontallyDefault)
54     , m_waitToDump(false)
55     , m_windowIsKey(true)
56     , m_globalFlag(false)
57 {
58 }
59
60 // Static Functions
61
62 static JSValueRef dumpAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
63 {
64     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
65     controller->setDumpAsText(true);
66     return JSValueMakeUndefined(context);
67 }
68
69 static JSValueRef dumpBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
70 {
71     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
72     controller->setDumpBackForwardList(true);
73     return JSValueMakeUndefined(context);
74 }
75
76 static JSValueRef dumpChildFramesAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
77 {
78     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
79     controller->setDumpChildFramesAsText(true);
80     return JSValueMakeUndefined(context);
81 }
82
83 static JSValueRef dumpChildFrameScrollPositionsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
84 {
85     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
86     controller->setDumpChildFrameScrollPositions(true);
87     return JSValueMakeUndefined(context);
88 }
89
90 static JSValueRef dumpDOMAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
91 {
92     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
93     controller->setDumpDOMAsWebArchive(true);
94     return JSValueMakeUndefined(context);
95 }
96
97 static JSValueRef dumpEditingCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
98 {
99     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
100     controller->setDumpEditingCallbacks(true);
101     return JSValueMakeUndefined(context);
102 }
103
104 static JSValueRef dumpFrameLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
105 {
106     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
107     controller->setDumpFrameLoadCallbacks(true);
108     return JSValueMakeUndefined(context);
109 }
110
111 static JSValueRef dumpResourceLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
112 {
113     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
114     controller->setDumpResourceLoadCallbacks(true);
115     return JSValueMakeUndefined(context);
116 }
117
118 static JSValueRef dumpSelectionRectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
119 {
120     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
121     controller->setDumpSelectionRect(true);
122     return JSValueMakeUndefined(context);
123 }
124
125 static JSValueRef dumpSourceAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
126 {
127     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
128     controller->setDumpSourceAsWebArchive(true);
129     return JSValueMakeUndefined(context);
130 }
131
132 static JSValueRef dumpTitleChangesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
133 {
134     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
135     controller->setDumpTitleChanges(true);
136     return JSValueMakeUndefined(context);
137 }
138
139 static JSValueRef pathToLocalResourceCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
140 {
141     if (argumentCount < 1)
142         return JSValueMakeUndefined(context);
143
144     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
145     JSRetainPtr<JSStringRef> localPath(Adopt, JSValueToStringCopy(context, arguments[0], exception));
146     ASSERT(!*exception);
147
148     return JSValueMakeString(context, controller->pathToLocalResource(context, localPath.get()));
149 }
150
151 static JSValueRef repaintSweepHorizontallyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
152 {
153     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
154     controller->setTestRepaintSweepHorizontally(true);
155     return JSValueMakeUndefined(context);
156 }
157
158 static JSValueRef setCallCloseOnWebViewsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
159 {
160     if (argumentCount < 1)
161         return JSValueMakeUndefined(context);
162
163     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
164     controller->setCallCloseOnWebViews(JSValueToBoolean(context, arguments[0]));
165     return JSValueMakeUndefined(context);
166 }
167
168 static JSValueRef setCanOpenWindowsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
169 {
170     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
171     controller->setCanOpenWindows(true);
172     return JSValueMakeUndefined(context);
173 }
174
175 static JSValueRef setCloseRemainingWindowsWhenCompleteCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
176 {
177     if (argumentCount < 1)
178         return JSValueMakeUndefined(context);
179
180     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
181     controller->setCloseRemainingWindowsWhenComplete(JSValueToBoolean(context, arguments[0]));
182     return JSValueMakeUndefined(context);
183 }
184
185 static JSValueRef testRepaintCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
186 {
187     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
188     controller->setTestRepaint(true);
189     return JSValueMakeUndefined(context);
190 }
191
192 static JSValueRef addFileToPasteboardOnDragCallback(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->setAddFileToPasteboardOnDrag(true);
196     return JSValueMakeUndefined(context);
197 }
198
199 static JSValueRef addDisallowedURLCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
200 {
201     // Has mac implementation
202     if (argumentCount < 1)
203         return JSValueMakeUndefined(context);
204
205     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
206     ASSERT(!*exception);
207
208     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
209     controller->addDisallowedURL(url.get());
210
211     return JSValueMakeUndefined(context);
212 }
213
214 static JSValueRef clearBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
215 {
216     // Has mac & windows implementation
217     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
218     controller->clearBackForwardList();
219
220     return JSValueMakeUndefined(context);
221 }
222
223 static JSValueRef decodeHostNameCallback(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> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
230     ASSERT(!*exception);
231
232     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
233     JSRetainPtr<JSStringRef> decodedHostName(Adopt, controller->copyDecodedHostName(name.get()));
234     return JSValueMakeString(context, decodedHostName.get());
235 }
236
237 static JSValueRef displayCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
238 {
239     // Has mac & windows implementation
240     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
241     controller->display();
242
243     return JSValueMakeUndefined(context);
244 }
245
246 static JSValueRef encodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
247 {
248     // Has mac implementation
249     if (argumentCount < 1)
250         return JSValueMakeUndefined(context);
251
252     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
253     ASSERT(!*exception);
254
255     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
256     JSRetainPtr<JSStringRef> encodedHostName(Adopt, controller->copyEncodedHostName(name.get()));
257     return JSValueMakeString(context, encodedHostName.get());
258 }
259
260 static JSValueRef execCommandCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
261 {
262     // Has Mac & Windows implementations.
263     if (argumentCount < 1)
264         return JSValueMakeUndefined(context);
265
266     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
267     ASSERT(!*exception);
268
269     // Ignoring the second parameter (userInterface), as this command emulates a manual action.
270
271     JSRetainPtr<JSStringRef> value;
272     if (argumentCount >= 3) {
273         value.adopt(JSValueToStringCopy(context, arguments[2], exception));
274         ASSERT(!*exception);
275     } else
276         value.adopt(JSStringCreateWithUTF8CString(""));
277
278
279     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
280     controller->execCommand(name.get(), value.get());
281
282     return JSValueMakeUndefined(context);
283 }
284
285 static JSValueRef keepWebHistoryCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
286 {
287     // Has mac implementation
288     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
289     controller->keepWebHistory();
290
291     return JSValueMakeUndefined(context);
292 }
293
294 static JSValueRef notifyDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
295 {
296     // Has mac & windows implementation
297     // May be able to be made platform independant by using shared WorkQueue
298     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
299     controller->notifyDone();
300
301     return JSValueMakeUndefined(context);
302 }
303
304 static JSValueRef queueBackNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
305 {
306     // Has mac & windows implementation
307     // May be able to be made platform independant by using shared WorkQueue
308     if (argumentCount < 1)
309         return JSValueMakeUndefined(context);
310
311     double howFarBackDouble = JSValueToNumber(context, arguments[0], exception);
312     ASSERT(!*exception);
313
314     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
315     controller->queueBackNavigation(static_cast<int>(howFarBackDouble));
316
317     return JSValueMakeUndefined(context);
318 }
319
320 static JSValueRef queueForwardNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
321 {
322     // Has mac & windows implementation
323     // May be able to be made platform independant by using shared WorkQueue
324     if (argumentCount < 1)
325         return JSValueMakeUndefined(context);
326
327     double howFarForwardDouble = JSValueToNumber(context, arguments[0], exception);
328     ASSERT(!*exception);
329
330     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
331     controller->queueForwardNavigation(static_cast<int>(howFarForwardDouble));
332
333     return JSValueMakeUndefined(context);
334 }
335
336 static JSValueRef queueLoadCallback(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     if (argumentCount < 1)
341         return JSValueMakeUndefined(context);
342
343     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
344     ASSERT(!*exception);
345
346     JSRetainPtr<JSStringRef> target;
347     if (argumentCount >= 2) {
348         target.adopt(JSValueToStringCopy(context, arguments[1], exception));
349         ASSERT(!*exception);
350     } else
351         target.adopt(JSStringCreateWithUTF8CString(""));
352
353     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
354     controller->queueLoad(url.get(), target.get());
355
356     return JSValueMakeUndefined(context);
357 }
358
359 static JSValueRef queueReloadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
360 {
361     // Has mac & windows implementation
362     // May be able to be made platform independant by using shared WorkQueue
363
364     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
365     controller->queueReload();
366
367     return JSValueMakeUndefined(context);
368 }
369
370 static JSValueRef queueScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
371 {
372     // Has mac & windows implementation
373     // May be able to be made platform independant by using shared WorkQueue
374     if (argumentCount < 1)
375         return JSValueMakeUndefined(context);
376
377     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
378     ASSERT(!*exception);
379
380     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
381     controller->queueScript(script.get());
382
383     return JSValueMakeUndefined(context);
384 }
385
386 static JSValueRef setAcceptsEditingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
387 {
388     // Has mac & windows implementation
389     if (argumentCount < 1)
390         return JSValueMakeUndefined(context);
391
392     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
393     controller->setAcceptsEditing(JSValueToBoolean(context, arguments[0]));
394
395     return JSValueMakeUndefined(context);
396 }
397
398 static JSValueRef setAuthorAndUserStylesEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
399 {
400     // Has mac & windows implementation
401     if (argumentCount < 1)
402         return JSValueMakeUndefined(context);
403
404     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
405     controller->setAuthorAndUserStylesEnabled(JSValueToBoolean(context, arguments[0]));
406
407     return JSValueMakeUndefined(context);
408 }
409
410 static JSValueRef setCustomPolicyDelegateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
411 {
412     // Has mac implementation
413     if (argumentCount < 1)
414         return JSValueMakeUndefined(context);
415
416     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
417     controller->setCustomPolicyDelegate(JSValueToBoolean(context, arguments[0]));
418
419     return JSValueMakeUndefined(context);
420 }
421
422 static JSValueRef setMainFrameIsFirstResponderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
423 {
424     // Has mac implementation
425     if (argumentCount < 1)
426         return JSValueMakeUndefined(context);
427
428     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
429     controller->setMainFrameIsFirstResponder(JSValueToBoolean(context, arguments[0]));
430
431     return JSValueMakeUndefined(context);
432 }
433
434 static JSValueRef setPrivateBrowsingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
435 {
436     // Has mac & windows implementation
437     if (argumentCount < 1)
438         return JSValueMakeUndefined(context);
439
440     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
441     controller->setPrivateBrowsingEnabled(JSValueToBoolean(context, arguments[0]));
442
443     return JSValueMakeUndefined(context);
444 }
445
446 static JSValueRef setTabKeyCyclesThroughElementsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
447 {
448     // Has mac & windows implementation
449     if (argumentCount < 1)
450         return JSValueMakeUndefined(context);
451
452     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
453     controller->setTabKeyCyclesThroughElements(JSValueToBoolean(context, arguments[0]));
454
455     return JSValueMakeUndefined(context);
456 }
457
458 static JSValueRef setUseDashboardCompatibilityModeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
459 {
460     // Has mac implementation
461     if (argumentCount < 1)
462         return JSValueMakeUndefined(context);
463
464     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
465     controller->setUseDashboardCompatibilityMode(JSValueToBoolean(context, arguments[0]));
466
467     return JSValueMakeUndefined(context);
468 }
469
470 static JSValueRef setUserStyleSheetEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
471 {
472     // Has mac implementation
473     if (argumentCount < 1)
474         return JSValueMakeUndefined(context);
475
476     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
477     controller->setUserStyleSheetEnabled(JSValueToBoolean(context, arguments[0]));
478
479     return JSValueMakeUndefined(context);
480 }
481
482 static JSValueRef setUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
483 {
484     // Has mac implementation
485     if (argumentCount < 1)
486         return JSValueMakeUndefined(context);
487
488     JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
489     ASSERT(!*exception);
490
491     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
492     controller->setUserStyleSheetLocation(path.get());
493
494     return JSValueMakeUndefined(context);
495 }
496
497 static JSValueRef setWindowIsKeyCallback(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     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
504     controller->setWindowIsKey(JSValueToBoolean(context, arguments[0]));
505
506     return JSValueMakeUndefined(context);
507 }
508
509 static JSValueRef waitUntilDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
510 {
511     // Has mac & windows implementation
512     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
513     controller->setWaitToDump(true);
514
515     return JSValueMakeUndefined(context);
516 }
517
518 static JSValueRef windowCountCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
519 {
520     // Has mac implementation
521     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
522     int windows = controller->windowCount();
523     return JSValueMakeNumber(context, windows);
524 }
525
526 // Static Values
527
528 static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
529 {
530     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
531     return JSValueMakeBoolean(context, controller->globalFlag());
532 }
533
534 static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
535 {
536     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
537     controller->setGlobalFlag(JSValueToBoolean(context, value));
538     return true;
539 }
540
541 // Object Creation
542
543 void LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
544 {
545     JSRetainPtr<JSStringRef> layoutTestContollerStr(Adopt, JSStringCreateWithUTF8CString("layoutTestController"));
546     JSValueRef layoutTestContollerObject = JSObjectMake(context, getJSClass(), this);
547     JSObjectSetProperty(context, windowObject, layoutTestContollerStr.get(), layoutTestContollerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
548 }
549
550 JSClassRef LayoutTestController::getJSClass()
551 {
552     static JSClassRef layoutTestControllerClass;
553
554     if (!layoutTestControllerClass) {
555         JSStaticValue* staticValues = LayoutTestController::staticValues();
556         JSStaticFunction* staticFunctions = LayoutTestController::staticFunctions();
557         JSClassDefinition classDefinition = {
558             0, kJSClassAttributeNone, "LayoutTestController", 0, staticValues, staticFunctions,
559             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
560         };
561
562         layoutTestControllerClass = JSClassCreate(&classDefinition);
563     }
564
565     return layoutTestControllerClass;
566 }
567
568 JSStaticValue* LayoutTestController::staticValues()
569 {
570     static JSStaticValue staticValues[] = {
571         { "globalFlag", getGlobalFlagCallback, setGlobalFlagCallback, kJSPropertyAttributeNone },
572         { 0, 0, 0, 0 }
573     };
574     return staticValues;
575
576 }
577
578 JSStaticFunction* LayoutTestController::staticFunctions()
579 {
580     static JSStaticFunction staticFunctions[] = {
581         { "addDisallowedURL", addDisallowedURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
582         { "addFileToPasteboardOnDrag", addFileToPasteboardOnDragCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
583         { "clearBackForwardList", clearBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
584         { "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
585         { "display", displayCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
586         { "dumpAsText", dumpAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
587         { "dumpBackForwardList", dumpBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
588         { "dumpChildFramesAsText", dumpChildFramesAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
589         { "dumpChildFrameScrollPositions", dumpChildFrameScrollPositionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
590         { "dumpDOMAsWebArchive", dumpDOMAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
591         { "dumpEditingCallbacks", dumpEditingCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
592         { "dumpFrameLoadCallbacks", dumpFrameLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
593         { "dumpResourceLoadCallbacks", dumpResourceLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
594         { "dumpSelectionRect", dumpSelectionRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
595         { "dumpSourceAsWebArchive", dumpSourceAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
596         { "dumpTitleChanges", dumpTitleChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
597         { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
598         { "execCommand", execCommandCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
599         { "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
600         { "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
601         { "pathToLocalResource", pathToLocalResourceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
602         { "queueBackNavigation", queueBackNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
603         { "queueForwardNavigation", queueForwardNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
604         { "queueLoad", queueLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
605         { "queueReload", queueReloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
606         { "queueScript", queueScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
607         { "repaintSweepHorizontally", repaintSweepHorizontallyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
608         { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
609         { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
610         { "setCallCloseOnWebViews", setCallCloseOnWebViewsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
611         { "setCanOpenWindows", setCanOpenWindowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
612         { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
613         { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
614         { "setMainFrameIsFirstResponder", setMainFrameIsFirstResponderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
615         { "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
616         { "setTabKeyCyclesThroughElements", setTabKeyCyclesThroughElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
617         { "setUseDashboardCompatibilityMode", setUseDashboardCompatibilityModeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
618         { "setUserStyleSheetEnabled", setUserStyleSheetEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
619         { "setUserStyleSheetLocation", setUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
620         { "setWindowIsKey", setWindowIsKeyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
621         { "testRepaint", testRepaintCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
622         { "waitUntilDone", waitUntilDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
623         { "windowCount", windowCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
624         { 0, 0, 0 }
625     };
626
627     return staticFunctions;
628 }
629
630