WebKitTools:
[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 = 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 keepWebHistoryCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
261 {
262     // Has mac implementation
263     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
264     controller->keepWebHistory();
265
266     return JSValueMakeUndefined(context);
267 }
268
269 static JSValueRef notifyDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
270 {
271     // Has mac & windows implementation
272     // May be able to be made platform independant by using shared WorkQueue
273     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
274     controller->notifyDone();
275
276     return JSValueMakeUndefined(context);
277 }
278
279 static JSValueRef queueBackNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
280 {
281     // Has mac & windows implementation
282     // May be able to be made platform independant by using shared WorkQueue
283     if (argumentCount < 1)
284         return JSValueMakeUndefined(context);
285
286     double howFarBackDouble = JSValueToNumber(context, arguments[0], exception);
287     ASSERT(!*exception);
288
289     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
290     controller->queueBackNavigation(static_cast<int>(howFarBackDouble));
291
292     return JSValueMakeUndefined(context);
293 }
294
295 static JSValueRef queueForwardNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
296 {
297     // Has mac & windows implementation
298     // May be able to be made platform independant by using shared WorkQueue
299     if (argumentCount < 1)
300         return JSValueMakeUndefined(context);
301
302     double howFarForwardDouble = JSValueToNumber(context, arguments[0], exception);
303     ASSERT(!*exception);
304
305     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
306     controller->queueForwardNavigation(static_cast<int>(howFarForwardDouble));
307
308     return JSValueMakeUndefined(context);
309 }
310
311 static JSValueRef queueLoadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
312 {
313     // Has mac & windows implementation
314     // May be able to be made platform independant by using shared WorkQueue
315     if (argumentCount < 1)
316         return JSValueMakeUndefined(context);
317
318     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
319     ASSERT(!*exception);
320
321     JSRetainPtr<JSStringRef> target;
322     if (argumentCount >= 2) {
323         target.adopt(JSValueToStringCopy(context, arguments[1], exception));
324         ASSERT(!*exception);
325     } else
326         target.adopt(JSStringCreateWithUTF8CString(""));
327
328     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
329     controller->queueLoad(url.get(), target.get());
330
331     return JSValueMakeUndefined(context);
332 }
333
334 static JSValueRef queueReloadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
335 {
336     // Has mac & windows implementation
337     // May be able to be made platform independant by using shared WorkQueue
338
339     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
340     controller->queueReload();
341
342     return JSValueMakeUndefined(context);
343 }
344
345 static JSValueRef queueScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
346 {
347     // Has mac & windows implementation
348     // May be able to be made platform independant by using shared WorkQueue
349     if (argumentCount < 1)
350         return JSValueMakeUndefined(context);
351
352     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
353     ASSERT(!*exception);
354
355     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
356     controller->queueScript(script.get());
357
358     return JSValueMakeUndefined(context);
359 }
360
361 static JSValueRef setAcceptsEditingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
362 {
363     // Has mac & windows implementation
364     if (argumentCount < 1)
365         return JSValueMakeUndefined(context);
366
367     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
368     controller->setAcceptsEditing(JSValueToBoolean(context, arguments[0]));
369
370     return JSValueMakeUndefined(context);
371 }
372
373 static JSValueRef setAuthorAndUserStylesEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
374 {
375     // Has mac & windows implementation
376     if (argumentCount < 1)
377         return JSValueMakeUndefined(context);
378
379     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
380     controller->setAuthorAndUserStylesEnabled(JSValueToBoolean(context, arguments[0]));
381
382     return JSValueMakeUndefined(context);
383 }
384
385 static JSValueRef setCustomPolicyDelegateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
386 {
387     // Has mac implementation
388     if (argumentCount < 1)
389         return JSValueMakeUndefined(context);
390
391     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
392     controller->setCustomPolicyDelegate(JSValueToBoolean(context, arguments[0]));
393
394     return JSValueMakeUndefined(context);
395 }
396
397 static JSValueRef setMainFrameIsFirstResponderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
398 {
399     // Has mac implementation
400     if (argumentCount < 1)
401         return JSValueMakeUndefined(context);
402
403     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
404     controller->setMainFrameIsFirstResponder(JSValueToBoolean(context, arguments[0]));
405
406     return JSValueMakeUndefined(context);
407 }
408
409 static JSValueRef setPrivateBrowsingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
410 {
411     // Has mac & windows implementation
412     if (argumentCount < 1)
413         return JSValueMakeUndefined(context);
414
415     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
416     controller->setPrivateBrowsingEnabled(JSValueToBoolean(context, arguments[0]));
417
418     return JSValueMakeUndefined(context);
419 }
420
421 static JSValueRef setTabKeyCyclesThroughElementsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
422 {
423     // Has mac & windows implementation
424     if (argumentCount < 1)
425         return JSValueMakeUndefined(context);
426
427     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
428     controller->setTabKeyCyclesThroughElements(JSValueToBoolean(context, arguments[0]));
429
430     return JSValueMakeUndefined(context);
431 }
432
433 static JSValueRef setUseDashboardCompatibilityModeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
434 {
435     // Has mac implementation
436     if (argumentCount < 1)
437         return JSValueMakeUndefined(context);
438
439     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
440     controller->setUseDashboardCompatibilityMode(JSValueToBoolean(context, arguments[0]));
441
442     return JSValueMakeUndefined(context);
443 }
444
445 static JSValueRef setUserStyleSheetEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
446 {
447     // Has mac implementation
448     if (argumentCount < 1)
449         return JSValueMakeUndefined(context);
450
451     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
452     controller->setUserStyleSheetEnabled(JSValueToBoolean(context, arguments[0]));
453
454     return JSValueMakeUndefined(context);
455 }
456
457 static JSValueRef setUserStyleSheetLocationCallback(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     JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
464     ASSERT(!*exception);
465
466     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
467     controller->setUserStyleSheetLocation(path.get());
468
469     return JSValueMakeUndefined(context);
470 }
471
472 static JSValueRef setWindowIsKeyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
473 {
474     // Has mac implementation
475     if (argumentCount < 1)
476         return JSValueMakeUndefined(context);
477
478     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
479     controller->setWindowIsKey(JSValueToBoolean(context, arguments[0]));
480
481     return JSValueMakeUndefined(context);
482 }
483
484 static JSValueRef waitUntilDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
485 {
486     // Has mac & windows implementation
487     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
488     controller->setWaitToDump(true);
489
490     return JSValueMakeUndefined(context);
491 }
492
493 static JSValueRef windowCountCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
494 {
495     // Has mac implementation
496     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
497     int windows = controller->windowCount();
498     return JSValueMakeNumber(context, windows);
499 }
500
501 // Static Values
502
503 static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
504 {
505     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
506     return JSValueMakeBoolean(context, controller->globalFlag());
507 }
508
509 static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
510 {
511     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
512     controller->setGlobalFlag(JSValueToBoolean(context, value));
513     return true;
514 }
515
516 // Object Creation
517
518 void LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
519 {
520     JSRetainPtr<JSStringRef> layoutTestContollerStr(Adopt, JSStringCreateWithUTF8CString("layoutTestController"));
521     JSValueRef layoutTestContollerObject = JSObjectMake(context, getJSClass(), this);
522     JSObjectSetProperty(context, windowObject, layoutTestContollerStr.get(), layoutTestContollerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
523 }
524
525 JSClassRef LayoutTestController::getJSClass()
526 {
527     static JSClassRef layoutTestControllerClass;
528
529     if (!layoutTestControllerClass) {
530         JSStaticValue* staticValues = LayoutTestController::staticValues();
531         JSStaticFunction* staticFunctions = LayoutTestController::staticFunctions();
532         JSClassDefinition classDefinition = {
533             0, kJSClassAttributeNone, "LayoutTestController", 0, staticValues, staticFunctions,
534             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
535         };
536
537         layoutTestControllerClass = JSClassCreate(&classDefinition);
538     }
539
540     return layoutTestControllerClass;
541 }
542
543 JSStaticValue* LayoutTestController::staticValues()
544 {
545     static JSStaticValue staticValues[] = {
546         { "globalFlag", getGlobalFlagCallback, setGlobalFlagCallback, kJSPropertyAttributeNone },
547         { 0, 0, 0, 0 }
548     };
549     return staticValues;
550
551 }
552
553 JSStaticFunction* LayoutTestController::staticFunctions()
554 {
555     static JSStaticFunction staticFunctions[] = {
556         { "addDisallowedURL", addDisallowedURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
557         { "addFileToPasteboardOnDrag", addFileToPasteboardOnDragCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
558         { "clearBackForwardList", clearBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
559         { "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
560         { "display", displayCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
561         { "dumpAsText", dumpAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
562         { "dumpBackForwardList", dumpBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
563         { "dumpChildFramesAsText", dumpChildFramesAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
564         { "dumpChildFrameScrollPositions", dumpChildFrameScrollPositionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
565         { "dumpDOMAsWebArchive", dumpDOMAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
566         { "dumpEditingCallbacks", dumpEditingCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
567         { "dumpFrameLoadCallbacks", dumpFrameLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
568         { "dumpResourceLoadCallbacks", dumpResourceLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
569         { "dumpSelectionRect", dumpSelectionRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
570         { "dumpSourceAsWebArchive", dumpSourceAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
571         { "dumpTitleChanges", dumpTitleChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
572         { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
573         { "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
574         { "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
575         { "pathToLocalResource", pathToLocalResourceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
576         { "queueBackNavigation", queueBackNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
577         { "queueForwardNavigation", queueForwardNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
578         { "queueLoad", queueLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
579         { "queueReload", queueReloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
580         { "queueScript", queueScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
581         { "repaintSweepHorizontally", repaintSweepHorizontallyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
582         { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
583         { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
584         { "setCallCloseOnWebViews", setCallCloseOnWebViewsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
585         { "setCanOpenWindows", setCanOpenWindowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
586         { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
587         { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
588         { "setMainFrameIsFirstResponder", setMainFrameIsFirstResponderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
589         { "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
590         { "setTabKeyCyclesThroughElements", setTabKeyCyclesThroughElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
591         { "setUseDashboardCompatibilityMode", setUseDashboardCompatibilityModeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
592         { "setUserStyleSheetEnabled", setUserStyleSheetEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
593         { "setUserStyleSheetLocation", setUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
594         { "setWindowIsKey", setWindowIsKeyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
595         { "testRepaint", testRepaintCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
596         { "waitUntilDone", waitUntilDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
597         { "windowCount", windowCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
598         { 0, 0, 0 }
599     };
600
601     return staticFunctions;
602 }
603
604