Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(214)

Side by Side Diff: webkit/api/src/ChromeClientImpl.cpp

Issue 385057: Deleted webkit/api which now lives in webkit.org (Closed)
Patch Set: Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webkit/api/src/ChromeClientImpl.h ('k') | webkit/api/src/ChromiumBridge.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "AccessibilityObject.h"
35 #include "AXObjectCache.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 "HitTestResult.h"
47 #include "IntRect.h"
48 #include "Node.h"
49 #include "NotificationPresenterImpl.h"
50 #include "Page.h"
51 #include "PopupMenuChromium.h"
52 #include "ScriptController.h"
53 #if USE(V8)
54 #include "V8Proxy.h"
55 #endif
56 #include "WebAccessibilityObject.h"
57 #include "WebConsoleMessage.h"
58 #include "WebCursorInfo.h"
59 #include "WebFileChooserCompletionImpl.h"
60 #include "WebFrameClient.h"
61 #include "WebFrameImpl.h"
62 #include "WebInputEvent.h"
63 #include "WebKit.h"
64 #include "WebPopupMenuImpl.h"
65 #include "WebPopupMenuInfo.h"
66 #include "WebRect.h"
67 #include "WebTextDirection.h"
68 #include "WebURLRequest.h"
69 #include "WebViewClient.h"
70 #include "WebViewImpl.h"
71 #include "WindowFeatures.h"
72 #include "WrappedResourceRequest.h"
73
74 using namespace WebCore;
75
76 namespace WebKit {
77
78 ChromeClientImpl::ChromeClientImpl(WebViewImpl* webView)
79 : m_webView(webView)
80 , m_toolbarsVisible(true)
81 , m_statusbarVisible(true)
82 , m_scrollbarsVisible(true)
83 , m_menubarVisible(true)
84 , m_resizable(true)
85 , m_ignoreNextSetCursor(false)
86 {
87 }
88
89 ChromeClientImpl::~ChromeClientImpl()
90 {
91 }
92
93 void ChromeClientImpl::chromeDestroyed()
94 {
95 // Our lifetime is bound to the WebViewImpl.
96 }
97
98 void ChromeClientImpl::setWindowRect(const FloatRect& r)
99 {
100 if (m_webView->client())
101 m_webView->client()->setWindowRect(IntRect(r));
102 }
103
104 FloatRect ChromeClientImpl::windowRect()
105 {
106 WebRect rect;
107 if (m_webView->client())
108 rect = m_webView->client()->rootWindowRect();
109 else {
110 // These numbers will be fairly wrong. The window's x/y coordinates will
111 // be the top left corner of the screen and the size will be the content
112 // size instead of the window size.
113 rect.width = m_webView->size().width;
114 rect.height = m_webView->size().height;
115 }
116 return FloatRect(rect);
117 }
118
119 FloatRect ChromeClientImpl::pageRect()
120 {
121 // We hide the details of the window's border thickness from the web page by
122 // simple re-using the window position here. So, from the point-of-view of
123 // the web page, the window has no border.
124 return windowRect();
125 }
126
127 float ChromeClientImpl::scaleFactor()
128 {
129 // This is supposed to return the scale factor of the web page. It looks like
130 // the implementor of the graphics layer is responsible for doing most of the
131 // operations associated with scaling. However, this value is used ins some
132 // cases by WebCore. For example, this is used as a scaling factor in canvas
133 // so that things drawn in it are scaled just like the web page is.
134 //
135 // We don't currently implement scaling, so just return 1.0 (no scaling).
136 return 1.0;
137 }
138
139 void ChromeClientImpl::focus()
140 {
141 if (!m_webView->client())
142 return;
143
144 m_webView->client()->didFocus();
145
146 // If accessibility is enabled, we should notify assistive technology that
147 // the active AccessibilityObject changed.
148 const Frame* frame = m_webView->focusedWebCoreFrame();
149 if (!frame)
150 return;
151
152 Document* doc = frame->document();
153
154 if (doc && doc->axObjectCache()->accessibilityEnabled()) {
155 Node* focusedNode = m_webView->focusedWebCoreNode();
156
157 if (!focusedNode) {
158 // Could not retrieve focused Node.
159 return;
160 }
161
162 // Retrieve the focused AccessibilityObject.
163 AccessibilityObject* focusedAccObj =
164 doc->axObjectCache()->getOrCreate(focusedNode->renderer());
165
166 // Alert assistive technology that focus changed.
167 if (focusedAccObj)
168 m_webView->client()->focusAccessibilityObject(WebAccessibilityObject(focusedAccObj));
169 }
170 }
171
172 void ChromeClientImpl::unfocus()
173 {
174 if (m_webView->client())
175 m_webView->client()->didBlur();
176 }
177
178 bool ChromeClientImpl::canTakeFocus(FocusDirection)
179 {
180 // For now the browser can always take focus if we're not running layout
181 // tests.
182 return !layoutTestMode();
183 }
184
185 void ChromeClientImpl::takeFocus(FocusDirection direction)
186 {
187 if (!m_webView->client())
188 return;
189 if (direction == FocusDirectionBackward)
190 m_webView->client()->focusPrevious();
191 else
192 m_webView->client()->focusNext();
193 }
194
195 void ChromeClientImpl::focusedNodeChanged(Node* node)
196 {
197 WebURL focus_url;
198 if (node && node->isLink()) {
199 // This HitTestResult hack is the easiest way to get a link URL out of a
200 // WebCore::Node.
201 HitTestResult hit_test(IntPoint(0, 0));
202 // This cast must be valid because of the isLink() check.
203 hit_test.setURLElement(reinterpret_cast<Element*>(node));
204 if (hit_test.isLiveLink())
205 focus_url = hit_test.absoluteLinkURL();
206 }
207 m_webView->client()->setKeyboardFocusURL(focus_url);
208 }
209
210 Page* ChromeClientImpl::createWindow(
211 Frame* frame, const FrameLoadRequest& r, const WindowFeatures& features)
212 {
213 if (!m_webView->client())
214 return 0;
215
216 WebViewImpl* newView = static_cast<WebViewImpl*>(
217 m_webView->client()->createView(WebFrameImpl::fromFrame(frame)));
218 if (!newView)
219 return 0;
220
221 // The request is empty when we are just being asked to open a blank window.
222 // This corresponds to window.open(""), for example.
223 if (!r.resourceRequest().isEmpty()) {
224 WrappedResourceRequest request(r.resourceRequest());
225 newView->mainFrame()->loadRequest(request);
226 }
227
228 return newView->page();
229 }
230
231 static inline bool currentEventShouldCauseBackgroundTab(const WebInputEvent* inputEvent)
232 {
233 if (!inputEvent)
234 return false;
235
236 if (inputEvent->type != WebInputEvent::MouseUp)
237 return false;
238
239 const WebMouseEvent* mouseEvent = static_cast<const WebMouseEvent*>(inputEvent);
240
241 WebNavigationPolicy policy;
242 unsigned short buttonNumber;
243 switch (mouseEvent->button) {
244 case WebMouseEvent::ButtonLeft:
245 buttonNumber = 0;
246 break;
247 case WebMouseEvent::ButtonMiddle:
248 buttonNumber = 1;
249 break;
250 case WebMouseEvent::ButtonRight:
251 buttonNumber = 2;
252 break;
253 default:
254 return false;
255 }
256 bool ctrl = mouseEvent->modifiers & WebMouseEvent::ControlKey;
257 bool shift = mouseEvent->modifiers & WebMouseEvent::ShiftKey;
258 bool alt = mouseEvent->modifiers & WebMouseEvent::AltKey;
259 bool meta = mouseEvent->modifiers & WebMouseEvent::MetaKey;
260
261 if (!WebViewImpl::navigationPolicyFromMouseEvent(buttonNumber, ctrl, shift, alt, meta, &policy))
262 return false;
263
264 return policy == WebNavigationPolicyNewBackgroundTab;
265 }
266
267 void ChromeClientImpl::show()
268 {
269 if (!m_webView->client())
270 return;
271
272 // If our default configuration was modified by a script or wasn't
273 // created by a user gesture, then show as a popup. Else, let this
274 // new window be opened as a toplevel window.
275 bool asPopup = !m_toolbarsVisible
276 || !m_statusbarVisible
277 || !m_scrollbarsVisible
278 || !m_menubarVisible
279 || !m_resizable;
280
281 WebNavigationPolicy policy = WebNavigationPolicyNewForegroundTab;
282 if (asPopup)
283 policy = WebNavigationPolicyNewPopup;
284 if (currentEventShouldCauseBackgroundTab(WebViewImpl::currentInputEvent()))
285 policy = WebNavigationPolicyNewBackgroundTab;
286
287 m_webView->client()->show(policy);
288 }
289
290 bool ChromeClientImpl::canRunModal()
291 {
292 return !!m_webView->client();
293 }
294
295 void ChromeClientImpl::runModal()
296 {
297 if (m_webView->client())
298 m_webView->client()->runModal();
299 }
300
301 void ChromeClientImpl::setToolbarsVisible(bool value)
302 {
303 m_toolbarsVisible = value;
304 }
305
306 bool ChromeClientImpl::toolbarsVisible()
307 {
308 return m_toolbarsVisible;
309 }
310
311 void ChromeClientImpl::setStatusbarVisible(bool value)
312 {
313 m_statusbarVisible = value;
314 }
315
316 bool ChromeClientImpl::statusbarVisible()
317 {
318 return m_statusbarVisible;
319 }
320
321 void ChromeClientImpl::setScrollbarsVisible(bool value)
322 {
323 m_scrollbarsVisible = value;
324 WebFrameImpl* web_frame = static_cast<WebFrameImpl*>(m_webView->mainFrame());
325 if (web_frame)
326 web_frame->setAllowsScrolling(value);
327 }
328
329 bool ChromeClientImpl::scrollbarsVisible()
330 {
331 return m_scrollbarsVisible;
332 }
333
334 void ChromeClientImpl::setMenubarVisible(bool value)
335 {
336 m_menubarVisible = value;
337 }
338
339 bool ChromeClientImpl::menubarVisible()
340 {
341 return m_menubarVisible;
342 }
343
344 void ChromeClientImpl::setResizable(bool value)
345 {
346 m_resizable = value;
347 }
348
349 void ChromeClientImpl::addMessageToConsole(MessageSource source,
350 MessageType type,
351 MessageLevel level,
352 const String& message,
353 unsigned lineNumber,
354 const String& sourceID)
355 {
356 if (m_webView->client()) {
357 m_webView->client()->didAddMessageToConsole(
358 WebConsoleMessage(static_cast<WebConsoleMessage::Level>(level), message),
359 sourceID,
360 lineNumber);
361 }
362 }
363
364 bool ChromeClientImpl::canRunBeforeUnloadConfirmPanel()
365 {
366 return !!m_webView->client();
367 }
368
369 bool ChromeClientImpl::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
370 {
371 if (m_webView->client()) {
372 return m_webView->client()->runModalBeforeUnloadDialog(
373 WebFrameImpl::fromFrame(frame), message);
374 }
375 return false;
376 }
377
378 void ChromeClientImpl::closeWindowSoon()
379 {
380 // Make sure this Page can no longer be found by JS.
381 m_webView->page()->setGroupName(String());
382
383 // Make sure that all loading is stopped. Ensures that JS stops executing!
384 m_webView->mainFrame()->stopLoading();
385
386 if (m_webView->client())
387 m_webView->client()->closeWidgetSoon();
388 }
389
390 // Although a Frame is passed in, we don't actually use it, since we
391 // already know our own m_webView.
392 void ChromeClientImpl::runJavaScriptAlert(Frame* frame, const String& message)
393 {
394 if (m_webView->client()) {
395 #if USE(V8)
396 // Before showing the JavaScript dialog, we give the proxy implementation
397 // a chance to process any pending console messages.
398 V8Proxy::processConsoleMessages();
399 #endif
400 m_webView->client()->runModalAlertDialog(
401 WebFrameImpl::fromFrame(frame), message);
402 }
403 }
404
405 // See comments for runJavaScriptAlert().
406 bool ChromeClientImpl::runJavaScriptConfirm(Frame* frame, const String& message)
407 {
408 if (m_webView->client()) {
409 return m_webView->client()->runModalConfirmDialog(
410 WebFrameImpl::fromFrame(frame), message);
411 }
412 return false;
413 }
414
415 // See comments for runJavaScriptAlert().
416 bool ChromeClientImpl::runJavaScriptPrompt(Frame* frame,
417 const String& message,
418 const String& defaultValue,
419 String& result)
420 {
421 if (m_webView->client()) {
422 WebString actualValue;
423 bool ok = m_webView->client()->runModalPromptDialog(
424 WebFrameImpl::fromFrame(frame),
425 message,
426 defaultValue,
427 &actualValue);
428 if (ok)
429 result = actualValue;
430 return ok;
431 }
432 return false;
433 }
434
435 void ChromeClientImpl::setStatusbarText(const String& message)
436 {
437 if (m_webView->client())
438 m_webView->client()->setStatusText(message);
439 }
440
441 bool ChromeClientImpl::shouldInterruptJavaScript()
442 {
443 // FIXME: implement me
444 return false;
445 }
446
447 bool ChromeClientImpl::tabsToLinks() const
448 {
449 // Returns true if anchors should accept keyboard focus with the tab key.
450 // This method is used in a convoluted fashion by EventHandler::tabsToLinks.
451 // It's a twisted path (self-evident, but more complicated than seems
452 // necessary), but the net result is that returning true from here, on a
453 // platform other than MAC or QT, lets anchors get keyboard focus.
454 return m_webView->tabsToLinks();
455 }
456
457 IntRect ChromeClientImpl::windowResizerRect() const
458 {
459 IntRect result;
460 if (m_webView->client())
461 result = m_webView->client()->windowResizerRect();
462 return result;
463 }
464
465 void ChromeClientImpl::repaint(
466 const IntRect& paintRect, bool contentChanged, bool immediate,
467 bool repaintContentOnly)
468 {
469 // Ignore spurious calls.
470 if (!contentChanged || paintRect.isEmpty())
471 return;
472 if (m_webView->client())
473 m_webView->client()->didInvalidateRect(paintRect);
474 }
475
476 void ChromeClientImpl::scroll(
477 const IntSize& scrollDelta, const IntRect& scrollRect,
478 const IntRect& clipRect)
479 {
480 if (m_webView->client()) {
481 int dx = scrollDelta.width();
482 int dy = scrollDelta.height();
483 m_webView->client()->didScrollRect(dx, dy, clipRect);
484 }
485 }
486
487 IntPoint ChromeClientImpl::screenToWindow(const IntPoint&) const
488 {
489 notImplemented();
490 return IntPoint();
491 }
492
493 IntRect ChromeClientImpl::windowToScreen(const IntRect& rect) const
494 {
495 IntRect screenRect(rect);
496
497 if (m_webView->client()) {
498 WebRect windowRect = m_webView->client()->windowRect();
499 screenRect.move(windowRect.x, windowRect.y);
500 }
501
502 return screenRect;
503 }
504
505 void ChromeClientImpl::contentsSizeChanged(Frame* frame, const IntSize& size) const
506 {
507 WebFrameImpl* webframe = WebFrameImpl::fromFrame(frame);
508 if (webframe->client())
509 webframe->client()->didChangeContentsSize(webframe, size);
510 }
511
512 void ChromeClientImpl::scrollbarsModeDidChange() const
513 {
514 }
515
516 void ChromeClientImpl::mouseDidMoveOverElement(
517 const HitTestResult& result, unsigned modifierFlags)
518 {
519 if (!m_webView->client())
520 return;
521 // Find out if the mouse is over a link, and if so, let our UI know...
522 if (result.isLiveLink() && !result.absoluteLinkURL().string().isEmpty())
523 m_webView->client()->setMouseOverURL(result.absoluteLinkURL());
524 else
525 m_webView->client()->setMouseOverURL(WebURL());
526 }
527
528 void ChromeClientImpl::setToolTip(const String& tooltipText, TextDirection dir)
529 {
530 if (!m_webView->client())
531 return;
532 WebTextDirection textDirection = (dir == RTL) ?
533 WebTextDirectionRightToLeft :
534 WebTextDirectionLeftToRight;
535 m_webView->client()->setToolTipText(
536 tooltipText, textDirection);
537 }
538
539 void ChromeClientImpl::print(Frame* frame)
540 {
541 if (m_webView->client())
542 m_webView->client()->printPage(WebFrameImpl::fromFrame(frame));
543 }
544
545 void ChromeClientImpl::exceededDatabaseQuota(Frame* frame, const String& databaseName)
546 {
547 // set a reasonable quota for now -- 5Mb should be enough for anybody
548 // TODO(dglazkov): this should be configurable
549 SecurityOrigin* origin = frame->document()->securityOrigin();
550 DatabaseTracker::tracker().setQuota(origin, 1024 * 1024 * 5);
551 }
552
553 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
554 void ChromeClientImpl::reachedMaxAppCacheSize(int64_t spaceNeeded)
555 {
556 ASSERT_NOT_REACHED();
557 }
558 #endif
559
560 void ChromeClientImpl::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser)
561 {
562 WebViewClient* client = m_webView->client();
563 if (!client)
564 return;
565
566 bool multipleFiles = fileChooser->allowsMultipleFiles();
567
568 WebString suggestion;
569 if (fileChooser->filenames().size() > 0)
570 suggestion = fileChooser->filenames()[0];
571
572 WebFileChooserCompletionImpl* chooserCompletion =
573 new WebFileChooserCompletionImpl(fileChooser);
574 bool ok = client->runFileChooser(multipleFiles,
575 WebString(),
576 suggestion,
577 chooserCompletion);
578 if (!ok) {
579 // Choosing failed, so do callback with an empty list.
580 chooserCompletion->didChooseFile(WebVector<WebString>());
581 }
582 }
583
584 void ChromeClientImpl::popupOpened(PopupContainer* popupContainer,
585 const IntRect& bounds,
586 bool activatable,
587 bool handleExternally)
588 {
589 if (!m_webView->client())
590 return;
591
592 WebWidget* webwidget;
593 if (handleExternally) {
594 WebPopupMenuInfo popupInfo;
595 getPopupMenuInfo(popupContainer, &popupInfo);
596 webwidget = m_webView->client()->createPopupMenu(popupInfo);
597 } else
598 webwidget = m_webView->client()->createPopupMenu(activatable);
599
600 static_cast<WebPopupMenuImpl*>(webwidget)->Init(popupContainer, bounds);
601 }
602
603 void ChromeClientImpl::setCursor(const WebCursorInfo& cursor)
604 {
605 if (m_ignoreNextSetCursor) {
606 m_ignoreNextSetCursor = false;
607 return;
608 }
609
610 if (m_webView->client())
611 m_webView->client()->didChangeCursor(cursor);
612 }
613
614 void ChromeClientImpl::setCursorForPlugin(const WebCursorInfo& cursor)
615 {
616 setCursor(cursor);
617
618 // Currently, Widget::setCursor is always called after this function in
619 // EventHandler.cpp and since we don't want that we set a flag indicating
620 // that the next SetCursor call is to be ignored.
621 m_ignoreNextSetCursor = true;
622 }
623
624 void ChromeClientImpl::formStateDidChange(const Node* node)
625 {
626 // The current history item is not updated yet. That happens lazily when
627 // WebFrame::currentHistoryItem is requested.
628 WebFrameImpl* webframe = WebFrameImpl::fromFrame(node->document()->frame());
629 if (webframe->client())
630 webframe->client()->didUpdateCurrentHistoryItem(webframe);
631 }
632
633 void ChromeClientImpl::getPopupMenuInfo(PopupContainer* popupContainer,
634 WebPopupMenuInfo* info)
635 {
636 const Vector<PopupItem*>& inputItems = popupContainer->popupData();
637
638 WebVector<WebPopupMenuInfo::Item> outputItems(inputItems.size());
639
640 for (size_t i = 0; i < inputItems.size(); ++i) {
641 const PopupItem& inputItem = *inputItems[i];
642 WebPopupMenuInfo::Item& outputItem = outputItems[i];
643
644 outputItem.label = inputItem.label;
645 outputItem.enabled = inputItem.enabled;
646
647 switch (inputItem.type) {
648 case PopupItem::TypeOption:
649 outputItem.type = WebPopupMenuInfo::Item::Option;
650 break;
651 case PopupItem::TypeGroup:
652 outputItem.type = WebPopupMenuInfo::Item::Group;
653 break;
654 case PopupItem::TypeSeparator:
655 outputItem.type = WebPopupMenuInfo::Item::Separator;
656 break;
657 default:
658 ASSERT_NOT_REACHED();
659 }
660 }
661
662 info->itemHeight = popupContainer->menuItemHeight();
663 info->selectedIndex = popupContainer->selectedIndex();
664 info->items.swap(outputItems);
665 }
666
667 #if ENABLE(NOTIFICATIONS)
668 NotificationPresenter* ChromeClientImpl::notificationPresenter() const
669 {
670 return m_webView->notificationPresenterImpl();
671 }
672 #endif
673
674 } // namespace WebKit
OLDNEW
« no previous file with comments | « webkit/api/src/ChromeClientImpl.h ('k') | webkit/api/src/ChromiumBridge.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698