1 /* |
|
2 * Copyright (C) 2010 Google Inc. All rights reserved. |
|
3 * Copyright (C) 2010 Pawel Hajdan (phajdan.jr@chromium.org) |
|
4 * |
|
5 * Redistribution and use in source and binary forms, with or without |
|
6 * modification, are permitted provided that the following conditions are |
|
7 * met: |
|
8 * |
|
9 * * Redistributions of source code must retain the above copyright |
|
10 * notice, this list of conditions and the following disclaimer. |
|
11 * * Redistributions in binary form must reproduce the above |
|
12 * copyright notice, this list of conditions and the following disclaimer |
|
13 * in the documentation and/or other materials provided with the |
|
14 * distribution. |
|
15 * * Neither the name of Google Inc. nor the names of its |
|
16 * contributors may be used to endorse or promote products derived from |
|
17 * this software without specific prior written permission. |
|
18 * |
|
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
30 */ |
|
31 |
|
32 #include "config.h" |
|
33 #include "LayoutTestController.h" |
|
34 |
|
35 #include "DRTDevToolsAgent.h" |
|
36 #include "TestShell.h" |
|
37 #include "WebViewHost.h" |
|
38 #include "base/string_util.h" |
|
39 #include "public/WebAnimationController.h" |
|
40 #include "public/WebConsoleMessage.h" |
|
41 #include "public/WebDocument.h" |
|
42 #include "public/WebFrame.h" |
|
43 #include "public/WebGeolocationServiceMock.h" |
|
44 #include "public/WebInputElement.h" |
|
45 #include "public/WebKit.h" |
|
46 #include "public/WebNotificationPresenter.h" |
|
47 #include "public/WebScriptSource.h" |
|
48 #include "public/WebSecurityPolicy.h" |
|
49 #include "public/WebSettings.h" |
|
50 #include "public/WebSize.h" |
|
51 #include "public/WebURL.h" |
|
52 #include "public/WebView.h" |
|
53 #include "webkit/support/webkit_support.h" |
|
54 #include <wtf/text/WTFString.h> |
|
55 |
|
56 #if OS(WINDOWS) |
|
57 #include <wtf/OwnArrayPtr.h> |
|
58 #endif |
|
59 |
|
60 using namespace WebCore; |
|
61 using namespace WebKit; |
|
62 using namespace std; |
|
63 |
|
64 LayoutTestController::LayoutTestController(TestShell* shell) |
|
65 : m_timeoutFactory(this) |
|
66 , m_shell(shell) |
|
67 , m_workQueue(this) |
|
68 { |
|
69 |
|
70 // Initialize the map that associates methods of this class with the names |
|
71 // they will use when called by JavaScript. The actual binding of those |
|
72 // names to their methods will be done by calling bindToJavaScript() (defined |
|
73 // by CppBoundClass, the parent to LayoutTestController). |
|
74 bindMethod("dumpAsText", &LayoutTestController::dumpAsText); |
|
75 bindMethod("dumpChildFrameScrollPositions", &LayoutTestController::dumpChildFrameScrollPositions); |
|
76 bindMethod("dumpChildFramesAsText", &LayoutTestController::dumpChildFramesAsText); |
|
77 bindMethod("dumpDatabaseCallbacks", &LayoutTestController::dumpDatabaseCallbacks); |
|
78 bindMethod("dumpEditingCallbacks", &LayoutTestController::dumpEditingCallbacks); |
|
79 bindMethod("dumpBackForwardList", &LayoutTestController::dumpBackForwardList); |
|
80 bindMethod("dumpFrameLoadCallbacks", &LayoutTestController::dumpFrameLoadCallbacks); |
|
81 bindMethod("dumpResourceLoadCallbacks", &LayoutTestController::dumpResourceLoadCallbacks); |
|
82 bindMethod("dumpStatusCallbacks", &LayoutTestController::dumpWindowStatusChanges); |
|
83 bindMethod("dumpTitleChanges", &LayoutTestController::dumpTitleChanges); |
|
84 bindMethod("setAcceptsEditing", &LayoutTestController::setAcceptsEditing); |
|
85 bindMethod("waitUntilDone", &LayoutTestController::waitUntilDone); |
|
86 bindMethod("notifyDone", &LayoutTestController::notifyDone); |
|
87 bindMethod("queueReload", &LayoutTestController::queueReload); |
|
88 bindMethod("queueLoadingScript", &LayoutTestController::queueLoadingScript); |
|
89 bindMethod("queueNonLoadingScript", &LayoutTestController::queueNonLoadingScript); |
|
90 bindMethod("queueLoad", &LayoutTestController::queueLoad); |
|
91 bindMethod("queueBackNavigation", &LayoutTestController::queueBackNavigation); |
|
92 bindMethod("queueForwardNavigation", &LayoutTestController::queueForwardNavigation); |
|
93 bindMethod("windowCount", &LayoutTestController::windowCount); |
|
94 bindMethod("setCanOpenWindows", &LayoutTestController::setCanOpenWindows); |
|
95 bindMethod("setCloseRemainingWindowsWhenComplete", &LayoutTestController::setCloseRemainingWindowsWhenComplete); |
|
96 bindMethod("objCIdentityIsEqual", &LayoutTestController::objCIdentityIsEqual); |
|
97 bindMethod("setAlwaysAcceptCookies", &LayoutTestController::setAlwaysAcceptCookies); |
|
98 bindMethod("showWebInspector", &LayoutTestController::showWebInspector); |
|
99 bindMethod("closeWebInspector", &LayoutTestController::closeWebInspector); |
|
100 bindMethod("setWindowIsKey", &LayoutTestController::setWindowIsKey); |
|
101 bindMethod("setTabKeyCyclesThroughElements", &LayoutTestController::setTabKeyCyclesThroughElements); |
|
102 bindMethod("setUserStyleSheetLocation", &LayoutTestController::setUserStyleSheetLocation); |
|
103 bindMethod("setUserStyleSheetEnabled", &LayoutTestController::setUserStyleSheetEnabled); |
|
104 bindMethod("setAuthorAndUserStylesEnabled", &LayoutTestController::setAuthorAndUserStylesEnabled); |
|
105 bindMethod("pathToLocalResource", &LayoutTestController::pathToLocalResource); |
|
106 bindMethod("addFileToPasteboardOnDrag", &LayoutTestController::addFileToPasteboardOnDrag); |
|
107 bindMethod("execCommand", &LayoutTestController::execCommand); |
|
108 bindMethod("isCommandEnabled", &LayoutTestController::isCommandEnabled); |
|
109 bindMethod("setPopupBlockingEnabled", &LayoutTestController::setPopupBlockingEnabled); |
|
110 bindMethod("setStopProvisionalFrameLoads", &LayoutTestController::setStopProvisionalFrameLoads); |
|
111 bindMethod("setSmartInsertDeleteEnabled", &LayoutTestController::setSmartInsertDeleteEnabled); |
|
112 bindMethod("setSelectTrailingWhitespaceEnabled", &LayoutTestController::setSelectTrailingWhitespaceEnabled); |
|
113 bindMethod("pauseAnimationAtTimeOnElementWithId", &LayoutTestController::pauseAnimationAtTimeOnElementWithId); |
|
114 bindMethod("pauseTransitionAtTimeOnElementWithId", &LayoutTestController::pauseTransitionAtTimeOnElementWithId); |
|
115 bindMethod("elementDoesAutoCompleteForElementWithId", &LayoutTestController::elementDoesAutoCompleteForElementWithId); |
|
116 bindMethod("numberOfActiveAnimations", &LayoutTestController::numberOfActiveAnimations); |
|
117 bindMethod("disableImageLoading", &LayoutTestController::disableImageLoading); |
|
118 bindMethod("setIconDatabaseEnabled", &LayoutTestController::setIconDatabaseEnabled); |
|
119 bindMethod("setCustomPolicyDelegate", &LayoutTestController::setCustomPolicyDelegate); |
|
120 bindMethod("setScrollbarPolicy", &LayoutTestController::setScrollbarPolicy); |
|
121 bindMethod("waitForPolicyDelegate", &LayoutTestController::waitForPolicyDelegate); |
|
122 bindMethod("setWillSendRequestClearHeader", &LayoutTestController::setWillSendRequestClearHeader); |
|
123 bindMethod("setWillSendRequestReturnsNullOnRedirect", &LayoutTestController::setWillSendRequestReturnsNullOnRedirect); |
|
124 bindMethod("setWillSendRequestReturnsNull", &LayoutTestController::setWillSendRequestReturnsNull); |
|
125 bindMethod("addOriginAccessWhitelistEntry", &LayoutTestController::addOriginAccessWhitelistEntry); |
|
126 bindMethod("removeOriginAccessWhitelistEntry", &LayoutTestController::removeOriginAccessWhitelistEntry); |
|
127 bindMethod("clearAllDatabases", &LayoutTestController::clearAllDatabases); |
|
128 bindMethod("setDatabaseQuota", &LayoutTestController::setDatabaseQuota); |
|
129 bindMethod("setPOSIXLocale", &LayoutTestController::setPOSIXLocale); |
|
130 bindMethod("counterValueForElementById", &LayoutTestController::counterValueForElementById); |
|
131 bindMethod("addUserScript", &LayoutTestController::addUserScript); |
|
132 bindMethod("addUserStyleSheet", &LayoutTestController::addUserStyleSheet); |
|
133 bindMethod("pageNumberForElementById", &LayoutTestController::pageNumberForElementById); |
|
134 bindMethod("numberOfPages", &LayoutTestController::numberOfPages); |
|
135 bindMethod("dumpSelectionRect", &LayoutTestController::dumpSelectionRect); |
|
136 bindMethod("grantDesktopNotificationPermission", &LayoutTestController::grantDesktopNotificationPermission); |
|
137 |
|
138 // The following are stubs. |
|
139 bindMethod("dumpAsWebArchive", &LayoutTestController::dumpAsWebArchive); |
|
140 bindMethod("setMainFrameIsFirstResponder", &LayoutTestController::setMainFrameIsFirstResponder); |
|
141 bindMethod("dumpSelectionRect", &LayoutTestController::dumpSelectionRect); |
|
142 bindMethod("display", &LayoutTestController::display); |
|
143 bindMethod("testRepaint", &LayoutTestController::testRepaint); |
|
144 bindMethod("repaintSweepHorizontally", &LayoutTestController::repaintSweepHorizontally); |
|
145 bindMethod("clearBackForwardList", &LayoutTestController::clearBackForwardList); |
|
146 bindMethod("keepWebHistory", &LayoutTestController::keepWebHistory); |
|
147 bindMethod("storeWebScriptObject", &LayoutTestController::storeWebScriptObject); |
|
148 bindMethod("accessStoredWebScriptObject", &LayoutTestController::accessStoredWebScriptObject); |
|
149 bindMethod("objCClassNameOf", &LayoutTestController::objCClassNameOf); |
|
150 bindMethod("addDisallowedURL", &LayoutTestController::addDisallowedURL); |
|
151 bindMethod("callShouldCloseOnWebView", &LayoutTestController::callShouldCloseOnWebView); |
|
152 bindMethod("setCallCloseOnWebViews", &LayoutTestController::setCallCloseOnWebViews); |
|
153 bindMethod("setPrivateBrowsingEnabled", &LayoutTestController::setPrivateBrowsingEnabled); |
|
154 bindMethod("setUseDashboardCompatibilityMode", &LayoutTestController::setUseDashboardCompatibilityMode); |
|
155 |
|
156 bindMethod("setJavaScriptCanAccessClipboard", &LayoutTestController::setJavaScriptCanAccessClipboard); |
|
157 bindMethod("setXSSAuditorEnabled", &LayoutTestController::setXSSAuditorEnabled); |
|
158 bindMethod("evaluateScriptInIsolatedWorld", &LayoutTestController::evaluateScriptInIsolatedWorld); |
|
159 bindMethod("overridePreference", &LayoutTestController::overridePreference); |
|
160 bindMethod("setAllowUniversalAccessFromFileURLs", &LayoutTestController::setAllowUniversalAccessFromFileURLs); |
|
161 bindMethod("setAllowFileAccessFromFileURLs", &LayoutTestController::setAllowFileAccessFromFileURLs); |
|
162 bindMethod("setTimelineProfilingEnabled", &LayoutTestController::setTimelineProfilingEnabled); |
|
163 bindMethod("evaluateInWebInspector", &LayoutTestController::evaluateInWebInspector); |
|
164 bindMethod("forceRedSelectionColors", &LayoutTestController::forceRedSelectionColors); |
|
165 bindMethod("setEditingBehavior", &LayoutTestController::setEditingBehavior); |
|
166 |
|
167 bindMethod("setGeolocationPermission", &LayoutTestController::setGeolocationPermission); |
|
168 bindMethod("setMockGeolocationPosition", &LayoutTestController::setMockGeolocationPosition); |
|
169 bindMethod("setMockGeolocationError", &LayoutTestController::setMockGeolocationError); |
|
170 bindMethod("abortModal", &LayoutTestController::abortModal); |
|
171 |
|
172 // The fallback method is called when an unknown method is invoked. |
|
173 bindFallbackMethod(&LayoutTestController::fallbackMethod); |
|
174 |
|
175 // Shared properties. |
|
176 // globalFlag is used by a number of layout tests in |
|
177 // LayoutTests\http\tests\security\dataURL. |
|
178 bindProperty("globalFlag", &m_globalFlag); |
|
179 // webHistoryItemCount is used by tests in LayoutTests\http\tests\history |
|
180 bindProperty("webHistoryItemCount", &m_webHistoryItemCount); |
|
181 } |
|
182 |
|
183 LayoutTestController::WorkQueue::~WorkQueue() |
|
184 { |
|
185 reset(); |
|
186 } |
|
187 |
|
188 void LayoutTestController::WorkQueue::processWorkSoon() |
|
189 { |
|
190 if (m_controller->m_shell->webViewHost()->topLoadingFrame()) |
|
191 return; |
|
192 |
|
193 if (!m_queue.isEmpty()) { |
|
194 // We delay processing queued work to avoid recursion problems. |
|
195 m_timer.Start(base::TimeDelta(), this, &WorkQueue::processWork); |
|
196 } else if (!m_controller->m_waitUntilDone) { |
|
197 m_controller->m_shell->testFinished(); |
|
198 } |
|
199 } |
|
200 |
|
201 void LayoutTestController::WorkQueue::processWork() |
|
202 { |
|
203 TestShell* shell = m_controller->m_shell; |
|
204 // Quit doing work once a load is in progress. |
|
205 while (!m_queue.isEmpty()) { |
|
206 bool startedLoad = m_queue.first()->run(shell); |
|
207 delete m_queue.takeFirst(); |
|
208 if (startedLoad) |
|
209 return; |
|
210 } |
|
211 |
|
212 if (!m_controller->m_waitUntilDone && !shell->webViewHost()->topLoadingFrame()) |
|
213 shell->testFinished(); |
|
214 } |
|
215 |
|
216 void LayoutTestController::WorkQueue::reset() |
|
217 { |
|
218 m_frozen = false; |
|
219 while (!m_queue.isEmpty()) { |
|
220 delete m_queue.takeFirst(); |
|
221 } |
|
222 } |
|
223 |
|
224 void LayoutTestController::WorkQueue::addWork(WorkItem* work) |
|
225 { |
|
226 if (m_frozen) { |
|
227 delete work; |
|
228 return; |
|
229 } |
|
230 m_queue.append(work); |
|
231 } |
|
232 |
|
233 void LayoutTestController::dumpAsText(const CppArgumentList& arguments, CppVariant* result) |
|
234 { |
|
235 m_dumpAsText = true; |
|
236 m_generatePixelResults = false; |
|
237 |
|
238 // Optional paramater, describing whether it's allowed to dump pixel results in dumpAsText mode. |
|
239 if (arguments.size() > 0 && arguments[0].isBool()) |
|
240 m_generatePixelResults = arguments[0].value.boolValue; |
|
241 |
|
242 result->setNull(); |
|
243 } |
|
244 |
|
245 void LayoutTestController::dumpDatabaseCallbacks(const CppArgumentList&, CppVariant* result) |
|
246 { |
|
247 // Do nothing; we don't use this flag anywhere for now |
|
248 result->setNull(); |
|
249 } |
|
250 |
|
251 void LayoutTestController::dumpEditingCallbacks(const CppArgumentList&, CppVariant* result) |
|
252 { |
|
253 m_dumpEditingCallbacks = true; |
|
254 result->setNull(); |
|
255 } |
|
256 |
|
257 void LayoutTestController::dumpBackForwardList(const CppArgumentList&, CppVariant* result) |
|
258 { |
|
259 m_dumpBackForwardList = true; |
|
260 result->setNull(); |
|
261 } |
|
262 |
|
263 void LayoutTestController::dumpFrameLoadCallbacks(const CppArgumentList&, CppVariant* result) |
|
264 { |
|
265 m_dumpFrameLoadCallbacks = true; |
|
266 result->setNull(); |
|
267 } |
|
268 |
|
269 void LayoutTestController::dumpResourceLoadCallbacks(const CppArgumentList&, CppVariant* result) |
|
270 { |
|
271 m_dumpResourceLoadCallbacks = true; |
|
272 result->setNull(); |
|
273 } |
|
274 |
|
275 void LayoutTestController::dumpChildFrameScrollPositions(const CppArgumentList&, CppVariant* result) |
|
276 { |
|
277 m_dumpChildFrameScrollPositions = true; |
|
278 result->setNull(); |
|
279 } |
|
280 |
|
281 void LayoutTestController::dumpChildFramesAsText(const CppArgumentList&, CppVariant* result) |
|
282 { |
|
283 m_dumpChildFramesAsText = true; |
|
284 result->setNull(); |
|
285 } |
|
286 |
|
287 void LayoutTestController::dumpWindowStatusChanges(const CppArgumentList&, CppVariant* result) |
|
288 { |
|
289 m_dumpWindowStatusChanges = true; |
|
290 result->setNull(); |
|
291 } |
|
292 |
|
293 void LayoutTestController::dumpTitleChanges(const CppArgumentList&, CppVariant* result) |
|
294 { |
|
295 m_dumpTitleChanges = true; |
|
296 result->setNull(); |
|
297 } |
|
298 |
|
299 void LayoutTestController::setAcceptsEditing(const CppArgumentList& arguments, CppVariant* result) |
|
300 { |
|
301 if (arguments.size() > 0 && arguments[0].isBool()) |
|
302 m_acceptsEditing = arguments[0].value.boolValue; |
|
303 result->setNull(); |
|
304 } |
|
305 |
|
306 void LayoutTestController::waitUntilDone(const CppArgumentList&, CppVariant* result) |
|
307 { |
|
308 if (!webkit_support::BeingDebugged()) { |
|
309 webkit_support::PostDelayedTaskFromHere( |
|
310 m_timeoutFactory.NewRunnableMethod(&LayoutTestController::notifyDoneTimedOut), |
|
311 m_shell->layoutTestTimeout()); |
|
312 } |
|
313 m_waitUntilDone = true; |
|
314 result->setNull(); |
|
315 } |
|
316 |
|
317 void LayoutTestController::notifyDone(const CppArgumentList&, CppVariant* result) |
|
318 { |
|
319 // Test didn't timeout. Kill the timeout timer. |
|
320 m_timeoutFactory.RevokeAll(); |
|
321 |
|
322 completeNotifyDone(false); |
|
323 result->setNull(); |
|
324 } |
|
325 |
|
326 void LayoutTestController::notifyDoneTimedOut() |
|
327 { |
|
328 completeNotifyDone(true); |
|
329 } |
|
330 |
|
331 void LayoutTestController::completeNotifyDone(bool isTimeout) |
|
332 { |
|
333 if (m_waitUntilDone && !m_shell->webViewHost()->topLoadingFrame() && m_workQueue.isEmpty()) { |
|
334 if (isTimeout) |
|
335 m_shell->testTimedOut(); |
|
336 else |
|
337 m_shell->testFinished(); |
|
338 } |
|
339 m_waitUntilDone = false; |
|
340 } |
|
341 |
|
342 class WorkItemBackForward : public LayoutTestController::WorkItem { |
|
343 public: |
|
344 WorkItemBackForward(int distance) : m_distance(distance) {} |
|
345 bool run(TestShell* shell) |
|
346 { |
|
347 shell->goToOffset(m_distance); |
|
348 return true; // FIXME: Did it really start a navigation? |
|
349 } |
|
350 private: |
|
351 int m_distance; |
|
352 }; |
|
353 |
|
354 void LayoutTestController::queueBackNavigation(const CppArgumentList& arguments, CppVariant* result) |
|
355 { |
|
356 if (arguments.size() > 0 && arguments[0].isNumber()) |
|
357 m_workQueue.addWork(new WorkItemBackForward(-arguments[0].toInt32())); |
|
358 result->setNull(); |
|
359 } |
|
360 |
|
361 void LayoutTestController::queueForwardNavigation(const CppArgumentList& arguments, CppVariant* result) |
|
362 { |
|
363 if (arguments.size() > 0 && arguments[0].isNumber()) |
|
364 m_workQueue.addWork(new WorkItemBackForward(arguments[0].toInt32())); |
|
365 result->setNull(); |
|
366 } |
|
367 |
|
368 class WorkItemReload : public LayoutTestController::WorkItem { |
|
369 public: |
|
370 bool run(TestShell* shell) |
|
371 { |
|
372 shell->reload(); |
|
373 return true; |
|
374 } |
|
375 }; |
|
376 |
|
377 void LayoutTestController::queueReload(const CppArgumentList&, CppVariant* result) |
|
378 { |
|
379 m_workQueue.addWork(new WorkItemReload); |
|
380 result->setNull(); |
|
381 } |
|
382 |
|
383 class WorkItemLoadingScript : public LayoutTestController::WorkItem { |
|
384 public: |
|
385 WorkItemLoadingScript(const string& script) : m_script(script) {} |
|
386 bool run(TestShell* shell) |
|
387 { |
|
388 shell->webView()->mainFrame()->executeScript(WebScriptSource(WebString::fromUTF8(m_script))); |
|
389 return true; // FIXME: Did it really start a navigation? |
|
390 } |
|
391 private: |
|
392 string m_script; |
|
393 }; |
|
394 |
|
395 class WorkItemNonLoadingScript : public LayoutTestController::WorkItem { |
|
396 public: |
|
397 WorkItemNonLoadingScript(const string& script) : m_script(script) {} |
|
398 bool run(TestShell* shell) |
|
399 { |
|
400 shell->webView()->mainFrame()->executeScript(WebScriptSource(WebString::fromUTF8(m_script))); |
|
401 return false; |
|
402 } |
|
403 private: |
|
404 string m_script; |
|
405 }; |
|
406 |
|
407 void LayoutTestController::queueLoadingScript(const CppArgumentList& arguments, CppVariant* result) |
|
408 { |
|
409 if (arguments.size() > 0 && arguments[0].isString()) |
|
410 m_workQueue.addWork(new WorkItemLoadingScript(arguments[0].toString())); |
|
411 result->setNull(); |
|
412 } |
|
413 |
|
414 void LayoutTestController::queueNonLoadingScript(const CppArgumentList& arguments, CppVariant* result) |
|
415 { |
|
416 if (arguments.size() > 0 && arguments[0].isString()) |
|
417 m_workQueue.addWork(new WorkItemNonLoadingScript(arguments[0].toString())); |
|
418 result->setNull(); |
|
419 } |
|
420 |
|
421 class WorkItemLoad : public LayoutTestController::WorkItem { |
|
422 public: |
|
423 WorkItemLoad(const WebURL& url, const WebString& target) |
|
424 : m_url(url) |
|
425 , m_target(target) {} |
|
426 bool run(TestShell* shell) |
|
427 { |
|
428 shell->webViewHost()->loadURLForFrame(m_url, m_target); |
|
429 return true; // FIXME: Did it really start a navigation? |
|
430 } |
|
431 private: |
|
432 WebURL m_url; |
|
433 WebString m_target; |
|
434 }; |
|
435 |
|
436 void LayoutTestController::queueLoad(const CppArgumentList& arguments, CppVariant* result) |
|
437 { |
|
438 if (arguments.size() > 0 && arguments[0].isString()) { |
|
439 // FIXME: Implement WebURL::resolve() and avoid GURL. |
|
440 GURL currentURL = m_shell->webView()->mainFrame()->url(); |
|
441 GURL fullURL = currentURL.Resolve(arguments[0].toString()); |
|
442 |
|
443 string target = ""; |
|
444 if (arguments.size() > 1 && arguments[1].isString()) |
|
445 target = arguments[1].toString(); |
|
446 |
|
447 m_workQueue.addWork(new WorkItemLoad(fullURL, WebString::fromUTF8(target))); |
|
448 } |
|
449 result->setNull(); |
|
450 } |
|
451 |
|
452 void LayoutTestController::objCIdentityIsEqual(const CppArgumentList& arguments, CppVariant* result) |
|
453 { |
|
454 if (arguments.size() < 2) { |
|
455 // This is the best we can do to return an error. |
|
456 result->setNull(); |
|
457 return; |
|
458 } |
|
459 result->set(arguments[0].isEqual(arguments[1])); |
|
460 } |
|
461 |
|
462 void LayoutTestController::reset() |
|
463 { |
|
464 if (m_shell) { |
|
465 m_shell->webView()->setZoomLevel(false, 0); |
|
466 m_shell->webView()->setTabKeyCyclesThroughElements(true); |
|
467 #if !OS(DARWIN) && !OS(WINDOWS) // Actually, TOOLKIT_GTK |
|
468 // (Constants copied because we can't depend on the header that defined |
|
469 // them from this file.) |
|
470 m_shell->webView()->setSelectionColors(0xff1e90ff, 0xff000000, 0xffc8c8c8, 0xff323232); |
|
471 #endif |
|
472 m_shell->webView()->removeAllUserContent(); |
|
473 } |
|
474 m_dumpAsText = false; |
|
475 m_dumpEditingCallbacks = false; |
|
476 m_dumpFrameLoadCallbacks = false; |
|
477 m_dumpResourceLoadCallbacks = false; |
|
478 m_dumpBackForwardList = false; |
|
479 m_dumpChildFrameScrollPositions = false; |
|
480 m_dumpChildFramesAsText = false; |
|
481 m_dumpWindowStatusChanges = false; |
|
482 m_dumpSelectionRect = false; |
|
483 m_dumpTitleChanges = false; |
|
484 m_generatePixelResults = true; |
|
485 m_acceptsEditing = true; |
|
486 m_waitUntilDone = false; |
|
487 m_canOpenWindows = false; |
|
488 m_testRepaint = false; |
|
489 m_sweepHorizontally = false; |
|
490 m_shouldAddFileToPasteboard = false; |
|
491 m_stopProvisionalFrameLoads = false; |
|
492 m_globalFlag.set(false); |
|
493 m_webHistoryItemCount.set(0); |
|
494 m_userStyleSheetLocation = WebURL(); |
|
495 |
|
496 webkit_support::SetAcceptAllCookies(false); |
|
497 WebSecurityPolicy::resetOriginAccessWhitelists(); |
|
498 |
|
499 // Reset the default quota for each origin to 5MB |
|
500 webkit_support::SetDatabaseQuota(5 * 1024 * 1024); |
|
501 |
|
502 setlocale(LC_ALL, ""); |
|
503 |
|
504 if (m_closeRemainingWindows) |
|
505 m_shell->closeRemainingWindows(); |
|
506 else |
|
507 m_closeRemainingWindows = true; |
|
508 m_workQueue.reset(); |
|
509 } |
|
510 |
|
511 void LayoutTestController::locationChangeDone() |
|
512 { |
|
513 m_webHistoryItemCount.set(m_shell->navigationEntryCount()); |
|
514 |
|
515 // No more new work after the first complete load. |
|
516 m_workQueue.setFrozen(true); |
|
517 |
|
518 if (!m_waitUntilDone) |
|
519 m_workQueue.processWorkSoon(); |
|
520 } |
|
521 |
|
522 void LayoutTestController::policyDelegateDone() |
|
523 { |
|
524 ASSERT(m_waitUntilDone); |
|
525 m_shell->testFinished(); |
|
526 m_waitUntilDone = false; |
|
527 } |
|
528 |
|
529 void LayoutTestController::setCanOpenWindows(const CppArgumentList&, CppVariant* result) |
|
530 { |
|
531 m_canOpenWindows = true; |
|
532 result->setNull(); |
|
533 } |
|
534 |
|
535 void LayoutTestController::setTabKeyCyclesThroughElements(const CppArgumentList& arguments, CppVariant* result) |
|
536 { |
|
537 if (arguments.size() > 0 && arguments[0].isBool()) |
|
538 m_shell->webView()->setTabKeyCyclesThroughElements(arguments[0].toBoolean()); |
|
539 result->setNull(); |
|
540 } |
|
541 |
|
542 void LayoutTestController::windowCount(const CppArgumentList&, CppVariant* result) |
|
543 { |
|
544 result->set(static_cast<int>(m_shell->windowCount())); |
|
545 } |
|
546 |
|
547 void LayoutTestController::setCloseRemainingWindowsWhenComplete(const CppArgumentList& arguments, CppVariant* result) |
|
548 { |
|
549 if (arguments.size() > 0 && arguments[0].isBool()) |
|
550 m_closeRemainingWindows = arguments[0].value.boolValue; |
|
551 result->setNull(); |
|
552 } |
|
553 |
|
554 void LayoutTestController::setAlwaysAcceptCookies(const CppArgumentList& arguments, CppVariant* result) |
|
555 { |
|
556 if (arguments.size() > 0) |
|
557 webkit_support::SetAcceptAllCookies(cppVariantToBool(arguments[0])); |
|
558 result->setNull(); |
|
559 } |
|
560 |
|
561 void LayoutTestController::showWebInspector(const CppArgumentList&, CppVariant* result) |
|
562 { |
|
563 m_shell->showDevTools(); |
|
564 result->setNull(); |
|
565 } |
|
566 |
|
567 void LayoutTestController::closeWebInspector(const CppArgumentList& args, CppVariant* result) |
|
568 { |
|
569 m_shell->closeDevTools(); |
|
570 result->setNull(); |
|
571 } |
|
572 |
|
573 void LayoutTestController::setWindowIsKey(const CppArgumentList& arguments, CppVariant* result) |
|
574 { |
|
575 if (arguments.size() > 0 && arguments[0].isBool()) |
|
576 m_shell->setFocus(m_shell->webView(), arguments[0].value.boolValue); |
|
577 result->setNull(); |
|
578 } |
|
579 |
|
580 void LayoutTestController::setUserStyleSheetEnabled(const CppArgumentList& arguments, CppVariant* result) |
|
581 { |
|
582 if (arguments.size() > 0 && arguments[0].isBool()) |
|
583 m_shell->webView()->settings()->setUserStyleSheetLocation(arguments[0].value.boolValue ? m_userStyleSheetLocation : WebURL()); |
|
584 result->setNull(); |
|
585 } |
|
586 |
|
587 void LayoutTestController::setUserStyleSheetLocation(const CppArgumentList& arguments, CppVariant* result) |
|
588 { |
|
589 if (arguments.size() > 0 && arguments[0].isString()) { |
|
590 m_userStyleSheetLocation = webkit_support::RewriteLayoutTestsURL(arguments[0].toString()); |
|
591 m_shell->webView()->settings()->setUserStyleSheetLocation(m_userStyleSheetLocation); |
|
592 } |
|
593 result->setNull(); |
|
594 } |
|
595 |
|
596 void LayoutTestController::setAuthorAndUserStylesEnabled(const CppArgumentList& arguments, CppVariant* result) |
|
597 { |
|
598 if (arguments.size() > 0 && arguments[0].isBool()) |
|
599 m_shell->webView()->settings()->setAuthorAndUserStylesEnabled(arguments[0].value.boolValue); |
|
600 result->setNull(); |
|
601 } |
|
602 |
|
603 void LayoutTestController::execCommand(const CppArgumentList& arguments, CppVariant* result) |
|
604 { |
|
605 result->setNull(); |
|
606 if (arguments.size() <= 0 || !arguments[0].isString()) |
|
607 return; |
|
608 |
|
609 std::string command = arguments[0].toString(); |
|
610 std::string value(""); |
|
611 // Ignore the second parameter (which is userInterface) |
|
612 // since this command emulates a manual action. |
|
613 if (arguments.size() >= 3 && arguments[2].isString()) |
|
614 value = arguments[2].toString(); |
|
615 |
|
616 // Note: webkit's version does not return the boolean, so neither do we. |
|
617 m_shell->webView()->focusedFrame()->executeCommand(WebString::fromUTF8(command), WebString::fromUTF8(value)); |
|
618 } |
|
619 |
|
620 void LayoutTestController::isCommandEnabled(const CppArgumentList& arguments, CppVariant* result) |
|
621 { |
|
622 if (arguments.size() <= 0 || !arguments[0].isString()) { |
|
623 result->setNull(); |
|
624 return; |
|
625 } |
|
626 |
|
627 std::string command = arguments[0].toString(); |
|
628 bool rv = m_shell->webView()->focusedFrame()->isCommandEnabled(WebString::fromUTF8(command)); |
|
629 result->set(rv); |
|
630 } |
|
631 |
|
632 void LayoutTestController::setPopupBlockingEnabled(const CppArgumentList& arguments, CppVariant* result) |
|
633 { |
|
634 if (arguments.size() > 0 && arguments[0].isBool()) { |
|
635 bool blockPopups = arguments[0].toBoolean(); |
|
636 m_shell->webView()->settings()->setJavaScriptCanOpenWindowsAutomatically(!blockPopups); |
|
637 } |
|
638 result->setNull(); |
|
639 } |
|
640 |
|
641 void LayoutTestController::setUseDashboardCompatibilityMode(const CppArgumentList&, CppVariant* result) |
|
642 { |
|
643 // We have no need to support Dashboard Compatibility Mode (mac-only) |
|
644 result->setNull(); |
|
645 } |
|
646 |
|
647 void LayoutTestController::setScrollbarPolicy(const CppArgumentList&, CppVariant* result) |
|
648 { |
|
649 // FIXME: implement. |
|
650 // Currently only has a non-null implementation on QT. |
|
651 result->setNull(); |
|
652 } |
|
653 |
|
654 void LayoutTestController::setCustomPolicyDelegate(const CppArgumentList& arguments, CppVariant* result) |
|
655 { |
|
656 if (arguments.size() > 0 && arguments[0].isBool()) { |
|
657 bool enable = arguments[0].value.boolValue; |
|
658 bool permissive = false; |
|
659 if (arguments.size() > 1 && arguments[1].isBool()) |
|
660 permissive = arguments[1].value.boolValue; |
|
661 m_shell->webViewHost()->setCustomPolicyDelegate(enable, permissive); |
|
662 } |
|
663 result->setNull(); |
|
664 } |
|
665 |
|
666 void LayoutTestController::waitForPolicyDelegate(const CppArgumentList&, CppVariant* result) |
|
667 { |
|
668 m_shell->webViewHost()->waitForPolicyDelegate(); |
|
669 m_waitUntilDone = true; |
|
670 result->setNull(); |
|
671 } |
|
672 |
|
673 void LayoutTestController::setWillSendRequestClearHeader(const CppArgumentList& arguments, CppVariant* result) |
|
674 { |
|
675 if (arguments.size() > 0 && arguments[0].isString()) { |
|
676 string header = arguments[0].toString(); |
|
677 if (!header.empty()) |
|
678 m_shell->webViewHost()->addClearHeader(String::fromUTF8(header.c_str())); |
|
679 } |
|
680 result->setNull(); |
|
681 } |
|
682 |
|
683 void LayoutTestController::setWillSendRequestReturnsNullOnRedirect(const CppArgumentList& arguments, CppVariant* result) |
|
684 { |
|
685 if (arguments.size() > 0 && arguments[0].isBool()) |
|
686 m_shell->webViewHost()->setBlockRedirects(arguments[0].value.boolValue); |
|
687 result->setNull(); |
|
688 } |
|
689 |
|
690 void LayoutTestController::setWillSendRequestReturnsNull(const CppArgumentList& arguments, CppVariant* result) |
|
691 { |
|
692 if (arguments.size() > 0 && arguments[0].isBool()) |
|
693 m_shell->webViewHost()->setRequestReturnNull(arguments[0].value.boolValue); |
|
694 result->setNull(); |
|
695 } |
|
696 |
|
697 void LayoutTestController::pathToLocalResource(const CppArgumentList& arguments, CppVariant* result) |
|
698 { |
|
699 result->setNull(); |
|
700 if (arguments.size() <= 0 || !arguments[0].isString()) |
|
701 return; |
|
702 |
|
703 string url = arguments[0].toString(); |
|
704 #if OS(WINDOWS) |
|
705 if (StartsWithASCII(url, "/tmp/", true)) { |
|
706 // We want a temp file. |
|
707 const unsigned tempPrefixLength = 5; |
|
708 size_t bufferSize = MAX_PATH; |
|
709 OwnArrayPtr<WCHAR> tempPath(new WCHAR[bufferSize]); |
|
710 DWORD tempLength = ::GetTempPathW(bufferSize, tempPath.get()); |
|
711 if (tempLength + url.length() - tempPrefixLength + 1 > bufferSize) { |
|
712 bufferSize = tempLength + url.length() - tempPrefixLength + 1; |
|
713 tempPath.set(new WCHAR[bufferSize]); |
|
714 tempLength = GetTempPathW(bufferSize, tempPath.get()); |
|
715 ASSERT(tempLength < bufferSize); |
|
716 } |
|
717 std::string resultPath(WebString(tempPath.get(), tempLength).utf8()); |
|
718 resultPath.append(url.substr(tempPrefixLength)); |
|
719 result->set(resultPath); |
|
720 return; |
|
721 } |
|
722 #endif |
|
723 |
|
724 // Some layout tests use file://// which we resolve as a UNC path. Normalize |
|
725 // them to just file:///. |
|
726 while (StartsWithASCII(url, "file:////", false)) |
|
727 url = url.substr(0, 8) + url.substr(9); |
|
728 result->set(webkit_support::RewriteLayoutTestsURL(url).spec()); |
|
729 } |
|
730 |
|
731 void LayoutTestController::addFileToPasteboardOnDrag(const CppArgumentList&, CppVariant* result) |
|
732 { |
|
733 result->setNull(); |
|
734 m_shouldAddFileToPasteboard = true; |
|
735 } |
|
736 |
|
737 void LayoutTestController::setStopProvisionalFrameLoads(const CppArgumentList&, CppVariant* result) |
|
738 { |
|
739 result->setNull(); |
|
740 m_stopProvisionalFrameLoads = true; |
|
741 } |
|
742 |
|
743 void LayoutTestController::setSmartInsertDeleteEnabled(const CppArgumentList& arguments, CppVariant* result) |
|
744 { |
|
745 if (arguments.size() > 0 && arguments[0].isBool()) |
|
746 m_shell->webViewHost()->setSmartInsertDeleteEnabled(arguments[0].value.boolValue); |
|
747 result->setNull(); |
|
748 } |
|
749 |
|
750 void LayoutTestController::setSelectTrailingWhitespaceEnabled(const CppArgumentList& arguments, CppVariant* result) |
|
751 { |
|
752 if (arguments.size() > 0 && arguments[0].isBool()) |
|
753 m_shell->webViewHost()->setSelectTrailingWhitespaceEnabled(arguments[0].value.boolValue); |
|
754 result->setNull(); |
|
755 } |
|
756 |
|
757 bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(const WebString& animationName, double time, const WebString& elementId) |
|
758 { |
|
759 WebFrame* webFrame = m_shell->webView()->mainFrame(); |
|
760 if (!webFrame) |
|
761 return false; |
|
762 |
|
763 WebAnimationController* controller = webFrame->animationController(); |
|
764 if (!controller) |
|
765 return false; |
|
766 |
|
767 WebElement element = webFrame->document().getElementById(elementId); |
|
768 if (element.isNull()) |
|
769 return false; |
|
770 return controller->pauseAnimationAtTime(element, animationName, time); |
|
771 } |
|
772 |
|
773 bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(const WebString& propertyName, double time, const WebString& elementId) |
|
774 { |
|
775 WebFrame* webFrame = m_shell->webView()->mainFrame(); |
|
776 if (!webFrame) |
|
777 return false; |
|
778 |
|
779 WebAnimationController* controller = webFrame->animationController(); |
|
780 if (!controller) |
|
781 return false; |
|
782 |
|
783 WebElement element = webFrame->document().getElementById(elementId); |
|
784 if (element.isNull()) |
|
785 return false; |
|
786 return controller->pauseTransitionAtTime(element, propertyName, time); |
|
787 } |
|
788 |
|
789 bool LayoutTestController::elementDoesAutoCompleteForElementWithId(const WebString& elementId) |
|
790 { |
|
791 WebFrame* webFrame = m_shell->webView()->mainFrame(); |
|
792 if (!webFrame) |
|
793 return false; |
|
794 |
|
795 WebElement element = webFrame->document().getElementById(elementId); |
|
796 if (element.isNull() || !element.hasTagName("input")) |
|
797 return false; |
|
798 |
|
799 WebInputElement inputElement = element.to<WebInputElement>(); |
|
800 return inputElement.autoComplete(); |
|
801 } |
|
802 |
|
803 int LayoutTestController::numberOfActiveAnimations() |
|
804 { |
|
805 WebFrame* webFrame = m_shell->webView()->mainFrame(); |
|
806 if (!webFrame) |
|
807 return -1; |
|
808 |
|
809 WebAnimationController* controller = webFrame->animationController(); |
|
810 if (!controller) |
|
811 return -1; |
|
812 |
|
813 return controller->numberOfActiveAnimations(); |
|
814 } |
|
815 |
|
816 void LayoutTestController::pauseAnimationAtTimeOnElementWithId(const CppArgumentList& arguments, CppVariant* result) |
|
817 { |
|
818 result->set(false); |
|
819 if (arguments.size() > 2 && arguments[0].isString() && arguments[1].isNumber() && arguments[2].isString()) { |
|
820 WebString animationName = cppVariantToWebString(arguments[0]); |
|
821 double time = arguments[1].toDouble(); |
|
822 WebString elementId = cppVariantToWebString(arguments[2]); |
|
823 result->set(pauseAnimationAtTimeOnElementWithId(animationName, time, elementId)); |
|
824 } |
|
825 } |
|
826 |
|
827 void LayoutTestController::pauseTransitionAtTimeOnElementWithId(const CppArgumentList& arguments, CppVariant* result) |
|
828 { |
|
829 result->set(false); |
|
830 if (arguments.size() > 2 && arguments[0].isString() && arguments[1].isNumber() && arguments[2].isString()) { |
|
831 WebString propertyName = cppVariantToWebString(arguments[0]); |
|
832 double time = arguments[1].toDouble(); |
|
833 WebString elementId = cppVariantToWebString(arguments[2]); |
|
834 result->set(pauseTransitionAtTimeOnElementWithId(propertyName, time, elementId)); |
|
835 } |
|
836 } |
|
837 |
|
838 void LayoutTestController::elementDoesAutoCompleteForElementWithId(const CppArgumentList& arguments, CppVariant* result) |
|
839 { |
|
840 if (arguments.size() != 1 || !arguments[0].isString()) { |
|
841 result->set(false); |
|
842 return; |
|
843 } |
|
844 WebString elementId = cppVariantToWebString(arguments[0]); |
|
845 result->set(elementDoesAutoCompleteForElementWithId(elementId)); |
|
846 } |
|
847 |
|
848 void LayoutTestController::numberOfActiveAnimations(const CppArgumentList&, CppVariant* result) |
|
849 { |
|
850 result->set(numberOfActiveAnimations()); |
|
851 } |
|
852 |
|
853 void LayoutTestController::disableImageLoading(const CppArgumentList&, CppVariant* result) |
|
854 { |
|
855 m_shell->webView()->settings()->setLoadsImagesAutomatically(false); |
|
856 result->setNull(); |
|
857 } |
|
858 |
|
859 void LayoutTestController::setIconDatabaseEnabled(const CppArgumentList&, CppVariant* result) |
|
860 { |
|
861 // We don't use the WebKit icon database. |
|
862 result->setNull(); |
|
863 } |
|
864 |
|
865 void LayoutTestController::callShouldCloseOnWebView(const CppArgumentList&, CppVariant* result) |
|
866 { |
|
867 result->set(m_shell->webView()->dispatchBeforeUnloadEvent()); |
|
868 } |
|
869 |
|
870 void LayoutTestController::grantDesktopNotificationPermission(const CppArgumentList& arguments, CppVariant* result) |
|
871 { |
|
872 if (arguments.size() != 1 || !arguments[0].isString()) { |
|
873 result->set(false); |
|
874 return; |
|
875 } |
|
876 m_shell->notificationPresenter()->grantPermission(cppVariantToWebString(arguments[0])); |
|
877 result->set(true); |
|
878 } |
|
879 |
|
880 // |
|
881 // Unimplemented stubs |
|
882 // |
|
883 |
|
884 void LayoutTestController::dumpAsWebArchive(const CppArgumentList& arguments, CppVariant* result) |
|
885 { |
|
886 result->setNull(); |
|
887 } |
|
888 |
|
889 void LayoutTestController::setMainFrameIsFirstResponder(const CppArgumentList& arguments, CppVariant* result) |
|
890 { |
|
891 result->setNull(); |
|
892 } |
|
893 |
|
894 void LayoutTestController::dumpSelectionRect(const CppArgumentList& arguments, CppVariant* result) |
|
895 { |
|
896 m_dumpSelectionRect = true; |
|
897 result->setNull(); |
|
898 } |
|
899 |
|
900 void LayoutTestController::display(const CppArgumentList& arguments, CppVariant* result) |
|
901 { |
|
902 WebViewHost* host = m_shell->webViewHost(); |
|
903 const WebKit::WebSize& size = m_shell->webView()->size(); |
|
904 WebRect rect(0, 0, size.width, size.height); |
|
905 host->updatePaintRect(rect); |
|
906 host->paintInvalidatedRegion(); |
|
907 host->displayRepaintMask(); |
|
908 result->setNull(); |
|
909 } |
|
910 |
|
911 void LayoutTestController::testRepaint(const CppArgumentList&, CppVariant* result) |
|
912 { |
|
913 m_testRepaint = true; |
|
914 result->setNull(); |
|
915 } |
|
916 |
|
917 void LayoutTestController::repaintSweepHorizontally(const CppArgumentList&, CppVariant* result) |
|
918 { |
|
919 m_sweepHorizontally = true; |
|
920 result->setNull(); |
|
921 } |
|
922 |
|
923 void LayoutTestController::clearBackForwardList(const CppArgumentList& arguments, CppVariant* result) |
|
924 { |
|
925 result->setNull(); |
|
926 } |
|
927 |
|
928 void LayoutTestController::keepWebHistory(const CppArgumentList& arguments, CppVariant* result) |
|
929 { |
|
930 result->setNull(); |
|
931 } |
|
932 |
|
933 void LayoutTestController::storeWebScriptObject(const CppArgumentList& arguments, CppVariant* result) |
|
934 { |
|
935 result->setNull(); |
|
936 } |
|
937 |
|
938 void LayoutTestController::accessStoredWebScriptObject(const CppArgumentList& arguments, CppVariant* result) |
|
939 { |
|
940 result->setNull(); |
|
941 } |
|
942 |
|
943 void LayoutTestController::objCClassNameOf(const CppArgumentList& arguments, CppVariant* result) |
|
944 { |
|
945 result->setNull(); |
|
946 } |
|
947 |
|
948 void LayoutTestController::addDisallowedURL(const CppArgumentList& arguments, CppVariant* result) |
|
949 { |
|
950 result->setNull(); |
|
951 } |
|
952 void LayoutTestController::setCallCloseOnWebViews(const CppArgumentList& arguments, CppVariant* result) |
|
953 { |
|
954 result->setNull(); |
|
955 } |
|
956 |
|
957 void LayoutTestController::setPrivateBrowsingEnabled(const CppArgumentList& arguments, CppVariant* result) |
|
958 { |
|
959 result->setNull(); |
|
960 } |
|
961 |
|
962 void LayoutTestController::setJavaScriptCanAccessClipboard(const CppArgumentList& arguments, CppVariant* result) |
|
963 { |
|
964 if (arguments.size() > 0 && arguments[0].isBool()) |
|
965 m_shell->webView()->settings()->setJavaScriptCanAccessClipboard(arguments[0].value.boolValue); |
|
966 result->setNull(); |
|
967 } |
|
968 |
|
969 void LayoutTestController::setXSSAuditorEnabled(const CppArgumentList& arguments, CppVariant* result) |
|
970 { |
|
971 if (arguments.size() > 0 && arguments[0].isBool()) |
|
972 m_shell->webView()->settings()->setXSSAuditorEnabled(arguments[0].value.boolValue); |
|
973 result->setNull(); |
|
974 } |
|
975 |
|
976 void LayoutTestController::evaluateScriptInIsolatedWorld(const CppArgumentList& arguments, CppVariant* result) |
|
977 { |
|
978 if (arguments.size() >= 2 && arguments[0].isNumber() && arguments[1].isString()) { |
|
979 WebScriptSource source(cppVariantToWebString(arguments[1])); |
|
980 // This relies on the iframe focusing itself when it loads. This is a bit |
|
981 // sketchy, but it seems to be what other tests do. |
|
982 m_shell->webView()->focusedFrame()->executeScriptInIsolatedWorld(arguments[0].toInt32(), &source, 1, 1); |
|
983 } |
|
984 result->setNull(); |
|
985 } |
|
986 |
|
987 void LayoutTestController::setAllowUniversalAccessFromFileURLs(const CppArgumentList& arguments, CppVariant* result) |
|
988 { |
|
989 if (arguments.size() > 0 && arguments[0].isBool()) |
|
990 m_shell->webView()->settings()->setAllowUniversalAccessFromFileURLs(arguments[0].value.boolValue); |
|
991 result->setNull(); |
|
992 } |
|
993 |
|
994 void LayoutTestController::setAllowFileAccessFromFileURLs(const CppArgumentList& arguments, CppVariant* result) |
|
995 { |
|
996 if (arguments.size() > 0 && arguments[0].isBool()) |
|
997 m_shell->webView()->settings()->setAllowFileAccessFromFileURLs(arguments[0].value.boolValue); |
|
998 result->setNull(); |
|
999 } |
|
1000 |
|
1001 // Need these conversions because the format of the value for booleans |
|
1002 // may vary - for example, on mac "1" and "0" are used for boolean. |
|
1003 bool LayoutTestController::cppVariantToBool(const CppVariant& value) |
|
1004 { |
|
1005 if (value.isBool()) |
|
1006 return value.toBoolean(); |
|
1007 if (value.isInt32()) |
|
1008 return value.toInt32(); |
|
1009 if (value.isString()) { |
|
1010 string valueString = value.toString(); |
|
1011 if (valueString == "true" || valueString == "1") |
|
1012 return true; |
|
1013 if (valueString == "false" || valueString == "0") |
|
1014 return false; |
|
1015 } |
|
1016 logErrorToConsole("Invalid value. Expected boolean value."); |
|
1017 return false; |
|
1018 } |
|
1019 |
|
1020 int32_t LayoutTestController::cppVariantToInt32(const CppVariant& value) |
|
1021 { |
|
1022 if (value.isInt32()) |
|
1023 return value.toInt32(); |
|
1024 if (value.isString()) { |
|
1025 int number; |
|
1026 if (StringToInt(value.toString(), &number)) |
|
1027 return number; |
|
1028 } |
|
1029 logErrorToConsole("Invalid value for preference. Expected integer value."); |
|
1030 return 0; |
|
1031 } |
|
1032 |
|
1033 WebString LayoutTestController::cppVariantToWebString(const CppVariant& value) |
|
1034 { |
|
1035 if (!value.isString()) { |
|
1036 logErrorToConsole("Invalid value for preference. Expected string value."); |
|
1037 return WebString(); |
|
1038 } |
|
1039 return WebString::fromUTF8(value.toString()); |
|
1040 } |
|
1041 |
|
1042 void LayoutTestController::overridePreference(const CppArgumentList& arguments, CppVariant* result) |
|
1043 { |
|
1044 result->setNull(); |
|
1045 if (arguments.size() != 2 || !arguments[0].isString()) |
|
1046 return; |
|
1047 |
|
1048 string key = arguments[0].toString(); |
|
1049 CppVariant value = arguments[1]; |
|
1050 WebSettings* settings = m_shell->webView()->settings(); |
|
1051 if (key == "WebKitStandardFont") |
|
1052 settings->setStandardFontFamily(cppVariantToWebString(value)); |
|
1053 else if (key == "WebKitFixedFont") |
|
1054 settings->setFixedFontFamily(cppVariantToWebString(value)); |
|
1055 else if (key == "WebKitSerifFont") |
|
1056 settings->setSerifFontFamily(cppVariantToWebString(value)); |
|
1057 else if (key == "WebKitSansSerifFont") |
|
1058 settings->setSansSerifFontFamily(cppVariantToWebString(value)); |
|
1059 else if (key == "WebKitCursiveFont") |
|
1060 settings->setCursiveFontFamily(cppVariantToWebString(value)); |
|
1061 else if (key == "WebKitFantasyFont") |
|
1062 settings->setFantasyFontFamily(cppVariantToWebString(value)); |
|
1063 else if (key == "WebKitDefaultFontSize") |
|
1064 settings->setDefaultFontSize(cppVariantToInt32(value)); |
|
1065 else if (key == "WebKitDefaultFixedFontSize") |
|
1066 settings->setDefaultFixedFontSize(cppVariantToInt32(value)); |
|
1067 else if (key == "WebKitMinimumFontSize") |
|
1068 settings->setMinimumFontSize(cppVariantToInt32(value)); |
|
1069 else if (key == "WebKitMinimumLogicalFontSize") |
|
1070 settings->setMinimumLogicalFontSize(cppVariantToInt32(value)); |
|
1071 else if (key == "WebKitDefaultTextEncodingName") |
|
1072 settings->setDefaultTextEncodingName(cppVariantToWebString(value)); |
|
1073 else if (key == "WebKitJavaScriptEnabled") |
|
1074 settings->setJavaScriptEnabled(cppVariantToBool(value)); |
|
1075 else if (key == "WebKitWebSecurityEnabled") |
|
1076 settings->setWebSecurityEnabled(cppVariantToBool(value)); |
|
1077 else if (key == "WebKitJavaScriptCanOpenWindowsAutomatically") |
|
1078 settings->setJavaScriptCanOpenWindowsAutomatically(cppVariantToBool(value)); |
|
1079 else if (key == "WebKitDisplayImagesKey") |
|
1080 settings->setLoadsImagesAutomatically(cppVariantToBool(value)); |
|
1081 else if (key == "WebKitPluginsEnabled") |
|
1082 settings->setPluginsEnabled(cppVariantToBool(value)); |
|
1083 else if (key == "WebKitDOMPasteAllowedPreferenceKey") |
|
1084 settings->setDOMPasteAllowed(cppVariantToBool(value)); |
|
1085 else if (key == "WebKitDeveloperExtrasEnabledPreferenceKey") |
|
1086 settings->setDeveloperExtrasEnabled(cppVariantToBool(value)); |
|
1087 else if (key == "WebKitShrinksStandaloneImagesToFit") |
|
1088 settings->setShrinksStandaloneImagesToFit(cppVariantToBool(value)); |
|
1089 else if (key == "WebKitTextAreasAreResizable") |
|
1090 settings->setTextAreasAreResizable(cppVariantToBool(value)); |
|
1091 else if (key == "WebKitJavaEnabled") |
|
1092 settings->setJavaEnabled(cppVariantToBool(value)); |
|
1093 else if (key == "WebKitUsesPageCachePreferenceKey") |
|
1094 settings->setUsesPageCache(cppVariantToBool(value)); |
|
1095 else if (key == "WebKitJavaScriptCanAccessClipboard") |
|
1096 settings->setJavaScriptCanAccessClipboard(cppVariantToBool(value)); |
|
1097 else if (key == "WebKitXSSAuditorEnabled") |
|
1098 settings->setXSSAuditorEnabled(cppVariantToBool(value)); |
|
1099 else if (key == "WebKitLocalStorageEnabledPreferenceKey") |
|
1100 settings->setLocalStorageEnabled(cppVariantToBool(value)); |
|
1101 else if (key == "WebKitOfflineWebApplicationCacheEnabled") |
|
1102 settings->setOfflineWebApplicationCacheEnabled(cppVariantToBool(value)); |
|
1103 else if (key == "WebKitTabToLinksPreferenceKey") |
|
1104 m_shell->webView()->setTabsToLinks(cppVariantToBool(value)); |
|
1105 else if (key == "WebKitWebGLEnabled") |
|
1106 settings->setExperimentalWebGLEnabled(cppVariantToBool(value)); |
|
1107 else { |
|
1108 string message("Invalid name for preference: "); |
|
1109 message.append(key); |
|
1110 logErrorToConsole(message); |
|
1111 } |
|
1112 } |
|
1113 |
|
1114 void LayoutTestController::fallbackMethod(const CppArgumentList&, CppVariant* result) |
|
1115 { |
|
1116 printf("CONSOLE MESSAGE: JavaScript ERROR: unknown method called on LayoutTestController\n"); |
|
1117 result->setNull(); |
|
1118 } |
|
1119 |
|
1120 void LayoutTestController::addOriginAccessWhitelistEntry(const CppArgumentList& arguments, CppVariant* result) |
|
1121 { |
|
1122 result->setNull(); |
|
1123 |
|
1124 if (arguments.size() != 4 || !arguments[0].isString() || !arguments[1].isString() |
|
1125 || !arguments[2].isString() || !arguments[3].isBool()) |
|
1126 return; |
|
1127 |
|
1128 WebKit::WebURL url(GURL(arguments[0].toString())); |
|
1129 if (!url.isValid()) |
|
1130 return; |
|
1131 |
|
1132 WebSecurityPolicy::addOriginAccessWhitelistEntry( |
|
1133 url, |
|
1134 cppVariantToWebString(arguments[1]), |
|
1135 cppVariantToWebString(arguments[2]), |
|
1136 arguments[3].toBoolean()); |
|
1137 } |
|
1138 |
|
1139 void LayoutTestController::removeOriginAccessWhitelistEntry(const CppArgumentList& arguments, CppVariant* result) |
|
1140 { |
|
1141 result->setNull(); |
|
1142 |
|
1143 if (arguments.size() != 4 || !arguments[0].isString() || !arguments[1].isString() |
|
1144 || !arguments[2].isString() || !arguments[3].isBool()) |
|
1145 return; |
|
1146 |
|
1147 WebKit::WebURL url(GURL(arguments[0].toString())); |
|
1148 if (!url.isValid()) |
|
1149 return; |
|
1150 |
|
1151 WebSecurityPolicy::removeOriginAccessWhitelistEntry( |
|
1152 url, |
|
1153 cppVariantToWebString(arguments[1]), |
|
1154 cppVariantToWebString(arguments[2]), |
|
1155 arguments[3].toBoolean()); |
|
1156 } |
|
1157 |
|
1158 void LayoutTestController::clearAllDatabases(const CppArgumentList& arguments, CppVariant* result) |
|
1159 { |
|
1160 result->setNull(); |
|
1161 webkit_support::ClearAllDatabases(); |
|
1162 } |
|
1163 |
|
1164 void LayoutTestController::setDatabaseQuota(const CppArgumentList& arguments, CppVariant* result) |
|
1165 { |
|
1166 result->setNull(); |
|
1167 if ((arguments.size() >= 1) && arguments[0].isInt32()) |
|
1168 webkit_support::SetDatabaseQuota(arguments[0].toInt32()); |
|
1169 } |
|
1170 |
|
1171 void LayoutTestController::setPOSIXLocale(const CppArgumentList& arguments, CppVariant* result) |
|
1172 { |
|
1173 result->setNull(); |
|
1174 if (arguments.size() == 1 && arguments[0].isString()) |
|
1175 setlocale(LC_ALL, arguments[0].toString().c_str()); |
|
1176 } |
|
1177 |
|
1178 void LayoutTestController::counterValueForElementById(const CppArgumentList& arguments, CppVariant* result) |
|
1179 { |
|
1180 result->setNull(); |
|
1181 if (arguments.size() < 1 || !arguments[0].isString()) |
|
1182 return; |
|
1183 WebFrame* frame = m_shell->webView()->mainFrame(); |
|
1184 if (!frame) |
|
1185 return; |
|
1186 WebString counterValue = frame->counterValueForElementById(cppVariantToWebString(arguments[0])); |
|
1187 if (counterValue.isNull()) |
|
1188 return; |
|
1189 result->set(counterValue.utf8()); |
|
1190 } |
|
1191 |
|
1192 static bool parsePageSizeParameters(const CppArgumentList& arguments, |
|
1193 int argOffset, |
|
1194 float* pageWidthInPixels, |
|
1195 float* pageHeightInPixels) |
|
1196 { |
|
1197 // WebKit is using the window width/height of DumpRenderTree as the |
|
1198 // default value of the page size. |
|
1199 // FIXME: share these values with other ports. |
|
1200 *pageWidthInPixels = 800; |
|
1201 *pageHeightInPixels = 600; |
|
1202 switch (arguments.size() - argOffset) { |
|
1203 case 2: |
|
1204 if (!arguments[argOffset].isNumber() || !arguments[1 + argOffset].isNumber()) |
|
1205 return false; |
|
1206 *pageWidthInPixels = static_cast<float>(arguments[argOffset].toInt32()); |
|
1207 *pageHeightInPixels = static_cast<float>(arguments[1 + argOffset].toInt32()); |
|
1208 // fall through. |
|
1209 case 0: |
|
1210 break; |
|
1211 default: |
|
1212 return false; |
|
1213 } |
|
1214 return true; |
|
1215 } |
|
1216 |
|
1217 void LayoutTestController::pageNumberForElementById(const CppArgumentList& arguments, CppVariant* result) |
|
1218 { |
|
1219 result->setNull(); |
|
1220 float pageWidthInPixels = 0; |
|
1221 float pageHeightInPixels = 0; |
|
1222 if (!parsePageSizeParameters(arguments, 1, |
|
1223 &pageWidthInPixels, &pageHeightInPixels)) |
|
1224 return; |
|
1225 if (!arguments[0].isString()) |
|
1226 return; |
|
1227 WebFrame* frame = m_shell->webView()->mainFrame(); |
|
1228 if (!frame) |
|
1229 return; |
|
1230 result->set(frame->pageNumberForElementById(cppVariantToWebString(arguments[0]), |
|
1231 pageWidthInPixels, pageHeightInPixels)); |
|
1232 } |
|
1233 |
|
1234 void LayoutTestController::numberOfPages(const CppArgumentList& arguments, CppVariant* result) |
|
1235 { |
|
1236 result->setNull(); |
|
1237 float pageWidthInPixels = 0; |
|
1238 float pageHeightInPixels = 0; |
|
1239 if (!parsePageSizeParameters(arguments, 0, &pageWidthInPixels, &pageHeightInPixels)) |
|
1240 return; |
|
1241 |
|
1242 WebFrame* frame = m_shell->webView()->mainFrame(); |
|
1243 if (!frame) |
|
1244 return; |
|
1245 WebSize size(pageWidthInPixels, pageHeightInPixels); |
|
1246 int numberOfPages = frame->printBegin(size); |
|
1247 frame->printEnd(); |
|
1248 result->set(numberOfPages); |
|
1249 } |
|
1250 |
|
1251 void LayoutTestController::logErrorToConsole(const std::string& text) |
|
1252 { |
|
1253 m_shell->webViewHost()->didAddMessageToConsole( |
|
1254 WebConsoleMessage(WebConsoleMessage::LevelError, WebString::fromUTF8(text)), |
|
1255 WebString(), 0); |
|
1256 } |
|
1257 |
|
1258 void LayoutTestController::setTimelineProfilingEnabled(const CppArgumentList& arguments, CppVariant* result) |
|
1259 { |
|
1260 result->setNull(); |
|
1261 if (arguments.size() < 1 || !arguments[0].isBool()) |
|
1262 return; |
|
1263 m_shell->drtDevToolsAgent()->setTimelineProfilingEnabled(arguments[0].toBoolean()); |
|
1264 } |
|
1265 |
|
1266 void LayoutTestController::evaluateInWebInspector(const CppArgumentList& arguments, CppVariant* result) |
|
1267 { |
|
1268 result->setNull(); |
|
1269 if (arguments.size() < 2 || !arguments[0].isInt32() || !arguments[1].isString()) |
|
1270 return; |
|
1271 m_shell->drtDevToolsAgent()->evaluateInWebInspector(arguments[0].toInt32(), arguments[1].toString()); |
|
1272 } |
|
1273 |
|
1274 void LayoutTestController::forceRedSelectionColors(const CppArgumentList& arguments, CppVariant* result) |
|
1275 { |
|
1276 result->setNull(); |
|
1277 m_shell->webView()->setSelectionColors(0xffee0000, 0xff00ee00, 0xff000000, 0xffc0c0c0); |
|
1278 } |
|
1279 |
|
1280 void LayoutTestController::addUserScript(const CppArgumentList& arguments, CppVariant* result) |
|
1281 { |
|
1282 result->setNull(); |
|
1283 if (arguments.size() < 3 || !arguments[0].isString() || !arguments[1].isBool() || !arguments[2].isBool()) |
|
1284 return; |
|
1285 WebView::addUserScript( |
|
1286 cppVariantToWebString(arguments[0]), WebVector<WebString>(), |
|
1287 arguments[1].toBoolean() ? WebView::UserScriptInjectAtDocumentStart : WebView::UserScriptInjectAtDocumentEnd, |
|
1288 arguments[2].toBoolean() ? WebView::UserContentInjectInAllFrames : WebView::UserContentInjectInTopFrameOnly); |
|
1289 } |
|
1290 |
|
1291 void LayoutTestController::addUserStyleSheet(const CppArgumentList& arguments, CppVariant* result) |
|
1292 { |
|
1293 result->setNull(); |
|
1294 if (arguments.size() < 2 || !arguments[0].isString() || !arguments[1].isBool()) |
|
1295 return; |
|
1296 WebView::addUserStyleSheet( |
|
1297 cppVariantToWebString(arguments[0]), WebVector<WebString>(), |
|
1298 arguments[2].toBoolean() ? WebView::UserContentInjectInAllFrames : WebView::UserContentInjectInTopFrameOnly); |
|
1299 } |
|
1300 |
|
1301 void LayoutTestController::setEditingBehavior(const CppArgumentList& arguments, CppVariant* results) |
|
1302 { |
|
1303 WebSettings* settings = m_shell->webView()->settings(); |
|
1304 string key = arguments[0].toString(); |
|
1305 if (key == "mac") |
|
1306 settings->setEditingBehavior(WebSettings::EditingBehaviorMac); |
|
1307 else if (key == "win") |
|
1308 settings->setEditingBehavior(WebSettings::EditingBehaviorWin); |
|
1309 else |
|
1310 logErrorToConsole("Passed invalid editing behavior. Should be 'mac' or 'win'."); |
|
1311 } |
|
1312 |
|
1313 void LayoutTestController::setGeolocationPermission(const CppArgumentList& arguments, CppVariant* result) |
|
1314 { |
|
1315 result->setNull(); |
|
1316 if (arguments.size() < 1 || !arguments[0].isBool()) |
|
1317 return; |
|
1318 WebGeolocationServiceMock::setMockGeolocationPermission(arguments[0].toBoolean()); |
|
1319 } |
|
1320 |
|
1321 void LayoutTestController::setMockGeolocationPosition(const CppArgumentList& arguments, CppVariant* result) |
|
1322 { |
|
1323 result->setNull(); |
|
1324 if (arguments.size() < 3 || !arguments[0].isNumber() || !arguments[1].isNumber() || !arguments[2].isNumber()) |
|
1325 return; |
|
1326 WebGeolocationServiceMock::setMockGeolocationPosition(arguments[0].toDouble(), arguments[1].toDouble(), arguments[2].toDouble()); |
|
1327 } |
|
1328 |
|
1329 void LayoutTestController::setMockGeolocationError(const CppArgumentList& arguments, CppVariant* result) |
|
1330 { |
|
1331 result->setNull(); |
|
1332 if (arguments.size() < 2 || !arguments[0].isInt32() || !arguments[1].isString()) |
|
1333 return; |
|
1334 WebGeolocationServiceMock::setMockGeolocationError(arguments[0].toInt32(), cppVariantToWebString(arguments[1])); |
|
1335 } |
|
1336 |
|
1337 void LayoutTestController::abortModal(const CppArgumentList& arguments, CppVariant* result) |
|
1338 { |
|
1339 result->setNull(); |
|
1340 } |
|