|
1 /* |
|
2 * Copyright (C) 2009 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 "ChromeClientImpl.h" |
|
33 |
|
34 #include "AXObjectCache.h" |
|
35 #include "AccessibilityObject.h" |
|
36 #include "CharacterNames.h" |
|
37 #include "Console.h" |
|
38 #include "Cursor.h" |
|
39 #include "DatabaseTracker.h" |
|
40 #include "Document.h" |
|
41 #include "DocumentLoader.h" |
|
42 #include "FileChooser.h" |
|
43 #include "FloatRect.h" |
|
44 #include "FrameLoadRequest.h" |
|
45 #include "FrameView.h" |
|
46 #include "GLES2Context.h" |
|
47 #include "Geolocation.h" |
|
48 #include "GeolocationService.h" |
|
49 #include "GeolocationServiceChromium.h" |
|
50 #include "GraphicsLayer.h" |
|
51 #include "HTMLNames.h" |
|
52 #include "HitTestResult.h" |
|
53 #include "IntRect.h" |
|
54 #include "Node.h" |
|
55 #include "NotificationPresenterImpl.h" |
|
56 #include "Page.h" |
|
57 #include "PopupMenuChromium.h" |
|
58 #include "ScriptController.h" |
|
59 #include "WebGeolocationService.h" |
|
60 #if USE(V8) |
|
61 #include "V8Proxy.h" |
|
62 #endif |
|
63 #include "WebAccessibilityObject.h" |
|
64 #include "WebConsoleMessage.h" |
|
65 #include "WebCursorInfo.h" |
|
66 #include "WebFileChooserCompletionImpl.h" |
|
67 #include "WebFrameClient.h" |
|
68 #include "WebFrameImpl.h" |
|
69 #include "WebInputEvent.h" |
|
70 #include "WebKit.h" |
|
71 #include "WebNode.h" |
|
72 #include "WebPopupMenuImpl.h" |
|
73 #include "WebPopupMenuInfo.h" |
|
74 #include "WebPopupType.h" |
|
75 #include "WebRect.h" |
|
76 #include "WebTextDirection.h" |
|
77 #include "WebURLRequest.h" |
|
78 #include "WebViewClient.h" |
|
79 #include "WebViewImpl.h" |
|
80 #include "WebWindowFeatures.h" |
|
81 #include "WindowFeatures.h" |
|
82 #include "WrappedResourceRequest.h" |
|
83 |
|
84 using namespace WebCore; |
|
85 |
|
86 namespace WebKit { |
|
87 |
|
88 // Converts a WebCore::PopupContainerType to a WebKit::WebPopupType. |
|
89 static WebPopupType convertPopupType(PopupContainer::PopupType type) |
|
90 { |
|
91 switch (type) { |
|
92 case PopupContainer::Select: |
|
93 return WebPopupTypeSelect; |
|
94 case PopupContainer::Suggestion: |
|
95 return WebPopupTypeSuggestion; |
|
96 default: |
|
97 ASSERT_NOT_REACHED(); |
|
98 return WebPopupTypeNone; |
|
99 } |
|
100 } |
|
101 |
|
102 ChromeClientImpl::ChromeClientImpl(WebViewImpl* webView) |
|
103 : m_webView(webView) |
|
104 , m_toolbarsVisible(true) |
|
105 , m_statusbarVisible(true) |
|
106 , m_scrollbarsVisible(true) |
|
107 , m_menubarVisible(true) |
|
108 , m_resizable(true) |
|
109 { |
|
110 } |
|
111 |
|
112 ChromeClientImpl::~ChromeClientImpl() |
|
113 { |
|
114 } |
|
115 |
|
116 void ChromeClientImpl::chromeDestroyed() |
|
117 { |
|
118 // Our lifetime is bound to the WebViewImpl. |
|
119 } |
|
120 |
|
121 void ChromeClientImpl::setWindowRect(const FloatRect& r) |
|
122 { |
|
123 if (m_webView->client()) |
|
124 m_webView->client()->setWindowRect(IntRect(r)); |
|
125 } |
|
126 |
|
127 FloatRect ChromeClientImpl::windowRect() |
|
128 { |
|
129 WebRect rect; |
|
130 if (m_webView->client()) |
|
131 rect = m_webView->client()->rootWindowRect(); |
|
132 else { |
|
133 // These numbers will be fairly wrong. The window's x/y coordinates will |
|
134 // be the top left corner of the screen and the size will be the content |
|
135 // size instead of the window size. |
|
136 rect.width = m_webView->size().width; |
|
137 rect.height = m_webView->size().height; |
|
138 } |
|
139 return FloatRect(rect); |
|
140 } |
|
141 |
|
142 FloatRect ChromeClientImpl::pageRect() |
|
143 { |
|
144 // We hide the details of the window's border thickness from the web page by |
|
145 // simple re-using the window position here. So, from the point-of-view of |
|
146 // the web page, the window has no border. |
|
147 return windowRect(); |
|
148 } |
|
149 |
|
150 float ChromeClientImpl::scaleFactor() |
|
151 { |
|
152 // This is supposed to return the scale factor of the web page. It looks like |
|
153 // the implementor of the graphics layer is responsible for doing most of the |
|
154 // operations associated with scaling. However, this value is used ins some |
|
155 // cases by WebCore. For example, this is used as a scaling factor in canvas |
|
156 // so that things drawn in it are scaled just like the web page is. |
|
157 // |
|
158 // We don't currently implement scaling, so just return 1.0 (no scaling). |
|
159 return 1.0; |
|
160 } |
|
161 |
|
162 void ChromeClientImpl::focus() |
|
163 { |
|
164 if (m_webView->client()) |
|
165 m_webView->client()->didFocus(); |
|
166 } |
|
167 |
|
168 void ChromeClientImpl::unfocus() |
|
169 { |
|
170 if (m_webView->client()) |
|
171 m_webView->client()->didBlur(); |
|
172 } |
|
173 |
|
174 bool ChromeClientImpl::canTakeFocus(FocusDirection) |
|
175 { |
|
176 // For now the browser can always take focus if we're not running layout |
|
177 // tests. |
|
178 return !layoutTestMode(); |
|
179 } |
|
180 |
|
181 void ChromeClientImpl::takeFocus(FocusDirection direction) |
|
182 { |
|
183 if (!m_webView->client()) |
|
184 return; |
|
185 if (direction == FocusDirectionBackward) |
|
186 m_webView->client()->focusPrevious(); |
|
187 else |
|
188 m_webView->client()->focusNext(); |
|
189 } |
|
190 |
|
191 void ChromeClientImpl::focusedNodeChanged(Node* node) |
|
192 { |
|
193 m_webView->client()->focusedNodeChanged(WebNode(node)); |
|
194 |
|
195 WebURL focusURL; |
|
196 if (node && node->isLink()) { |
|
197 // This HitTestResult hack is the easiest way to get a link URL out of a |
|
198 // WebCore::Node. |
|
199 HitTestResult hitTest(IntPoint(0, 0)); |
|
200 // This cast must be valid because of the isLink() check. |
|
201 hitTest.setURLElement(static_cast<Element*>(node)); |
|
202 if (hitTest.isLiveLink()) |
|
203 focusURL = hitTest.absoluteLinkURL(); |
|
204 } |
|
205 m_webView->client()->setKeyboardFocusURL(focusURL); |
|
206 |
|
207 if (!node) |
|
208 return; |
|
209 |
|
210 // If accessibility is enabled, we should notify assistive technology that |
|
211 // the active AccessibilityObject changed. |
|
212 Document* document = node->document(); |
|
213 if (!document) { |
|
214 ASSERT_NOT_REACHED(); |
|
215 return; |
|
216 } |
|
217 if (document && document->axObjectCache()->accessibilityEnabled()) { |
|
218 // Retrieve the focused AccessibilityObject. |
|
219 AccessibilityObject* focusedAccObj = |
|
220 document->axObjectCache()->getOrCreate(node->renderer()); |
|
221 |
|
222 // Alert assistive technology that focus changed. |
|
223 if (focusedAccObj) |
|
224 m_webView->client()->focusAccessibilityObject(WebAccessibilityObject(focusedAccObj)); |
|
225 } |
|
226 } |
|
227 |
|
228 Page* ChromeClientImpl::createWindow( |
|
229 Frame* frame, const FrameLoadRequest& r, const WindowFeatures& features) |
|
230 { |
|
231 if (!m_webView->client()) |
|
232 return 0; |
|
233 |
|
234 WebViewImpl* newView = static_cast<WebViewImpl*>( |
|
235 m_webView->client()->createView(WebFrameImpl::fromFrame(frame), features, r.frameName())); |
|
236 if (!newView) |
|
237 return 0; |
|
238 |
|
239 // The request is empty when we are just being asked to open a blank window. |
|
240 // This corresponds to window.open(""), for example. |
|
241 if (!r.resourceRequest().isEmpty()) { |
|
242 WrappedResourceRequest request(r.resourceRequest()); |
|
243 newView->mainFrame()->loadRequest(request); |
|
244 } |
|
245 |
|
246 return newView->page(); |
|
247 } |
|
248 |
|
249 static inline bool currentEventShouldCauseBackgroundTab(const WebInputEvent* inputEvent) |
|
250 { |
|
251 if (!inputEvent) |
|
252 return false; |
|
253 |
|
254 if (inputEvent->type != WebInputEvent::MouseUp) |
|
255 return false; |
|
256 |
|
257 const WebMouseEvent* mouseEvent = static_cast<const WebMouseEvent*>(inputEvent); |
|
258 |
|
259 WebNavigationPolicy policy; |
|
260 unsigned short buttonNumber; |
|
261 switch (mouseEvent->button) { |
|
262 case WebMouseEvent::ButtonLeft: |
|
263 buttonNumber = 0; |
|
264 break; |
|
265 case WebMouseEvent::ButtonMiddle: |
|
266 buttonNumber = 1; |
|
267 break; |
|
268 case WebMouseEvent::ButtonRight: |
|
269 buttonNumber = 2; |
|
270 break; |
|
271 default: |
|
272 return false; |
|
273 } |
|
274 bool ctrl = mouseEvent->modifiers & WebMouseEvent::ControlKey; |
|
275 bool shift = mouseEvent->modifiers & WebMouseEvent::ShiftKey; |
|
276 bool alt = mouseEvent->modifiers & WebMouseEvent::AltKey; |
|
277 bool meta = mouseEvent->modifiers & WebMouseEvent::MetaKey; |
|
278 |
|
279 if (!WebViewImpl::navigationPolicyFromMouseEvent(buttonNumber, ctrl, shift, alt, meta, &policy)) |
|
280 return false; |
|
281 |
|
282 return policy == WebNavigationPolicyNewBackgroundTab; |
|
283 } |
|
284 |
|
285 void ChromeClientImpl::show() |
|
286 { |
|
287 if (!m_webView->client()) |
|
288 return; |
|
289 |
|
290 // If our default configuration was modified by a script or wasn't |
|
291 // created by a user gesture, then show as a popup. Else, let this |
|
292 // new window be opened as a toplevel window. |
|
293 bool asPopup = !m_toolbarsVisible |
|
294 || !m_statusbarVisible |
|
295 || !m_scrollbarsVisible |
|
296 || !m_menubarVisible |
|
297 || !m_resizable; |
|
298 |
|
299 WebNavigationPolicy policy = WebNavigationPolicyNewForegroundTab; |
|
300 if (asPopup) |
|
301 policy = WebNavigationPolicyNewPopup; |
|
302 if (currentEventShouldCauseBackgroundTab(WebViewImpl::currentInputEvent())) |
|
303 policy = WebNavigationPolicyNewBackgroundTab; |
|
304 |
|
305 m_webView->client()->show(policy); |
|
306 } |
|
307 |
|
308 bool ChromeClientImpl::canRunModal() |
|
309 { |
|
310 return !!m_webView->client(); |
|
311 } |
|
312 |
|
313 void ChromeClientImpl::runModal() |
|
314 { |
|
315 if (m_webView->client()) |
|
316 m_webView->client()->runModal(); |
|
317 } |
|
318 |
|
319 void ChromeClientImpl::setToolbarsVisible(bool value) |
|
320 { |
|
321 m_toolbarsVisible = value; |
|
322 } |
|
323 |
|
324 bool ChromeClientImpl::toolbarsVisible() |
|
325 { |
|
326 return m_toolbarsVisible; |
|
327 } |
|
328 |
|
329 void ChromeClientImpl::setStatusbarVisible(bool value) |
|
330 { |
|
331 m_statusbarVisible = value; |
|
332 } |
|
333 |
|
334 bool ChromeClientImpl::statusbarVisible() |
|
335 { |
|
336 return m_statusbarVisible; |
|
337 } |
|
338 |
|
339 void ChromeClientImpl::setScrollbarsVisible(bool value) |
|
340 { |
|
341 m_scrollbarsVisible = value; |
|
342 WebFrameImpl* web_frame = static_cast<WebFrameImpl*>(m_webView->mainFrame()); |
|
343 if (web_frame) |
|
344 web_frame->setCanHaveScrollbars(value); |
|
345 } |
|
346 |
|
347 bool ChromeClientImpl::scrollbarsVisible() |
|
348 { |
|
349 return m_scrollbarsVisible; |
|
350 } |
|
351 |
|
352 void ChromeClientImpl::setMenubarVisible(bool value) |
|
353 { |
|
354 m_menubarVisible = value; |
|
355 } |
|
356 |
|
357 bool ChromeClientImpl::menubarVisible() |
|
358 { |
|
359 return m_menubarVisible; |
|
360 } |
|
361 |
|
362 void ChromeClientImpl::setResizable(bool value) |
|
363 { |
|
364 m_resizable = value; |
|
365 } |
|
366 |
|
367 void ChromeClientImpl::addMessageToConsole(MessageSource source, |
|
368 MessageType type, |
|
369 MessageLevel level, |
|
370 const String& message, |
|
371 unsigned lineNumber, |
|
372 const String& sourceID) |
|
373 { |
|
374 if (m_webView->client()) { |
|
375 m_webView->client()->didAddMessageToConsole( |
|
376 WebConsoleMessage(static_cast<WebConsoleMessage::Level>(level), message), |
|
377 sourceID, |
|
378 lineNumber); |
|
379 } |
|
380 } |
|
381 |
|
382 bool ChromeClientImpl::canRunBeforeUnloadConfirmPanel() |
|
383 { |
|
384 return !!m_webView->client(); |
|
385 } |
|
386 |
|
387 bool ChromeClientImpl::runBeforeUnloadConfirmPanel(const String& message, Frame* frame) |
|
388 { |
|
389 if (m_webView->client()) { |
|
390 return m_webView->client()->runModalBeforeUnloadDialog( |
|
391 WebFrameImpl::fromFrame(frame), message); |
|
392 } |
|
393 return false; |
|
394 } |
|
395 |
|
396 void ChromeClientImpl::closeWindowSoon() |
|
397 { |
|
398 // Make sure this Page can no longer be found by JS. |
|
399 m_webView->page()->setGroupName(String()); |
|
400 |
|
401 // Make sure that all loading is stopped. Ensures that JS stops executing! |
|
402 m_webView->mainFrame()->stopLoading(); |
|
403 |
|
404 if (m_webView->client()) |
|
405 m_webView->client()->closeWidgetSoon(); |
|
406 } |
|
407 |
|
408 // Although a Frame is passed in, we don't actually use it, since we |
|
409 // already know our own m_webView. |
|
410 void ChromeClientImpl::runJavaScriptAlert(Frame* frame, const String& message) |
|
411 { |
|
412 if (m_webView->client()) { |
|
413 #if USE(V8) |
|
414 // Before showing the JavaScript dialog, we give the proxy implementation |
|
415 // a chance to process any pending console messages. |
|
416 V8Proxy::processConsoleMessages(); |
|
417 #endif |
|
418 m_webView->client()->runModalAlertDialog( |
|
419 WebFrameImpl::fromFrame(frame), message); |
|
420 } |
|
421 } |
|
422 |
|
423 // See comments for runJavaScriptAlert(). |
|
424 bool ChromeClientImpl::runJavaScriptConfirm(Frame* frame, const String& message) |
|
425 { |
|
426 if (m_webView->client()) { |
|
427 return m_webView->client()->runModalConfirmDialog( |
|
428 WebFrameImpl::fromFrame(frame), message); |
|
429 } |
|
430 return false; |
|
431 } |
|
432 |
|
433 // See comments for runJavaScriptAlert(). |
|
434 bool ChromeClientImpl::runJavaScriptPrompt(Frame* frame, |
|
435 const String& message, |
|
436 const String& defaultValue, |
|
437 String& result) |
|
438 { |
|
439 if (m_webView->client()) { |
|
440 WebString actualValue; |
|
441 bool ok = m_webView->client()->runModalPromptDialog( |
|
442 WebFrameImpl::fromFrame(frame), |
|
443 message, |
|
444 defaultValue, |
|
445 &actualValue); |
|
446 if (ok) |
|
447 result = actualValue; |
|
448 return ok; |
|
449 } |
|
450 return false; |
|
451 } |
|
452 |
|
453 void ChromeClientImpl::setStatusbarText(const String& message) |
|
454 { |
|
455 if (m_webView->client()) |
|
456 m_webView->client()->setStatusText(message); |
|
457 } |
|
458 |
|
459 bool ChromeClientImpl::shouldInterruptJavaScript() |
|
460 { |
|
461 // FIXME: implement me |
|
462 return false; |
|
463 } |
|
464 |
|
465 bool ChromeClientImpl::tabsToLinks() const |
|
466 { |
|
467 // Returns true if anchors should accept keyboard focus with the tab key. |
|
468 // This method is used in a convoluted fashion by EventHandler::tabsToLinks. |
|
469 // It's a twisted path (self-evident, but more complicated than seems |
|
470 // necessary), but the net result is that returning true from here, on a |
|
471 // platform other than MAC or QT, lets anchors get keyboard focus. |
|
472 return m_webView->tabsToLinks(); |
|
473 } |
|
474 |
|
475 IntRect ChromeClientImpl::windowResizerRect() const |
|
476 { |
|
477 IntRect result; |
|
478 if (m_webView->client()) |
|
479 result = m_webView->client()->windowResizerRect(); |
|
480 return result; |
|
481 } |
|
482 |
|
483 void ChromeClientImpl::invalidateWindow(const IntRect&, bool) |
|
484 { |
|
485 notImplemented(); |
|
486 } |
|
487 |
|
488 void ChromeClientImpl::invalidateContentsAndWindow(const IntRect& updateRect, bool /*immediate*/) |
|
489 { |
|
490 if (updateRect.isEmpty()) |
|
491 return; |
|
492 if (m_webView->client()) |
|
493 m_webView->client()->didInvalidateRect(updateRect); |
|
494 } |
|
495 |
|
496 void ChromeClientImpl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate) |
|
497 { |
|
498 m_webView->hidePopups(); |
|
499 invalidateContentsAndWindow(updateRect, immediate); |
|
500 } |
|
501 |
|
502 void ChromeClientImpl::scroll( |
|
503 const IntSize& scrollDelta, const IntRect& scrollRect, |
|
504 const IntRect& clipRect) |
|
505 { |
|
506 m_webView->hidePopups(); |
|
507 if (m_webView->client()) { |
|
508 int dx = scrollDelta.width(); |
|
509 int dy = scrollDelta.height(); |
|
510 m_webView->client()->didScrollRect(dx, dy, clipRect); |
|
511 } |
|
512 } |
|
513 |
|
514 IntPoint ChromeClientImpl::screenToWindow(const IntPoint&) const |
|
515 { |
|
516 notImplemented(); |
|
517 return IntPoint(); |
|
518 } |
|
519 |
|
520 IntRect ChromeClientImpl::windowToScreen(const IntRect& rect) const |
|
521 { |
|
522 IntRect screenRect(rect); |
|
523 |
|
524 if (m_webView->client()) { |
|
525 WebRect windowRect = m_webView->client()->windowRect(); |
|
526 screenRect.move(windowRect.x, windowRect.y); |
|
527 } |
|
528 |
|
529 return screenRect; |
|
530 } |
|
531 |
|
532 void ChromeClientImpl::contentsSizeChanged(Frame* frame, const IntSize& size) const |
|
533 { |
|
534 WebFrameImpl* webframe = WebFrameImpl::fromFrame(frame); |
|
535 if (webframe->client()) |
|
536 webframe->client()->didChangeContentsSize(webframe, size); |
|
537 } |
|
538 |
|
539 void ChromeClientImpl::scrollbarsModeDidChange() const |
|
540 { |
|
541 } |
|
542 |
|
543 void ChromeClientImpl::mouseDidMoveOverElement( |
|
544 const HitTestResult& result, unsigned modifierFlags) |
|
545 { |
|
546 if (!m_webView->client()) |
|
547 return; |
|
548 // Find out if the mouse is over a link, and if so, let our UI know... |
|
549 if (result.isLiveLink() && !result.absoluteLinkURL().string().isEmpty()) |
|
550 m_webView->client()->setMouseOverURL(result.absoluteLinkURL()); |
|
551 else |
|
552 m_webView->client()->setMouseOverURL(WebURL()); |
|
553 } |
|
554 |
|
555 void ChromeClientImpl::setToolTip(const String& tooltipText, TextDirection dir) |
|
556 { |
|
557 if (!m_webView->client()) |
|
558 return; |
|
559 WebTextDirection textDirection = (dir == RTL) ? |
|
560 WebTextDirectionRightToLeft : |
|
561 WebTextDirectionLeftToRight; |
|
562 m_webView->client()->setToolTipText( |
|
563 tooltipText, textDirection); |
|
564 } |
|
565 |
|
566 void ChromeClientImpl::print(Frame* frame) |
|
567 { |
|
568 if (m_webView->client()) |
|
569 m_webView->client()->printPage(WebFrameImpl::fromFrame(frame)); |
|
570 } |
|
571 |
|
572 void ChromeClientImpl::exceededDatabaseQuota(Frame* frame, const String& databaseName) |
|
573 { |
|
574 // Chromium users cannot currently change the default quota |
|
575 } |
|
576 |
|
577 #if ENABLE(OFFLINE_WEB_APPLICATIONS) |
|
578 void ChromeClientImpl::reachedMaxAppCacheSize(int64_t spaceNeeded) |
|
579 { |
|
580 ASSERT_NOT_REACHED(); |
|
581 } |
|
582 #endif |
|
583 |
|
584 void ChromeClientImpl::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser) |
|
585 { |
|
586 WebViewClient* client = m_webView->client(); |
|
587 if (!client) |
|
588 return; |
|
589 |
|
590 WebFileChooserParams params; |
|
591 params.multiSelect = fileChooser->allowsMultipleFiles(); |
|
592 #if ENABLE(DIRECTORY_UPLOAD) |
|
593 params.directory = fileChooser->allowsDirectoryUpload(); |
|
594 #else |
|
595 params.directory = false; |
|
596 #endif |
|
597 params.acceptTypes = fileChooser->acceptTypes(); |
|
598 params.selectedFiles = fileChooser->filenames(); |
|
599 if (params.selectedFiles.size() > 0) |
|
600 params.initialValue = params.selectedFiles[0]; |
|
601 WebFileChooserCompletionImpl* chooserCompletion = |
|
602 new WebFileChooserCompletionImpl(fileChooser); |
|
603 |
|
604 if (client->runFileChooser(params, chooserCompletion)) |
|
605 return; |
|
606 |
|
607 // Choosing failed, so do callback with an empty list. |
|
608 chooserCompletion->didChooseFile(WebVector<WebString>()); |
|
609 } |
|
610 |
|
611 void ChromeClientImpl::chooseIconForFiles(const Vector<WebCore::String>&, WebCore::FileChooser*) |
|
612 { |
|
613 notImplemented(); |
|
614 } |
|
615 |
|
616 void ChromeClientImpl::popupOpened(PopupContainer* popupContainer, |
|
617 const IntRect& bounds, |
|
618 bool handleExternally) |
|
619 { |
|
620 if (!m_webView->client()) |
|
621 return; |
|
622 |
|
623 WebWidget* webwidget; |
|
624 if (handleExternally) { |
|
625 WebPopupMenuInfo popupInfo; |
|
626 getPopupMenuInfo(popupContainer, &popupInfo); |
|
627 webwidget = m_webView->client()->createPopupMenu(popupInfo); |
|
628 } else { |
|
629 webwidget = m_webView->client()->createPopupMenu( |
|
630 convertPopupType(popupContainer->popupType())); |
|
631 // We only notify when the WebView has to handle the popup, as when |
|
632 // the popup is handled externally, the fact that a popup is showing is |
|
633 // transparent to the WebView. |
|
634 m_webView->popupOpened(popupContainer); |
|
635 } |
|
636 static_cast<WebPopupMenuImpl*>(webwidget)->Init(popupContainer, bounds); |
|
637 } |
|
638 |
|
639 void ChromeClientImpl::popupClosed(WebCore::PopupContainer* popupContainer) |
|
640 { |
|
641 m_webView->popupClosed(popupContainer); |
|
642 } |
|
643 |
|
644 void ChromeClientImpl::setCursor(const WebCursorInfo& cursor) |
|
645 { |
|
646 if (m_webView->client()) |
|
647 m_webView->client()->didChangeCursor(cursor); |
|
648 } |
|
649 |
|
650 void ChromeClientImpl::setCursorForPlugin(const WebCursorInfo& cursor) |
|
651 { |
|
652 setCursor(cursor); |
|
653 } |
|
654 |
|
655 void ChromeClientImpl::formStateDidChange(const Node* node) |
|
656 { |
|
657 // The current history item is not updated yet. That happens lazily when |
|
658 // WebFrame::currentHistoryItem is requested. |
|
659 WebFrameImpl* webframe = WebFrameImpl::fromFrame(node->document()->frame()); |
|
660 if (webframe->client()) |
|
661 webframe->client()->didUpdateCurrentHistoryItem(webframe); |
|
662 } |
|
663 |
|
664 void ChromeClientImpl::getPopupMenuInfo(PopupContainer* popupContainer, |
|
665 WebPopupMenuInfo* info) |
|
666 { |
|
667 const Vector<PopupItem*>& inputItems = popupContainer->popupData(); |
|
668 |
|
669 WebVector<WebPopupMenuInfo::Item> outputItems(inputItems.size()); |
|
670 |
|
671 for (size_t i = 0; i < inputItems.size(); ++i) { |
|
672 const PopupItem& inputItem = *inputItems[i]; |
|
673 WebPopupMenuInfo::Item& outputItem = outputItems[i]; |
|
674 |
|
675 outputItem.label = inputItem.label; |
|
676 outputItem.enabled = inputItem.enabled; |
|
677 |
|
678 switch (inputItem.type) { |
|
679 case PopupItem::TypeOption: |
|
680 outputItem.type = WebPopupMenuInfo::Item::Option; |
|
681 break; |
|
682 case PopupItem::TypeGroup: |
|
683 outputItem.type = WebPopupMenuInfo::Item::Group; |
|
684 break; |
|
685 case PopupItem::TypeSeparator: |
|
686 outputItem.type = WebPopupMenuInfo::Item::Separator; |
|
687 break; |
|
688 default: |
|
689 ASSERT_NOT_REACHED(); |
|
690 } |
|
691 } |
|
692 |
|
693 info->itemHeight = popupContainer->menuItemHeight(); |
|
694 info->itemFontSize = popupContainer->menuItemFontSize(); |
|
695 info->selectedIndex = popupContainer->selectedIndex(); |
|
696 info->items.swap(outputItems); |
|
697 info->rightAligned = popupContainer->menuStyle().textDirection() == RTL; |
|
698 } |
|
699 |
|
700 void ChromeClientImpl::didChangeAccessibilityObjectState(AccessibilityObject* obj) |
|
701 { |
|
702 // Alert assistive technology about the accessibility object state change |
|
703 if (obj) |
|
704 m_webView->client()->didChangeAccessibilityObjectState(WebAccessibilityObject(obj)); |
|
705 } |
|
706 |
|
707 #if ENABLE(NOTIFICATIONS) |
|
708 NotificationPresenter* ChromeClientImpl::notificationPresenter() const |
|
709 { |
|
710 return m_webView->notificationPresenterImpl(); |
|
711 } |
|
712 #endif |
|
713 |
|
714 void ChromeClientImpl::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation) |
|
715 { |
|
716 GeolocationServiceChromium* geolocationService = static_cast<GeolocationServiceChromium*>(geolocation->getGeolocationService()); |
|
717 geolocationService->geolocationServiceBridge()->attachBridgeIfNeeded(); |
|
718 m_webView->client()->geolocationService()->requestPermissionForFrame(geolocationService->geolocationServiceBridge()->getBridgeId(), frame->document()->url()); |
|
719 } |
|
720 |
|
721 void ChromeClientImpl::cancelGeolocationPermissionRequestForFrame(Frame* frame, Geolocation* geolocation) |
|
722 { |
|
723 GeolocationServiceChromium* geolocationService = static_cast<GeolocationServiceChromium*>(geolocation->getGeolocationService()); |
|
724 m_webView->client()->geolocationService()->cancelPermissionRequestForFrame(geolocationService->geolocationServiceBridge()->getBridgeId(), frame->document()->url()); |
|
725 } |
|
726 |
|
727 #if USE(ACCELERATED_COMPOSITING) |
|
728 void ChromeClientImpl::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer) |
|
729 { |
|
730 m_webView->setRootGraphicsLayer(graphicsLayer ? graphicsLayer->platformLayer() : 0); |
|
731 } |
|
732 |
|
733 void ChromeClientImpl::scheduleCompositingLayerSync() |
|
734 { |
|
735 m_webView->setRootLayerNeedsDisplay(); |
|
736 } |
|
737 |
|
738 PassOwnPtr<GLES2Context> ChromeClientImpl::getOnscreenGLES2Context() |
|
739 { |
|
740 return m_webView->getOnscreenGLES2Context(); |
|
741 } |
|
742 |
|
743 PassOwnPtr<GLES2Context> ChromeClientImpl::getOffscreenGLES2Context() |
|
744 { |
|
745 return m_webView->getOffscreenGLES2Context(); |
|
746 } |
|
747 #endif |
|
748 |
|
749 bool ChromeClientImpl::supportsFullscreenForNode(const WebCore::Node* node) |
|
750 { |
|
751 if (m_webView->client() && node->hasTagName(WebCore::HTMLNames::videoTag)) |
|
752 return m_webView->client()->supportsFullscreen(); |
|
753 return false; |
|
754 } |
|
755 |
|
756 void ChromeClientImpl::enterFullscreenForNode(WebCore::Node* node) |
|
757 { |
|
758 if (m_webView->client()) |
|
759 m_webView->client()->enterFullscreenForNode(WebNode(node)); |
|
760 } |
|
761 |
|
762 void ChromeClientImpl::exitFullscreenForNode(WebCore::Node* node) |
|
763 { |
|
764 if (m_webView->client()) |
|
765 m_webView->client()->exitFullscreenForNode(WebNode(node)); |
|
766 } |
|
767 |
|
768 } // namespace WebKit |