1 /*
2 * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "config.h"
30 #include "LayoutTestController.h"
31
32 #include "WorkQueue.h"
33 #include "WorkQueueItem.h"
34 #include <JavaScriptCore/JSObjectRef.h>
35 #include <JavaScriptCore/JSRetainPtr.h>
36 #include <wtf/Assertions.h>
37 #include <wtf/MathExtras.h>
38
LayoutTestController(const std::string & testPathOrURL,const std::string & expectedPixelHash)39 LayoutTestController::LayoutTestController(const std::string& testPathOrURL, const std::string& expectedPixelHash)
40 : m_dumpAsText(false)
41 , m_dumpAsPDF(false)
42 , m_dumpBackForwardList(false)
43 , m_dumpChildFrameScrollPositions(false)
44 , m_dumpChildFramesAsText(false)
45 , m_dumpDatabaseCallbacks(false)
46 , m_dumpDOMAsWebArchive(false)
47 , m_dumpSelectionRect(false)
48 , m_dumpSourceAsWebArchive(false)
49 , m_dumpStatusCallbacks(false)
50 , m_dumpTitleChanges(false)
51 , m_dumpEditingCallbacks(false)
52 , m_dumpResourceLoadCallbacks(false)
53 , m_dumpResourceResponseMIMETypes(false)
54 , m_dumpWillCacheResponse(false)
55 , m_dumpFrameLoadCallbacks(false)
56 , m_callCloseOnWebViews(true)
57 , m_canOpenWindows(false)
58 , m_closeRemainingWindowsWhenComplete(true)
59 , m_stopProvisionalFrameLoads(false)
60 , m_testOnscreen(false)
61 , m_testRepaint(false)
62 , m_testRepaintSweepHorizontally(false)
63 , m_waitToDump(false)
64 , m_willSendRequestReturnsNullOnRedirect(false)
65 , m_windowIsKey(true)
66 , m_globalFlag(false)
67 , m_testPathOrURL(testPathOrURL)
68 , m_expectedPixelHash(expectedPixelHash)
69 {
70 }
71
72 // Static Functions
73
dumpAsTextCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)74 static JSValueRef dumpAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
75 {
76 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
77 controller->setDumpAsText(true);
78 return JSValueMakeUndefined(context);
79 }
80
dumpAsPDFCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)81 static JSValueRef dumpAsPDFCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
82 {
83 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
84 controller->setDumpAsPDF(true);
85 return JSValueMakeUndefined(context);
86 }
87
dumpBackForwardListCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)88 static JSValueRef dumpBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
89 {
90 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
91 controller->setDumpBackForwardList(true);
92 return JSValueMakeUndefined(context);
93 }
94
dumpChildFramesAsTextCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)95 static JSValueRef dumpChildFramesAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
96 {
97 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
98 controller->setDumpChildFramesAsText(true);
99 return JSValueMakeUndefined(context);
100 }
101
dumpChildFrameScrollPositionsCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)102 static JSValueRef dumpChildFrameScrollPositionsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
103 {
104 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
105 controller->setDumpChildFrameScrollPositions(true);
106 return JSValueMakeUndefined(context);
107 }
108
dumpDatabaseCallbacksCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)109 static JSValueRef dumpDatabaseCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
110 {
111 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
112 controller->setDumpDatabaseCallbacks(true);
113 return JSValueMakeUndefined(context);
114 }
115
dumpDOMAsWebArchiveCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)116 static JSValueRef dumpDOMAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
117 {
118 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
119 controller->setDumpDOMAsWebArchive(true);
120 return JSValueMakeUndefined(context);
121 }
122
dumpEditingCallbacksCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)123 static JSValueRef dumpEditingCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
124 {
125 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
126 controller->setDumpEditingCallbacks(true);
127 return JSValueMakeUndefined(context);
128 }
129
dumpResourceLoadCallbacksCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)130 static JSValueRef dumpResourceLoadCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
131 {
132 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
133 controller->setDumpResourceLoadCallbacks(true);
134 return JSValueMakeUndefined(context);
135 }
136
dumpResourceResponseMIMETypesCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)137 static JSValueRef dumpResourceResponseMIMETypesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
138 {
139 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
140 controller->setDumpResourceResponseMIMETypes(true);
141 return JSValueMakeUndefined(context);
142 }
143
dumpSelectionRectCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)144 static JSValueRef dumpSelectionRectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
145 {
146 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
147 controller->setDumpSelectionRect(true);
148 return JSValueMakeUndefined(context);
149 }
150
dumpSourceAsWebArchiveCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)151 static JSValueRef dumpSourceAsWebArchiveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
152 {
153 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
154 controller->setDumpSourceAsWebArchive(true);
155 return JSValueMakeUndefined(context);
156 }
157
dumpStatusCallbacksCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)158 static JSValueRef dumpStatusCallbacksCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
159 {
160 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
161 controller->setDumpStatusCallbacks(true);
162 return JSValueMakeUndefined(context);
163 }
164
dumpTitleChangesCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)165 static JSValueRef dumpTitleChangesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
166 {
167 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
168 controller->setDumpTitleChanges(true);
169 return JSValueMakeUndefined(context);
170 }
171
dumpWillCacheResponseCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)172 static JSValueRef dumpWillCacheResponseCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
173 {
174 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
175 controller->setDumpWillCacheResponse(true);
176 return JSValueMakeUndefined(context);
177 }
178
pathToLocalResourceCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)179 static JSValueRef pathToLocalResourceCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
180 {
181 if (argumentCount < 1)
182 return JSValueMakeUndefined(context);
183
184 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
185 JSRetainPtr<JSStringRef> localPath(Adopt, JSValueToStringCopy(context, arguments[0], exception));
186 ASSERT(!*exception);
187
188 JSRetainPtr<JSStringRef> convertedPath(Adopt, controller->pathToLocalResource(context, localPath.get()));
189 if (!convertedPath)
190 return JSValueMakeUndefined(context);
191
192 return JSValueMakeString(context, convertedPath.get());
193 }
194
repaintSweepHorizontallyCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)195 static JSValueRef repaintSweepHorizontallyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
196 {
197 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
198 controller->setTestRepaintSweepHorizontally(true);
199 return JSValueMakeUndefined(context);
200 }
201
setCallCloseOnWebViewsCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)202 static JSValueRef setCallCloseOnWebViewsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
203 {
204 if (argumentCount < 1)
205 return JSValueMakeUndefined(context);
206
207 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
208 controller->setCallCloseOnWebViews(JSValueToBoolean(context, arguments[0]));
209 return JSValueMakeUndefined(context);
210 }
211
setCanOpenWindowsCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)212 static JSValueRef setCanOpenWindowsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
213 {
214 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
215 controller->setCanOpenWindows(true);
216 return JSValueMakeUndefined(context);
217 }
218
setCloseRemainingWindowsWhenCompleteCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)219 static JSValueRef setCloseRemainingWindowsWhenCompleteCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
220 {
221 if (argumentCount < 1)
222 return JSValueMakeUndefined(context);
223
224 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
225 controller->setCloseRemainingWindowsWhenComplete(JSValueToBoolean(context, arguments[0]));
226 return JSValueMakeUndefined(context);
227 }
228
testOnscreenCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)229 static JSValueRef testOnscreenCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
230 {
231 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
232 controller->setTestOnscreen(true);
233 return JSValueMakeUndefined(context);
234 }
235
testRepaintCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)236 static JSValueRef testRepaintCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
237 {
238 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
239 controller->setTestRepaint(true);
240 return JSValueMakeUndefined(context);
241 }
242
addDisallowedURLCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)243 static JSValueRef addDisallowedURLCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
244 {
245 // Has mac implementation
246 if (argumentCount < 1)
247 return JSValueMakeUndefined(context);
248
249 JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
250 ASSERT(!*exception);
251
252 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
253 controller->addDisallowedURL(url.get());
254
255 return JSValueMakeUndefined(context);
256 }
257
clearAllDatabasesCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)258 static JSValueRef clearAllDatabasesCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
259 {
260 // Has mac & windows implementation
261 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
262 controller->clearAllDatabases();
263
264 return JSValueMakeUndefined(context);
265 }
266
clearBackForwardListCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)267 static JSValueRef clearBackForwardListCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
268 {
269 // Has mac & windows implementation
270 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
271 controller->clearBackForwardList();
272
273 return JSValueMakeUndefined(context);
274 }
275
clearPersistentUserStyleSheetCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)276 static JSValueRef clearPersistentUserStyleSheetCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
277 {
278 // Has mac & windows implementation
279 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
280 controller->clearPersistentUserStyleSheet();
281
282 return JSValueMakeUndefined(context);
283 }
284
decodeHostNameCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)285 static JSValueRef decodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
286 {
287 // Has mac implementation
288 if (argumentCount < 1)
289 return JSValueMakeUndefined(context);
290
291 JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
292 ASSERT(!*exception);
293
294 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
295 JSRetainPtr<JSStringRef> decodedHostName(Adopt, controller->copyDecodedHostName(name.get()));
296 return JSValueMakeString(context, decodedHostName.get());
297 }
298
disableImageLoadingCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)299 static JSValueRef disableImageLoadingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
300 {
301 // Has mac implementation, needs windows implementation
302 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
303 controller->disableImageLoading();
304
305 return JSValueMakeUndefined(context);
306 }
307
dispatchPendingLoadRequestsCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)308 static JSValueRef dispatchPendingLoadRequestsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
309 {
310 // Has mac implementation, needs windows implementation
311 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
312 controller->dispatchPendingLoadRequests();
313
314 return JSValueMakeUndefined(context);
315 }
316
displayCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)317 static JSValueRef displayCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
318 {
319 // Has mac & windows implementation
320 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
321 controller->display();
322
323 return JSValueMakeUndefined(context);
324 }
325
encodeHostNameCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)326 static JSValueRef encodeHostNameCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
327 {
328 // Has mac implementation
329 if (argumentCount < 1)
330 return JSValueMakeUndefined(context);
331
332 JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
333 ASSERT(!*exception);
334
335 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
336 JSRetainPtr<JSStringRef> encodedHostName(Adopt, controller->copyEncodedHostName(name.get()));
337 return JSValueMakeString(context, encodedHostName.get());
338 }
339
execCommandCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)340 static JSValueRef execCommandCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
341 {
342 // Has Mac & Windows implementations.
343 if (argumentCount < 1)
344 return JSValueMakeUndefined(context);
345
346 JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
347 ASSERT(!*exception);
348
349 // Ignoring the second parameter (userInterface), as this command emulates a manual action.
350
351 JSRetainPtr<JSStringRef> value;
352 if (argumentCount >= 3) {
353 value.adopt(JSValueToStringCopy(context, arguments[2], exception));
354 ASSERT(!*exception);
355 } else
356 value.adopt(JSStringCreateWithUTF8CString(""));
357
358
359 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
360 controller->execCommand(name.get(), value.get());
361
362 return JSValueMakeUndefined(context);
363 }
364
isCommandEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)365 static JSValueRef isCommandEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
366 {
367 // Has Mac implementation.
368
369 if (argumentCount < 1)
370 return JSValueMakeUndefined(context);
371
372 JSRetainPtr<JSStringRef> name(Adopt, JSValueToStringCopy(context, arguments[0], exception));
373 ASSERT(!*exception);
374
375 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
376
377 return JSValueMakeBoolean(context, controller->isCommandEnabled(name.get()));
378 }
379
keepWebHistoryCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)380 static JSValueRef keepWebHistoryCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
381 {
382 // Has mac implementation
383 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
384 controller->keepWebHistory();
385
386 return JSValueMakeUndefined(context);
387 }
388
notifyDoneCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)389 static JSValueRef notifyDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
390 {
391 // Has mac & windows implementation
392 // May be able to be made platform independant by using shared WorkQueue
393 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
394 controller->notifyDone();
395 return JSValueMakeUndefined(context);
396 }
397
queueBackNavigationCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)398 static JSValueRef queueBackNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
399 {
400 // Has mac & windows implementation
401 // May be able to be made platform independant by using shared WorkQueue
402 if (argumentCount < 1)
403 return JSValueMakeUndefined(context);
404
405 double howFarBackDouble = JSValueToNumber(context, arguments[0], exception);
406 ASSERT(!*exception);
407
408 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
409 controller->queueBackNavigation(static_cast<int>(howFarBackDouble));
410
411 return JSValueMakeUndefined(context);
412 }
413
queueForwardNavigationCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)414 static JSValueRef queueForwardNavigationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
415 {
416 // Has mac & windows implementation
417 // May be able to be made platform independant by using shared WorkQueue
418 if (argumentCount < 1)
419 return JSValueMakeUndefined(context);
420
421 double howFarForwardDouble = JSValueToNumber(context, arguments[0], exception);
422 ASSERT(!*exception);
423
424 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
425 controller->queueForwardNavigation(static_cast<int>(howFarForwardDouble));
426
427 return JSValueMakeUndefined(context);
428 }
429
queueLoadCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)430 static JSValueRef queueLoadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
431 {
432 // Has mac & windows implementation
433 // May be able to be made platform independant by using shared WorkQueue
434 if (argumentCount < 1)
435 return JSValueMakeUndefined(context);
436
437 JSRetainPtr<JSStringRef> url(Adopt, JSValueToStringCopy(context, arguments[0], exception));
438 ASSERT(!*exception);
439
440 JSRetainPtr<JSStringRef> target;
441 if (argumentCount >= 2) {
442 target.adopt(JSValueToStringCopy(context, arguments[1], exception));
443 ASSERT(!*exception);
444 } else
445 target.adopt(JSStringCreateWithUTF8CString(""));
446
447 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
448 controller->queueLoad(url.get(), target.get());
449
450 return JSValueMakeUndefined(context);
451 }
452
queueReloadCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)453 static JSValueRef queueReloadCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
454 {
455 // Has mac & windows implementation
456 // May be able to be made platform independant by using shared WorkQueue
457
458 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
459 controller->queueReload();
460
461 return JSValueMakeUndefined(context);
462 }
463
queueLoadingScriptCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)464 static JSValueRef queueLoadingScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
465 {
466 // Has mac & windows implementation
467 // May be able to be made platform independant by using shared WorkQueue
468 if (argumentCount < 1)
469 return JSValueMakeUndefined(context);
470
471 JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
472 ASSERT(!*exception);
473
474 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
475 controller->queueLoadingScript(script.get());
476
477 return JSValueMakeUndefined(context);
478 }
479
queueNonLoadingScriptCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)480 static JSValueRef queueNonLoadingScriptCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
481 {
482 // Has mac & windows implementation
483 // May be able to be made platform independant by using shared WorkQueue
484 if (argumentCount < 1)
485 return JSValueMakeUndefined(context);
486
487 JSRetainPtr<JSStringRef> script(Adopt, JSValueToStringCopy(context, arguments[0], exception));
488 ASSERT(!*exception);
489
490 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
491 controller->queueNonLoadingScript(script.get());
492
493 return JSValueMakeUndefined(context);
494 }
495
setAcceptsEditingCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)496 static JSValueRef setAcceptsEditingCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
497 {
498 // Has mac & windows implementation
499 if (argumentCount < 1)
500 return JSValueMakeUndefined(context);
501
502 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
503 controller->setAcceptsEditing(JSValueToBoolean(context, arguments[0]));
504
505 return JSValueMakeUndefined(context);
506 }
507
setAppCacheMaximumSizeCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)508 static JSValueRef setAppCacheMaximumSizeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
509 {
510 // Has mac implementation
511 if (argumentCount < 1)
512 return JSValueMakeUndefined(context);
513
514 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
515
516 double size = JSValueToNumber(context, arguments[0], NULL);
517 if (!isnan(size))
518 controller->setAppCacheMaximumSize(static_cast<unsigned long long>(size));
519
520 return JSValueMakeUndefined(context);
521
522 }
523
setAuthorAndUserStylesEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)524 static JSValueRef setAuthorAndUserStylesEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
525 {
526 // Has mac & windows implementation
527 if (argumentCount < 1)
528 return JSValueMakeUndefined(context);
529
530 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
531 controller->setAuthorAndUserStylesEnabled(JSValueToBoolean(context, arguments[0]));
532
533 return JSValueMakeUndefined(context);
534 }
535
setCacheModelCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)536 static JSValueRef setCacheModelCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
537 {
538 // Has Mac implementation.
539 if (argumentCount < 1)
540 return JSValueMakeUndefined(context);
541
542 int cacheModel = JSValueToNumber(context, arguments[0], exception);
543 ASSERT(!*exception);
544
545 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
546 controller->setCacheModel(cacheModel);
547
548 return JSValueMakeUndefined(context);
549 }
550
setCustomPolicyDelegateCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)551 static JSValueRef setCustomPolicyDelegateCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
552 {
553 // Has mac implementation
554 if (argumentCount < 1)
555 return JSValueMakeUndefined(context);
556
557 bool permissive = false;
558 if (argumentCount >= 2)
559 permissive = JSValueToBoolean(context, arguments[1]);
560
561 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
562 controller->setCustomPolicyDelegate(JSValueToBoolean(context, arguments[0]), permissive);
563
564 return JSValueMakeUndefined(context);
565 }
566
setDatabaseQuotaCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)567 static JSValueRef setDatabaseQuotaCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
568 {
569 // Has mac implementation
570 if (argumentCount < 1)
571 return JSValueMakeUndefined(context);
572
573 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
574
575 double quota = JSValueToNumber(context, arguments[0], NULL);
576 if (!isnan(quota))
577 controller->setDatabaseQuota(static_cast<unsigned long long>(quota));
578
579 return JSValueMakeUndefined(context);
580
581 }
582
setIconDatabaseEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)583 static JSValueRef setIconDatabaseEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
584 {
585 // Has mac & windows implementation
586 if (argumentCount < 1)
587 return JSValueMakeUndefined(context);
588
589 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
590 controller->setIconDatabaseEnabled(JSValueToBoolean(context, arguments[0]));
591
592 return JSValueMakeUndefined(context);
593 }
594
setJavaScriptProfilingEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)595 static JSValueRef setJavaScriptProfilingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
596 {
597 if (argumentCount < 1)
598 return JSValueMakeUndefined(context);
599
600 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
601 controller->setJavaScriptProfilingEnabled(JSValueToBoolean(context, arguments[0]));
602
603 return JSValueMakeUndefined(context);
604 }
605
setMainFrameIsFirstResponderCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)606 static JSValueRef setMainFrameIsFirstResponderCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
607 {
608 // Has mac implementation
609 if (argumentCount < 1)
610 return JSValueMakeUndefined(context);
611
612 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
613 controller->setMainFrameIsFirstResponder(JSValueToBoolean(context, arguments[0]));
614
615 return JSValueMakeUndefined(context);
616 }
617
setPersistentUserStyleSheetLocationCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)618 static JSValueRef setPersistentUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
619 {
620 // Has mac implementation
621 if (argumentCount < 1)
622 return JSValueMakeUndefined(context);
623
624 JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
625 ASSERT(!*exception);
626
627 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
628 controller->setPersistentUserStyleSheetLocation(path.get());
629
630 return JSValueMakeUndefined(context);
631 }
632
setPrivateBrowsingEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)633 static JSValueRef setPrivateBrowsingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
634 {
635 // Has mac & windows implementation
636 if (argumentCount < 1)
637 return JSValueMakeUndefined(context);
638
639 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
640 controller->setPrivateBrowsingEnabled(JSValueToBoolean(context, arguments[0]));
641
642 return JSValueMakeUndefined(context);
643 }
644
setXSSAuditorEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)645 static JSValueRef setXSSAuditorEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
646 {
647 // Has mac & windows implementation
648 if (argumentCount < 1)
649 return JSValueMakeUndefined(context);
650
651 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
652 controller->setXSSAuditorEnabled(JSValueToBoolean(context, arguments[0]));
653
654 return JSValueMakeUndefined(context);
655 }
656
setTabKeyCyclesThroughElementsCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)657 static JSValueRef setTabKeyCyclesThroughElementsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
658 {
659 // Has mac & windows implementation
660 if (argumentCount < 1)
661 return JSValueMakeUndefined(context);
662
663 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
664 controller->setTabKeyCyclesThroughElements(JSValueToBoolean(context, arguments[0]));
665
666 return JSValueMakeUndefined(context);
667 }
668
setUseDashboardCompatibilityModeCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)669 static JSValueRef setUseDashboardCompatibilityModeCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
670 {
671 // Has mac implementation
672 if (argumentCount < 1)
673 return JSValueMakeUndefined(context);
674
675 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
676 controller->setUseDashboardCompatibilityMode(JSValueToBoolean(context, arguments[0]));
677
678 return JSValueMakeUndefined(context);
679 }
680
setUserStyleSheetEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)681 static JSValueRef setUserStyleSheetEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
682 {
683 // Has mac implementation
684 if (argumentCount < 1)
685 return JSValueMakeUndefined(context);
686
687 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
688 controller->setUserStyleSheetEnabled(JSValueToBoolean(context, arguments[0]));
689
690 return JSValueMakeUndefined(context);
691 }
692
setUserStyleSheetLocationCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)693 static JSValueRef setUserStyleSheetLocationCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
694 {
695 // Has mac implementation
696 if (argumentCount < 1)
697 return JSValueMakeUndefined(context);
698
699 JSRetainPtr<JSStringRef> path(Adopt, JSValueToStringCopy(context, arguments[0], exception));
700 ASSERT(!*exception);
701
702 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
703 controller->setUserStyleSheetLocation(path.get());
704
705 return JSValueMakeUndefined(context);
706 }
707
setWillSendRequestReturnsNullOnRedirectCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)708 static JSValueRef setWillSendRequestReturnsNullOnRedirectCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
709 {
710 // Has cross-platform implementation
711 if (argumentCount < 1)
712 return JSValueMakeUndefined(context);
713
714 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
715 controller->setWillSendRequestReturnsNullOnRedirect(JSValueToBoolean(context, arguments[0]));
716
717 return JSValueMakeUndefined(context);
718 }
719
setWindowIsKeyCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)720 static JSValueRef setWindowIsKeyCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
721 {
722 // Has mac implementation
723 if (argumentCount < 1)
724 return JSValueMakeUndefined(context);
725
726 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
727 controller->setWindowIsKey(JSValueToBoolean(context, arguments[0]));
728
729 return JSValueMakeUndefined(context);
730 }
731
waitUntilDoneCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)732 static JSValueRef waitUntilDoneCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
733 {
734 // Has mac & windows implementation
735 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
736 controller->setWaitToDump(true);
737
738 return JSValueMakeUndefined(context);
739 }
740
windowCountCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)741 static JSValueRef windowCountCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
742 {
743 // Has mac implementation
744 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
745 int windows = controller->windowCount();
746 return JSValueMakeNumber(context, windows);
747 }
748
setPopupBlockingEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)749 static JSValueRef setPopupBlockingEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
750 {
751 // Has mac & windows implementation
752 if (argumentCount < 1)
753 return JSValueMakeUndefined(context);
754
755 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
756 controller->setPopupBlockingEnabled(JSValueToBoolean(context, arguments[0]));
757
758 return JSValueMakeUndefined(context);
759 }
760
setSmartInsertDeleteEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)761 static JSValueRef setSmartInsertDeleteEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
762 {
763 if (argumentCount < 1)
764 return JSValueMakeUndefined(context);
765
766 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
767 controller->setSmartInsertDeleteEnabled(JSValueToBoolean(context, arguments[0]));
768 return JSValueMakeUndefined(context);
769 }
770
setSelectTrailingWhitespaceEnabledCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)771 static JSValueRef setSelectTrailingWhitespaceEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
772 {
773 if (argumentCount < 1)
774 return JSValueMakeUndefined(context);
775
776 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
777 controller->setSelectTrailingWhitespaceEnabled(JSValueToBoolean(context, arguments[0]));
778 return JSValueMakeUndefined(context);
779 }
780
setStopProvisionalFrameLoadsCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)781 static JSValueRef setStopProvisionalFrameLoadsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
782 {
783 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
784 controller->setStopProvisionalFrameLoads(true);
785 return JSValueMakeUndefined(context);
786 }
787
elementDoesAutoCompleteForElementWithIdCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)788 static JSValueRef elementDoesAutoCompleteForElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
789 {
790 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
791 JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[0], exception));
792 ASSERT(!*exception);
793
794 bool autoCompletes = controller->elementDoesAutoCompleteForElementWithId(elementId.get());
795
796 return JSValueMakeBoolean(context, autoCompletes);
797 }
798
pauseAnimationAtTimeOnElementWithIdCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)799 static JSValueRef pauseAnimationAtTimeOnElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
800 {
801 if (argumentCount != 3)
802 return JSValueMakeUndefined(context);
803
804 JSRetainPtr<JSStringRef> animationName(Adopt, JSValueToStringCopy(context, arguments[0], exception));
805 ASSERT(!*exception);
806 double time = JSValueToNumber(context, arguments[1], exception);
807 ASSERT(!*exception);
808 JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
809 ASSERT(!*exception);
810
811 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
812 return JSValueMakeBoolean(context, controller->pauseAnimationAtTimeOnElementWithId(animationName.get(), time, elementId.get()));
813 }
814
pauseTransitionAtTimeOnElementWithIdCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)815 static JSValueRef pauseTransitionAtTimeOnElementWithIdCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
816 {
817 if (argumentCount != 3)
818 return JSValueMakeUndefined(context);
819
820 JSRetainPtr<JSStringRef> propertyName(Adopt, JSValueToStringCopy(context, arguments[0], exception));
821 ASSERT(!*exception);
822 double time = JSValueToNumber(context, arguments[1], exception);
823 ASSERT(!*exception);
824 JSRetainPtr<JSStringRef> elementId(Adopt, JSValueToStringCopy(context, arguments[2], exception));
825 ASSERT(!*exception);
826
827 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
828 return JSValueMakeBoolean(context, controller->pauseTransitionAtTimeOnElementWithId(propertyName.get(), time, elementId.get()));
829 }
830
numberOfActiveAnimationsCallback(JSContextRef context,JSObjectRef function,JSObjectRef thisObject,size_t argumentCount,const JSValueRef arguments[],JSValueRef * exception)831 static JSValueRef numberOfActiveAnimationsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
832 {
833 if (argumentCount != 0)
834 return JSValueMakeUndefined(context);
835
836 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
837 return JSValueMakeNumber(context, controller->numberOfActiveAnimations());
838 }
839
waitForPolicyDelegateCallback(JSContextRef context,JSObjectRef,JSObjectRef thisObject,size_t,const JSValueRef[],JSValueRef *)840 static JSValueRef waitForPolicyDelegateCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t, const JSValueRef[], JSValueRef*)
841 {
842 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
843 controller->waitForPolicyDelegate();
844 return JSValueMakeUndefined(context);
845 }
846
847 // Static Values
848
getGlobalFlagCallback(JSContextRef context,JSObjectRef thisObject,JSStringRef propertyName,JSValueRef * exception)849 static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
850 {
851 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
852 return JSValueMakeBoolean(context, controller->globalFlag());
853 }
854
getWebHistoryItemCountCallback(JSContextRef context,JSObjectRef thisObject,JSStringRef propertyName,JSValueRef * exception)855 static JSValueRef getWebHistoryItemCountCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
856 {
857 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
858 return JSValueMakeNumber(context, controller->webHistoryItemCount());
859 }
860
setGlobalFlagCallback(JSContextRef context,JSObjectRef thisObject,JSStringRef propertyName,JSValueRef value,JSValueRef * exception)861 static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
862 {
863 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
864 controller->setGlobalFlag(JSValueToBoolean(context, value));
865 return true;
866 }
867
layoutTestControllerObjectFinalize(JSObjectRef object)868 static void layoutTestControllerObjectFinalize(JSObjectRef object)
869 {
870 LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(object));
871 controller->deref();
872 }
873
874 // Object Creation
875
makeWindowObject(JSContextRef context,JSObjectRef windowObject,JSValueRef * exception)876 void LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
877 {
878 JSRetainPtr<JSStringRef> layoutTestContollerStr(Adopt, JSStringCreateWithUTF8CString("layoutTestController"));
879 ref();
880 JSValueRef layoutTestContollerObject = JSObjectMake(context, getJSClass(), this);
881 JSObjectSetProperty(context, windowObject, layoutTestContollerStr.get(), layoutTestContollerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
882 }
883
getJSClass()884 JSClassRef LayoutTestController::getJSClass()
885 {
886 static JSClassRef layoutTestControllerClass;
887
888 if (!layoutTestControllerClass) {
889 JSStaticValue* staticValues = LayoutTestController::staticValues();
890 JSStaticFunction* staticFunctions = LayoutTestController::staticFunctions();
891 JSClassDefinition classDefinition = {
892 0, kJSClassAttributeNone, "LayoutTestController", 0, staticValues, staticFunctions,
893 0, layoutTestControllerObjectFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
894 };
895
896 layoutTestControllerClass = JSClassCreate(&classDefinition);
897 }
898
899 return layoutTestControllerClass;
900 }
901
staticValues()902 JSStaticValue* LayoutTestController::staticValues()
903 {
904 static JSStaticValue staticValues[] = {
905 { "globalFlag", getGlobalFlagCallback, setGlobalFlagCallback, kJSPropertyAttributeNone },
906 { "webHistoryItemCount", getWebHistoryItemCountCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
907 { 0, 0, 0, 0 }
908 };
909 return staticValues;
910 }
911
staticFunctions()912 JSStaticFunction* LayoutTestController::staticFunctions()
913 {
914 static JSStaticFunction staticFunctions[] = {
915 { "addDisallowedURL", addDisallowedURLCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
916 { "clearAllDatabases", clearAllDatabasesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
917 { "clearBackForwardList", clearBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
918 { "clearPersistentUserStyleSheet", clearPersistentUserStyleSheetCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
919 { "decodeHostName", decodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
920 { "disableImageLoading", disableImageLoadingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
921 { "dispatchPendingLoadRequests", dispatchPendingLoadRequestsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
922 { "display", displayCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
923 { "dumpAsText", dumpAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
924 { "dumpBackForwardList", dumpBackForwardListCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
925 { "dumpChildFrameScrollPositions", dumpChildFrameScrollPositionsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
926 { "dumpChildFramesAsText", dumpChildFramesAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
927 { "dumpDOMAsWebArchive", dumpDOMAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
928 { "dumpDatabaseCallbacks", dumpDatabaseCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
929 { "dumpEditingCallbacks", dumpEditingCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
930 { "dumpResourceLoadCallbacks", dumpResourceLoadCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
931 { "dumpResourceResponseMIMETypes", dumpResourceResponseMIMETypesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
932 { "dumpSelectionRect", dumpSelectionRectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
933 { "dumpSourceAsWebArchive", dumpSourceAsWebArchiveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
934 { "dumpStatusCallbacks", dumpStatusCallbacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
935 { "dumpTitleChanges", dumpTitleChangesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
936 { "dumpWillCacheResponse", dumpWillCacheResponseCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
937 { "elementDoesAutoCompleteForElementWithId", elementDoesAutoCompleteForElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
938 { "encodeHostName", encodeHostNameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
939 { "execCommand", execCommandCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
940 { "isCommandEnabled", isCommandEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
941 { "keepWebHistory", keepWebHistoryCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
942 { "notifyDone", notifyDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
943 { "numberOfActiveAnimations", numberOfActiveAnimationsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
944 { "pathToLocalResource", pathToLocalResourceCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
945 { "pauseAnimationAtTimeOnElementWithId", pauseAnimationAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
946 { "pauseTransitionAtTimeOnElementWithId", pauseTransitionAtTimeOnElementWithIdCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
947 { "printToPDF", dumpAsPDFCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
948 { "queueBackNavigation", queueBackNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
949 { "queueForwardNavigation", queueForwardNavigationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
950 { "queueLoad", queueLoadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
951 { "queueLoadingScript", queueLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
952 { "queueNonLoadingScript", queueNonLoadingScriptCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
953 { "queueReload", queueReloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
954 { "repaintSweepHorizontally", repaintSweepHorizontallyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
955 { "setAcceptsEditing", setAcceptsEditingCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
956 { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
957 { "setAppCacheMaximumSize", setAppCacheMaximumSizeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
958 { "setCallCloseOnWebViews", setCallCloseOnWebViewsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
959 { "setCanOpenWindows", setCanOpenWindowsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
960 { "setCacheModel", setCacheModelCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
961 { "setCloseRemainingWindowsWhenComplete", setCloseRemainingWindowsWhenCompleteCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
962 { "setCustomPolicyDelegate", setCustomPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
963 { "setDatabaseQuota", setDatabaseQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
964 { "setIconDatabaseEnabled", setIconDatabaseEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
965 { "setJavaScriptProfilingEnabled", setJavaScriptProfilingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
966 { "setMainFrameIsFirstResponder", setMainFrameIsFirstResponderCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
967 { "setPersistentUserStyleSheetLocation", setPersistentUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
968 { "setPopupBlockingEnabled", setPopupBlockingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
969 { "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
970 { "setXSSAuditorEnabled", setXSSAuditorEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
971 { "setSelectTrailingWhitespaceEnabled", setSelectTrailingWhitespaceEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
972 { "setSmartInsertDeleteEnabled", setSmartInsertDeleteEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
973 { "setStopProvisionalFrameLoads", setStopProvisionalFrameLoadsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
974 { "setTabKeyCyclesThroughElements", setTabKeyCyclesThroughElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
975 { "setUseDashboardCompatibilityMode", setUseDashboardCompatibilityModeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
976 { "setUserStyleSheetEnabled", setUserStyleSheetEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
977 { "setUserStyleSheetLocation", setUserStyleSheetLocationCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
978 { "setWillSendRequestReturnsNullOnRedirect", setWillSendRequestReturnsNullOnRedirectCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
979 { "setWindowIsKey", setWindowIsKeyCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
980 { "testOnscreen", testOnscreenCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
981 { "testRepaint", testRepaintCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
982 { "waitForPolicyDelegate", waitForPolicyDelegateCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
983 { "waitUntilDone", waitUntilDoneCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
984 { "windowCount", windowCountCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
985 { 0, 0, 0 }
986 };
987
988 return staticFunctions;
989 }
990
queueBackNavigation(int howFarBack)991 void LayoutTestController::queueBackNavigation(int howFarBack)
992 {
993 WorkQueue::shared()->queue(new BackItem(howFarBack));
994 }
995
queueForwardNavigation(int howFarForward)996 void LayoutTestController::queueForwardNavigation(int howFarForward)
997 {
998 WorkQueue::shared()->queue(new ForwardItem(howFarForward));
999 }
1000
queueLoadingScript(JSStringRef script)1001 void LayoutTestController::queueLoadingScript(JSStringRef script)
1002 {
1003 WorkQueue::shared()->queue(new LoadingScriptItem(script));
1004 }
1005
queueNonLoadingScript(JSStringRef script)1006 void LayoutTestController::queueNonLoadingScript(JSStringRef script)
1007 {
1008 WorkQueue::shared()->queue(new NonLoadingScriptItem(script));
1009 }
1010
queueReload()1011 void LayoutTestController::queueReload()
1012 {
1013 WorkQueue::shared()->queue(new ReloadItem);
1014 }
1015