10847e2f46b4bc30b2e3545cbede4aa59c696351
[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     PageGroupLoadDeferrer deferrer(m_webPagePrivate->m_page, true);
240     TimerBase::fireTimersInNestedEventLoop();
241
242     int x = features.xSet ? features.x : 0;
243     int y = features.ySet ? features.y : 0;
244     int width = features.widthSet? features.width : -1;
245     int height = features.heightSet ? features.height : -1;
246     unsigned flags = 0;
247
248     if (features.menuBarVisible)
249         flags |= WebPageClient::FlagWindowHasMenuBar;
250     if (features.statusBarVisible)
251         flags |= WebPageClient::FlagWindowHasStatusBar;
252     if (features.toolBarVisible)
253         flags |= WebPageClient::FlagWindowHasToolBar;
254     if (features.locationBarVisible)
255         flags |= WebPageClient::FlagWindowHasLocationBar;
256     if (features.scrollbarsVisible)
257         flags |= WebPageClient::FlagWindowHasScrollBar;
258     if (features.resizable)
259         flags |= WebPageClient::FlagWindowIsResizable;
260     if (features.fullscreen)
261         flags |= WebPageClient::FlagWindowIsFullScreen;
262     if (features.dialog)
263         flags |= WebPageClient::FlagWindowIsDialog;
264
265     WebPage* webPage = m_webPagePrivate->m_client->createWindow(x, y, width, height, flags, url.string(), request.frameName());
266     if (!webPage)
267         return 0;
268
269 #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
270     if (m_webPagePrivate->m_dumpRenderTree)
271         m_webPagePrivate->m_dumpRenderTree->windowCreated(webPage);
272 #endif
273
274     return webPage->d->m_page;
275 }
276
277 void ChromeClientBlackBerry::show()
278 {
279     notImplemented();
280 }
281
282 bool ChromeClientBlackBerry::canRunModal()
283 {
284     notImplemented();
285     return false;
286 }
287
288 void ChromeClientBlackBerry::runModal()
289 {
290     notImplemented();
291 }
292
293 bool ChromeClientBlackBerry::selectItemWritingDirectionIsNatural()
294 {
295     return false;
296 }
297
298 bool ChromeClientBlackBerry::selectItemAlignmentFollowsMenuWritingDirection()
299 {
300     return true;
301 }
302
303 bool ChromeClientBlackBerry::hasOpenedPopup() const
304 {
305     return m_webPagePrivate->m_webPage->hasOpenedPopup();
306 }
307
308 PassRefPtr<PopupMenu> ChromeClientBlackBerry::createPopupMenu(PopupMenuClient* client) const
309 {
310     return adoptRef(new PopupMenuBlackBerry(client));
311 }
312
313 PassRefPtr<SearchPopupMenu> ChromeClientBlackBerry::createSearchPopupMenu(PopupMenuClient* client) const
314 {
315     return adoptRef(new SearchPopupMenuBlackBerry(client));
316 }
317
318 PagePopup* ChromeClientBlackBerry::openPagePopup(PagePopupClient* client, const IntRect& originBoundsInRootView)
319 {
320     closePagePopup(0);
321
322     PagePopupBlackBerry* webPopup = new PagePopupBlackBerry(m_webPagePrivate, client, rootViewToScreen(originBoundsInRootView));
323     m_webPagePrivate->m_webPage->popupOpened(webPopup);
324     if (webPopup->sendCreatePopupWebViewRequest())
325         return webPopup;
326
327     closePagePopup(0);
328     return 0;
329 }
330
331 void ChromeClientBlackBerry::closePagePopup(PagePopup*)
332 {
333     if (!hasOpenedPopup())
334         return;
335
336     PagePopupBlackBerry* webPopup = m_webPagePrivate->m_webPage->popup();
337     webPopup->closePopup();
338     delete webPopup;
339 }
340
341 void ChromeClientBlackBerry::setToolbarsVisible(bool)
342 {
343     notImplemented();
344 }
345
346 bool ChromeClientBlackBerry::toolbarsVisible()
347 {
348     notImplemented();
349     return false;
350 }
351
352 void ChromeClientBlackBerry::setStatusbarVisible(bool)
353 {
354     notImplemented();
355 }
356
357 bool ChromeClientBlackBerry::statusbarVisible()
358 {
359     notImplemented();
360     return false;
361 }
362
363 void ChromeClientBlackBerry::setScrollbarsVisible(bool)
364 {
365     notImplemented();
366 }
367
368 bool ChromeClientBlackBerry::scrollbarsVisible()
369 {
370     notImplemented();
371     return false;
372 }
373
374 void ChromeClientBlackBerry::setMenubarVisible(bool)
375 {
376     notImplemented();
377 }
378
379 bool ChromeClientBlackBerry::menubarVisible()
380 {
381     notImplemented();
382     return false;
383 }
384
385 void ChromeClientBlackBerry::setResizable(bool)
386 {
387     notImplemented();
388 }
389
390 bool ChromeClientBlackBerry::canRunBeforeUnloadConfirmPanel()
391 {
392     return true;
393 }
394
395 bool ChromeClientBlackBerry::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
396 {
397 #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
398     if (m_webPagePrivate->m_dumpRenderTree)
399         return m_webPagePrivate->m_dumpRenderTree->runBeforeUnloadConfirmPanel(message);
400 #endif
401
402     TimerBase::fireTimersInNestedEventLoop();
403     CString latinOrigin = toOriginString(frame);
404     return m_webPagePrivate->m_client->runBeforeUnloadConfirmPanel(message.characters(), message.length(), latinOrigin.data(), latinOrigin.length());
405 }
406
407 void ChromeClientBlackBerry::closeWindowSoon()
408 {
409     if (m_webPagePrivate->m_page->openedByDOM())
410         m_webPagePrivate->m_client->scheduleCloseWindow();
411 }
412
413 void ChromeClientBlackBerry::setStatusbarText(const String& status)
414 {
415     m_webPagePrivate->m_client->setStatus(status);
416
417 #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
418     if (m_webPagePrivate->m_dumpRenderTree)
419         m_webPagePrivate->m_dumpRenderTree->setStatusText(status);
420 #endif
421 }
422
423 IntRect ChromeClientBlackBerry::windowResizerRect() const
424 {
425     notImplemented();
426     return IntRect();
427 }
428
429 IntPoint ChromeClientBlackBerry::screenToRootView(const IntPoint& screenPos) const
430 {
431     IntPoint windowPoint;
432     if (Window* window = m_webPagePrivate->m_client->window())
433         windowPoint = window->windowLocation();
434
435     windowPoint.move(-screenPos.x(), -screenPos.y());
436     return windowPoint;
437 }
438
439 IntRect ChromeClientBlackBerry::rootViewToScreen(const IntRect& windowRect) const
440 {
441     IntRect windowPoint(windowRect);
442     IntPoint location;
443     if (Window* window = m_webPagePrivate->m_client->window())
444         location = window->windowLocation();
445
446     windowPoint.move(location.x(), location.y());
447     return windowPoint;
448 }
449
450 void ChromeClientBlackBerry::mouseDidMoveOverElement(const HitTestResult& result, unsigned int modifierFlags)
451 {
452     notImplemented();
453 }
454
455 void ChromeClientBlackBerry::setToolTip(const String& tooltip, TextDirection)
456 {
457     m_webPagePrivate->m_client->setToolTip(tooltip);
458 }
459
460 #if ENABLE(EVENT_MODE_METATAGS)
461 void ChromeClientBlackBerry::didReceiveCursorEventMode(Frame* frame, CursorEventMode mode) const
462 {
463     if (m_webPagePrivate->m_mainFrame != frame)
464         return;
465
466     m_webPagePrivate->didReceiveCursorEventMode(mode);
467 }
468
469 void ChromeClientBlackBerry::didReceiveTouchEventMode(Frame* frame, TouchEventMode mode) const
470 {
471     if (m_webPagePrivate->m_mainFrame != frame)
472         return;
473
474     m_webPagePrivate->didReceiveTouchEventMode(mode);
475 }
476 #endif
477
478 void ChromeClientBlackBerry::dispatchViewportPropertiesDidChange(const ViewportArguments& arguments) const
479 {
480     m_webPagePrivate->dispatchViewportPropertiesDidChange(arguments);
481 }
482
483 void ChromeClientBlackBerry::print(Frame*)
484 {
485     notImplemented();
486 }
487
488 void ChromeClientBlackBerry::exceededDatabaseQuota(Frame* frame, const String& name, DatabaseDetails details)
489 {
490 #if ENABLE(SQL_DATABASE)
491     Document* document = frame->document();
492     if (!document)
493         return;
494
495     SecurityOrigin* origin = document->securityOrigin();
496
497 #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
498     if (m_webPagePrivate->m_dumpRenderTree) {
499         m_webPagePrivate->m_dumpRenderTree->exceededDatabaseQuota(origin, name);
500         return;
501     }
502 #endif
503
504     DatabaseManager& manager = DatabaseManager::manager();
505
506     unsigned long long originUsage = tracker.usageForOrigin(origin);
507     unsigned long long currentQuota = tracker.quotaForOrigin(origin);
508
509     unsigned long long estimatedSize = details.expectedUsage();
510     const String& nameStr = details.displayName();
511
512     String originStr = origin->toString();
513
514     unsigned long long quota = m_webPagePrivate->m_client->databaseQuota(originStr, nameStr, originUsage, currentQuota, estimatedSize);
515
516     manager.setQuota(origin, quota);
517 #endif
518 }
519
520 void ChromeClientBlackBerry::runOpenPanel(Frame*, PassRefPtr<FileChooser> chooser)
521 {
522     SharedArray<BlackBerry::Platform::String> initialFiles;
523     unsigned numberOfInitialFiles = chooser->settings().selectedFiles.size();
524     if (numberOfInitialFiles > 0)
525         initialFiles.reset(new BlackBerry::Platform::String[numberOfInitialFiles], numberOfInitialFiles);
526     for (unsigned i = 0; i < numberOfInitialFiles; ++i)
527         initialFiles[i] = chooser->settings().selectedFiles[i];
528
529     SharedArray<BlackBerry::Platform::String> acceptMIMETypes;
530     unsigned numberOfTypes = chooser->settings().acceptMIMETypes.size();
531     if (numberOfTypes > 0)
532         acceptMIMETypes.reset(new BlackBerry::Platform::String[numberOfTypes], numberOfTypes);
533     for (unsigned i = 0; i < numberOfTypes; ++i)
534         acceptMIMETypes[i] = chooser->settings().acceptMIMETypes[i];
535
536     BlackBerry::Platform::String capture;
537 #if ENABLE(MEDIA_CAPTURE)
538     capture = chooser->settings().capture;
539 #endif
540
541     SharedArray<BlackBerry::Platform::String> chosenFiles;
542
543     {
544         PageGroupLoadDeferrer deferrer(m_webPagePrivate->m_page, true);
545         TimerBase::fireTimersInNestedEventLoop();
546
547         if (!m_webPagePrivate->m_client->chooseFilenames(chooser->settings().allowsMultipleFiles, acceptMIMETypes, initialFiles, capture, chosenFiles))
548             return;
549     }
550
551     Vector<String> files(chosenFiles.length());
552     for (unsigned i = 0; i < chosenFiles.length(); ++i)
553         files[i] = chosenFiles[i];
554     chooser->chooseFiles(files);
555 }
556
557 void ChromeClientBlackBerry::loadIconForFiles(const Vector<String>& filenames, FileIconLoader* loader)
558 {
559     loader->notifyFinished(Icon::createIconForFiles(filenames));
560 }
561
562 void ChromeClientBlackBerry::setCursor(const Cursor&)
563 {
564     notImplemented();
565 }
566
567 void ChromeClientBlackBerry::formStateDidChange(const Node* node)
568 {
569     m_webPagePrivate->m_inputHandler->nodeTextChanged(node);
570 }
571
572 void ChromeClientBlackBerry::scrollbarsModeDidChange() const
573 {
574     notImplemented();
575 }
576
577 void ChromeClientBlackBerry::contentsSizeChanged(Frame* frame, const IntSize& size) const
578 {
579     if (frame != m_webPagePrivate->m_mainFrame)
580         return;
581
582     m_webPagePrivate->contentsSizeChanged(size);
583 }
584
585 void ChromeClientBlackBerry::invalidateRootView(const IntRect& updateRect, bool immediate)
586 {
587     m_webPagePrivate->m_backingStore->d->repaint(updateRect, false /*contentChanged*/, immediate);
588 }
589
590 void ChromeClientBlackBerry::invalidateContentsAndRootView(const IntRect& updateRect, bool immediate)
591 {
592     m_webPagePrivate->m_backingStore->d->repaint(updateRect, true /*contentChanged*/, immediate);
593 }
594
595 void ChromeClientBlackBerry::invalidateContentsForSlowScroll(const IntSize& delta, const IntRect& updateRect, bool immediate, const ScrollView* scrollView)
596 {
597     if (scrollView != m_webPagePrivate->m_mainFrame->view())
598         invalidateContentsAndRootView(updateRect, true /*immediate*/);
599     else {
600         BackingStoreClient* backingStoreClient = m_webPagePrivate->backingStoreClient();
601         ASSERT(backingStoreClient);
602         backingStoreClient->checkOriginOfCurrentScrollOperation();
603
604         m_webPagePrivate->m_backingStore->d->slowScroll(delta, updateRect, immediate);
605     }
606 }
607
608 void ChromeClientBlackBerry::scroll(const IntSize& delta, const IntRect& scrollViewRect, const IntRect& clipRect)
609 {
610     // FIXME: There's a chance the function is called indirectly by FrameView's dtor
611     // when the Frame's view() is null. We probably want to fix it in another way, but
612     // at this moment let's do a quick fix.
613     if (!m_webPagePrivate->m_mainFrame->view())
614         return;
615
616     BackingStoreClient* backingStoreClient = m_webPagePrivate->backingStoreClient();
617     ASSERT(backingStoreClient);
618     backingStoreClient->checkOriginOfCurrentScrollOperation();
619
620     m_webPagePrivate->m_backingStore->d->scroll(delta, scrollViewRect, clipRect);
621
622     // Shift the spell check dialog box as we scroll.
623     m_webPagePrivate->m_inputHandler->redrawSpellCheckDialogIfRequired();
624 }
625
626 void ChromeClientBlackBerry::scrollableAreasDidChange()
627 {
628     typedef HashSet<ScrollableArea*> ScrollableAreaSet;
629     const ScrollableAreaSet* scrollableAreas = m_webPagePrivate->m_mainFrame->view()->scrollableAreas();
630
631     bool hasAtLeastOneInRegionScrollableArea = false;
632     ScrollableAreaSet::iterator end = scrollableAreas->end();
633     for (ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != end; ++it) {
634         if ((*it) != m_webPagePrivate->m_page->mainFrame()->view()) {
635             hasAtLeastOneInRegionScrollableArea = true;
636             break;
637         }
638     }
639
640     m_webPagePrivate->setHasInRegionScrollableAreas(hasAtLeastOneInRegionScrollableArea);
641 }
642
643 void ChromeClientBlackBerry::scrollRectIntoView(const IntRect&, const ScrollView*) const
644 {
645     m_webPagePrivate->notifyTransformedScrollChanged();
646 }
647
648 bool ChromeClientBlackBerry::shouldInterruptJavaScript()
649 {
650     TimerBase::fireTimersInNestedEventLoop();
651     return m_webPagePrivate->m_client->shouldInterruptJavaScript();
652 }
653
654 KeyboardUIMode ChromeClientBlackBerry::keyboardUIMode()
655 {
656     bool tabsToLinks = true;
657
658 #if !defined(PUBLIC_BUILD) || !PUBLIC_BUILD
659     if (m_webPagePrivate->m_dumpRenderTree)
660         tabsToLinks = DumpRenderTreeSupport::linksIncludedInFocusChain();
661 #endif
662
663     return tabsToLinks ? KeyboardAccessTabsToLinks : KeyboardAccessDefault;
664 }
665
666 PlatformPageClient ChromeClientBlackBerry::platformPageClient() const
667 {
668     return m_webPagePrivate;
669 }
670
671 #if ENABLE(TOUCH_EVENTS)
672 void ChromeClientBlackBerry::needTouchEvents(bool value)
673 {
674 }
675 #endif
676
677 void ChromeClientBlackBerry::reachedMaxAppCacheSize(int64_t spaceNeeded)
678 {
679     notImplemented();
680 }
681
682 void ChromeClientBlackBerry::layoutUpdated(Frame* frame) const
683 {
684     if (frame != m_webPagePrivate->m_mainFrame)
685         return;
686
687     m_webPagePrivate->layoutFinished();
688 }
689
690 void ChromeClientBlackBerry::overflowExceedsContentsSize(Frame* frame) const
691 {
692     if (frame != m_webPagePrivate->m_mainFrame)
693         return;
694
695 #if DEBUG_OVERFLOW_DETECTION
696     BlackBerry::Platform::logAlways(BlackBerry::Platform::LogLevelInfo,
697         "ChromeClientBlackBerry::overflowExceedsContentsSize contents=%s overflow=%f x %f",
698         BlackBerry::Platform::IntRect(frame->contentRenderer()->documentRect()).toString().c_str(),
699         frame->contentRenderer()->rightAbsoluteVisibleOverflow().toFloat(),
700         frame->contentRenderer()->bottomAbsoluteVisibleOverflow().toFloat());
701 #endif
702     m_webPagePrivate->overflowExceedsContentsSize();
703 }
704
705 void ChromeClientBlackBerry::didDiscoverFrameSet(Frame* frame) const
706 {
707     if (frame != m_webPagePrivate->m_mainFrame)
708         return;
709
710     BBLOG(BlackBerry::Platform::LogLevelInfo, "ChromeClientBlackBerry::didDiscoverFrameSet");
711     if (m_webPagePrivate->loadState() == WebPagePrivate::Committed) {
712         m_webPagePrivate->setShouldUseFixedDesktopMode(true);
713         m_webPagePrivate->zoomToInitialScaleOnLoad();
714     }
715 }
716
717 int ChromeClientBlackBerry::reflowWidth() const
718 {
719     return m_webPagePrivate->reflowWidth();
720 }
721
722 void ChromeClientBlackBerry::chooseIconForFiles(const Vector<String>&, FileChooser*)
723 {
724     notImplemented();
725 }
726
727 bool ChromeClientBlackBerry::supportsFullscreenForNode(const Node* node)
728 {
729     return node->hasTagName(HTMLNames::videoTag);
730 }
731
732 void ChromeClientBlackBerry::enterFullscreenForNode(Node* node)
733 {
734     if (!supportsFullscreenForNode(node))
735         return;
736
737     m_webPagePrivate->enterFullscreenForNode(node);
738 }
739
740 void ChromeClientBlackBerry::exitFullscreenForNode(Node* node)
741 {
742     m_webPagePrivate->exitFullscreenForNode(node);
743 }
744
745 #if ENABLE(FULLSCREEN_API)
746 bool ChromeClientBlackBerry::supportsFullScreenForElement(const WebCore::Element* element, bool withKeyboard)
747 {
748     return !withKeyboard;
749 }
750
751 void ChromeClientBlackBerry::enterFullScreenForElement(WebCore::Element* element)
752 {
753     element->document()->webkitWillEnterFullScreenForElement(element);
754     m_webPagePrivate->enterFullScreenForElement(element);
755     element->document()->webkitDidEnterFullScreenForElement(element);
756     m_fullScreenElement = element;
757 }
758
759 void ChromeClientBlackBerry::exitFullScreenForElement(WebCore::Element*)
760 {
761     // The element passed into this function is not reliable, i.e. it could
762     // be null. In addition the parameter may be disappearing in the future.
763     // So we use the reference to the element we saved above.
764     ASSERT(m_fullScreenElement);
765     m_fullScreenElement->document()->webkitWillExitFullScreenForElement(m_fullScreenElement.get());
766     m_webPagePrivate->exitFullScreenForElement(m_fullScreenElement.get());
767     m_fullScreenElement->document()->webkitDidExitFullScreenForElement(m_fullScreenElement.get());
768     m_fullScreenElement.clear();
769 }
770
771 void ChromeClientBlackBerry::fullScreenRendererChanged(RenderBox*)
772 {
773     m_webPagePrivate->adjustFullScreenElementDimensionsIfNeeded();
774 }
775 #endif
776
777 #if ENABLE(SVG)
778 void ChromeClientBlackBerry::didSetSVGZoomAndPan(Frame* frame, unsigned short zoomAndPan)
779 {
780     // For top-level SVG document, there is no viewport tag, we use viewport's user-scalable
781     // to enable/disable zoom when top-level SVG document's zoomAndPan changed. Because there is no viewport
782     // tag, other fields with default value in ViewportArguments are ok.
783     if (frame == m_webPagePrivate->m_page->mainFrame()) {
784         ViewportArguments arguments;
785         switch (zoomAndPan) {
786         case SVGZoomAndPan::SVG_ZOOMANDPAN_DISABLE:
787             arguments.userScalable = 0;
788             break;
789         case SVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY:
790             arguments.userScalable = 1;
791             break;
792         default:
793             return;
794         }
795         didReceiveViewportArguments(frame, arguments);
796     }
797 }
798 #endif
799
800 #if USE(ACCELERATED_COMPOSITING)
801 void ChromeClientBlackBerry::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer)
802 {
803     // If the graphicsLayer parameter is 0, WebCore is actually
804     // trying to remove a previously attached layer.
805     m_webPagePrivate->setRootLayerWebKitThread(frame, graphicsLayer ? graphicsLayer->platformLayer() : 0);
806 }
807
808 void ChromeClientBlackBerry::setNeedsOneShotDrawingSynchronization()
809 {
810     m_webPagePrivate->setNeedsOneShotDrawingSynchronization();
811 }
812
813 void ChromeClientBlackBerry::scheduleCompositingLayerFlush()
814 {
815     m_webPagePrivate->scheduleRootLayerCommit();
816 }
817
818 bool ChromeClientBlackBerry::allowsAcceleratedCompositing() const
819 {
820     return true;
821 }
822 #endif
823
824 PassOwnPtr<ColorChooser> ChromeClientBlackBerry::createColorChooser(ColorChooserClient*, const Color&)
825 {
826     return nullptr;
827 }
828
829 #if ENABLE(NAVIGATOR_CONTENT_UTILS)
830 void ChromeClientBlackBerry::registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title)
831 {
832     m_webPagePrivate->m_client->registerProtocolHandler(scheme, baseURL, url, title);
833 }
834
835 #if ENABLE(CUSTOM_SCHEME_HANDLER)
836 ChromeClient::CustomHandlersState ChromeClientBlackBerry::isProtocolHandlerRegistered(const String& scheme, const String& baseURL, const String& url)
837 {
838     return static_cast<CustomHandlersState>(m_webPagePrivate->m_client->isProtocolHandlerRegistered(scheme, baseURL, url));
839 }
840
841 void ChromeClientBlackBerry::unregisterProtocolHandler(const String& scheme, const String& baseURL, const String& url)
842 {
843     m_webPagePrivate->m_client->unregisterProtocolHandler(scheme, baseURL, url);
844 }
845 #endif
846 #endif
847
848 void ChromeClientBlackBerry::addSearchProvider(const BlackBerry::Platform::String& originURL, const BlackBerry::Platform::String& newURL)
849 {
850     // See if the input URL host matches of the origin host.
851     KURL originHost = KURL(KURL(), originURL);
852     KURL url = KURL(KURL(), newURL);
853     if (url.isValid() && originHost.host() == url.host())
854         m_webPagePrivate->client()->addSearchProvider(newURL);
855 }
856
857 int ChromeClientBlackBerry::isSearchProviderInstalled(const BlackBerry::Platform::String& originURL, const BlackBerry::Platform::String& newURL)
858 {
859 //    Returns a value based on comparing url to the URLs of the results pages of the installed search engines.
860 //    0 - None of the installed search engines match url.
861 //    1 - One or more installed search engines match url, but none are the user's default search engine.
862 //    2 - The user's default search engine matches url.
863
864     // See if the input URL host matches of the origin host.
865     KURL originHost = KURL(KURL(), originURL);
866     KURL url = KURL(KURL(), newURL);
867     if (url.isValid() && originHost.host() == url.host())
868         return m_webPagePrivate->client()->isSearchProviderInstalled(newURL);
869     return 0;
870 }
871
872 } // namespace WebCore