summaryrefslogtreecommitdiff
path: root/Source/WebKit/blackberry/Api/WebPage.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
commit2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch)
tree988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebKit/blackberry/Api/WebPage.cpp
parentdd91e772430dc294e3bf478c119ef8d43c0a3358 (diff)
downloadqtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/WebKit/blackberry/Api/WebPage.cpp')
-rw-r--r--Source/WebKit/blackberry/Api/WebPage.cpp882
1 files changed, 680 insertions, 202 deletions
diff --git a/Source/WebKit/blackberry/Api/WebPage.cpp b/Source/WebKit/blackberry/Api/WebPage.cpp
index ad433607e..21e906a3b 100644
--- a/Source/WebKit/blackberry/Api/WebPage.cpp
+++ b/Source/WebKit/blackberry/Api/WebPage.cpp
@@ -25,12 +25,17 @@
#include "BackingStoreClient.h"
#include "BackingStoreCompositingSurface.h"
#include "BackingStore_p.h"
+#if ENABLE(BATTERY_STATUS)
+#include "BatteryClientBlackBerry.h"
+#endif
#include "CString.h"
#include "CachedImage.h"
#include "Chrome.h"
#include "ChromeClientBlackBerry.h"
#include "ContextMenuClientBlackBerry.h"
#include "CookieManager.h"
+#include "CredentialManager.h"
+#include "CredentialTransformData.h"
#include "DOMSupport.h"
#include "Database.h"
#include "DatabaseSync.h"
@@ -46,17 +51,16 @@
#include "EditorClientBlackBerry.h"
#include "FocusController.h"
#include "FrameLoaderClientBlackBerry.h"
-#if ENABLE(CLIENT_BASED_GEOLOCATION)
#if ENABLE_DRT
#include "GeolocationClientMock.h"
#endif
#include "GeolocationControllerClientBlackBerry.h"
-#endif
#include "GroupSettings.h"
#include "HTMLAreaElement.h"
#include "HTMLFrameOwnerElement.h"
#include "HTMLImageElement.h"
#include "HTMLInputElement.h"
+#include "HTMLMediaElement.h"
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
#include "HTTPParsers.h"
@@ -72,7 +76,7 @@
#include "LayerWebKitThread.h"
#include "NetworkManager.h"
#include "NodeRenderStyle.h"
-#if ENABLE(NOTIFICATIONS)
+#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
#include "NotificationPresenterImpl.h"
#endif
#include "Page.h"
@@ -82,6 +86,8 @@
#include "PlatformWheelEvent.h"
#include "PluginDatabase.h"
#include "PluginView.h"
+#include "RenderLayerBacking.h"
+#include "RenderLayerCompositor.h"
#include "RenderText.h"
#include "RenderThemeBlackBerry.h"
#include "RenderTreeAsText.h"
@@ -99,12 +105,17 @@
#include "ThreadCheck.h"
#include "TouchEventHandler.h"
#include "TransformationMatrix.h"
+#if ENABLE(VIBRATION)
+#include "VibrationClientBlackBerry.h"
+#endif
#include "VisiblePosition.h"
#if ENABLE(WEBDOM)
#include "WebDOMDocument.h"
#endif
+#include "WebKitVersion.h"
#include "WebPageClient.h"
#include "WebSocket.h"
+#include "WebViewportArguments.h"
#include "npapi.h"
#include "runtime_root.h"
@@ -120,9 +131,10 @@
#if USE(ACCELERATED_COMPOSITING)
#include "FrameLayers.h"
-#include "WebPageCompositor.h"
+#include "WebPageCompositor_p.h"
#endif
+#include <BlackBerryPlatformDeviceInfo.h>
#include <BlackBerryPlatformExecutableMessage.h>
#include <BlackBerryPlatformITPolicy.h>
#include <BlackBerryPlatformKeyboardEvent.h>
@@ -140,14 +152,19 @@
#include <memalloc.h>
#endif
-#if ENABLE(SKIA_GPU_CANVAS)
-#include "BlackBerryPlatformGraphics.h"
+#if ENABLE(ACCELERATED_2D_CANVAS)
+#include "SharedGraphicsContext3D.h"
#include "GrContext.h"
#endif
+#if ENABLE(REQUEST_ANIMATION_FRAME)
+#include "PlatformScreen.h"
+#endif
+
#define DEBUG_BLOCK_ZOOM 0
#define DEBUG_TOUCH_EVENTS 0
#define DEBUG_WEBPAGE_LOAD 0
+#define DEBUG_AC_COMMIT 0
using namespace std;
using namespace WebCore;
@@ -192,16 +209,16 @@ static KURL parseUrl(const String& url)
}
// Helper functions to convert to and from WebCore types.
-static inline MouseEventType toWebCoreMouseEventType(const Platform::MouseEvent::Type type)
+static inline WebCore::PlatformEvent::Type toWebCoreMouseEventType(const BlackBerry::Platform::MouseEvent::Type type)
{
switch (type) {
- case Platform::MouseEvent::MouseButtonDown:
- return MouseEventPressed;
+ case BlackBerry::Platform::MouseEvent::MouseButtonDown:
+ return WebCore::PlatformEvent::MousePressed;
case Platform::MouseEvent::MouseButtonUp:
- return MouseEventReleased;
+ return WebCore::PlatformEvent::MouseReleased;
case Platform::MouseEvent::MouseMove:
default:
- return MouseEventMoved;
+ return WebCore::PlatformEvent::MouseMoved;
}
}
@@ -262,6 +279,31 @@ static inline WebPage::BackForwardId backForwardIdFromHistoryItem(HistoryItem* i
return reinterpret_cast<WebPage::BackForwardId>(item);
}
+void WebPage::setUserViewportArguments(const WebViewportArguments& viewportArguments)
+{
+ d->m_userViewportArguments = *(viewportArguments.d);
+}
+
+void WebPage::resetUserViewportArguments()
+{
+ d->m_userViewportArguments = ViewportArguments();
+}
+
+template <bool WebPagePrivate::* isActive>
+class DeferredTask: public WebPagePrivate::DeferredTaskBase {
+public:
+ static void finishOrCancel(WebPagePrivate* webPagePrivate)
+ {
+ webPagePrivate->*isActive = false;
+ }
+protected:
+ DeferredTask(WebPagePrivate* webPagePrivate)
+ : DeferredTaskBase(webPagePrivate, isActive)
+ {
+ }
+ typedef DeferredTask<isActive> DeferredTaskType;
+};
+
WebPagePrivate::WebPagePrivate(WebPage* webPage, WebPageClient* client, const IntRect& rect)
: m_webPage(webPage)
, m_client(client)
@@ -270,6 +312,7 @@ WebPagePrivate::WebPagePrivate(WebPage* webPage, WebPageClient* client, const In
, m_currentContextNode(0)
, m_webSettings(0) // Initialized by init.
, m_visible(false)
+ , m_activationState(ActivationActive)
, m_shouldResetTilesWhenShown(false)
, m_userScalable(true)
, m_userPerformedManualZoom(false)
@@ -317,10 +360,8 @@ WebPagePrivate::WebPagePrivate(WebPage* webPage, WebPageClient* client, const In
, m_lastUserEventTimestamp(0.0)
, m_pluginMouseButtonPressed(false)
, m_pluginMayOpenNewTab(false)
- , m_geolocationClient(0)
, m_inRegionScrollStartingNode(0)
#if USE(ACCELERATED_COMPOSITING)
- , m_isAcceleratedCompositingActive(false)
, m_rootLayerCommitTimer(adoptPtr(new Timer<WebPagePrivate>(this, &WebPagePrivate::rootLayerCommitTimerFired)))
, m_needsOneShotDrawingSynchronization(false)
, m_needsCommit(false)
@@ -330,7 +371,14 @@ WebPagePrivate::WebPagePrivate(WebPage* webPage, WebPageClient* client, const In
, m_fullscreenVideoNode(0)
, m_hasInRegionScrollableAreas(false)
, m_updateDelegatedOverlaysDispatched(false)
+ , m_deferredTasksTimer(this, &WebPagePrivate::deferredTasksTimerFired)
{
+ static bool isInitialized = false;
+ if (!isInitialized) {
+ isInitialized = true;
+ BlackBerry::Platform::DeviceInfo::instance();
+ defaultUserAgent();
+ }
}
WebPage::WebPage(WebPageClient* client, const WebString& pageGroupName, const Platform::IntRect& rect)
@@ -380,7 +428,7 @@ WebPagePrivate::~WebPagePrivate()
WebPage::~WebPage()
{
- delete d;
+ deleteGuardedObject(d);
d = 0;
}
@@ -415,36 +463,36 @@ void WebPagePrivate::init(const WebString& pageGroupName)
pageClients.dragClient = dragClient;
pageClients.inspectorClient = inspectorClient;
-#if ENABLE(CLIENT_BASED_GEOLOCATION)
- // Note the object will be destroyed when the page is destroyed.
+ m_page = new Page(pageClients);
#if ENABLE_DRT
- if (getenv("drtRun"))
- pageClients.geolocationClient = new GeolocationClientMock();
- else
-#endif
- pageClients.geolocationClient = m_geolocationClient = new GeolocationControllerClientBlackBerry(this);
+ if (getenv("drtRun")) {
+ // In case running in DumpRenderTree mode set the controller to mock provider.
+ GeolocationClientMock* mock = new GeolocationClientMock();
+ WebCore::provideGeolocationTo(m_page, mock);
+ mock->setController(WebCore::GeolocationController::from(m_page));
+ } else
#else
- pageClients.geolocationClient = m_geolocationClient;
+ WebCore::provideGeolocationTo(m_page, new GeolocationControllerClientBlackBerry(this));
+#endif
+ WebCore::provideDeviceOrientationTo(m_page, new DeviceOrientationClientBlackBerry(this));
+ WebCore::provideDeviceMotionTo(m_page, new DeviceMotionClientBlackBerry(this));
+#if ENABLE(VIBRATION)
+ WebCore::provideVibrationTo(m_page, new VibrationClientBlackBerry());
#endif
- pageClients.deviceMotionClient = new DeviceMotionClientBlackBerry(this);
- pageClients.deviceOrientationClient = new DeviceOrientationClientBlackBerry(this);
- m_page = new Page(pageClients);
-
-#if ENABLE(NOTIFICATIONS)
- WebCore::provideNotification(m_page, NotificationPresenterImpl::instance());
+#if ENABLE(BATTERY_STATUS)
+ WebCore::provideBatteryTo(m_page, new WebCore::BatteryClientBlackBerry);
#endif
-#if ENABLE(CLIENT_BASED_GEOLOCATION) && ENABLE_DRT
- // In case running in DumpRenderTree mode set the controller to mock provider.
- if (getenv("drtRun"))
- static_cast<GeolocationClientMock*>(pageClients.geolocationClient)->setController(m_page->geolocationController());
+#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
+ WebCore::provideNotification(m_page, NotificationPresenterImpl::instance());
#endif
m_page->setCustomHTMLTokenizerChunkSize(256);
m_page->setCustomHTMLTokenizerTimeDelay(0.3);
m_webSettings = WebSettings::createFromStandardSettings();
+ m_webSettings->setUserAgentString(defaultUserAgent());
// FIXME: We explicitly call setDelegate() instead of passing ourself in createFromStandardSettings()
// so that we only get one didChangeSettings() callback when we set the page group name. This causes us
@@ -463,7 +511,7 @@ void WebPagePrivate::init(const WebString& pageGroupName)
Platform::Settings* settings = Platform::Settings::get();
m_page->settings()->setWebGLEnabled(settings && settings->isWebGLSupported());
#endif
-#if ENABLE(SKIA_GPU_CANVAS)
+#if ENABLE(ACCELERATED_2D_CANVAS)
m_page->settings()->setCanvasUsesAcceleratedDrawing(true);
m_page->settings()->setAccelerated2dCanvasEnabled(true);
#endif
@@ -485,11 +533,34 @@ void WebPagePrivate::init(const WebString& pageGroupName)
blockClickRadius = int(roundf(0.35 * Platform::Graphics::Screen::primaryScreen()->pixelsPerInch(0).width())); // The clicked rectangle area should be a fixed unit of measurement.
m_page->settings()->setDelegateSelectionPaint(true);
+
+#if ENABLE(REQUEST_ANIMATION_FRAME)
+ m_page->windowScreenDidChange((PlatformDisplayID)0);
+#endif
+
+#if ENABLE(WEB_TIMING)
+ m_page->settings()->setMemoryInfoEnabled(true);
+#endif
}
-void WebPagePrivate::load(const char* url, const char* networkToken, const char* method, Platform::NetworkRequest::CachePolicy cachePolicy, const char* data, size_t dataLength, const char* const* headers, size_t headersLength, bool isInitial, bool mustHandleInternally, bool forceDownload, const char* overrideContentType)
+class DeferredTaskLoadManualScript: public DeferredTask<&WebPagePrivate::m_wouldLoadManualScript> {
+public:
+ explicit DeferredTaskLoadManualScript(WebPagePrivate* webPagePrivate, const KURL& url)
+ : DeferredTaskType(webPagePrivate)
+ {
+ webPagePrivate->m_cachedManualScript = url;
+ }
+private:
+ virtual void performInternal(WebPagePrivate* webPagePrivate)
+ {
+ webPagePrivate->m_mainFrame->script()->executeIfJavaScriptURL(webPagePrivate->m_cachedManualScript, DoNotReplaceDocumentIfJavaScriptURL);
+ }
+};
+
+void WebPagePrivate::load(const char* url, const char* networkToken, const char* method, Platform::NetworkRequest::CachePolicy cachePolicy, const char* data, size_t dataLength, const char* const* headers, size_t headersLength, bool isInitial, bool mustHandleInternally, bool forceDownload, const char* overrideContentType, const char* suggestedSaveName)
{
stopCurrentLoad();
+ DeferredTaskLoadManualScript::finishOrCancel(this);
String urlString(url);
if (urlString.startsWith("vs:", false)) {
@@ -501,10 +572,9 @@ void WebPagePrivate::load(const char* url, const char* networkToken, const char*
KURL kurl = parseUrl(urlString);
if (protocolIs(kurl, "javascript")) {
// Never run javascript while loading is deferred.
- if (m_page->defersLoading()) {
- FrameLoaderClientBlackBerry* frameLoaderClient = static_cast<FrameLoaderClientBlackBerry*>(m_mainFrame->loader()->client());
- frameLoaderClient->setDeferredManualScript(kurl);
- } else
+ if (m_page->defersLoading())
+ m_deferredTasks.append(adoptPtr(new DeferredTaskLoadManualScript(this, kurl)));
+ else
m_mainFrame->script()->executeIfJavaScriptURL(kurl, DoNotReplaceDocumentIfJavaScriptURL);
return;
}
@@ -512,7 +582,7 @@ void WebPagePrivate::load(const char* url, const char* networkToken, const char*
if (isInitial)
NetworkManager::instance()->setInitialURL(kurl);
- ResourceRequest request(kurl, "" /* referrer */);
+ ResourceRequest request(kurl);
request.setToken(networkToken);
if (isInitial || mustHandleInternally)
request.setMustHandleInternally(true);
@@ -530,6 +600,8 @@ void WebPagePrivate::load(const char* url, const char* networkToken, const char*
if (forceDownload)
request.setForceDownload(true);
+ request.setSuggestedSaveName(suggestedSaveName);
+
m_mainFrame->loader()->load(request, "" /* name */, false);
}
@@ -556,7 +628,7 @@ void WebPage::loadFile(const char* path, const char* overrideContentType)
void WebPage::download(const Platform::NetworkRequest& request)
{
- d->load(request.getUrlRef().c_str(), 0, "GET", Platform::NetworkRequest::UseProtocolCachePolicy, 0, 0, 0, 0, false, false, true, "");
+ d->load(request.getUrlRef().c_str(), 0, "GET", Platform::NetworkRequest::UseProtocolCachePolicy, 0, 0, 0, 0, false, false, true, "", request.getSuggestedSaveName().c_str());
}
void WebPagePrivate::loadString(const char* string, const char* baseURL, const char* contentType, const char* failingURL)
@@ -711,8 +783,7 @@ void WebPagePrivate::stopCurrentLoad()
m_mainFrame->loader()->stopAllLoaders();
// Cancel any deferred script that hasn't been processed yet.
- FrameLoaderClientBlackBerry* frameLoaderClient = static_cast<FrameLoaderClientBlackBerry*>(m_mainFrame->loader()->client());
- frameLoaderClient->setDeferredManualScript(KURL());
+ DeferredTaskLoadManualScript::finishOrCancel(this);
}
void WebPage::stopLoading()
@@ -781,23 +852,19 @@ void WebPagePrivate::setLoadState(LoadState state)
{
unscheduleZoomAboutPoint();
-#if ENABLE(SKIA_GPU_CANVAS)
+#if ENABLE(ACCELERATED_2D_CANVAS)
if (m_page->settings()->canvasUsesAcceleratedDrawing()) {
// Free GPU resources as we're on a new page.
// This will help us to free memory pressure.
- Platform::Graphics::makeSharedResourceContextCurrent(Platform::Graphics::GLES2);
+ SharedGraphicsContext3D::get()->makeContextCurrent();
GrContext* grContext = Platform::Graphics::getGrContext();
grContext->freeGpuResources();
}
#endif
#if USE(ACCELERATED_COMPOSITING)
- // FIXME: compositor may only be touched on the compositing thread.
- // However, it's created/destroyed by a sync command so this is harmless.
- if (m_compositor) {
- m_compositor->setLayoutRectForCompositing(IntRect());
- m_compositor->setContentsSizeForCompositing(IntSize());
- }
+ if (isAcceleratedCompositingActive() && !compositorDrawsRootLayer())
+ syncDestroyCompositorOnCompositingThread();
#endif
m_previousContentsSize = IntSize();
m_backingStore->d->resetRenderQueue();
@@ -817,6 +884,12 @@ void WebPagePrivate::setLoadState(LoadState state)
// Check if we have already process the meta viewport tag, this only happens on history navigation
if (!m_didRestoreFromPageCache) {
m_viewportArguments = ViewportArguments();
+
+ // At the moment we commit a new load, set the viewport arguments
+ // to any fallback values. If there is a meta viewport in the
+ // content it will overwrite the fallback arguments soon.
+ dispatchViewportPropertiesDidChange(m_userViewportArguments);
+
m_userScalable = m_webSettings->isUserScalable();
resetScales();
} else {
@@ -845,6 +918,9 @@ void WebPagePrivate::setLoadState(LoadState state)
toggleTextReflowIfEnabledForBlockZoomOnly();
#endif
+ // Notify InputHandler of state change.
+ m_inputHandler->enableInputMode(false);
+
// Set the scroll to origin here and notify the client since we'll be
// zooming below without any real contents yet thus the contents size
// we report to the client could make our current scroll position invalid.
@@ -1175,14 +1251,32 @@ bool WebPagePrivate::shouldSendResizeEvent()
void WebPagePrivate::willDeferLoading()
{
+ m_deferredTasksTimer.stop();
m_client->willDeferLoading();
}
void WebPagePrivate::didResumeLoading()
{
+ if (!m_deferredTasks.isEmpty())
+ m_deferredTasksTimer.startOneShot(0);
m_client->didResumeLoading();
}
+void WebPagePrivate::deferredTasksTimerFired(WebCore::Timer<WebPagePrivate>*)
+{
+ ASSERT(!m_deferredTasks.isEmpty());
+ if (!m_deferredTasks.isEmpty())
+ return;
+
+ OwnPtr<DeferredTaskBase> task = m_deferredTasks[0].release();
+ m_deferredTasks.remove(0);
+
+ if (!m_deferredTasks.isEmpty())
+ m_deferredTasksTimer.startOneShot(0);
+
+ task->perform(this);
+}
+
bool WebPagePrivate::scrollBy(int deltaX, int deltaY, bool scrollMainFrame)
{
IntSize delta(deltaX, deltaY);
@@ -1547,6 +1641,11 @@ bool WebPage::isUserScalable() const
return d->isUserScalable();
}
+void WebPage::setUserScalable(bool userScalable)
+{
+ d->setUserScalable(userScalable);
+}
+
double WebPage::currentScale() const
{
return d->currentScale();
@@ -1843,7 +1942,7 @@ bool WebPagePrivate::setViewMode(ViewMode mode)
return true; // Needs re-layout!
}
-void WebPagePrivate::setCursor(PlatformCursorHandle handle)
+void WebPagePrivate::setCursor(PlatformCursor handle)
{
if (m_currentCursor.type() != handle.type()) {
m_currentCursor = handle;
@@ -1930,6 +2029,10 @@ void WebPagePrivate::didPluginEnterFullScreen(PluginView* plugin, const char* wi
{
m_fullScreenPluginView = plugin;
m_client->didPluginEnterFullScreen();
+
+ if (!m_client->window())
+ return;
+
Platform::Graphics::Window::setTransparencyDiscardFilter(windowUniquePrefix);
m_client->window()->setSensitivityFullscreenOverride(true);
}
@@ -1938,6 +2041,10 @@ void WebPagePrivate::didPluginExitFullScreen(PluginView* plugin, const char* win
{
m_fullScreenPluginView = 0;
m_client->didPluginExitFullScreen();
+
+ if (!m_client->window())
+ return;
+
Platform::Graphics::Window::setTransparencyDiscardFilter(0);
m_client->window()->setSensitivityFullscreenOverride(false);
}
@@ -1987,14 +2094,41 @@ bool WebPagePrivate::isActive() const
return m_client->isActive();
}
+Credential WebPagePrivate::authenticationChallenge(const KURL& url, const ProtectionSpace& protectionSpace)
+{
+ WebString username;
+ WebString password;
+
+#if ENABLE(BLACKBERRY_CREDENTIAL_PERSIST)
+ if (!m_webSettings->isPrivateBrowsingEnabled())
+ credentialManager().autofillAuthenticationChallenge(protectionSpace, username, password);
+#endif
+
+ m_client->authenticationChallenge(protectionSpace.realm().characters(), protectionSpace.realm().length(), username, password);
+
+#if ENABLE(BLACKBERRY_CREDENTIAL_PERSIST)
+ Credential inputCredential(username, password, CredentialPersistencePermanent);
+ if (!m_webSettings->isPrivateBrowsingEnabled())
+ credentialManager().saveCredentialIfConfirmed(this, CredentialTransformData(url, protectionSpace, inputCredential));
+#else
+ Credential inputCredential(username, password, CredentialPersistenceNone);
+#endif
+ return inputCredential;
+}
+
+PageClientBlackBerry::SaveCredentialType WebPagePrivate::notifyShouldSaveCredential(bool isNew)
+{
+ return static_cast<PageClientBlackBerry::SaveCredentialType>(m_client->notifyShouldSaveCredential(isNew));
+}
+
bool WebPagePrivate::useFixedLayout() const
{
return true;
}
-ActiveNodeContext WebPagePrivate::activeNodeContext(TargetDetectionStrategy strategy)
+Platform::WebContext WebPagePrivate::webContext(TargetDetectionStrategy strategy)
{
- ActiveNodeContext context;
+ Platform::WebContext context;
RefPtr<Node> node = contextNode(strategy);
m_currentContextNode = node;
@@ -2007,16 +2141,16 @@ ActiveNodeContext WebPagePrivate::activeNodeContext(TargetDetectionStrategy stra
if (Node* linkNode = node->enclosingLinkEventParentOrSelf()) {
KURL href;
if (linkNode->isLink() && linkNode->hasAttributes()) {
- if (Attribute* attribute = linkNode->attributes()->getAttributeItem(HTMLNames::hrefAttr))
+ if (Attribute* attribute = static_cast<Element*>(linkNode)->getAttributeItem(HTMLNames::hrefAttr))
href = linkNode->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(attribute->value()));
}
String pattern = findPatternStringForUrl(href);
if (!pattern.isEmpty())
- context.setPattern(pattern);
+ context.setPattern(pattern.utf8().data());
if (!href.string().isEmpty()) {
- context.setUrl(href.string());
+ context.setUrl(href.string().utf8().data());
// Links are non-selectable by default, but selection should be allowed
// providing the page is selectable, use the parent to determine it.
@@ -2026,58 +2160,75 @@ ActiveNodeContext WebPagePrivate::activeNodeContext(TargetDetectionStrategy stra
}
if (!nodeAllowSelectionOverride && !node->canStartSelection())
- context.resetFlag(ActiveNodeContext::IsSelectable);
+ context.resetFlag(Platform::WebContext::IsSelectable);
if (node->isHTMLElement()) {
HTMLImageElement* imageElement = 0;
+ HTMLMediaElement* mediaElement = 0;
+
if (node->hasTagName(HTMLNames::imgTag))
imageElement = static_cast<HTMLImageElement*>(node.get());
else if (node->hasTagName(HTMLNames::areaTag))
imageElement = static_cast<HTMLAreaElement*>(node.get())->imageElement();
+
+ if (static_cast<HTMLElement*>(node.get())->isMediaElement())
+ mediaElement = static_cast<HTMLMediaElement*>(node.get());
+
if (imageElement && imageElement->renderer()) {
+ context.setFlag(Platform::WebContext::IsImage);
// FIXME: At the mean time, we only show "Save Image" when the image data is available.
if (CachedResource* cachedResource = imageElement->cachedImage()) {
if (cachedResource->isLoaded() && cachedResource->data()) {
String url = stripLeadingAndTrailingHTMLSpaces(imageElement->getAttribute(HTMLNames::srcAttr).string());
- context.setImageSrc(node->document()->completeURL(url).string());
+ context.setSrc(node->document()->completeURL(url).string().utf8().data());
}
}
String alt = imageElement->altText();
if (!alt.isNull())
- context.setImageAlt(alt);
+ context.setAlt(alt.utf8().data());
+ }
+
+ if (mediaElement) {
+ if (mediaElement->hasAudio())
+ context.setFlag(Platform::WebContext::IsAudio);
+ if (mediaElement->hasVideo())
+ context.setFlag(Platform::WebContext::IsVideo);
+
+ String src = stripLeadingAndTrailingHTMLSpaces(mediaElement->getAttribute(HTMLNames::srcAttr).string());
+ context.setSrc(node->document()->completeURL(src).string().utf8().data());
}
}
if (node->isTextNode()) {
Text* curText = static_cast<Text*>(node.get());
if (!curText->wholeText().isEmpty())
- context.setText(curText->wholeText());
+ context.setText(curText->wholeText().utf8().data());
}
if (node->isElementNode()) {
Element* element = static_cast<Element*>(node->shadowAncestorNode());
if (DOMSupport::isTextBasedContentEditableElement(element)) {
- context.setFlag(ActiveNodeContext::IsInput);
+ context.setFlag(Platform::WebContext::IsInput);
if (element->hasTagName(HTMLNames::inputTag))
- context.setFlag(ActiveNodeContext::IsSingleLine);
+ context.setFlag(Platform::WebContext::IsSingleLine);
if (DOMSupport::isPasswordElement(element))
- context.setFlag(ActiveNodeContext::IsPassword);
+ context.setFlag(Platform::WebContext::IsPassword);
String elementText(DOMSupport::inputElementText(element));
if (!elementText.stripWhiteSpace().isEmpty())
- context.setText(elementText);
+ context.setText(elementText.utf8().data());
}
}
if (node->isFocusable())
- context.setFlag(ActiveNodeContext::IsFocusable);
+ context.setFlag(Platform::WebContext::IsFocusable);
return context;
}
-ActiveNodeContext WebPage::activeNodeContext(TargetDetectionStrategy strategy) const
+Platform::WebContext WebPage::webContext(TargetDetectionStrategy strategy) const
{
- return d->activeNodeContext(strategy);
+ return d->webContext(strategy);
}
void WebPagePrivate::updateCursor()
@@ -2090,7 +2241,7 @@ void WebPagePrivate::updateCursor()
else if (m_lastMouseEvent.button() == RightButton)
buttonMask = Platform::MouseEvent::ScreenRightMouseButton;
- Platform::MouseEvent event(buttonMask, buttonMask, mapToTransformed(m_lastMouseEvent.pos()), mapToTransformed(m_lastMouseEvent.globalPos()), 0, 0);
+ BlackBerry::Platform::MouseEvent event(buttonMask, buttonMask, mapToTransformed(m_lastMouseEvent.position()), mapToTransformed(m_lastMouseEvent.globalPosition()), 0, 0);
m_webPage->mouseEvent(event);
}
@@ -2347,6 +2498,8 @@ void WebPagePrivate::assignFocus(Platform::FocusDirection direction)
void WebPage::assignFocus(Platform::FocusDirection direction)
{
+ if (d->m_page->defersLoading())
+ return;
d->assignFocus(direction);
}
@@ -2398,7 +2551,7 @@ PassRefPtr<Node> WebPagePrivate::contextNode(TargetDetectionStrategy strategy)
if (isTouching)
contentPos = lastFatFingersResult.adjustedPosition();
else
- contentPos = mapFromViewportToContents(m_lastMouseEvent.pos());
+ contentPos = mapFromViewportToContents(m_lastMouseEvent.position());
if (strategy == RectBased) {
FatFingersResult result = FatFingers(this, lastFatFingersResult.adjustedPosition(), FatFingers::Text).findBestPoint();
@@ -2509,6 +2662,17 @@ Node* WebPagePrivate::adjustedBlockZoomNodeForZoomLimits(Node* node)
acceptableNodeSize = newScaleForBlockZoomRect(rectForNode(node), 1.0, 0) < maxBlockZoomScale();
}
+ // Don't use a node if it is too close to the size of the actual contents.
+ if (initialNode != node) {
+ IntRect nodeRect = rectForNode(node);
+ nodeRect = adjustRectOffsetForFrameOffset(nodeRect, node);
+ nodeRect.intersect(IntRect(IntPoint::zero(), contentsSize()));
+ int nodeArea = nodeRect.width() * nodeRect.height();
+ int pageArea = contentsSize().width() * contentsSize().height();
+ if (static_cast<double>(pageArea - nodeArea) / pageArea < minimumExpandingRatio)
+ return initialNode;
+ }
+
return node;
}
@@ -2645,7 +2809,7 @@ IntRect WebPagePrivate::blockZoomRectForNode(Node* node)
int originalArea = originalRect.width() * originalRect.height();
int pageArea = contentsSize().width() * contentsSize().height();
- double blockToPageRatio = static_cast<double>(1 - originalArea / pageArea);
+ double blockToPageRatio = static_cast<double>(pageArea - originalArea) / pageArea;
double blockExpansionRatio = 5.0 * blockToPageRatio * blockToPageRatio;
if (!tnode->hasTagName(HTMLNames::imgTag) && !tnode->hasTagName(HTMLNames::inputTag) && !tnode->hasTagName(HTMLNames::textareaTag)) {
@@ -2654,7 +2818,7 @@ IntRect WebPagePrivate::blockZoomRectForNode(Node* node)
IntRect tRect = rectForNode(tnode);
int tempBlockArea = tRect.width() * tRect.height();
// Don't expand the block if it will be too large relative to the content.
- if (static_cast<double>(1 - tempBlockArea / pageArea) < minimumExpandingRatio)
+ if (static_cast<double>(pageArea - tempBlockArea) / pageArea < minimumExpandingRatio)
break;
if (tRect.isEmpty())
continue; // No renderer.
@@ -2662,7 +2826,7 @@ IntRect WebPagePrivate::blockZoomRectForNode(Node* node)
continue; // The size of this parent is very close to the child, no need to go to this parent.
// Don't expand the block if the parent node size is already almost the size of actual visible size.
IntSize actualSize = actualVisibleSize();
- if (static_cast<double>(1 - tRect.width() / actualSize.width()) < minimumExpandingRatio)
+ if (static_cast<double>(actualSize.width() - tRect.width()) / actualSize.width() < minimumExpandingRatio)
break;
if (tempBlockArea < blockExpansionRatio * originalArea) {
blockRect = tRect;
@@ -2825,7 +2989,7 @@ void WebPage::destroy()
if (loader)
loader->detachFromParent();
- delete this;
+ deleteGuardedObject(this);
}
WebPageClient* WebPage::client() const
@@ -2879,12 +3043,50 @@ bool WebPage::isVisible() const
return d->m_visible;
}
+#if ENABLE(PAGE_VISIBILITY_API)
+class DeferredTaskSetPageVisibilityState: public DeferredTask<&WebPagePrivate::m_wouldSetPageVisibilityState> {
+public:
+ explicit DeferredTaskSetPageVisibilityState(WebPagePrivate* webPagePrivate)
+ : DeferredTaskType(webPagePrivate)
+ {
+ }
+private:
+ virtual void performInternal(WebPagePrivate* webPagePrivate)
+ {
+ webPagePrivate->setPageVisibilityState();
+ }
+};
+
+void WebPagePrivate::setPageVisibilityState()
+{
+ if (m_page->defersLoading())
+ m_deferredTasks.append(adoptPtr(new DeferredTaskSetPageVisibilityState(this)));
+ else {
+ DeferredTaskSetPageVisibilityState::finishOrCancel(this);
+
+ static bool s_initialVisibilityState = true;
+
+ m_page->setVisibilityState(m_visible && m_activationState == ActivationActive ? PageVisibilityStateVisible : PageVisibilityStateHidden, s_initialVisibilityState);
+ s_initialVisibilityState = false;
+ }
+}
+#endif
+
+void WebPagePrivate::setVisible(bool visible)
+{
+ m_visible = visible;
+
+#if ENABLE(PAGE_VISIBILITY_API)
+ setPageVisibilityState();
+#endif
+}
+
void WebPage::setVisible(bool visible)
{
if (d->m_visible == visible)
return;
- d->m_visible = visible;
+ d->setVisible(visible);
if (!visible) {
d->suspendBackingStore();
@@ -2903,6 +3105,7 @@ void WebPage::setVisible(bool visible)
// And release layer resources can reduce memory consumption.
d->suspendRootLayerCommit();
#endif
+
return;
}
@@ -2971,6 +3174,8 @@ bool WebPage::setBatchEditingActive(bool active)
bool WebPage::setInputSelection(unsigned start, unsigned end)
{
+ if (d->m_page->defersLoading())
+ return false;
return d->m_inputHandler->setSelection(start, end);
}
@@ -2979,23 +3184,101 @@ int WebPage::inputCaretPosition() const
return d->m_inputHandler->caretPosition();
}
-void WebPage::popupListClosed(int size, bool* selecteds)
+class DeferredTaskPopupListSelectMultiple: public DeferredTask<&WebPagePrivate::m_wouldPopupListSelectMultiple> {
+public:
+ DeferredTaskPopupListSelectMultiple(WebPagePrivate* webPagePrivate, int size, const bool* selecteds)
+ : DeferredTaskType(webPagePrivate)
+ {
+ webPagePrivate->m_cachedPopupListSelecteds.append(selecteds, size);
+ }
+private:
+ virtual void performInternal(WebPagePrivate* webPagePrivate)
+ {
+ webPagePrivate->m_webPage->popupListClosed(webPagePrivate->m_cachedPopupListSelecteds.size(), webPagePrivate->m_cachedPopupListSelecteds.data());
+ }
+};
+
+class DeferredTaskPopupListSelectSingle: public DeferredTask<&WebPagePrivate::m_wouldPopupListSelectSingle> {
+public:
+ explicit DeferredTaskPopupListSelectSingle(WebPagePrivate* webPagePrivate, int index)
+ : DeferredTaskType(webPagePrivate)
+ {
+ webPagePrivate->m_cachedPopupListSelectedIndex = index;
+ }
+private:
+ virtual void performInternal(WebPagePrivate* webPagePrivate)
+ {
+ webPagePrivate->m_webPage->popupListClosed(webPagePrivate->m_cachedPopupListSelectedIndex);
+ }
+};
+
+void WebPage::popupListClosed(int size, const bool* selecteds)
{
+ DeferredTaskPopupListSelectSingle::finishOrCancel(d);
+ if (d->m_page->defersLoading()) {
+ d->m_deferredTasks.append(adoptPtr(new DeferredTaskPopupListSelectMultiple(d, size, selecteds)));
+ return;
+ }
+ DeferredTaskPopupListSelectMultiple::finishOrCancel(d);
d->m_inputHandler->setPopupListIndexes(size, selecteds);
}
void WebPage::popupListClosed(int index)
{
+ DeferredTaskPopupListSelectMultiple::finishOrCancel(d);
+ if (d->m_page->defersLoading()) {
+ d->m_deferredTasks.append(adoptPtr(new DeferredTaskPopupListSelectSingle(d, index)));
+ return;
+ }
+ DeferredTaskPopupListSelectSingle::finishOrCancel(d);
d->m_inputHandler->setPopupListIndex(index);
}
+class DeferredTaskSetDateTimeInput: public DeferredTask<&WebPagePrivate::m_wouldSetDateTimeInput> {
+public:
+ explicit DeferredTaskSetDateTimeInput(WebPagePrivate* webPagePrivate, WebString value)
+ : DeferredTaskType(webPagePrivate)
+ {
+ webPagePrivate->m_cachedDateTimeInput = value;
+ }
+private:
+ virtual void performInternal(WebPagePrivate* webPagePrivate)
+ {
+ webPagePrivate->m_webPage->setDateTimeInput(webPagePrivate->m_cachedDateTimeInput);
+ }
+};
+
void WebPage::setDateTimeInput(const WebString& value)
{
+ if (d->m_page->defersLoading()) {
+ d->m_deferredTasks.append(adoptPtr(new DeferredTaskSetDateTimeInput(d, value)));
+ return;
+ }
+ DeferredTaskSetDateTimeInput::finishOrCancel(d);
d->m_inputHandler->setInputValue(String(value.impl()));
}
+class DeferredTaskSetColorInput: public DeferredTask<&WebPagePrivate::m_wouldSetColorInput> {
+public:
+ explicit DeferredTaskSetColorInput(WebPagePrivate* webPagePrivate, WebString value)
+ : DeferredTaskType(webPagePrivate)
+ {
+ webPagePrivate->m_cachedColorInput = value;
+ }
+private:
+ virtual void performInternal(WebPagePrivate* webPagePrivate)
+ {
+ webPagePrivate->m_webPage->setColorInput(webPagePrivate->m_cachedColorInput);
+ }
+};
+
void WebPage::setColorInput(const WebString& value)
{
+ if (d->m_page->defersLoading()) {
+ d->m_deferredTasks.append(adoptPtr(new DeferredTaskSetColorInput(d, value)));
+ return;
+ }
+ DeferredTaskSetColorInput::finishOrCancel(d);
d->m_inputHandler->setInputValue(String(value.impl()));
}
@@ -3012,7 +3295,7 @@ void WebPage::resetVirtualViewportOnCommitted(bool reset)
IntSize WebPagePrivate::recomputeVirtualViewportFromViewportArguments()
{
- static ViewportArguments defaultViewportArguments;
+ static const ViewportArguments defaultViewportArguments;
if (m_viewportArguments == defaultViewportArguments)
return IntSize();
@@ -3021,9 +3304,11 @@ IntSize WebPagePrivate::recomputeVirtualViewportFromViewportArguments()
int deviceHeight = Platform::Graphics::Screen::primaryScreen()->height();
FloatSize currentPPI = Platform::Graphics::Screen::primaryScreen()->pixelsPerInch(-1);
int deviceDPI = int(roundf((currentPPI.width() + currentPPI.height()) / 2));
- if (m_viewportArguments.targetDensityDpi == ViewportArguments::ValueAuto) {
- // Auto means 160dpi if we leave it alone. This looks terrible for pages wanting 1:1.
- // FIXME: This is insufficient for devices with high dpi, as they will render content unreadably small.
+ if (m_viewportArguments.targetDensityDpi == ViewportArguments::ValueAuto
+ && !Platform::DeviceInfo::instance()->isMobile()) {
+ // If the content provider hasn't specified a target dpi and we have a large
+ // screen we assume the content is fine and set the targetDensityDpi to our dpi.
+ // On smaller screen mobile devices we skip this and use WebCore dpi scaling.
m_viewportArguments.targetDensityDpi = deviceDPI;
}
@@ -3098,6 +3383,15 @@ void WebPage::onInputLocaleChanged(bool isRTL)
void WebPagePrivate::suspendBackingStore()
{
#if USE(ACCELERATED_COMPOSITING)
+ if (m_backingStore->d->isOpenGLCompositing()) {
+ // A visible web page's backing store can be suspended when another web
+ // page is taking over the backing store.
+ if (m_visible)
+ setCompositorDrawsRootLayer(true);
+
+ return;
+ }
+
resetCompositingSurface();
#endif
}
@@ -3106,10 +3400,6 @@ void WebPagePrivate::resumeBackingStore()
{
ASSERT(m_webPage->isVisible());
-#if USE(ACCELERATED_COMPOSITING)
- setNeedsOneShotDrawingSynchronization();
-#endif
-
bool directRendering = m_backingStore->d->shouldDirectRenderingToWindow();
if (!m_backingStore->d->isActive()
|| shouldResetTilesWhenShown()
@@ -3117,6 +3407,12 @@ void WebPagePrivate::resumeBackingStore()
// We need to reset all tiles so that we do not show any tiles whose content may
// have been replaced by another WebPage instance (i.e. another tab).
BackingStorePrivate::setCurrentBackingStoreOwner(m_webPage);
+
+ // If we're OpenGL compositing, switching to accel comp drawing of the root layer
+ // is a good substitute for backingstore blitting.
+ if (m_backingStore->d->isOpenGLCompositing())
+ setCompositorDrawsRootLayer(!m_backingStore->d->isActive());
+
m_backingStore->d->orientationChanged(); // Updates tile geometry and creates visible tile buffer.
m_backingStore->d->resetTiles(true /* resetBackground */);
m_backingStore->d->updateTiles(false /* updateVisible */, false /* immediate */);
@@ -3125,10 +3421,17 @@ void WebPagePrivate::resumeBackingStore()
if (m_backingStore->d->renderVisibleContents() && !m_backingStore->d->isSuspended() && !directRendering)
m_backingStore->d->blitVisibleContents();
} else {
+ if (m_backingStore->d->isOpenGLCompositing())
+ setCompositorDrawsRootLayer(false);
+
// Rendering was disabled while we were hidden, so we need to update all tiles.
m_backingStore->d->updateTiles(true /* updateVisible */, false /* immediate */);
}
+#if USE(ACCELERATED_COMPOSITING)
+ setNeedsOneShotDrawingSynchronization();
+#endif
+
setShouldResetTilesWhenShown(false);
}
@@ -3411,6 +3714,9 @@ bool WebPage::mouseEvent(const Platform::MouseEvent& mouseEvent, bool* wheelDelt
if (!d->m_mainFrame->view())
return false;
+ if (d->m_page->defersLoading())
+ return false;
+
PluginView* pluginView = d->m_fullScreenPluginView.get();
if (pluginView)
return d->dispatchMouseEventToFullScreenPlugin(pluginView, mouseEvent);
@@ -3494,10 +3800,10 @@ bool WebPagePrivate::handleMouseEvent(PlatformMouseEvent& mouseEvent)
{
EventHandler* eventHandler = m_mainFrame->eventHandler();
- if (mouseEvent.eventType() == MouseEventMoved)
+ if (mouseEvent.type() == WebCore::PlatformEvent::MouseMoved)
return eventHandler->mouseMoved(mouseEvent);
- if (mouseEvent.eventType() == MouseEventScroll)
+ if (mouseEvent.type() == WebCore::PlatformEvent::MouseScroll)
return true;
Node* node = 0;
@@ -3509,11 +3815,12 @@ bool WebPagePrivate::handleMouseEvent(PlatformMouseEvent& mouseEvent)
}
if (!node) {
- HitTestResult result = eventHandler->hitTestResultAtPoint(mapFromViewportToContents(mouseEvent.pos()), false /*allowShadowContent*/);
+ HitTestResult result = eventHandler->hitTestResultAtPoint(mapFromViewportToContents(mouseEvent.position()), false /*allowShadowContent*/);
node = result.innerNode();
}
- if (mouseEvent.eventType() == MouseEventPressed) {
+ if (mouseEvent.type() == WebCore::PlatformEvent::MousePressed) {
+ m_inputHandler->enableInputMode();
if (m_inputHandler->willOpenPopupForNode(node)) {
// Do not allow any human generated mouse or keyboard events to select <option>s in the list box
// because we use a pop up dialog to handle the actual selections. This prevents options from
@@ -3533,7 +3840,7 @@ bool WebPagePrivate::handleMouseEvent(PlatformMouseEvent& mouseEvent)
}
} else
eventHandler->handleMousePressEvent(mouseEvent);
- } else if (mouseEvent.eventType() == MouseEventReleased) {
+ } else if (mouseEvent.type() == WebCore::PlatformEvent::MouseReleased) {
// FIXME: For <select> and <options> elements, we explicitly do not forward this event to WebCore so
// as to preserve symmetry with the MouseEventPressed handling (above). This has the side-effect that
// mouseup events are not fired on such elements for human generated mouse release events. See RIM Bug #1579.
@@ -3586,13 +3893,16 @@ bool WebPage::touchEvent(const Platform::TouchEvent& event)
#endif
#if ENABLE(TOUCH_EVENTS)
+ if (!d->m_mainFrame)
+ return false;
+
+ if (d->m_page->defersLoading())
+ return false;
+
PluginView* pluginView = d->m_fullScreenPluginView.get();
if (pluginView)
return d->dispatchTouchEventToFullScreenPlugin(pluginView, event);
- if (!d->m_mainFrame)
- return false;
-
Platform::TouchEvent tEvent = event;
for (unsigned i = 0; i < event.m_points.size(); i++) {
tEvent.m_points[i].m_pos = d->mapFromTransformed(tEvent.m_points[i].m_pos);
@@ -3710,6 +4020,9 @@ bool WebPagePrivate::dispatchTouchEventToFullScreenPlugin(PluginView* plugin, co
bool WebPage::touchPointAsMouseEvent(const Platform::TouchPoint& point)
{
+ if (d->m_page->defersLoading())
+ return false;
+
PluginView* pluginView = d->m_fullScreenPluginView.get();
if (pluginView)
return d->dispatchTouchPointAsMouseEventToFullScreenPlugin(pluginView, point);
@@ -3755,11 +4068,15 @@ bool WebPagePrivate::dispatchTouchPointAsMouseEventToFullScreenPlugin(PluginView
void WebPage::touchEventCancel()
{
d->m_pluginMayOpenNewTab = false;
+ if (d->m_page->defersLoading())
+ return;
d->m_touchEventHandler->touchEventCancel();
}
void WebPage::touchEventCancelAndClearFocusedNode()
{
+ if (d->m_page->defersLoading())
+ return;
d->m_touchEventHandler->touchEventCancelAndClearFocusedNode();
}
@@ -3978,6 +4295,9 @@ bool WebPage::keyEvent(const Platform::KeyboardEvent& keyboardEvent)
if (!d->m_mainFrame->view())
return false;
+ if (d->m_page->defersLoading())
+ return false;
+
ASSERT(d->m_page->focusController());
bool handled = d->m_inputHandler->handleKeyboardInput(keyboardEvent);
@@ -3993,6 +4313,9 @@ bool WebPage::keyEvent(const Platform::KeyboardEvent& keyboardEvent)
bool WebPage::deleteTextRelativeToCursor(unsigned int leftOffset, unsigned int rightOffset)
{
+ if (d->m_page->defersLoading())
+ return false;
+
return d->m_inputHandler->deleteTextRelativeToCursor(leftOffset, rightOffset);
}
@@ -4028,11 +4351,15 @@ int32_t WebPage::finishComposition()
int32_t WebPage::setComposingText(spannable_string_t* spannableString, int32_t relativeCursorPosition)
{
+ if (d->m_page->defersLoading())
+ return -1;
return d->m_inputHandler->setComposingText(spannableString, relativeCursorPosition);
}
int32_t WebPage::commitText(spannable_string_t* spannableString, int32_t relativeCursorPosition)
{
+ if (d->m_page->defersLoading())
+ return -1;
return d->m_inputHandler->commitText(spannableString, relativeCursorPosition);
}
@@ -4041,8 +4368,26 @@ void WebPage::setSpellCheckingEnabled(bool enabled)
static_cast<EditorClientBlackBerry*>(d->m_page->editorClient())->enableSpellChecking(enabled);
}
+class DeferredTaskSelectionCancelled: public DeferredTask<&WebPagePrivate::m_wouldCancelSelection> {
+public:
+ explicit DeferredTaskSelectionCancelled(WebPagePrivate* webPagePrivate)
+ : DeferredTaskType(webPagePrivate)
+ {
+ }
+private:
+ virtual void performInternal(WebPagePrivate* webPagePrivate)
+ {
+ webPagePrivate->m_webPage->selectionCancelled();
+ }
+};
+
void WebPage::selectionCancelled()
{
+ if (d->m_page->defersLoading()) {
+ d->m_deferredTasks.append(adoptPtr(new DeferredTaskSelectionCancelled(d)));
+ return;
+ }
+ DeferredTaskSelectionCancelled::finishOrCancel(d);
d->m_selectionHandler->cancelSelection();
}
@@ -4066,23 +4411,29 @@ WebString WebPage::selectedText() const
WebString WebPage::cutSelectedText()
{
WebString selectedText = d->m_selectionHandler->selectedText();
- if (!selectedText.isEmpty())
+ if (!d->m_page->defersLoading() && !selectedText.isEmpty())
d->m_inputHandler->deleteSelection();
return selectedText;
}
void WebPage::insertText(const WebString& string)
{
+ if (d->m_page->defersLoading())
+ return;
d->m_inputHandler->insertText(string);
}
void WebPage::clearCurrentInputField()
{
+ if (d->m_page->defersLoading())
+ return;
d->m_inputHandler->clearField();
}
void WebPage::cut()
{
+ if (d->m_page->defersLoading())
+ return;
d->m_inputHandler->cut();
}
@@ -4093,11 +4444,15 @@ void WebPage::copy()
void WebPage::paste()
{
+ if (d->m_page->defersLoading())
+ return;
d->m_inputHandler->paste();
}
void WebPage::setSelection(const Platform::IntPoint& startPoint, const Platform::IntPoint& endPoint)
{
+ if (d->m_page->defersLoading())
+ return;
// Transform this events coordinates to webkit content coordinates.
// FIXME: Don't transform the sentinel, because it may be transformed to a floating number
// which could be rounded to 0 or other numbers. This workaround should be removed after
@@ -4112,6 +4467,8 @@ void WebPage::setSelection(const Platform::IntPoint& startPoint, const Platform:
void WebPage::setCaretPosition(const Platform::IntPoint& position)
{
+ if (d->m_page->defersLoading())
+ return;
// Handled by selection handler as it's point based.
// Transform this events coordinates to webkit content coordinates.
d->m_selectionHandler->setCaretPosition(d->mapFromTransformed(position));
@@ -4119,6 +4476,8 @@ void WebPage::setCaretPosition(const Platform::IntPoint& position)
void WebPage::selectAtPoint(const Platform::IntPoint& location)
{
+ if (d->m_page->defersLoading())
+ return;
// Transform this events coordinates to webkit content coordinates if it
// is not the sentinel value.
IntPoint selectionLocation =
@@ -4343,7 +4702,7 @@ bool WebPage::blockZoom(int x, int y)
IntRect tRect = d->mapFromTransformed(blockRect);
int blockArea = tRect.width() * tRect.height();
int pageArea = d->contentsSize().width() * d->contentsSize().height();
- double blockToPageRatio = static_cast<double>(1 - blockArea / pageArea);
+ double blockToPageRatio = static_cast<double>(pageArea - blockArea) / pageArea;
if (blockToPageRatio < minimumExpandingRatio) {
// Restore old adjust node because zoom was canceled.
d->m_currentBlockZoomAdjustedNode = tempBlockZoomAdjustedNode;
@@ -4552,8 +4911,27 @@ bool WebPage::zoomToOneOne()
return d->zoomAboutPoint(scale, d->centerOfVisibleContentsRect());
}
+class DeferredTaskSetFocused: public DeferredTask<&WebPagePrivate::m_wouldSetFocused> {
+public:
+ explicit DeferredTaskSetFocused(WebPagePrivate* webPagePrivate, bool focused)
+ : DeferredTaskType(webPagePrivate)
+ {
+ webPagePrivate->m_cachedFocused = focused;
+ }
+private:
+ virtual void performInternal(WebPagePrivate* webPagePrivate)
+ {
+ webPagePrivate->m_webPage->setFocused(webPagePrivate->m_cachedFocused);
+ }
+};
+
void WebPage::setFocused(bool focused)
{
+ if (d->m_page->defersLoading()) {
+ d->m_deferredTasks.append(adoptPtr(new DeferredTaskSetFocused(d, focused)));
+ return;
+ }
+ DeferredTaskSetFocused::finishOrCancel(d);
FocusController* focusController = d->m_page->focusController();
focusController->setActive(focused);
if (focused) {
@@ -4564,9 +4942,18 @@ void WebPage::setFocused(bool focused)
focusController->setFocused(focused);
}
-bool WebPage::findNextString(const char* text, bool forward)
+bool WebPage::findNextString(const char* text, bool forward, bool caseSensitive, bool wrap, bool highlightAllMatches)
{
- return d->m_inPageSearchManager->findNextString(String::fromUTF8(text), forward);
+ WebCore::FindOptions findOptions = WebCore::StartInSelection;
+ if (!forward)
+ findOptions |= WebCore::Backwards;
+ if (!caseSensitive)
+ findOptions |= WebCore::CaseInsensitive;
+
+ // The WebCore::FindOptions::WrapAround boolean actually wraps the search
+ // within the current frame as opposed to the entire Document, so we have to
+ // provide our own wrapping code to wrap at the whole Document level.
+ return d->m_inPageSearchManager->findNextString(String::fromUTF8(text), findOptions, wrap, highlightAllMatches);
}
void WebPage::runLayoutTests()
@@ -4771,8 +5158,24 @@ void WebPage::clearCookies()
void WebPage::clearLocalStorage()
{
- BlackBerry::WebKit::clearLocalStorage(d->m_page->groupName());
- clearDatabase(d->m_page->groupName());
+ if (PageGroup* group = d->m_page->groupPtr()) {
+ if (StorageNamespace* storage = group->localStorage())
+ storage->clearAllOriginsForDeletion();
+ }
+}
+
+void WebPage::clearCredentials()
+{
+#if ENABLE(BLACKBERRY_CREDENTIAL_PERSIST)
+ credentialManager().clearCredentials();
+#endif
+}
+
+void WebPage::clearNeverRememberSites()
+{
+#if ENABLE(BLACKBERRY_CREDENTIAL_PERSIST)
+ credentialManager().clearNeverRememberSites();
+#endif
}
void WebPage::clearCache()
@@ -4943,6 +5346,15 @@ void WebPage::notifyDeviceIdleStateChange(bool enterIdle)
(*it)->handleIdleEvent(enterIdle);
}
+void WebPagePrivate::notifyAppActivationStateChange(ActivationStateType activationState)
+{
+ m_activationState = activationState;
+
+#if ENABLE(PAGE_VISIBILITY_API)
+ setPageVisibilityState();
+#endif
+}
+
void WebPage::notifyAppActivationStateChange(ActivationStateType activationState)
{
#if ENABLE(VIDEO)
@@ -4960,11 +5372,10 @@ void WebPage::notifyAppActivationStateChange(ActivationStateType activationState
case ActivationStandby:
(*it)->handleAppStandbyEvent();
break;
- default: // FIXME: Get rid of the default to force a compiler error instead of using a runtime error. See PR #121109.
- ASSERT_NOT_REACHED();
- break;
}
}
+
+ d->notifyAppActivationStateChange(activationState);
}
void WebPage::notifySwipeEvent()
@@ -5043,10 +5454,41 @@ void WebPage::disablePasswordEcho()
void WebPage::dispatchInspectorMessage(const std::string& message)
{
- String stringMessage(message.c_str(), message.length());
+ String stringMessage = String::fromUTF8(message.data(), message.length());
d->m_page->inspectorController()->dispatchMessageFromFrontend(stringMessage);
}
+bool WebPagePrivate::compositorDrawsRootLayer() const
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (Platform::userInterfaceThreadMessageClient()->isCurrentThread())
+ return m_compositor && m_compositor->drawsRootLayer();
+
+ // WebKit thread implementation:
+ RenderView* renderView = m_mainFrame->contentRenderer();
+ if (!renderView || !renderView->layer() || !renderView->layer()->backing())
+ return false;
+
+ return !renderView->layer()->backing()->paintingGoesToWindow();
+#else
+ return false;
+#endif
+}
+
+void WebPagePrivate::setCompositorDrawsRootLayer(bool compositorDrawsRootLayer)
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_page->settings()->forceCompositingMode() == compositorDrawsRootLayer)
+ return;
+
+ // When the BlackBerry port forces compositing mode, the root layer stops
+ // painting to window and starts painting to layer instead.
+ m_page->settings()->setForceCompositingMode(compositorDrawsRootLayer);
+ if (FrameView* view = m_mainFrame->view())
+ view->updateCompositingLayers();
+#endif
+}
+
#if USE(ACCELERATED_COMPOSITING)
void WebPagePrivate::drawLayersOnCommit()
{
@@ -5055,7 +5497,7 @@ void WebPagePrivate::drawLayersOnCommit()
// animations. And only if we don't need a one shot drawing sync.
ASSERT(!needsOneShotDrawingSynchronization());
- if (!m_webPage->isVisible() || !m_backingStore->d->isActive())
+ if (!m_webPage->isVisible())
return;
m_backingStore->d->willDrawLayersOnCommit();
@@ -5065,52 +5507,12 @@ void WebPagePrivate::drawLayersOnCommit()
return;
}
- if (m_client->window()->windowUsage() == Platform::Graphics::Window::GLES2Usage) {
- m_backingStore->d->blitVisibleContents();
- return; // blitVisibleContents() includes drawSubLayers() in this case.
- }
-
- if (!drawSubLayers())
- return;
-
- // If we use the compositing surface, we need to re-blit the
- // backingstore and blend the compositing surface on top of that
- // in order to get the newly drawn layers on screen.
- if (!SurfacePool::globalSurfacePool()->compositingSurface())
- return;
-
- // If there are no visible layers, return early.
- if (lastCompositingResults().isEmpty() && lastCompositingResults().wasEmpty)
- return;
-
- if (m_backingStore->d->shouldDirectRenderingToWindow())
- return;
-
- m_backingStore->d->blitVisibleContents();
-}
-
-bool WebPagePrivate::drawSubLayers(const IntRect& dstRect, const FloatRect& contents)
-{
- ASSERT(Platform::userInterfaceThreadMessageClient()->isCurrentThread());
- if (!Platform::userInterfaceThreadMessageClient()->isCurrentThread())
- return false;
-
- if (m_compositor) {
- m_compositor->setCompositingOntoMainWindow(
- m_client->window()->windowUsage() == Platform::Graphics::Window::GLES2Usage);
- return m_compositor->drawLayers(dstRect, contents);
- }
-
- return false;
-}
-
-bool WebPagePrivate::drawSubLayers()
-{
- ASSERT(Platform::userInterfaceThreadMessageClient()->isCurrentThread());
- if (!Platform::userInterfaceThreadMessageClient()->isCurrentThread())
- return false;
+#if DEBUG_AC_COMMIT
+ Platform::log(Platform::LogLevelCritical, "%s", WTF_PRETTY_FUNCTION);
+#endif
- return m_backingStore->d->drawSubLayers();
+ if (!m_backingStore->d->shouldDirectRenderingToWindow())
+ m_backingStore->d->blitVisibleContents();
}
void WebPagePrivate::scheduleRootLayerCommit()
@@ -5119,8 +5521,12 @@ void WebPagePrivate::scheduleRootLayerCommit()
return;
m_needsCommit = true;
- if (!m_rootLayerCommitTimer->isActive())
+ if (!m_rootLayerCommitTimer->isActive()) {
+#if DEBUG_AC_COMMIT
+ Platform::log(Platform::LogLevelCritical, "%s: m_rootLayerCommitTimer->isActive() = %d", WTF_PRETTY_FUNCTION, m_rootLayerCommitTimer->isActive());
+#endif
m_rootLayerCommitTimer->startOneShot(0);
+ }
}
static bool needsLayoutRecursive(FrameView* view)
@@ -5147,19 +5553,57 @@ LayerRenderingResults WebPagePrivate::lastCompositingResults() const
return LayerRenderingResults();
}
+void WebPagePrivate::setCompositor(PassRefPtr<WebPageCompositorPrivate> compositor)
+{
+ using namespace BlackBerry::Platform;
+
+ // The m_compositor member has to be modified during a sync call for thread
+ // safe access to m_compositor and its refcount.
+ if (!userInterfaceThreadMessageClient()->isCurrentThread()) {
+ userInterfaceThreadMessageClient()->dispatchSyncMessage(createMethodCallMessage(&WebPagePrivate::setCompositor, this, compositor));
+ return;
+ }
+
+ m_compositor = compositor;
+
+ // The previous compositor, if any, has now released it's OpenGL resources,
+ // so we can safely free the owned context, if any.
+ m_ownedContext.clear();
+}
+
void WebPagePrivate::commitRootLayer(const IntRect& layoutRectForCompositing,
- const IntSize& contentsSizeForCompositing)
+ const IntSize& contentsSizeForCompositing,
+ bool drawsRootLayer)
{
+#if DEBUG_AC_COMMIT
+ Platform::log(Platform::LogLevelCritical, "%s: m_compositor = 0x%x",
+ WTF_PRETTY_FUNCTION, m_compositor.get());
+#endif
+
if (!m_frameLayers || !m_compositor)
return;
+ if (m_frameLayers->rootLayer() && m_frameLayers->rootLayer()->layerCompositingThread() != m_compositor->rootLayer())
+ m_compositor->setRootLayer(m_frameLayers->rootLayer()->layerCompositingThread());
+
m_compositor->setLayoutRectForCompositing(layoutRectForCompositing);
m_compositor->setContentsSizeForCompositing(contentsSizeForCompositing);
+ m_compositor->setDrawsRootLayer(drawsRootLayer);
m_compositor->commit(m_frameLayers->rootLayer());
}
bool WebPagePrivate::commitRootLayerIfNeeded()
{
+#if DEBUG_AC_COMMIT
+ Platform::log(Platform::LogLevelCritical, "%s: m_suspendRootLayerCommit = %d, m_needsCommit = %d, m_frameLayers = 0x%x, m_frameLayers->hasLayer() = %d, needsLayoutRecursive() = %d",
+ WTF_PRETTY_FUNCTION,
+ m_suspendRootLayerCommit,
+ m_needsCommit,
+ m_frameLayers.get(),
+ m_frameLayers && m_frameLayers->hasLayer(),
+ m_mainFrame && m_mainFrame->view() && needsLayoutRecursive(m_mainFrame->view()));
+#endif
+
if (m_suspendRootLayerCommit)
return false;
@@ -5199,6 +5643,7 @@ bool WebPagePrivate::commitRootLayerIfNeeded()
// and that's what the layer renderer wants.
IntRect layoutRectForCompositing(scrollPosition(), actualVisibleSize());
IntSize contentsSizeForCompositing = contentsSize();
+ bool drawsRootLayer = compositorDrawsRootLayer();
// Commit changes made to the layers synchronously with the compositing thread.
Platform::userInterfaceThreadMessageClient()->dispatchSyncMessage(
@@ -5206,7 +5651,8 @@ bool WebPagePrivate::commitRootLayerIfNeeded()
&WebPagePrivate::commitRootLayer,
this,
layoutRectForCompositing,
- contentsSizeForCompositing));
+ contentsSizeForCompositing,
+ drawsRootLayer));
return true;
}
@@ -5216,6 +5662,10 @@ void WebPagePrivate::rootLayerCommitTimerFired(Timer<WebPagePrivate>*)
if (m_suspendRootLayerCommit)
return;
+#if DEBUG_AC_COMMIT
+ Platform::log(Platform::LogLevelCritical, "%s", WTF_PRETTY_FUNCTION);
+#endif
+
// The commit timer may have fired just before the layout timer, or for some
// other reason we need layout. It's not allowed to commit when a layout is
// pending, becaues a commit can cause parts of the web page to be rendered
@@ -5224,20 +5674,30 @@ void WebPagePrivate::rootLayerCommitTimerFired(Timer<WebPagePrivate>*)
// to handle a one shot drawing synchronization after the layout.
requestLayoutIfNeeded();
- bool isSingleTargetWindow = SurfacePool::globalSurfacePool()->compositingSurface()
- || m_client->window()->windowUsage() == Platform::Graphics::Window::GLES2Usage;
-
- // If we are doing direct rendering and have a single rendering target,
- // committing is equivalent to a one shot drawing synchronization.
- // We need to re-render the web page, re-render the layers, and
- // then blit them on top of the re-rendered web page.
- if (isSingleTargetWindow && m_backingStore->d->shouldDirectRenderingToWindow())
- setNeedsOneShotDrawingSynchronization();
+ // If we transitioned to drawing the root layer using compositor instead of
+ // backing store, doing a one shot drawing synchronization with the
+ // backing store is never necessary, because the backing store draws
+ // nothing.
+ if (!compositorDrawsRootLayer()) {
+ bool isSingleTargetWindow = SurfacePool::globalSurfacePool()->compositingSurface()
+ || m_backingStore->d->isOpenGLCompositing();
+
+ // If we are doing direct rendering and have a single rendering target,
+ // committing is equivalent to a one shot drawing synchronization.
+ // We need to re-render the web page, re-render the layers, and
+ // then blit them on top of the re-rendered web page.
+ if (isSingleTargetWindow && m_backingStore->d->shouldDirectRenderingToWindow())
+ setNeedsOneShotDrawingSynchronization();
+
+ if (needsOneShotDrawingSynchronization()) {
+#if DEBUG_AC_COMMIT
+ Platform::log(Platform::LogLevelCritical, "%s: OneShotDrawingSynchronization code path!", WTF_PRETTY_FUNCTION);
+#endif
- if (needsOneShotDrawingSynchronization()) {
- const IntRect windowRect = IntRect(IntPoint::zero(), viewportSize());
- m_backingStore->d->repaint(windowRect, true /*contentChanged*/, true /*immediate*/);
- return;
+ const IntRect windowRect = IntRect(IntPoint::zero(), viewportSize());
+ m_backingStore->d->repaint(windowRect, true /*contentChanged*/, true /*immediate*/);
+ return;
+ }
}
// If the web page needs layout, the commit will fail.
@@ -5246,28 +5706,6 @@ void WebPagePrivate::rootLayerCommitTimerFired(Timer<WebPagePrivate>*)
drawLayersOnCommit();
}
-void WebPagePrivate::setIsAcceleratedCompositingActive(bool active)
-{
- // Backing store can be null here because it happens during teardown.
- if (m_isAcceleratedCompositingActive == active || !m_backingStore)
- return;
-
- m_isAcceleratedCompositingActive = active;
-
- if (!active) {
- m_compositor.clear();
- resetCompositingSurface();
- return;
- }
-
- if (!m_compositor) {
- m_compositor = adoptPtr(new WebPageCompositor(this));
- m_isAcceleratedCompositingActive = m_compositor->hardwareCompositing();
- if (!m_isAcceleratedCompositingActive)
- m_compositor.clear();
- }
-}
-
void WebPagePrivate::resetCompositingSurface()
{
if (!Platform::userInterfaceThreadMessageClient()->isCurrentThread()) {
@@ -5319,19 +5757,13 @@ void WebPagePrivate::setRootLayerCompositingThread(LayerCompositingThread* layer
return;
}
- // Depending on whether we have a root layer or not,
- // this method will turn on or off accelerated compositing.
if (!layer) {
- // Don't ASSERT(m_compositor) here because we may be called in
- // the process of destruction of WebPage where we have already
- // called syncDestroyCompositorOnCompositingThread() to destroy
- // the compositor.
- setIsAcceleratedCompositingActive(false);
- return;
- }
-
- if (!m_compositor)
- setIsAcceleratedCompositingActive(true);
+ // Keep the compositor around, a single web page will frequently enter
+ // and leave compositing mode many times. Instead we destroy it when
+ // navigating to a new page.
+ resetCompositingSurface();
+ } else if (!m_compositor)
+ createCompositor();
// Don't ASSERT(m_compositor) here because setIsAcceleratedCompositingActive(true)
// may not turn accelerated compositing on since m_backingStore is 0.
@@ -5339,9 +5771,34 @@ void WebPagePrivate::setRootLayerCompositingThread(LayerCompositingThread* layer
m_compositor->setRootLayer(layer);
}
+bool WebPagePrivate::createCompositor()
+{
+ // If there's no window, the compositor will be supplied by the API client
+ if (!m_client->window())
+ return false;
+
+ m_ownedContext = GLES2Context::create(this);
+ m_compositor = WebPageCompositorPrivate::create(this, 0);
+ m_compositor->setContext(m_ownedContext.get());
+
+ if (!m_compositor->hardwareCompositing()) {
+ destroyCompositor();
+ return false;
+ }
+
+ return true;
+}
+
void WebPagePrivate::destroyCompositor()
{
- m_compositor.clear();
+ // We shouldn't release the compositor unless we created and own the
+ // context. If the compositor was created from the WebPageCompositor API,
+ // keep it around and reuse it later.
+ if (!m_ownedContext)
+ return;
+
+ m_compositor.clear();
+ m_ownedContext.clear();
}
void WebPagePrivate::syncDestroyCompositorOnCompositingThread()
@@ -5366,7 +5823,7 @@ void WebPagePrivate::suspendRootLayerCommit()
m_suspendRootLayerCommit = true;
- if (!m_frameLayers || !m_frameLayers->hasLayer() || !m_compositor)
+ if (!m_compositor)
return;
Platform::userInterfaceThreadMessageClient()->dispatchSyncMessage(
@@ -5392,6 +5849,11 @@ bool WebPagePrivate::needsOneShotDrawingSynchronization()
void WebPagePrivate::setNeedsOneShotDrawingSynchronization()
{
+ if (compositorDrawsRootLayer()) {
+ scheduleRootLayerCommit();
+ return;
+ }
+
// This means we have to commit layers on next render, or render on the next commit,
// whichever happens first.
m_needsCommit = true;
@@ -5477,9 +5939,6 @@ void WebPagePrivate::didChangeSettings(WebSettings* webSettings)
coreSettings->setDownloadableBinaryFontsEnabled(webSettings->downloadableBinaryFontsEnabled());
coreSettings->setSpatialNavigationEnabled(m_webSettings->isSpatialNavigationEnabled());
- // UserScalable should be reset by new settings.
- setUserScalable(webSettings->isUserScalable());
-
WebString stylesheetURL = webSettings->userStyleSheetString();
if (stylesheetURL.isEmpty())
stylesheetURL = webSettings->userStyleSheetLocation();
@@ -5599,5 +6058,24 @@ void WebPagePrivate::frameUnloaded(const Frame* frame)
m_inPageSearchManager->frameUnloaded(frame);
}
+const String& WebPagePrivate::defaultUserAgent()
+{
+ static String* defaultUserAgent = new String;
+ if (defaultUserAgent->isEmpty()) {
+ BlackBerry::Platform::DeviceInfo* info = BlackBerry::Platform::DeviceInfo::instance();
+ char uaBuffer[256];
+ int uaSize = snprintf(uaBuffer, 256, "Mozilla/5.0 (%s) AppleWebKit/%d.%d+ (KHTML, like Gecko) Version/%s %sSafari/%d.%d+",
+ info->family(), WEBKIT_MAJOR_VERSION, WEBKIT_MINOR_VERSION, info->osVersion(),
+ info->isMobile() ? "Mobile " : "", WEBKIT_MAJOR_VERSION, WEBKIT_MINOR_VERSION);
+
+ if (uaSize <= 0 || uaSize >= 256)
+ BLACKBERRY_CRASH();
+
+ defaultUserAgent->append(uaBuffer);
+ }
+
+ return *defaultUserAgent;
+}
+
}
}