[BlackBerry] Reader Mode: Opening two links quickly from reader mode causes browser...
[WebKit-https.git] / Source / WebKit / blackberry / WebCoreSupport / ChromeClientBlackBerry.cpp
1 /*
2  * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
3  * Copyright (C) 2010, 2011, 2012 Research In Motion Limited. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19
20 #include "config.h"
21 #include "ChromeClientBlackBerry.h"
22
23 #include "BackingStore.h"
24 #include "BackingStoreClient.h"
25 #include "BackingStore_p.h"
26 #include "ColorChooser.h"
27 #include "DatabaseManager.h"
28 #include "Document.h"
29 #include "DumpRenderTreeClient.h"
30 #include "DumpRenderTreeSupport.h"
31 #include "FileChooser.h"
32 #include "FileIconLoader.h"
33 #include "Frame.h"
34 #include "FrameLoadRequest.h"
35 #include "FrameLoader.h"
36 #include "Geolocation.h"
37 #include "GeolocationClientBlackBerry.h"
38 #include "GraphicsLayer.h"
39 #include "HTMLInputElement.h"
40 #include "HTMLNames.h"
41 #include "HitTestResult.h"
42 #include "Icon.h"
43 #include "InputHandler.h"
44 #include "KURL.h"
45 #include "Node.h"
46 #include "NotImplemented.h"
47 #include "Page.h"
48 #include "PageGroup.h"
49 #include "PageGroupLoadDeferrer.h"
50 #include "PagePopupBlackBerry.h"
51 #include "PagePopupClient.h"
52 #include "PopupMenuBlackBerry.h"
53 #include "RenderView.h"
54 #include "SVGZoomAndPan.h"
55 #include "SearchPopupMenuBlackBerry.h"
56 #include "SecurityOrigin.h"
57 #include "Settings.h"
58 #include "SharedPointer.h"
59 #include "ViewportArguments.h"
60 #include "WebPage.h"
61 #include "WebPageClient.h"
62 #include "WebPage_p.h"
63 #include "WebPopupType.h"
64 #include "WebSettings.h"
65 #include "WindowFeatures.h"
66
67 #include <BlackBerryPlatformLog.h>
68 #include <BlackBerryPlatformSettings.h>
69 #include <BlackBerryPlatformString.h>
70 #include <BlackBerryPlatformWindow.h>
71
72 #include <wtf/text/CString.h>
73 #include <wtf/text/WTFString.h>
74
75 #define DEBUG_OVERFLOW_DETECTION 0
76
77 using namespace BlackBerry::WebKit;
78
79 using BlackBerry::Platform::Graphics::Window;
80
81 namespace WebCore {
82
83 static CString toOriginString(Frame* frame)
84 {
85     return frame->document()->securityOrigin()->toString().latin1();
86 }
87
88 ChromeClientBlackBerry::ChromeClientBlackBerry(WebPagePrivate* pagePrivate)
89     : m_webPagePrivate(pagePrivate)
90 {
91 }
92
93 void ChromeClientBlackBerry::addMessageToConsole(MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID)
94 {
95 #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
96     if (m_webPagePrivate->m_dumpRenderTree) {
97         m_webPagePrivate->m_dumpRenderTree->addMessageToConsole(message, lineNumber, sourceID);
98         return;
99     }
100 #endif
101
102     m_webPagePrivate->m_client->addMessageToConsole(message.characters(), message.length(), sourceID.characters(), sourceID.length(), lineNumber);
103 }
104
105 void ChromeClientBlackBerry::runJavaScriptAlert(Frame* frame, const String& message)
106 {
107 #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
108     if (m_webPagePrivate->m_dumpRenderTree) {
109         m_webPagePrivate->m_dumpRenderTree->runJavaScriptAlert(message);
110         return;
111     }
112 #endif
113
114     TimerBase::fireTimersInNestedEventLoop();
115     CString latinOrigin = toOriginString(frame);
116     m_webPagePrivate->m_client->runJavaScriptAlert(message.characters(), message.length(), latinOrigin.data(), latinOrigin.length());
117 }
118
119 bool ChromeClientBlackBerry::runJavaScriptConfirm(Frame* frame, const String& message)
120 {
121 #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
122     if (m_webPagePrivate->m_dumpRenderTree)
123         return m_webPagePrivate->m_dumpRenderTree->runJavaScriptConfirm(message);
124 #endif
125
126     TimerBase::fireTimersInNestedEventLoop();
127     CString latinOrigin = toOriginString(frame);
128     return m_webPagePrivate->m_client->runJavaScriptConfirm(message.characters(), message.length(), latinOrigin.data(), latinOrigin.length());
129 }
130
131 bool ChromeClientBlackBerry::runJavaScriptPrompt(Frame* frame, const String& message, const String& defaultValue, String& result)
132 {
133 #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
134     if (m_webPagePrivate->m_dumpRenderTree) {
135         result = m_webPagePrivate->m_dumpRenderTree->runJavaScriptPrompt(message, defaultValue);
136         return true;
137     }
138 #endif
139
140     TimerBase::fireTimersInNestedEventLoop();
141     CString latinOrigin = toOriginString(frame);
142     BlackBerry::Platform::String clientResult;
143     if (m_webPagePrivate->m_client->runJavaScriptPrompt(message.characters(), message.length(), defaultValue.characters(), defaultValue.length(), latinOrigin.data(), latinOrigin.length(), clientResult)) {
144         result = clientResult;
145         return true;
146     }
147     return false;
148 }
149
150 void ChromeClientBlackBerry::chromeDestroyed()
151 {
152     // Destroy popup if we have.
153     closePagePopup(0);
154     delete this;
155 }
156
157 void ChromeClientBlackBerry::setWindowRect(const FloatRect&)
158 {
159     // The window dimensions are fixed in the RIM port.
160 }
161
162 FloatRect ChromeClientBlackBerry::windowRect()
163 {
164     IntSize windowSize;
165
166     if (Window* window = m_webPagePrivate->m_client->window())
167         windowSize = window->windowSize();
168
169     // Use logical (density-independent) pixels instead of physical screen pixels.
170     FloatRect rect = FloatRect(0, 0, windowSize.width(), windowSize.height());
171     if (!m_webPagePrivate->m_page->settings()->applyDeviceScaleFactorInCompositor())
172         rect.scale(1 / m_webPagePrivate->m_page->deviceScaleFactor());
173     return rect;
174 }
175
176 FloatRect ChromeClientBlackBerry::pageRect()
177 {
178     notImplemented();
179     return FloatRect();
180 }
181
182 float ChromeClientBlackBerry::scaleFactor()
183 {
184     return 1;
185 }
186
187 void ChromeClientBlackBerry::focus()
188 {
189     notImplemented();
190 }
191
192 void ChromeClientBlackBerry::unfocus()
193 {
194     notImplemented();
195 }
196
197 bool ChromeClientBlackBerry::canTakeFocus(FocusDirection)
198 {
199     notImplemented();
200     return false;
201 }
202
203 void ChromeClientBlackBerry::takeFocus(FocusDirection)
204 {
205     notImplemented();
206 }
207
208 void ChromeClientBlackBerry::focusedNodeChanged(Node*)
209 {
210     m_webPagePrivate->m_inputHandler->focusedNodeChanged();
211 }
212
213 void ChromeClientBlackBerry::focusedFrameChanged(Frame*)
214 {
215     // To be used by In-region backing store context switching.
216 }
217
218 bool ChromeClientBlackBerry::shouldForceDocumentStyleSelectorUpdate()
219 {
220     return !m_webPagePrivate->m_webSettings->isJavaScriptEnabled() && !m_webPagePrivate->m_inputHandler->processingChange();
221 }
222
223 Page* ChromeClientBlackBerry::createWindow(Frame* frame, const FrameLoadRequest& request, const WindowFeatures& features, const NavigationAction&)
224 {
225     // Bail out early when we aren't allowed to display the target origin, otherwise,
226     // it would be harmful and the window would be useless. This is the same check
227     // as the one in FrameLoader::loadFrameRequest().
228     const KURL& url = request.resourceRequest().url();
229     if (!request.requester()->canDisplay(url)) {
230         frame->loader()->reportLocalLoadFailed(frame, url.string());
231         return 0;
232     }
233
234 #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
235     if (m_webPagePrivate->m_dumpRenderTree && !m_webPagePrivate->m_dumpRenderTree->allowsOpeningWindow())
236         return 0;
237 #endif
238
239     int x = features.xSet ? features.x : 0;
240     int y = features.ySet ? features.y : 0;
241     int width = features.widthSet? features.width : -1;
242     int height = features.heightSet ? features.height : -1;
243     unsigned flags = 0;
244
245     if (features.menuBarVisible)
246         flags |= WebPageClient::FlagWindowHasMenuBar;
247     if (features.statusBarVisible)
248         flags |= WebPageClient::FlagWindowHasStatusBar;
249     if (features.toolBarVisible)
250         flags |= WebPageClient::FlagWindowHasToolBar;
251     if (features.locationBarVisible)
252         flags |= WebPageClient::FlagWindowHasLocationBar;
253     if (features.scrollbarsVisible)
254         flags |= WebPageClient::FlagWindowHasScrollBar;
255     if (features.resizable)
256         flags |= WebPageClient::FlagWindowIsResizable;
257     if (features.fullscreen)
258         flags |= WebPageClient::FlagWindowIsFullScreen;
259     if (features.dialog)
260         flags |= WebPageClient::FlagWindowIsDialog;
261
262     WebPage* webPage = m_webPagePrivate->m_client->createWindow(x, y, width, height, flags, url.string(), request.frameName());
263     if (!webPage)
264         return 0;
265
266 #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
267     if (m_webPagePrivate->m_dumpRenderTree)
268         m_webPagePrivate->m_dumpRenderTree->windowCreated(webPage);
269 #endif
270
271     return webPage->d->m_page;
272 }
273
274 void ChromeClientBlackBerry::show()
275 {
276     notImplemented();
277 }
278
279 bool ChromeClientBlackBerry::canRunModal()
280 {
281     notImplemented();
282     return false;
283 }
284
285 void ChromeClientBlackBerry::runModal()
286 {
287     notImplemented();
288 }
289
290 bool ChromeClientBlackBerry::selectItemWritingDirectionIsNatural()
291 {
292     return false;
293 }
294
295 bool ChromeClientBlackBerry::selectItemAlignmentFollowsMenuWritingDirection()
296 {
297     return true;
298 }
299
300 bool ChromeClientBlackBerry::hasOpenedPopup() const
301 {
302     return m_webPagePrivate->m_webPage->hasOpenedPopup();
303 }
304
305 PassRefPtr<PopupMenu> ChromeClientBlackBerry::createPopupMenu(PopupMenuClient* client) const
306 {
307     return adoptRef(new PopupMenuBlackBerry(client));
308 }
309
310 PassRefPtr<SearchPopupMenu> ChromeClientBlackBerry::createSearchPopupMenu(PopupMenuClient* client) const
311 {
312     return adoptRef(new SearchPopupMenuBlackBerry(client));
313 }
314
315 PagePopup* ChromeClientBlackBerry::openPagePopup(PagePopupClient* client, const IntRect& originBoundsInRootView)
316 {
317     closePagePopup(0);
318
319     PagePopupBlackBerry* webPopup = new PagePopupBlackBerry(m_webPagePrivate, client, rootViewToScreen(originBoundsInRootView));
320     m_webPagePrivate->m_webPage->popupOpened(webPopup);
321     if (webPopup->sendCreatePopupWebViewRequest())
322         return webPopup;
323
324     closePagePopup(0);
325     return 0;
326 }
327
328 void ChromeClientBlackBerry::closePagePopup(PagePopup*)
329 {
330     if (!hasOpenedPopup())
331         return;
332
333     PagePopupBlackBerry* webPopup = m_webPagePrivate->m_webPage->popup();
334     webPopup->closePopup();
335     delete webPopup;
336 }
337
338 void ChromeClientBlackBerry::setToolbarsVisible(bool)
339 {
340     notImplemented();
341 }
342
343 bool ChromeClientBlackBerry::toolbarsVisible()
344 {
345     notImplemented();
346     return false;
347 }
348
349 void ChromeClientBlackBerry::setStatusbarVisible(bool)
350 {
351     notImplemented();
352 }
353
354 bool ChromeClientBlackBerry::statusbarVisible()
355 {
356     notImplemented();
357     return false;
358 }
359
360 void ChromeClientBlackBerry::setScrollbarsVisible(bool)
361 {
362     notImplemented();
363 }
364
365 bool ChromeClientBlackBerry::scrollbarsVisible()
366 {
367     notImplemented();
368     return false;
369 }
370
371 void ChromeClientBlackBerry::setMenubarVisible(bool)
372 {
373     notImplemented();
374 }
375
376 bool ChromeClientBlackBerry::menubarVisible()
377 {
378     notImplemented();
379     return false;
380 }
381
382 void ChromeClientBlackBerry::setResizable(bool)
383 {
384     notImplemented();
385 }
386
387 bool ChromeClientBlackBerry::canRunBeforeUnloadConfirmPanel()
388 {
389     return true;
390 }
391
392 bool ChromeClientBlackBerry::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
393 {
394 #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
395     if (m_webPagePrivate->m_dumpRenderTree)
396         return m_webPagePrivate->m_dumpRenderTree->runBeforeUnloadConfirmPanel(message);
397 #endif
398
399     TimerBase::fireTimersInNestedEventLoop();
400     CString latinOrigin = toOriginString(frame);
401     return m_webPagePrivate->m_client->runBeforeUnloadConfirmPanel(message.characters(), message.length(), latinOrigin.data(), latinOrigin.length());
402 }
403
404 void ChromeClientBlackBerry::closeWindowSoon()
405 {
406     if (m_webPagePrivate->m_page->openedByDOM())
407         m_webPagePrivate->m_client->scheduleCloseWindow();
408 }
409
410 void ChromeClientBlackBerry::setStatusbarText(const String& status)
411 {
412     m_webPagePrivate->m_client->setStatus(status);
413
414 #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
415     if (m_webPagePrivate->m_dumpRenderTree)
416         m_webPagePrivate->m_dumpRenderTree->setStatusText(status);
417 #endif
418 }
419
420 IntRect ChromeClientBlackBerry::windowResizerRect() const
421 {
422     notImplemented();
423     return IntRect();
424 }
425
426 IntPoint ChromeClientBlackBerry::screenToRootView(const IntPoint& screenPos) const
427 {
428     IntPoint windowPoint;
429     if (Window* window = m_webPagePrivate->m_client->window())
430         windowPoint = window->windowLocation();
431
432     windowPoint.move(-screenPos.x(), -screenPos.y());
433     return windowPoint;
434 }
435
436 IntRect ChromeClientBlackBerry::rootViewToScreen(const IntRect& windowRect) const
437 {
438     IntRect windowPoint(windowRect);
439     IntPoint location;
440     if (Window* window = m_webPagePrivate->m_client->window())
441         location = window->windowLocation();
442
443     windowPoint.move(location.x(), location.y());
444     return windowPoint;
445 }
446
447 void ChromeClientBlackBerry::mouseDidMoveOverElement(const HitTestResult& result, unsigned int modifierFlags)
448 {
449     notImplemented();
450 }
451
452 void ChromeClientBlackBerry::setToolTip(const String& tooltip, TextDirection)
453 {
454     m_webPagePrivate->m_client->setToolTip(tooltip);
455 }
456
457 #if ENABLE(EVENT_MODE_METATAGS)
458 void ChromeClientBlackBerry::didReceiveCursorEventMode(Frame* frame, CursorEventMode mode) const
459 {
460     if (m_webPagePrivate->m_mainFrame != frame)
461         return;
462
463     m_webPagePrivate->didReceiveCursorEventMode(mode);
464 }
465
466 void ChromeClientBlackBerry::didReceiveTouchEventMode(Frame* frame, TouchEventMode mode) const
467 {
468     if (m_webPagePrivate->m_mainFrame != frame)
469         return;
470
471     m_webPagePrivate->didReceiveTouchEventMode(mode);
472 }
473 #endif
474
475 void ChromeClientBlackBerry::dispatchViewportPropertiesDidChange(const ViewportArguments& arguments) const
476 {
477     m_webPagePrivate->dispatchViewportPropertiesDidChange(arguments);
478 }
479
480 void ChromeClientBlackBerry::print(Frame*)
481 {
482     notImplemented();
483 }
484
485 void ChromeClientBlackBerry::exceededDatabaseQuota(Frame* frame, const String& name, DatabaseDetails details)
486 {
487 #if ENABLE(SQL_DATABASE)
488     Document* document = frame->document();
489     if (!document)
490         return;
491
492     SecurityOrigin* origin = document->securityOrigin();
493
494 #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
495     if (m_webPagePrivate->m_dumpRenderTree) {
496         m_webPagePrivate->m_dumpRenderTree->exceededDatabaseQuota(origin, name);
497         return;
498     }
499 #endif
500
501     DatabaseManager& manager = DatabaseManager::manager();
502
503     unsigned long long originUsage = tracker.usageForOrigin(origin);
504     unsigned long long currentQuota = tracker.quotaForOrigin(origin);
505
506     unsigned long long estimatedSize = details.expectedUsage();
507     const String& nameStr = details.displayName();
508
509     String originStr = origin->toString();
510
511     unsigned long long quota = m_webPagePrivate->m_client->databaseQuota(originStr, nameStr, originUsage, currentQuota, estimatedSize);
512
513     manager.setQuota(origin, quota);
514 #endif
515 }
516
517 void ChromeClientBlackBerry::runOpenPanel(Frame*, PassRefPtr<FileChooser> chooser)
518 {
519     SharedArray<BlackBerry::Platform::String> initialFiles;
520     unsigned numberOfInitialFiles = chooser->settings().selectedFiles.size();
521     if (numberOfInitialFiles > 0)
522         initialFiles.reset(new BlackBerry::Platform::String[numberOfInitialFiles], numberOfInitialFiles);
523     for (unsigned i = 0; i < numberOfInitialFiles; ++i)
524         initialFiles[i] = chooser->settings().selectedFiles[i];
525
526     SharedArray<BlackBerry::Platform::String> acceptMIMETypes;
527     unsigned numberOfTypes = chooser->settings().acceptMIMETypes.size();
528     if (numberOfTypes > 0)
529         acceptMIMETypes.reset(new BlackBerry::Platform::String[numberOfTypes], numberOfTypes);
530     for (unsigned i = 0; i < numberOfTypes; ++i)
531         acceptMIMETypes[i] = chooser->settings().acceptMIMETypes[i];
532
533     BlackBerry::Platform::String capture;
534 #if ENABLE(MEDIA_CAPTURE)
535     capture = chooser->settings().capture;
536 #endif
537
538     SharedArray<BlackBerry::Platform::String> chosenFiles;
539
540     {
541         PageGroupLoadDeferrer deferrer(m_webPagePrivate->m_page, true);
542         TimerBase::fireTimersInNestedEventLoop();
543
544         if (!m_webPagePrivate->m_client->chooseFilenames(chooser->settings().allowsMultipleFiles, acceptMIMETypes, initialFiles, capture, chosenFiles))
545             return;
546     }
547
548     Vector<String> files(chosenFiles.length());
549     for (unsigned i = 0; i < chosenFiles.length(); ++i)
550         files[i] = chosenFiles[i];
551     chooser->chooseFiles(files);
552 }
553
554 void ChromeClientBlackBerry::loadIconForFiles(const Vector<String>& filenames, FileIconLoader* loader)
555 {
556     loader->notifyFinished(Icon::createIconForFiles(filenames));
557 }
558
559 void ChromeClientBlackBerry::setCursor(const Cursor&)
560 {
561     notImplemented();
562 }
563
564 void ChromeClientBlackBerry::formStateDidChange(const Node* node)
565 {
566     m_webPagePrivate->m_inputHandler->nodeTextChanged(node);
567 }
568
569 void ChromeClientBlackBerry::scrollbarsModeDidChange() const
570 {
571     notImplemented();
572 }
573
574 void ChromeClientBlackBerry::contentsSizeChanged(Frame* frame, const IntSize& size) const
575 {
576     if (frame != m_webPagePrivate->m_mainFrame)
577         return;
578
579     m_webPagePrivate->contentsSizeChanged(size);
580 }
581
582 void ChromeClientBlackBerry::invalidateRootView(const IntRect& updateRect, bool immediate)
583 {
584     m_webPagePrivate->m_backingStore->d->repaint(updateRect, false /*contentChanged*/, immediate);
585 }
586
587 void ChromeClientBlackBerry::invalidateContentsAndRootView(const IntRect& updateRect, bool immediate)
588 {
589     m_webPagePrivate->m_backingStore->d->repaint(updateRect, true /*contentChanged*/, immediate);
590 }
591
592 void ChromeClientBlackBerry::invalidateContentsForSlowScroll(const IntSize& delta, const IntRect& updateRect, bool immediate, const ScrollView* scrollView)
593 {
594     if (scrollView != m_webPagePrivate->m_mainFrame->view())
595         invalidateContentsAndRootView(updateRect, true /*immediate*/);
596     else {
597         BackingStoreClient* backingStoreClient = m_webPagePrivate->backingStoreClient();
598         ASSERT(backingStoreClient);
599         backingStoreClient->checkOriginOfCurrentScrollOperation();
600
601         m_webPagePrivate->m_backingStore->d->slowScroll(delta, updateRect, immediate);
602     }
603 }
604
605 void ChromeClientBlackBerry::scroll(const IntSize& delta, const IntRect& scrollViewRect, const IntRect& clipRect)
606 {
607     // FIXME: There's a chance the function is called indirectly by FrameView's dtor
608     // when the Frame's view() is null. We probably want to fix it in another way, but
609     // at this moment let's do a quick fix.
610     if (!m_webPagePrivate->m_mainFrame->view())
611         return;
612
613     BackingStoreClient* backingStoreClient = m_webPagePrivate->backingStoreClient();
614     ASSERT(backingStoreClient);
615     backingStoreClient->checkOriginOfCurrentScrollOperation();
616
617     m_webPagePrivate->m_backingStore->d->scroll(delta, scrollViewRect, clipRect);
618
619     // Shift the spell check dialog box as we scroll.
620     m_webPagePrivate->m_inputHandler->redrawSpellCheckDialogIfRequired();
621 }
622
623 void ChromeClientBlackBerry::scrollableAreasDidChange()
624 {
625     typedef HashSet<ScrollableArea*> ScrollableAreaSet;
626     const ScrollableAreaSet* scrollableAreas = m_webPagePrivate->m_mainFrame->view()->scrollableAreas();
627
628     bool hasAtLeastOneInRegionScrollableArea = false;
629     ScrollableAreaSet::iterator end = scrollableAreas->end();
630     for (ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != end; ++it) {
631         if ((*it) != m_webPagePrivate->m_page->mainFrame()->view()) {
632             hasAtLeastOneInRegionScrollableArea = true;
633             break;
634         }
635     }
636
637     m_webPagePrivate->setHasInRegionScrollableAreas(hasAtLeastOneInRegionScrollableArea);
638 }
639
640 void ChromeClientBlackBerry::scrollRectIntoView(const IntRect&, const ScrollView*) const
641 {
642     m_webPagePrivate->notifyTransformedScrollChanged();
643 }
644
645 bool ChromeClientBlackBerry::shouldInterruptJavaScript()
646 {
647     TimerBase::fireTimersInNestedEventLoop();
648     return m_webPagePrivate->m_client->shouldInterruptJavaScript();
649 }
650
651 KeyboardUIMode ChromeClientBlackBerry::keyboardUIMode()
652 {
653     bool tabsToLinks = true;
654
655 #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
656     if (m_webPagePrivate->m_dumpRenderTree)
657         tabsToLinks = DumpRenderTreeSupport::linksIncludedInFocusChain();
658 #endif
659
660     return tabsToLinks ? KeyboardAccessTabsToLinks : KeyboardAccessDefault;
661 }
662
663 PlatformPageClient ChromeClientBlackBerry::platformPageClient() const
664 {
665     return m_webPagePrivate;
666 }
667
668 #if ENABLE(TOUCH_EVENTS)
669 void ChromeClientBlackBerry::needTouchEvents(bool value)
670 {
671 }
672 #endif
673
674 void ChromeClientBlackBerry::reachedMaxAppCacheSize(int64_t spaceNeeded)
675 {
676     notImplemented();
677 }
678
679 void ChromeClientBlackBerry::layoutUpdated(Frame* frame) const
680 {
681     if (frame != m_webPagePrivate->m_mainFrame)
682         return;
683
684     m_webPagePrivate->layoutFinished();
685 }
686
687 void ChromeClientBlackBerry::overflowExceedsContentsSize(Frame* frame) const
688 {
689     if (frame != m_webPagePrivate->m_mainFrame)
690         return;
691
692 #if DEBUG_OVERFLOW_DETECTION
693     BlackBerry::Platform::logAlways(BlackBerry::Platform::LogLevelInfo,
694         "ChromeClientBlackBerry::overflowExceedsContentsSize contents=%s overflow=%f x %f",
695         BlackBerry::Platform::IntRect(frame->contentRenderer()->documentRect()).toString().c_str(),
696         frame->contentRenderer()->rightAbsoluteVisibleOverflow().toFloat(),
697         frame->contentRenderer()->bottomAbsoluteVisibleOverflow().toFloat());
698 #endif
699     m_webPagePrivate->overflowExceedsContentsSize();
700 }
701
702 void ChromeClientBlackBerry::didDiscoverFrameSet(Frame* frame) const
703 {
704     if (frame != m_webPagePrivate->m_mainFrame)
705         return;
706
707     BBLOG(BlackBerry::Platform::LogLevelInfo, "ChromeClientBlackBerry::didDiscoverFrameSet");
708     if (m_webPagePrivate->loadState() == WebPagePrivate::Committed) {
709         m_webPagePrivate->setShouldUseFixedDesktopMode(true);
710         m_webPagePrivate->zoomToInitialScaleOnLoad();
711     }
712 }
713
714 int ChromeClientBlackBerry::reflowWidth() const
715 {
716     return m_webPagePrivate->reflowWidth();
717 }
718
719 void ChromeClientBlackBerry::chooseIconForFiles(const Vector<String>&, FileChooser*)
720 {
721     notImplemented();
722 }
723
724 bool ChromeClientBlackBerry::supportsFullscreenForNode(const Node* node)
725 {
726     return node->hasTagName(HTMLNames::videoTag);
727 }
728
729 void ChromeClientBlackBerry::enterFullscreenForNode(Node* node)
730 {
731     if (!supportsFullscreenForNode(node))
732         return;
733
734     m_webPagePrivate->enterFullscreenForNode(node);
735 }
736
737 void ChromeClientBlackBerry::exitFullscreenForNode(Node* node)
738 {
739     m_webPagePrivate->exitFullscreenForNode(node);
740 }
741
742 #if ENABLE(FULLSCREEN_API)
743 bool ChromeClientBlackBerry::supportsFullScreenForElement(const WebCore::Element* element, bool withKeyboard)
744 {
745     return !withKeyboard;
746 }
747
748 void ChromeClientBlackBerry::enterFullScreenForElement(WebCore::Element* element)
749 {
750     element->document()->webkitWillEnterFullScreenForElement(element);
751     m_webPagePrivate->enterFullScreenForElement(element);
752     element->document()->webkitDidEnterFullScreenForElement(element);
753     m_fullScreenElement = element;
754 }
755
756 void ChromeClientBlackBerry::exitFullScreenForElement(WebCore::Element*)
757 {
758     // The element passed into this function is not reliable, i.e. it could
759     // be null. In addition the parameter may be disappearing in the future.
760     // So we use the reference to the element we saved above.
761     ASSERT(m_fullScreenElement);
762     m_fullScreenElement->document()->webkitWillExitFullScreenForElement(m_fullScreenElement.get());
763     m_webPagePrivate->exitFullScreenForElement(m_fullScreenElement.get());
764     m_fullScreenElement->document()->webkitDidExitFullScreenForElement(m_fullScreenElement.get());
765     m_fullScreenElement.clear();
766 }
767
768 void ChromeClientBlackBerry::fullScreenRendererChanged(RenderBox*)
769 {
770     m_webPagePrivate->adjustFullScreenElementDimensionsIfNeeded();
771 }
772 #endif
773
774 #if ENABLE(SVG)
775 void ChromeClientBlackBerry::didSetSVGZoomAndPan(Frame* frame, unsigned short zoomAndPan)
776 {
777     // For top-level SVG document, there is no viewport tag, we use viewport's user-scalable
778     // to enable/disable zoom when top-level SVG document's zoomAndPan changed. Because there is no viewport
779     // tag, other fields with default value in ViewportArguments are ok.
780     if (frame == m_webPagePrivate->m_page->mainFrame()) {
781         ViewportArguments arguments;
782         switch (zoomAndPan) {
783         case SVGZoomAndPan::SVG_ZOOMANDPAN_DISABLE:
784             arguments.userScalable = 0;
785             break;
786         case SVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY:
787             arguments.userScalable = 1;
788             break;
789         default:
790             return;
791         }
792         didReceiveViewportArguments(frame, arguments);
793     }
794 }
795 #endif
796
797 #if USE(ACCELERATED_COMPOSITING)
798 void ChromeClientBlackBerry::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer)
799 {
800     // If the graphicsLayer parameter is 0, WebCore is actually
801     // trying to remove a previously attached layer.
802     m_webPagePrivate->setRootLayerWebKitThread(frame, graphicsLayer ? graphicsLayer->platformLayer() : 0);
803 }
804
805 void ChromeClientBlackBerry::setNeedsOneShotDrawingSynchronization()
806 {
807     m_webPagePrivate->setNeedsOneShotDrawingSynchronization();
808 }
809
810 void ChromeClientBlackBerry::scheduleCompositingLayerFlush()
811 {
812     m_webPagePrivate->scheduleRootLayerCommit();
813 }
814
815 bool ChromeClientBlackBerry::allowsAcceleratedCompositing() const
816 {
817     return true;
818 }
819 #endif
820
821 PassOwnPtr<ColorChooser> ChromeClientBlackBerry::createColorChooser(ColorChooserClient*, const Color&)
822 {
823     return nullptr;
824 }
825
826 #if ENABLE(NAVIGATOR_CONTENT_UTILS)
827 void ChromeClientBlackBerry::registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title)
828 {
829     m_webPagePrivate->m_client->registerProtocolHandler(scheme, baseURL, url, title);
830 }
831
832 #if ENABLE(CUSTOM_SCHEME_HANDLER)
833 ChromeClient::CustomHandlersState ChromeClientBlackBerry::isProtocolHandlerRegistered(const String& scheme, const String& baseURL, const String& url)
834 {
835     return static_cast<CustomHandlersState>(m_webPagePrivate->m_client->isProtocolHandlerRegistered(scheme, baseURL, url));
836 }
837
838 void ChromeClientBlackBerry::unregisterProtocolHandler(const String& scheme, const String& baseURL, const String& url)
839 {
840     m_webPagePrivate->m_client->unregisterProtocolHandler(scheme, baseURL, url);
841 }
842 #endif
843 #endif
844
845 void ChromeClientBlackBerry::addSearchProvider(const BlackBerry::Platform::String& originURL, const BlackBerry::Platform::String& newURL)
846 {
847     // See if the input URL host matches of the origin host.
848     KURL originHost = KURL(KURL(), originURL);
849     KURL url = KURL(KURL(), newURL);
850     if (url.isValid() && originHost.host() == url.host())
851         m_webPagePrivate->client()->addSearchProvider(newURL);
852 }
853
854 int ChromeClientBlackBerry::isSearchProviderInstalled(const BlackBerry::Platform::String& originURL, const BlackBerry::Platform::String& newURL)
855 {
856 //    Returns a value based on comparing url to the URLs of the results pages of the installed search engines.
857 //    0 - None of the installed search engines match url.
858 //    1 - One or more installed search engines match url, but none are the user's default search engine.
859 //    2 - The user's default search engine matches url.
860
861     // See if the input URL host matches of the origin host.
862     KURL originHost = KURL(KURL(), originURL);
863     KURL url = KURL(KURL(), newURL);
864     if (url.isValid() && originHost.host() == url.host())
865         return m_webPagePrivate->client()->isSearchProviderInstalled(newURL);
866     return 0;
867 }
868
869 } // namespace WebCore