OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2010, 2011, 2012 Google 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 are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | |
31 #include "config.h" | |
32 #include "WebViewHost.h" | |
33 | |
34 #include "DRTDevToolsAgent.h" | |
35 #include "Task.h" | |
36 #include "TestNavigationController.h" | |
37 #include "TestShell.h" | |
38 #include "WebCachedURLRequest.h" | |
39 #include "WebConsoleMessage.h" | |
40 #include "WebContextMenuData.h" | |
41 #include "WebDOMMessageEvent.h" | |
42 #include "WebDataSource.h" | |
43 #include "WebDocument.h" | |
44 #include "WebElement.h" | |
45 #include "WebFrame.h" | |
46 #include "WebHistoryItem.h" | |
47 #include "WebKit.h" | |
48 #include "WebNode.h" | |
49 #include "WebPluginParams.h" | |
50 #include "WebPopupMenu.h" | |
51 #include "WebPopupType.h" | |
52 #include "WebPrintParams.h" | |
53 #include "WebRange.h" | |
54 #include "WebScreenInfo.h" | |
55 #include "WebSerializedScriptValue.h" | |
56 #include "WebUserGestureIndicator.h" | |
57 #include "WebView.h" | |
58 #include "WebWindowFeatures.h" | |
59 #include "webkit/support/test_media_stream_client.h" | |
60 #include "webkit/support/webkit_support.h" | |
61 #include <cctype> | |
62 #include <clocale> | |
63 #include "public/platform/WebCString.h" | |
64 #include "public/platform/WebCompositorOutputSurface.h" | |
65 #include "public/platform/WebCompositorSupport.h" | |
66 #include "public/platform/WebDragData.h" | |
67 #include "public/platform/WebRect.h" | |
68 #include "public/platform/WebSize.h" | |
69 #include "public/platform/WebStorageNamespace.h" | |
70 #include "public/platform/WebThread.h" | |
71 #include "public/platform/WebURLRequest.h" | |
72 #include "public/platform/WebURLResponse.h" | |
73 | |
74 #include <wtf/Assertions.h> | |
75 #include <wtf/OwnArrayPtr.h> | |
76 #include <wtf/PassOwnPtr.h> | |
77 #include <wtf/Vector.h> | |
78 | |
79 using namespace WebCore; | |
80 using namespace WebKit; | |
81 using namespace WebTestRunner; | |
82 using namespace std; | |
83 | |
84 static const int screenWidth = 1920; | |
85 static const int screenHeight = 1080; | |
86 | |
87 const int WebViewHost::screenUnavailableBorder = 8; | |
88 | |
89 static int nextPageID = 1; | |
90 | |
91 // WebViewClient ------------------------------------------------------------- | |
92 | |
93 WebView* WebViewHost::createView(WebFrame* creator, const WebURLRequest&, const
WebWindowFeatures&, const WebString&, WebNavigationPolicy) | |
94 { | |
95 WebUserGestureIndicator::consumeUserGesture(); | |
96 return m_shell->createNewWindow(WebURL())->webView(); | |
97 } | |
98 | |
99 WebWidget* WebViewHost::createPopupMenu(WebPopupType type) | |
100 { | |
101 switch (type) { | |
102 case WebKit::WebPopupTypeNone: | |
103 case WebKit::WebPopupTypePage: | |
104 case WebKit::WebPopupTypeHelperPlugin: | |
105 break; | |
106 case WebKit::WebPopupTypeSelect: | |
107 case WebKit::WebPopupTypeSuggestion: | |
108 m_popupmenus.append(WebPopupMenu::create(0)); | |
109 return m_popupmenus.last(); | |
110 } | |
111 return 0; | |
112 } | |
113 | |
114 WebWidget* WebViewHost::createPopupMenu(const WebPopupMenuInfo&) | |
115 { | |
116 // Do not use this method. It's been replaced by createExternalPopupMenu. | |
117 ASSERT_NOT_REACHED(); | |
118 return 0; | |
119 } | |
120 | |
121 WebStorageNamespace* WebViewHost::createSessionStorageNamespace(unsigned quota) | |
122 { | |
123 return webkit_support::CreateSessionStorageNamespace(quota); | |
124 } | |
125 | |
126 void WebViewHost::didAddMessageToConsole(const WebConsoleMessage& message, const
WebString& sourceName, unsigned sourceLine) | |
127 { | |
128 } | |
129 | |
130 void WebViewHost::didStartLoading() | |
131 { | |
132 } | |
133 | |
134 void WebViewHost::didStopLoading() | |
135 { | |
136 } | |
137 | |
138 bool WebViewHost::shouldBeginEditing(const WebRange& range) | |
139 { | |
140 return true; | |
141 } | |
142 | |
143 bool WebViewHost::shouldEndEditing(const WebRange& range) | |
144 { | |
145 return true; | |
146 } | |
147 | |
148 bool WebViewHost::shouldInsertNode(const WebNode& node, const WebRange& range, W
ebEditingAction action) | |
149 { | |
150 return true; | |
151 } | |
152 | |
153 bool WebViewHost::shouldInsertText(const WebString& text, const WebRange& range,
WebEditingAction action) | |
154 { | |
155 return true; | |
156 } | |
157 | |
158 bool WebViewHost::shouldChangeSelectedRange( | |
159 const WebRange& fromRange, const WebRange& toRange, WebTextAffinity affinity
, bool stillSelecting) | |
160 { | |
161 return true; | |
162 } | |
163 | |
164 bool WebViewHost::shouldDeleteRange(const WebRange& range) | |
165 { | |
166 return true; | |
167 } | |
168 | |
169 bool WebViewHost::shouldApplyStyle(const WebString& style, const WebRange& range
) | |
170 { | |
171 return true; | |
172 } | |
173 | |
174 bool WebViewHost::handleCurrentKeyboardEvent() | |
175 { | |
176 if (m_editCommandName.empty()) | |
177 return false; | |
178 WebFrame* frame = webView()->focusedFrame(); | |
179 if (!frame) | |
180 return false; | |
181 | |
182 return frame->executeCommand(WebString::fromUTF8(m_editCommandName), WebStri
ng::fromUTF8(m_editCommandValue)); | |
183 } | |
184 | |
185 // WebKit::WebPrerendererClient | |
186 | |
187 void WebViewHost::willAddPrerender(WebKit::WebPrerender*) | |
188 { | |
189 } | |
190 | |
191 | |
192 void WebViewHost::runModalAlertDialog(WebFrame*, const WebString& message) | |
193 { | |
194 } | |
195 | |
196 bool WebViewHost::runModalConfirmDialog(WebFrame*, const WebString& message) | |
197 { | |
198 return true; | |
199 } | |
200 | |
201 bool WebViewHost::runModalPromptDialog(WebFrame* frame, const WebString& message
, | |
202 const WebString& defaultValue, WebString*
) | |
203 { | |
204 return true; | |
205 } | |
206 | |
207 void WebViewHost::showContextMenu(WebFrame*, const WebContextMenuData& contextMe
nuData) | |
208 { | |
209 } | |
210 | |
211 void WebViewHost::didUpdateLayout() | |
212 { | |
213 #if OS(DARWIN) | |
214 static bool queryingPreferredSize = false; | |
215 if (queryingPreferredSize) | |
216 return; | |
217 | |
218 queryingPreferredSize = true; | |
219 // Query preferred width to emulate the same functionality in Chromium: | |
220 // see RenderView::CheckPreferredSize (src/content/renderer/render_view.cc) | |
221 // and TabContentsViewMac::RenderViewCreated (src/chrome/browser/tab_content
s/tab_contents_view_mac.mm) | |
222 webView()->contentsPreferredMinimumSize(); | |
223 queryingPreferredSize = false; | |
224 #endif | |
225 } | |
226 | |
227 void WebViewHost::navigateBackForwardSoon(int offset) | |
228 { | |
229 navigationController()->goToOffset(offset); | |
230 } | |
231 | |
232 int WebViewHost::historyBackListCount() | |
233 { | |
234 return navigationController()->lastCommittedEntryIndex(); | |
235 } | |
236 | |
237 int WebViewHost::historyForwardListCount() | |
238 { | |
239 int currentIndex =navigationController()->lastCommittedEntryIndex(); | |
240 return navigationController()->entryCount() - currentIndex - 1; | |
241 } | |
242 | |
243 // WebWidgetClient ----------------------------------------------------------- | |
244 | |
245 void WebViewHost::didAutoResize(const WebSize& newSize) | |
246 { | |
247 // Purposely don't include the virtualWindowBorder in this case so that | |
248 // window.inner[Width|Height] is the same as window.outer[Width|Height] | |
249 setWindowRect(WebRect(0, 0, newSize.width, newSize.height)); | |
250 } | |
251 | |
252 class WebViewHostDRTLayerTreeViewClient : public webkit_support::DRTLayerTreeVie
wClient { | |
253 public: | |
254 explicit WebViewHostDRTLayerTreeViewClient(WebViewHost* host) | |
255 : m_host(host) { } | |
256 virtual ~WebViewHostDRTLayerTreeViewClient() { } | |
257 | |
258 virtual void Layout() { m_host->webView()->layout(); } | |
259 virtual void ScheduleComposite() { m_host->proxy()->scheduleComposite(); } | |
260 | |
261 private: | |
262 WebViewHost* m_host; | |
263 }; | |
264 | |
265 void WebViewHost::initializeLayerTreeView() | |
266 { | |
267 m_layerTreeViewClient = adoptPtr(new WebViewHostDRTLayerTreeViewClient(this)
); | |
268 if (m_shell->softwareCompositingEnabled()) { | |
269 m_layerTreeView = adoptPtr(webkit_support::CreateLayerTreeView( | |
270 webkit_support::SOFTWARE_CONTEXT, | |
271 m_layerTreeViewClient.get(), | |
272 m_shell->webCompositorThread())); | |
273 } else { | |
274 m_layerTreeView = adoptPtr(webkit_support::CreateLayerTreeView( | |
275 webkit_support::MESA_CONTEXT, | |
276 m_layerTreeViewClient.get(), | |
277 m_shell->webCompositorThread())); | |
278 } | |
279 | |
280 ASSERT(m_layerTreeView); | |
281 updateViewportSize(); | |
282 m_layerTreeView->setSurfaceReady(); | |
283 } | |
284 | |
285 WebLayerTreeView* WebViewHost::layerTreeView() | |
286 { | |
287 return m_layerTreeView.get(); | |
288 } | |
289 | |
290 void WebViewHost::scheduleAnimation() | |
291 { | |
292 if (m_finished) { | |
293 return; | |
294 } | |
295 if (!m_animateScheduled) { | |
296 m_animateScheduled = true; | |
297 postDelayedTask(new HostMethodTask(this, &WebViewHost::animateNow), 1); | |
298 } | |
299 } | |
300 | |
301 void WebViewHost::animateNow() | |
302 { | |
303 if (m_animateScheduled) { | |
304 m_animateScheduled = false; | |
305 webView()->animate(0.0); | |
306 } | |
307 } | |
308 | |
309 void WebViewHost::didFocus() | |
310 { | |
311 } | |
312 | |
313 void WebViewHost::didBlur() | |
314 { | |
315 } | |
316 | |
317 WebScreenInfo WebViewHost::screenInfo() | |
318 { | |
319 // We don't need to set actual values. | |
320 WebScreenInfo info; | |
321 info.depth = 24; | |
322 info.depthPerComponent = 8; | |
323 info.isMonochrome = false; | |
324 info.rect = WebRect(0, 0, screenWidth, screenHeight); | |
325 // Use values different from info.rect for testing. | |
326 info.availableRect = WebRect(screenUnavailableBorder, screenUnavailableBorde
r, | |
327 screenWidth - screenUnavailableBorder * 2, | |
328 screenHeight - screenUnavailableBorder * 2); | |
329 return info; | |
330 } | |
331 | |
332 void WebViewHost::show(WebNavigationPolicy) | |
333 { | |
334 m_hasWindow = true; | |
335 } | |
336 | |
337 | |
338 | |
339 void WebViewHost::closeWidget() | |
340 { | |
341 m_hasWindow = false; | |
342 m_shell->closeWindow(this); | |
343 // No more code here, we should be deleted at this point. | |
344 } | |
345 | |
346 void WebViewHost::closeWidgetSoon() | |
347 { | |
348 postDelayedTask(new HostMethodTask(this, &WebViewHost::closeWidget), 0); | |
349 } | |
350 | |
351 void WebViewHost::didChangeCursor(const WebCursorInfo& cursorInfo) | |
352 { | |
353 if (!hasWindow()) | |
354 return; | |
355 m_currentCursor = cursorInfo; | |
356 } | |
357 | |
358 WebRect WebViewHost::windowRect() | |
359 { | |
360 return m_windowRect; | |
361 } | |
362 | |
363 void WebViewHost::setWindowRect(const WebRect& rect) | |
364 { | |
365 m_windowRect = rect; | |
366 const int border2 = TestShell::virtualWindowBorder * 2; | |
367 if (m_windowRect.width <= border2) | |
368 m_windowRect.width = 1 + border2; | |
369 if (m_windowRect.height <= border2) | |
370 m_windowRect.height = 1 + border2; | |
371 int width = m_windowRect.width - border2; | |
372 int height = m_windowRect.height - border2; | |
373 webWidget()->resize(WebSize(width, height)); | |
374 updateViewportSize(); | |
375 } | |
376 | |
377 WebRect WebViewHost::rootWindowRect() | |
378 { | |
379 return windowRect(); | |
380 } | |
381 | |
382 WebRect WebViewHost::windowResizerRect() | |
383 { | |
384 // Not necessary. | |
385 return WebRect(); | |
386 } | |
387 | |
388 void WebViewHost::runModal() | |
389 { | |
390 if (m_shell->isDisplayingModalDialog()) { | |
391 // DumpRenderTree doesn't support real modal dialogs, so a test shouldn'
t try to start two modal dialogs at the same time. | |
392 ASSERT_NOT_REACHED(); | |
393 return; | |
394 } | |
395 // This WebViewHost might get deleted before RunMessageLoop() returns, so ke
ep a copy of the m_shell member variable around. | |
396 ASSERT(m_shell->webViewHost() != this); | |
397 TestShell* shell = m_shell; | |
398 shell->setIsDisplayingModalDialog(true); | |
399 bool oldState = webkit_support::MessageLoopNestableTasksAllowed(); | |
400 webkit_support::MessageLoopSetNestableTasksAllowed(true); | |
401 m_inModalLoop = true; | |
402 webkit_support::RunMessageLoop(); | |
403 webkit_support::MessageLoopSetNestableTasksAllowed(oldState); | |
404 shell->setIsDisplayingModalDialog(false); | |
405 } | |
406 | |
407 bool WebViewHost::enterFullScreen() | |
408 { | |
409 postDelayedTask(new HostMethodTask(this, &WebViewHost::enterFullScreenNow),
0); | |
410 return true; | |
411 } | |
412 | |
413 void WebViewHost::exitFullScreen() | |
414 { | |
415 postDelayedTask(new HostMethodTask(this, &WebViewHost::exitFullScreenNow), 0
); | |
416 } | |
417 | |
418 // WebFrameClient ------------------------------------------------------------ | |
419 | |
420 WebPlugin* WebViewHost::createPlugin(WebFrame* frame, const WebPluginParams& par
ams) | |
421 { | |
422 return webkit_support::CreateWebPlugin(frame, params); | |
423 } | |
424 | |
425 WebApplicationCacheHost* WebViewHost::createApplicationCacheHost(WebFrame* frame
, WebApplicationCacheHostClient* client) | |
426 { | |
427 return webkit_support::CreateApplicationCacheHost(frame, client); | |
428 } | |
429 | |
430 void WebViewHost::loadURLExternally(WebFrame* frame, const WebURLRequest& reques
t, WebNavigationPolicy policy) | |
431 { | |
432 loadURLExternally(frame, request, policy, WebString()); | |
433 } | |
434 | |
435 void WebViewHost::loadURLExternally(WebFrame*, const WebURLRequest& request, Web
NavigationPolicy policy, const WebString& downloadName) | |
436 { | |
437 ASSERT(policy != WebKit::WebNavigationPolicyCurrentTab); | |
438 WebViewHost* another = m_shell->createNewWindow(request.url()); | |
439 if (another) | |
440 another->show(policy); | |
441 } | |
442 | |
443 WebNavigationPolicy WebViewHost::decidePolicyForNavigation( | |
444 WebFrame*, const WebURLRequest&, WebNavigationType, WebNavigationPolicy defa
ultPolicy, bool) | |
445 { | |
446 return defaultPolicy; | |
447 } | |
448 | |
449 WebURLError WebViewHost::cancelledError(WebFrame*, const WebURLRequest& request) | |
450 { | |
451 return webkit_support::CreateCancelledError(request); | |
452 } | |
453 | |
454 void WebViewHost::unableToImplementPolicyWithError(WebFrame* frame, const WebURL
Error& error) | |
455 { | |
456 } | |
457 | |
458 void WebViewHost::didCreateDataSource(WebFrame*, WebDataSource* ds) | |
459 { | |
460 ds->setExtraData(m_pendingExtraData.leakPtr()); | |
461 } | |
462 | |
463 void WebViewHost::didCommitProvisionalLoad(WebFrame* frame, bool isNewNavigation
) | |
464 { | |
465 updateForCommittedLoad(frame, isNewNavigation); | |
466 } | |
467 | |
468 void WebViewHost::didClearWindowObject(WebFrame* frame) | |
469 { | |
470 m_shell->bindJSObjectsToWindow(frame); | |
471 } | |
472 | |
473 void WebViewHost::didReceiveTitle(WebFrame* frame, const WebString& title, WebTe
xtDirection direction) | |
474 { | |
475 setPageTitle(title); | |
476 } | |
477 | |
478 void WebViewHost::didChangeIcon(WebFrame* , WebIconURL::Type) | |
479 { | |
480 } | |
481 | |
482 void WebViewHost::didNavigateWithinPage(WebFrame* frame, bool isNewNavigation) | |
483 { | |
484 frame->dataSource()->setExtraData(m_pendingExtraData.leakPtr()); | |
485 | |
486 updateForCommittedLoad(frame, isNewNavigation); | |
487 } | |
488 | |
489 void WebViewHost::willSendRequest(WebFrame* frame, unsigned, WebURLRequest& requ
est, const WebURLResponse&) | |
490 { | |
491 if (request.url().isEmpty()) | |
492 return; | |
493 | |
494 request.setExtraData(webkit_support::CreateWebURLRequestExtraData(frame->doc
ument().referrerPolicy())); | |
495 } | |
496 | |
497 void WebViewHost::openFileSystem(WebFrame* frame, WebFileSystemType type, long l
ong size, bool create, WebFileSystemCallbacks* callbacks) | |
498 { | |
499 webkit_support::OpenFileSystem(frame, type, size, create, callbacks); | |
500 } | |
501 | |
502 void WebViewHost::deleteFileSystem(WebKit::WebFrame* frame, WebKit::WebFileSyste
mType type, WebKit::WebFileSystemCallbacks* callbacks) | |
503 { | |
504 webkit_support::DeleteFileSystem(frame, type, callbacks); | |
505 } | |
506 | |
507 bool WebViewHost::willCheckAndDispatchMessageEvent(WebFrame* sourceFrame, WebFra
me* targetFrame, WebSecurityOrigin target, WebDOMMessageEvent event) | |
508 { | |
509 return false; | |
510 } | |
511 | |
512 // WebTestDelegate ------------------------------------------------------------ | |
513 | |
514 void WebViewHost::setEditCommand(const string& name, const string& value) | |
515 { | |
516 m_editCommandName = name; | |
517 m_editCommandValue = value; | |
518 } | |
519 | |
520 void WebViewHost::clearEditCommand() | |
521 { | |
522 m_editCommandName.clear(); | |
523 m_editCommandValue.clear(); | |
524 } | |
525 | |
526 void WebViewHost::setGamepadData(const WebGamepads& pads) | |
527 { | |
528 webkit_support::SetGamepadData(pads); | |
529 } | |
530 | |
531 void WebViewHost::printMessage(const std::string& message) | |
532 { | |
533 printf("%s", message.c_str()); | |
534 } | |
535 | |
536 void WebViewHost::postTask(WebTask* task) | |
537 { | |
538 ::postTask(task); | |
539 } | |
540 | |
541 void WebViewHost::postDelayedTask(WebTask* task, long long ms) | |
542 { | |
543 ::postDelayedTask(task, ms); | |
544 } | |
545 | |
546 WebString WebViewHost::registerIsolatedFileSystem(const WebVector<WebString>& ab
soluteFilenames) | |
547 { | |
548 return webkit_support::RegisterIsolatedFileSystem(absoluteFilenames); | |
549 } | |
550 | |
551 long long WebViewHost::getCurrentTimeInMillisecond() | |
552 { | |
553 return webkit_support::GetCurrentTimeInMillisecond(); | |
554 } | |
555 | |
556 WebKit::WebString WebViewHost::getAbsoluteWebStringFromUTF8Path(const std::strin
g& path) | |
557 { | |
558 return webkit_support::GetAbsoluteWebStringFromUTF8Path(path); | |
559 } | |
560 | |
561 WebURL WebViewHost::localFileToDataURL(const WebKit::WebURL& url) | |
562 { | |
563 return webkit_support::LocalFileToDataURL(url); | |
564 } | |
565 | |
566 WebURL WebViewHost::rewriteLayoutTestsURL(const std::string& url) | |
567 { | |
568 return webkit_support::RewriteLayoutTestsURL(url); | |
569 } | |
570 | |
571 WebPreferences* WebViewHost::preferences() | |
572 { | |
573 return m_shell->preferences(); | |
574 } | |
575 | |
576 void WebViewHost::applyPreferences() | |
577 { | |
578 m_shell->applyPreferences(); | |
579 } | |
580 | |
581 std::string WebViewHost::makeURLErrorDescription(const WebKit::WebURLError& erro
r) | |
582 { | |
583 return webkit_support::MakeURLErrorDescription(error); | |
584 } | |
585 | |
586 void WebViewHost::showDevTools() | |
587 { | |
588 m_shell->showDevTools(); | |
589 } | |
590 | |
591 void WebViewHost::closeDevTools() | |
592 { | |
593 m_shell->closeDevTools(); | |
594 } | |
595 | |
596 void WebViewHost::evaluateInWebInspector(long callID, const std::string& script) | |
597 { | |
598 m_shell->drtDevToolsAgent()->evaluateInWebInspector(callID, script); | |
599 } | |
600 | |
601 void WebViewHost::clearAllDatabases() | |
602 { | |
603 webkit_support::ClearAllDatabases(); | |
604 } | |
605 | |
606 void WebViewHost::setDatabaseQuota(int quota) | |
607 { | |
608 webkit_support::SetDatabaseQuota(quota); | |
609 } | |
610 | |
611 void WebViewHost::setDeviceScaleFactor(float deviceScaleFactor) | |
612 { | |
613 webView()->setDeviceScaleFactor(deviceScaleFactor); | |
614 updateViewportSize(); | |
615 } | |
616 | |
617 void WebViewHost::setFocus(WebTestProxyBase* proxy, bool focused) | |
618 { | |
619 for (size_t i = 0; i < m_shell->windowList().size(); ++i) { | |
620 if (m_shell->windowList()[i]->proxy() == proxy) | |
621 m_shell->setFocus(m_shell->windowList()[i]->webWidget(), focused); | |
622 } | |
623 } | |
624 | |
625 void WebViewHost::setAcceptAllCookies(bool acceptCookies) | |
626 { | |
627 webkit_support::SetAcceptAllCookies(acceptCookies); | |
628 } | |
629 | |
630 string WebViewHost::pathToLocalResource(const string& url) | |
631 { | |
632 #if OS(WINDOWS) | |
633 if (!url.find("/tmp/")) { | |
634 // We want a temp file. | |
635 const unsigned tempPrefixLength = 5; | |
636 size_t bufferSize = MAX_PATH; | |
637 OwnArrayPtr<WCHAR> tempPath = adoptArrayPtr(new WCHAR[bufferSize]); | |
638 DWORD tempLength = ::GetTempPathW(bufferSize, tempPath.get()); | |
639 if (tempLength + url.length() - tempPrefixLength + 1 > bufferSize) { | |
640 bufferSize = tempLength + url.length() - tempPrefixLength + 1; | |
641 tempPath = adoptArrayPtr(new WCHAR[bufferSize]); | |
642 tempLength = GetTempPathW(bufferSize, tempPath.get()); | |
643 ASSERT(tempLength < bufferSize); | |
644 } | |
645 string resultPath(WebString(tempPath.get(), tempLength).utf8()); | |
646 resultPath.append(url.substr(tempPrefixLength)); | |
647 return resultPath; | |
648 } | |
649 #endif | |
650 | |
651 // Some layout tests use file://// which we resolve as a UNC path. Normalize | |
652 // them to just file:///. | |
653 string lowerUrl = url; | |
654 string result = url; | |
655 transform(lowerUrl.begin(), lowerUrl.end(), lowerUrl.begin(), ::tolower); | |
656 while (!lowerUrl.find("file:////")) { | |
657 result = result.substr(0, 8) + result.substr(9); | |
658 lowerUrl = lowerUrl.substr(0, 8) + lowerUrl.substr(9); | |
659 } | |
660 return webkit_support::RewriteLayoutTestsURL(result).spec(); | |
661 } | |
662 | |
663 void WebViewHost::setLocale(const std::string& locale) | |
664 { | |
665 setlocale(LC_ALL, locale.c_str()); | |
666 } | |
667 | |
668 void WebViewHost::testFinished() | |
669 { | |
670 m_finished = true; | |
671 m_shell->testFinished(this); | |
672 } | |
673 | |
674 void WebViewHost::closeRemainingWindows() | |
675 { | |
676 m_shell->closeRemainingWindows(); | |
677 } | |
678 | |
679 int WebViewHost::navigationEntryCount() | |
680 { | |
681 return m_shell->navigationEntryCount(); | |
682 } | |
683 | |
684 void WebViewHost::goToOffset(int offset) | |
685 { | |
686 m_shell->goToOffset(offset); | |
687 } | |
688 | |
689 void WebViewHost::reload() | |
690 { | |
691 m_shell->reload(); | |
692 } | |
693 | |
694 void WebViewHost::loadURLForFrame(const WebURL& url, const string& frameName) | |
695 { | |
696 if (!url.isValid()) | |
697 return; | |
698 TestShell::resizeWindowForTest(this, url); | |
699 navigationController()->loadEntry(TestNavigationEntry::create(-1, url, WebSt
ring(), WebString::fromUTF8(frameName)).get()); | |
700 } | |
701 | |
702 bool WebViewHost::allowExternalPages() | |
703 { | |
704 return m_shell->allowExternalPages(); | |
705 } | |
706 | |
707 void WebViewHost::captureHistoryForWindow(WebTestProxyBase* proxy, WebVector<Web
HistoryItem>* history, size_t* currentEntryIndex) | |
708 { | |
709 for (size_t i = 0; i < m_shell->windowList().size(); ++i) { | |
710 if (m_shell->windowList()[i]->proxy() == proxy) | |
711 m_shell->captureHistoryForWindow(i, history, currentEntryIndex); | |
712 } | |
713 } | |
714 | |
715 WebMediaPlayer* WebViewHost::createWebMediaPlayer(WebFrame* frame, const WebURL&
url, WebMediaPlayerClient* client) | |
716 { | |
717 return webkit_support::CreateMediaPlayer(frame, url, client, | |
718 testMediaStreamClient() | |
719 ); | |
720 } | |
721 | |
722 // Public functions ----------------------------------------------------------- | |
723 | |
724 WebViewHost::WebViewHost(TestShell* shell) | |
725 : m_shell(shell) | |
726 , m_proxy(0) | |
727 , m_webWidget(0) | |
728 , m_shutdownWasInvoked(false) | |
729 { | |
730 reset(); | |
731 } | |
732 | |
733 WebViewHost::~WebViewHost() | |
734 { | |
735 ASSERT(m_shutdownWasInvoked); | |
736 if (m_inModalLoop) | |
737 webkit_support::QuitMessageLoop(); | |
738 } | |
739 | |
740 void WebViewHost::shutdown() | |
741 { | |
742 ASSERT(!m_shutdownWasInvoked); | |
743 | |
744 // DevTools frontend page is supposed to be navigated only once and | |
745 // loading another URL in that Page is an error. | |
746 if (m_shell->devToolsWebView() != this) { | |
747 // Navigate to an empty page to fire all the destruction logic for the | |
748 // current page. | |
749 loadURLForFrame(GURL("about:blank"), string()); | |
750 } | |
751 | |
752 for (Vector<WebKit::WebWidget*>::iterator it = m_popupmenus.begin(); | |
753 it < m_popupmenus.end(); ++it) | |
754 (*it)->close(); | |
755 | |
756 webWidget()->willCloseLayerTreeView(); | |
757 m_layerTreeView.clear(); | |
758 webWidget()->close(); | |
759 m_webWidget = 0; | |
760 m_shutdownWasInvoked = true; | |
761 } | |
762 | |
763 void WebViewHost::setWebWidget(WebKit::WebWidget* widget) | |
764 { | |
765 m_webWidget = widget; | |
766 m_proxy->setWidget(widget); | |
767 webView()->setSpellCheckClient(proxy()->spellCheckClient()); | |
768 webView()->setValidationMessageClient(proxy()->validationMessageClient()); | |
769 webView()->setPrerendererClient(this); | |
770 } | |
771 | |
772 WebView* WebViewHost::webView() const | |
773 { | |
774 ASSERT(m_webWidget); | |
775 // DRT does not support popup widgets. So m_webWidget is always a WebView. | |
776 return static_cast<WebView*>(m_webWidget); | |
777 } | |
778 | |
779 WebWidget* WebViewHost::webWidget() const | |
780 { | |
781 ASSERT(m_webWidget); | |
782 return m_webWidget; | |
783 } | |
784 | |
785 WebTestProxyBase* WebViewHost::proxy() const | |
786 { | |
787 ASSERT(m_proxy); | |
788 return m_proxy; | |
789 } | |
790 | |
791 void WebViewHost::setProxy(WebTestProxyBase* proxy) | |
792 { | |
793 ASSERT(!m_proxy); | |
794 ASSERT(proxy); | |
795 m_proxy = proxy; | |
796 } | |
797 | |
798 void WebViewHost::reset() | |
799 { | |
800 m_pageId = -1; | |
801 m_lastPageIdUpdated = -1; | |
802 m_hasWindow = false; | |
803 m_inModalLoop = false; | |
804 m_animateScheduled = false; | |
805 m_finished = false; | |
806 | |
807 m_navigationController = adoptPtr(new TestNavigationController(this)); | |
808 | |
809 m_pendingExtraData.clear(); | |
810 m_editCommandName.clear(); | |
811 m_editCommandValue.clear(); | |
812 | |
813 m_currentCursor = WebCursorInfo(); | |
814 m_windowRect = WebRect(); | |
815 // m_proxy is not set when reset() is invoked from the constructor. | |
816 if (m_proxy) | |
817 proxy()->reset(); | |
818 | |
819 if (m_webWidget) { | |
820 webView()->mainFrame()->setName(WebString()); | |
821 } | |
822 } | |
823 | |
824 void WebViewHost::setClientWindowRect(const WebKit::WebRect& rect) | |
825 { | |
826 setWindowRect(rect); | |
827 } | |
828 | |
829 void WebViewHost::enableAutoResizeMode(const WebSize& minSize, const WebSize& ma
xSize) | |
830 { | |
831 webView()->enableAutoResizeMode(minSize, maxSize); | |
832 } | |
833 | |
834 void WebViewHost::disableAutoResizeMode(const WebKit::WebSize& newSize) | |
835 { | |
836 if (!newSize.isEmpty()) | |
837 setWindowRect(WebRect(0, 0, newSize.width, newSize.height)); | |
838 webView()->disableAutoResizeMode(); | |
839 if (!newSize.isEmpty()) | |
840 webView()->resize(newSize); | |
841 } | |
842 | |
843 bool WebViewHost::navigate(const TestNavigationEntry& entry, bool reload) | |
844 { | |
845 // Get the right target frame for the entry. | |
846 WebFrame* frame = webView()->mainFrame(); | |
847 if (!entry.targetFrame().isEmpty()) | |
848 frame = webView()->findFrameByName(entry.targetFrame()); | |
849 | |
850 // TODO(mpcomplete): should we clear the target frame, or should | |
851 // back/forward navigations maintain the target frame? | |
852 | |
853 // A navigation resulting from loading a javascript URL should not be | |
854 // treated as a browser initiated event. Instead, we want it to look as if | |
855 // the page initiated any load resulting from JS execution. | |
856 if (!GURL(entry.URL()).SchemeIs("javascript")) | |
857 setPendingExtraData(adoptPtr(new TestShellExtraData(entry.pageID()))); | |
858 | |
859 // If we are reloading, then WebKit will use the state of the current page. | |
860 // Otherwise, we give it the state to navigate to. | |
861 if (reload) { | |
862 frame->reload(false); | |
863 } else if (!entry.contentState().isNull()) { | |
864 ASSERT(entry.pageID() != -1); | |
865 frame->loadHistoryItem(entry.contentState()); | |
866 } else { | |
867 ASSERT(entry.pageID() == -1); | |
868 frame->loadRequest(WebURLRequest(entry.URL())); | |
869 } | |
870 | |
871 // In case LoadRequest failed before DidCreateDataSource was called. | |
872 setPendingExtraData(nullptr); | |
873 | |
874 // Restore focus to the main frame prior to loading new request. | |
875 // This makes sure that we don't have a focused iframe. Otherwise, that | |
876 // iframe would keep focus when the SetFocus called immediately after | |
877 // LoadRequest, thus making some tests fail (see http://b/issue?id=845337 | |
878 // for more details). | |
879 webView()->setFocusedFrame(frame); | |
880 m_shell->setFocus(webView(), true); | |
881 | |
882 return true; | |
883 } | |
884 | |
885 // Private functions ---------------------------------------------------------- | |
886 | |
887 void WebViewHost::updateForCommittedLoad(WebFrame* frame, bool isNewNavigation) | |
888 { | |
889 // Code duplicated from RenderView::DidCommitLoadForFrame. | |
890 TestShellExtraData* extraData = static_cast<TestShellExtraData*>(frame->data
Source()->extraData()); | |
891 const WebURL& url = frame->dataSource()->request().url(); | |
892 bool nonBlankPageAfterReset = m_pageId == -1 && !url.isEmpty() && strcmp(url
.spec().data(), "about:blank"); | |
893 | |
894 if (isNewNavigation || nonBlankPageAfterReset) { | |
895 // New navigation. | |
896 updateSessionHistory(frame); | |
897 m_pageId = nextPageID++; | |
898 } else if (extraData && extraData->pendingPageID != -1 && !extraData->reques
tCommitted) { | |
899 // This is a successful session history navigation! | |
900 updateSessionHistory(frame); | |
901 m_pageId = extraData->pendingPageID; | |
902 } | |
903 | |
904 // Don't update session history multiple times. | |
905 if (extraData) | |
906 extraData->requestCommitted = true; | |
907 | |
908 updateURL(frame); | |
909 } | |
910 | |
911 void WebViewHost::updateURL(WebFrame* frame) | |
912 { | |
913 WebDataSource* ds = frame->dataSource(); | |
914 ASSERT(ds); | |
915 const WebURLRequest& request = ds->request(); | |
916 RefPtr<TestNavigationEntry> entry(TestNavigationEntry::create()); | |
917 | |
918 // The referrer will be empty on https->http transitions. It | |
919 // would be nice if we could get the real referrer from somewhere. | |
920 entry->setPageID(m_pageId); | |
921 if (ds->hasUnreachableURL()) | |
922 entry->setURL(ds->unreachableURL()); | |
923 else | |
924 entry->setURL(request.url()); | |
925 | |
926 const WebHistoryItem& historyItem = frame->currentHistoryItem(); | |
927 if (!historyItem.isNull()) | |
928 entry->setContentState(historyItem); | |
929 | |
930 navigationController()->didNavigateToEntry(entry.get()); | |
931 m_lastPageIdUpdated = max(m_lastPageIdUpdated, m_pageId); | |
932 } | |
933 | |
934 void WebViewHost::updateSessionHistory(WebFrame* frame) | |
935 { | |
936 // If we have a valid page ID at this point, then it corresponds to the page | |
937 // we are navigating away from. Otherwise, this is the first navigation, so | |
938 // there is no past session history to record. | |
939 if (m_pageId == -1) | |
940 return; | |
941 | |
942 TestNavigationEntry* entry = navigationController()->entryWithPageID(m_pageI
d); | |
943 if (!entry) | |
944 return; | |
945 | |
946 const WebHistoryItem& historyItem = webView()->mainFrame()->previousHistoryI
tem(); | |
947 if (historyItem.isNull()) | |
948 return; | |
949 | |
950 entry->setContentState(historyItem); | |
951 } | |
952 | |
953 void WebViewHost::updateViewportSize() | |
954 { | |
955 if (!m_layerTreeView) | |
956 return; | |
957 | |
958 WebSize deviceViewportSize(webWidget()->size().width * webView()->deviceScal
eFactor(), | |
959 webWidget()->size().height * webView()->deviceScaleFactor()); | |
960 m_layerTreeView->setViewportSize(webWidget()->size(), deviceViewportSize); | |
961 } | |
962 | |
963 void WebViewHost::printFrameDescription(WebFrame* webframe) | |
964 { | |
965 string name8 = webframe->uniqueName().utf8(); | |
966 if (webframe == webView()->mainFrame()) { | |
967 if (!name8.length()) { | |
968 fputs("main frame", stdout); | |
969 return; | |
970 } | |
971 printf("main frame \"%s\"", name8.c_str()); | |
972 return; | |
973 } | |
974 if (!name8.length()) { | |
975 fputs("frame (anonymous)", stdout); | |
976 return; | |
977 } | |
978 printf("frame \"%s\"", name8.c_str()); | |
979 } | |
980 | |
981 void WebViewHost::setPendingExtraData(PassOwnPtr<TestShellExtraData> extraData) | |
982 { | |
983 m_pendingExtraData = extraData; | |
984 } | |
985 | |
986 void WebViewHost::setPageTitle(const WebString&) | |
987 { | |
988 // Nothing to do in layout test. | |
989 } | |
990 | |
991 void WebViewHost::enterFullScreenNow() | |
992 { | |
993 webView()->willEnterFullScreen(); | |
994 webView()->didEnterFullScreen(); | |
995 } | |
996 | |
997 void WebViewHost::exitFullScreenNow() | |
998 { | |
999 webView()->willExitFullScreen(); | |
1000 webView()->didExitFullScreen(); | |
1001 } | |
1002 | |
1003 webkit_support::TestMediaStreamClient* WebViewHost::testMediaStreamClient() | |
1004 { | |
1005 if (!m_testMediaStreamClient.get()) | |
1006 m_testMediaStreamClient = adoptPtr(new webkit_support::TestMediaStreamCl
ient()); | |
1007 return m_testMediaStreamClient.get(); | |
1008 } | |
OLD | NEW |