9271cba912429b009188c299be0a36cb06884370
[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 repaintSweepHorizontallyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
140 {
141     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
142     controller->setTestRepaintSweepHorizontally(true);
143     return JSValueMakeUndefined(context);
144 }
145
146 static JSValueRef setCallCloseOnWebViewsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
147 {
148     if (argumentCount < 1)
149         return JSValueMakeUndefined(context);
150
151     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
152     controller->setCallCloseOnWebViews(JSValueToBoolean(context, arguments[0]));
153     return JSValueMakeUndefined(context);
154 }
155
156 static JSValueRef setCanOpenWindowsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
157 {
158     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
159     controller->setCanOpenWindows(true);
160     return JSValueMakeUndefined(context);
161 }
162
163 static JSValueRef setCloseRemainingWindowsWhenCompleteCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
164 {
165     if (argumentCount < 1)
166         return JSValueMakeUndefined(context);
167
168     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
169     controller->setCloseRemainingWindowsWhenComplete(JSValueToBoolean(context, arguments[0]));
170     return JSValueMakeUndefined(context);
171 }
172
173 static JSValueRef testRepaintCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
174 {
175     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
176     controller->setTestRepaint(true);
177     return JSValueMakeUndefined(context);
178 }
179
180 static JSValueRef addFileToPasteboardOnDragCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
181 {
182     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
183     controller->setAddFileToPasteboardOnDrag(true);
184     return JSValueMakeUndefined(context);
185 }
186
187 static JSValueRef addDisallowedURLCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
188 {
189     // Has mac implementation
190     if (argumentCount < 1)
191         return JSValueMakeUndefined(context);
192
193     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
194     ASSERT(!*exception);
195
196     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
197     controller->addDisallowedURL(url.get());
198
199     return JSValueMakeUndefined(context);
200 }
201
202 static JSValueRef clearBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
203 {
204     // Has mac & windows implementation
205     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
206     controller->clearBackForwardList();
207
208     return JSValueMakeUndefined(context);
209 }
210
211 static JSValueRef decodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
212 {
213     // Has mac implementation
214     if (argumentCount < 1)
215         return JSValueMakeUndefined(context);
216
217     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
218     ASSERT(!*exception);
219
220     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
221     JSRetainPtr<JSStringRef> decodedHostName(Adopt, controller->copyDecodedHostName(name.get()));
222     return JSValueMakeString(context, decodedHostName.get());
223 }
224
225 static JSValueRef displayCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
226 {
227     // Has mac & windows implementation
228     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
229     controller->display();
230
231     return JSValueMakeUndefined(context);
232 }
233
234 static JSValueRef encodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
235 {
236     // Has mac implementation
237     if (argumentCount < 1)
238         return JSValueMakeUndefined(context);
239
240     JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
241     ASSERT(!*exception);
242
243     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
244     JSRetainPtr<JSStringRef> encodedHostName(Adopt, controller->copyEncodedHostName(name.get()));
245     return JSValueMakeString(context, encodedHostName.get());
246 }
247
248 static JSValueRef keepWebHistoryCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
249 {
250     // Has mac implementation
251     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
252     controller->keepWebHistory();
253
254     return JSValueMakeUndefined(context);
255 }
256
257 static JSValueRef notifyDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
258 {
259     // Has mac & windows implementation
260     // May be able to be made platform independant by using shared WorkQueue
261     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
262     controller->notifyDone();
263
264     return JSValueMakeUndefined(context);
265 }
266
267 static JSValueRef queueBackNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
268 {
269     // Has mac & windows implementation
270     // May be able to be made platform independant by using shared WorkQueue
271     if (argumentCount < 1)
272         return JSValueMakeUndefined(context);
273
274     double howFarBackDouble = JSValueToNumber(context, arguments[0], exception);
275     ASSERT(!*exception);
276
277     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
278     controller->queueBackNavigation(static_cast<int>(howFarBackDouble));
279
280     return JSValueMakeUndefined(context);
281 }
282
283 static JSValueRef queueForwardNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
284 {
285     // Has mac & windows implementation
286     // May be able to be made platform independant by using shared WorkQueue
287     if (argumentCount < 1)
288         return JSValueMakeUndefined(context);
289
290     double howFarForwardDouble = JSValueToNumber(context, arguments[0], exception);
291     ASSERT(!*exception);
292
293     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
294     controller->queueForwardNavigation(static_cast<int>(howFarForwardDouble));
295
296     return JSValueMakeUndefined(context);
297 }
298
299 static JSValueRef queueLoadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
300 {
301     // Has mac & windows implementation
302     // May be able to be made platform independant by using shared WorkQueue
303     if (argumentCount < 1)
304         return JSValueMakeUndefined(context);
305
306     JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
307     ASSERT(!*exception);
308
309     JSRetainPtr<JSStringRef> target;
310     if (argumentCount >= 2) {
311         target.adopt(JSValueToStringCopy(context, arguments[1], exception));
312         ASSERT(!*exception);
313     } else
314         target.adopt(JSStringCreateWithUTF8CString(""));
315
316     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
317     controller->queueLoad(url.get(), target.get());
318
319     return JSValueMakeUndefined(context);
320 }
321
322 static JSValueRef queueReloadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
323 {
324     // Has mac & windows implementation
325     // May be able to be made platform independant by using shared WorkQueue
326
327     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
328     controller->queueReload();
329
330     return JSValueMakeUndefined(context);
331 }
332
333 static JSValueRef queueScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
334 {
335     // Has mac & windows implementation
336     // May be able to be made platform independant by using shared WorkQueue
337     if (argumentCount < 1)
338         return JSValueMakeUndefined(context);
339
340     JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
341     ASSERT(!*exception);
342
343     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
344     controller->queueScript(script.get());
345
346     return JSValueMakeUndefined(context);
347 }
348
349 static JSValueRef setAcceptsEditingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
350 {
351     // Has mac & windows implementation
352     if (argumentCount < 1)
353         return JSValueMakeUndefined(context);
354
355     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
356     controller->setAcceptsEditing(JSValueToBoolean(context, arguments[0]));
357
358     return JSValueMakeUndefined(context);
359 }
360
361 static JSValueRef setAuthorAndUserStylesEnabledCallback(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->setAuthorAndUserStylesEnabled(JSValueToBoolean(context, arguments[0]));
369
370     return JSValueMakeUndefined(context);
371 }
372
373 static JSValueRef setCustomPolicyDelegateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
374 {
375     // Has mac implementation
376     if (argumentCount < 1)
377         return JSValueMakeUndefined(context);
378
379     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
380     controller->setCustomPolicyDelegate(JSValueToBoolean(context, arguments[0]));
381
382     return JSValueMakeUndefined(context);
383 }
384
385 static JSValueRef setMainFrameIsFirstResponderCallback(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->setMainFrameIsFirstResponder(JSValueToBoolean(context, arguments[0]));
393
394     return JSValueMakeUndefined(context);
395 }
396
397 static JSValueRef setPrivateBrowsingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
398 {
399     // Has mac & windows implementation
400     if (argumentCount < 1)
401         return JSValueMakeUndefined(context);
402
403     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
404     controller->setPrivateBrowsingEnabled(JSValueToBoolean(context, arguments[0]));
405
406     return JSValueMakeUndefined(context);
407 }
408
409 static JSValueRef setTabKeyCyclesThroughElementsCallback(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->setTabKeyCyclesThroughElements(JSValueToBoolean(context, arguments[0]));
417
418     return JSValueMakeUndefined(context);
419 }
420
421 static JSValueRef setUseDashboardCompatibilityModeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
422 {
423     // Has mac implementation
424     if (argumentCount < 1)
425         return JSValueMakeUndefined(context);
426
427     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
428     controller->setUseDashboardCompatibilityMode(JSValueToBoolean(context, arguments[0]));
429
430     return JSValueMakeUndefined(context);
431 }
432
433 static JSValueRef setUserStyleSheetEnabledCallback(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->setUserStyleSheetEnabled(JSValueToBoolean(context, arguments[0]));
441
442     return JSValueMakeUndefined(context);
443 }
444
445 static JSValueRef setUserStyleSheetLocationCallback(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     JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
452     ASSERT(!*exception);
453
454     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
455     controller->setUserStyleSheetLocation(path.get());
456
457     return JSValueMakeUndefined(context);
458 }
459
460 static JSValueRef setWindowIsKeyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
461 {
462     // Has mac implementation
463     if (argumentCount < 1)
464         return JSValueMakeUndefined(context);
465
466     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
467     controller->setWindowIsKey(JSValueToBoolean(context, arguments[0]));
468
469     return JSValueMakeUndefined(context);
470 }
471
472 static JSValueRef waitUntilDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
473 {
474     // Has mac & windows implementation
475     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
476     controller->setWaitToDump(true);
477
478     return JSValueMakeUndefined(context);
479 }
480
481 static JSValueRef windowCountCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
482 {
483     // Has mac implementation
484     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
485     int windows = controller->windowCount();
486     return JSValueMakeNumber(context, windows);
487 }
488
489 // Static Values
490
491 static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
492 {
493     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
494     return JSValueMakeBoolean(context, controller->globalFlag());
495 }
496
497 static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
498 {
499     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
500     controller->setGlobalFlag(JSValueToBoolean(context, value));
501     return true;
502 }
503
504 // Object Creation
505
506 void LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
507 {
508     JSRetainPtr<JSStringRef> layoutTestContollerStr(Adopt, JSStringCreateWithUTF8CString("layoutTestController"));
509     JSValueRef layoutTestContollerObject = JSObjectMake(context, getJSClass(), this);
510     JSObjectSetProperty(context, windowObject, layoutTestContollerStr.get(), layoutTestContollerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
511 }
512
513 JSClassRef LayoutTestController::getJSClass()
514 {
515     static JSClassRef layoutTestControllerClass;
516
517     if (!layoutTestControllerClass) {
518         JSStaticValue* staticValues = LayoutTestController::staticValues();
519         JSStaticFunction* staticFunctions = LayoutTestController::staticFunctions();
520         JSClassDefinition classDefinition = {
521             0, kJSClassAttributeNone, "LayoutTestController", 0, staticValues, staticFunctions,
522             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
523         };
524
525         layoutTestControllerClass = JSClassCreate(&classDefinition);
526     }
527
528     return layoutTestControllerClass;
529 }
530
531 JSStaticValue* LayoutTestController::staticValues()
532 {
533     static JSStaticValue staticValues[] = {
534         { "globalFlag", getGlobalFlagCallback, setGlobalFlagCallback, kJSPropertyAttributeNone },
535         { 0, 0, 0, 0 }
536     };
537     return staticValues;
538
539 }
540
541 JSStaticFunction* LayoutTestController::staticFunctions()
542 {
543     static JSStaticFunction staticFunctions[] = {
544         { "addDisallowedURL", addDisallowedURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
545         { "addFileToPasteboardOnDrag", addFileToPasteboardOnDragCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
546         { "clearBackForwardList", clearBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
547         { "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
548         { "display", displayCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
549         { "dumpAsText", dumpAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
550         { "dumpBackForwardList", dumpBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
551         { "dumpChildFramesAsText", dumpChildFramesAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
552         { "dumpChildFrameScrollPositions", dumpChildFrameScrollPositionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
553         { "dumpDOMAsWebArchive", dumpDOMAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
554         { "dumpEditingCallbacks", dumpEditingCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
555         { "dumpFrameLoadCallbacks", dumpFrameLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
556         { "dumpResourceLoadCallbacks", dumpResourceLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
557         { "dumpSelectionRect", dumpSelectionRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
558         { "dumpSourceAsWebArchive", dumpSourceAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
559         { "dumpTitleChanges", dumpTitleChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
560         { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
561         { "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
562         { "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
563         { "queueBackNavigation", queueBackNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
564         { "queueForwardNavigation", queueForwardNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
565         { "queueLoad", queueLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
566         { "queueReload", queueReloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
567         { "queueScript", queueScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
568         { "repaintSweepHorizontally", repaintSweepHorizontallyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
569         { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
570         { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
571         { "setCallCloseOnWebViews", setCallCloseOnWebViewsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
572         { "setCanOpenWindows", setCanOpenWindowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
573         { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
574         { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
575         { "setMainFrameIsFirstResponder", setMainFrameIsFirstResponderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
576         { "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
577         { "setTabKeyCyclesThroughElements", setTabKeyCyclesThroughElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
578         { "setUseDashboardCompatibilityMode", setUseDashboardCompatibilityModeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
579         { "setUserStyleSheetEnabled", setUserStyleSheetEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
580         { "setUserStyleSheetLocation", setUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
581         { "setWindowIsKey", setWindowIsKeyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
582         { "testRepaint", testRepaintCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
583         { "waitUntilDone", waitUntilDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
584         { "windowCount", windowCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
585         { 0, 0, 0 }
586     };
587
588     return staticFunctions;
589 }
590
591