diff options
Diffstat (limited to 'Source/WebKit')
-rw-r--r-- | Source/WebKit/android/content/PhoneEmailDetector.cpp | 18 | ||||
-rw-r--r-- | Source/WebKit/android/content/PhoneEmailDetector.h | 6 | ||||
-rw-r--r-- | Source/WebKit/android/content/address_detector.cpp | 7 | ||||
-rw-r--r-- | Source/WebKit/android/content/address_detector.h | 1 | ||||
-rw-r--r-- | Source/WebKit/android/content/content_detector.cpp | 13 | ||||
-rw-r--r-- | Source/WebKit/android/content/content_detector.h | 7 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebCoreFrameBridge.cpp | 6 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebHistory.cpp | 7 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebHistory.h | 4 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebIconDatabase.cpp | 27 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebIconDatabase.h | 2 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebViewCore.cpp | 33 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebViewCore.h | 5 | ||||
-rw-r--r-- | Source/WebKit/android/nav/WebView.cpp | 90 |
14 files changed, 195 insertions, 31 deletions
diff --git a/Source/WebKit/android/content/PhoneEmailDetector.cpp b/Source/WebKit/android/content/PhoneEmailDetector.cpp index d188c0b..ca97a71 100644 --- a/Source/WebKit/android/content/PhoneEmailDetector.cpp +++ b/Source/WebKit/android/content/PhoneEmailDetector.cpp @@ -31,6 +31,7 @@ #include "base/utf_string_conversions.h" #include "net/base/escape.h" #include "PhoneEmailDetector.h" +#include "Settings.h" #include "WebString.h" #define LOG_TAG "PhoneNumberDetector" @@ -56,18 +57,31 @@ PhoneEmailDetector::PhoneEmailDetector() { } +bool PhoneEmailDetector::IsEnabled(const WebKit::WebHitTestInfo& hit_test) +{ + WebCore::Settings* settings = GetSettings(hit_test); + if (!settings) + return false; + m_isPhoneDetectionEnabled = settings->formatDetectionTelephone(); + m_isEmailDetectionEnabled = settings->formatDetectionEmail(); + return m_isEmailDetectionEnabled || m_isPhoneDetectionEnabled; +} + bool PhoneEmailDetector::FindContent(const string16::const_iterator& begin, const string16::const_iterator& end, size_t* start_pos, size_t* end_pos) { FindReset(&m_findState); - m_foundResult = FindPartialNumber(begin, end - begin, &m_findState); + m_foundResult = FOUND_NONE; + if (m_isPhoneDetectionEnabled) + m_foundResult = FindPartialNumber(begin, end - begin, &m_findState); if (m_foundResult == FOUND_COMPLETE) m_prefix = kTelSchemaPrefix; else { FindReset(&m_findState); - m_foundResult = FindPartialEMail(begin, end - begin, &m_findState); + if (m_isEmailDetectionEnabled) + m_foundResult = FindPartialEMail(begin, end - begin, &m_findState); m_prefix = kEmailSchemaPrefix; } *start_pos = m_findState.mStartResult; diff --git a/Source/WebKit/android/content/PhoneEmailDetector.h b/Source/WebKit/android/content/PhoneEmailDetector.h index b61de62..74ff5b1 100644 --- a/Source/WebKit/android/content/PhoneEmailDetector.h +++ b/Source/WebKit/android/content/PhoneEmailDetector.h @@ -66,10 +66,16 @@ private: virtual size_t GetMaximumContentLength() { return NAVIGATION_MAX_PHONE_LENGTH * 4; } + virtual bool IsEnabled(const WebKit::WebHitTestInfo& hit_test) OVERRIDE; DISALLOW_COPY_AND_ASSIGN(PhoneEmailDetector); FindState m_findState; FoundState m_foundResult; const char* m_prefix; + // TODO: This shouldn't be done like this. PhoneEmailDetector should be + // refactored into two pieces and follow the IsEnabled style. This will + // only work because we always call IsEnabled before FindContent + bool m_isPhoneDetectionEnabled; + bool m_isEmailDetectionEnabled; }; diff --git a/Source/WebKit/android/content/address_detector.cpp b/Source/WebKit/android/content/address_detector.cpp index a6d36e9..f6657d9 100644 --- a/Source/WebKit/android/content/address_detector.cpp +++ b/Source/WebKit/android/content/address_detector.cpp @@ -40,6 +40,7 @@ #include "base/utf_string_conversions.h" #include "net/base/escape.h" +#include "Settings.h" #include "WebString.h" #include <wtf/HashSet.h> @@ -90,6 +91,7 @@ const char16 kNewlineDelimiters[] = { ',', '*', 0x2022, // Unicode bullet + 0, }; char16 SafePreviousChar(const string16::const_iterator& it, @@ -156,6 +158,11 @@ size_t AddressDetector::GetMaximumContentLength() { return kMaxAddressLength; } +bool AddressDetector::IsEnabled(const WebKit::WebHitTestInfo& hit_test) { + WebCore::Settings* settings = GetSettings(hit_test); + return settings && settings->formatDetectionAddress(); +} + bool AddressDetector::FindContent(const string16::const_iterator& begin, const string16::const_iterator& end, size_t* start_pos, size_t* end_pos) { HouseNumberParser house_number_parser; diff --git a/Source/WebKit/android/content/address_detector.h b/Source/WebKit/android/content/address_detector.h index be34375..6dc4ce8 100644 --- a/Source/WebKit/android/content/address_detector.h +++ b/Source/WebKit/android/content/address_detector.h @@ -60,6 +60,7 @@ class AddressDetector : public ContentDetector { virtual std::string GetContentText(const WebKit::WebRange& range) OVERRIDE; virtual GURL GetIntentURL(const std::string& content_text) OVERRIDE; virtual size_t GetMaximumContentLength() OVERRIDE; + virtual bool IsEnabled(const WebKit::WebHitTestInfo& hit_test) OVERRIDE; // Internal structs and classes. Required to be visible by the unit tests. struct Word { diff --git a/Source/WebKit/android/content/content_detector.cpp b/Source/WebKit/android/content/content_detector.cpp index b29a457..e423207 100644 --- a/Source/WebKit/android/content/content_detector.cpp +++ b/Source/WebKit/android/content/content_detector.cpp @@ -39,11 +39,18 @@ #include "public/android/WebDOMTextContentWalker.h" #include "public/android/WebHitTestInfo.h" +#include "Document.h" +#include "Node.h" +#include "Page.h" +#include "Settings.h" + using WebKit::WebDOMTextContentWalker; using WebKit::WebRange; ContentDetector::Result ContentDetector::FindTappedContent( const WebKit::WebHitTestInfo& hit_test) { + if (!IsEnabled(hit_test)) + return Result(); WebKit::WebRange range = FindContentRange(hit_test); if (range.isNull()) return Result(); @@ -84,3 +91,9 @@ WebRange ContentDetector::FindContentRange( return WebRange(); } + +WebCore::Settings* ContentDetector::GetSettings(const WebKit::WebHitTestInfo& hit_test) { + if (!hit_test.node() || !hit_test.node()->document()) + return 0; + return hit_test.node()->document()->page()->settings(); +} diff --git a/Source/WebKit/android/content/content_detector.h b/Source/WebKit/android/content/content_detector.h index 041cbc9..270928d 100644 --- a/Source/WebKit/android/content/content_detector.h +++ b/Source/WebKit/android/content/content_detector.h @@ -44,6 +44,10 @@ namespace WebKit { class WebHitTestInfo; } +namespace WebCore { +class Settings; +} + // Base class for text-based content detectors. class ContentDetector { public: @@ -82,6 +86,9 @@ class ContentDetector { size_t* start_pos, size_t* end_pos) = 0; + virtual bool IsEnabled(const WebKit::WebHitTestInfo& hit_test) = 0; + WebCore::Settings* GetSettings(const WebKit::WebHitTestInfo& hit_test); + // Extracts and processes the text of the detected content. virtual std::string GetContentText(const WebKit::WebRange& range) = 0; diff --git a/Source/WebKit/android/jni/WebCoreFrameBridge.cpp b/Source/WebKit/android/jni/WebCoreFrameBridge.cpp index af582fa..829c21c 100644 --- a/Source/WebKit/android/jni/WebCoreFrameBridge.cpp +++ b/Source/WebKit/android/jni/WebCoreFrameBridge.cpp @@ -1290,12 +1290,12 @@ static void LoadData(JNIEnv *env, jobject obj, jstring baseUrl, jstring data, WebCore::ResourceRequest request(jstringToWtfString(env, baseUrl)); // Setup the substituteData - const char* dataStr = env->GetStringUTFChars(data, NULL); + WTF::CString cData = jstringToWtfString(env, data).utf8(); + const char* dataStr = cData.data(); WTF::RefPtr<WebCore::SharedBuffer> sharedBuffer = WebCore::SharedBuffer::create(); ALOG_ASSERT(dataStr, "nativeLoadData has a null data string."); - sharedBuffer->append(dataStr, strlen(dataStr)); - env->ReleaseStringUTFChars(data, dataStr); + sharedBuffer->append(dataStr, strlen(dataStr)); // copy dataStr WebCore::SubstituteData substituteData(sharedBuffer, jstringToWtfString(env, mimeType), jstringToWtfString(env, encoding), diff --git a/Source/WebKit/android/jni/WebHistory.cpp b/Source/WebKit/android/jni/WebHistory.cpp index 0c4652a..b6972e4 100644 --- a/Source/WebKit/android/jni/WebHistory.cpp +++ b/Source/WebKit/android/jni/WebHistory.cpp @@ -263,10 +263,11 @@ static jobject WebHistoryGetFavicon(JNIEnv* env, jobject obj, jint ptr) return 0; WebHistoryItem* item = reinterpret_cast<WebHistoryItem*>(ptr); MutexLocker locker(item->m_lock); - if (!item->m_faviconCached && !item->m_favicon.isNull()) { + if (!item->m_faviconCached && item->m_favicon) { jobject favicon = GraphicsJNI::createBitmap(env, - new SkBitmap(item->m_favicon), + item->m_favicon, false, NULL); + item->m_favicon = 0; // Framework now owns the pointer item->m_faviconCached = env->NewGlobalRef(favicon); env->DeleteLocalRef(favicon); } @@ -345,6 +346,7 @@ void WebHistoryItem::updateHistoryItem(WebCore::HistoryItem* item) { // FIXME: This method should not be used from outside WebCore and will be removed. // http://trac.webkit.org/changeset/81484 WebCore::Image* icon = WebCore::iconDatabase().synchronousIconForPageURL(url, WebCore::IntSize(16, 16)); + delete webItem->m_favicon; webItem->m_favicon = webcoreImageToSkBitmap(icon); if (webItem->m_faviconCached) { env->DeleteGlobalRef(webItem->m_faviconCached); @@ -361,6 +363,7 @@ void WebHistoryItem::updateHistoryItem(WebCore::HistoryItem* item) { WebHistoryItem::~WebHistoryItem() { + delete m_favicon; JNIEnv* env = JSC::Bindings::getJNIEnv(); if (!env) { ALOGW("Failed to get JNIEnv*! Potential memory leak!"); diff --git a/Source/WebKit/android/jni/WebHistory.h b/Source/WebKit/android/jni/WebHistory.h index c628f7c..e89959c 100644 --- a/Source/WebKit/android/jni/WebHistory.h +++ b/Source/WebKit/android/jni/WebHistory.h @@ -55,12 +55,14 @@ class WebHistoryItem : public WebCore::AndroidWebHistoryBridge { public: WebHistoryItem(WebHistoryItem* parent) : WebCore::AndroidWebHistoryBridge(0) + , m_favicon(0) , m_faviconCached(0) , m_dataCached(0) , m_parent(parent) {} WebHistoryItem(WebCore::HistoryItem* item) : WebCore::AndroidWebHistoryBridge(item) + , m_favicon(0) , m_faviconCached(0) , m_dataCached(0) , m_parent(0) @@ -76,7 +78,7 @@ public: String m_url; String m_originalUrl; String m_title; - SkBitmap m_favicon; + SkBitmap* m_favicon; WTF::Vector<char> m_data; jobject m_faviconCached; jobject m_dataCached; diff --git a/Source/WebKit/android/jni/WebIconDatabase.cpp b/Source/WebKit/android/jni/WebIconDatabase.cpp index da8ce63..e9219df 100644 --- a/Source/WebKit/android/jni/WebIconDatabase.cpp +++ b/Source/WebKit/android/jni/WebIconDatabase.cpp @@ -50,26 +50,31 @@ namespace android { -SkBitmap webcoreImageToSkBitmap(WebCore::Image* icon) +SkBitmap* webcoreImageToSkBitmap(WebCore::Image* icon) { - SkBitmap bm; if (!icon) - return bm; + return 0; WebCore::SharedBuffer* buffer = icon->data(); if (!buffer) - return bm; - SkImageDecoder::DecodeMemory(buffer->data(), buffer->size(), &bm, - SkBitmap::kNo_Config, - SkImageDecoder::kDecodePixels_Mode); + return 0; + SkBitmap* bm = new SkBitmap; + if (!SkImageDecoder::DecodeMemory(buffer->data(), buffer->size(), bm, + SkBitmap::kNo_Config, + SkImageDecoder::kDecodePixels_Mode) + || bm->isNull() || !bm->width() || !bm->height() + || bm->config() == SkBitmap::kNo_Config) { + delete bm; + return 0; + } return bm; } jobject webcoreImageToJavaBitmap(JNIEnv* env, WebCore::Image* icon) { - SkBitmap bm = webcoreImageToSkBitmap(icon); - if (bm.isNull()) - return NULL; - return GraphicsJNI::createBitmap(env, new SkBitmap(bm), false, NULL); + SkBitmap* bm = webcoreImageToSkBitmap(icon); + if (!bm) + return 0; + return GraphicsJNI::createBitmap(env, bm, false, NULL); } static WebIconDatabase* gIconDatabaseClient = new WebIconDatabase(); diff --git a/Source/WebKit/android/jni/WebIconDatabase.h b/Source/WebKit/android/jni/WebIconDatabase.h index c3e7947..7b7c937 100644 --- a/Source/WebKit/android/jni/WebIconDatabase.h +++ b/Source/WebKit/android/jni/WebIconDatabase.h @@ -74,7 +74,7 @@ namespace android { bool mDeliveryRequested; }; - SkBitmap webcoreImageToSkBitmap(WebCore::Image* icon); + SkBitmap* webcoreImageToSkBitmap(WebCore::Image* icon); jobject webcoreImageToJavaBitmap(JNIEnv* env, WebCore::Image* icon); }; diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index d07b00e..3d86761 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -178,6 +178,9 @@ FILE* gRenderTreeFile = 0; // prerenders #define PRERENDER_AFTER_SCROLL_DELAY 750 +#define TOUCH_FLAG_HIT_HANDLER 0x1 +#define TOUCH_FLAG_PREVENT_DEFAULT 0x2 + //////////////////////////////////////////////////////////////////////////////////////////////// namespace android { @@ -843,8 +846,11 @@ BaseLayerAndroid* WebViewCore::createBaseLayer(GraphicsLayerAndroid* root) Color viewBackground = view->baseBackgroundColor(); background = bodyHasCSSBackground ? viewBackground.blend(background) : viewBackground; } - bodyHasFixedBackgroundImage = style->hasFixedBackgroundImage() - && FixedBackgroundImageLayerAndroid::GetCachedImage(style); + if (style->hasFixedBackgroundImage()) { + Image* backgroundImage = FixedBackgroundImageLayerAndroid::GetCachedImage(style); + if (backgroundImage && backgroundImage->width() > 1 && backgroundImage->height() > 1) + bodyHasFixedBackgroundImage = true; + } } PicturePileLayerContent* content = new PicturePileLayerContent(m_content); @@ -1552,7 +1558,7 @@ void WebViewCore::layerToAbsoluteOffset(const LayerAndroid* layer, IntPoint& off while (layer) { const SkPoint& pos = layer->getPosition(); offset.move(pos.fX, pos.fY); - const IntPoint& scroll = layer->scrollOffset(); + const IntPoint& scroll = layer->getScrollOffset(); offset.move(-scroll.x(), -scroll.y()); layer = static_cast<LayerAndroid*>(layer->getParent()); } @@ -1599,7 +1605,11 @@ bool WebViewCore::isLtr(const Position& position) SelectText* WebViewCore::createSelectText(const VisibleSelection& selection) { bool isCaret = selection.isCaret(); - if (selection.isNone() || (!selection.isContentEditable() && isCaret)) + if (selection.isNone() || (!selection.isContentEditable() && isCaret) + || !selection.start().anchorNode() + || !selection.start().anchorNode()->renderer() + || !selection.end().anchorNode() + || !selection.end().anchorNode()->renderer()) return 0; RefPtr<Range> range = selection.firstRange(); @@ -3178,9 +3188,9 @@ GraphicsLayerAndroid* WebViewCore::graphicsRootLayer() const } #endif -bool WebViewCore::handleTouchEvent(int action, Vector<int>& ids, Vector<IntPoint>& points, int actionIndex, int metaState) +int WebViewCore::handleTouchEvent(int action, Vector<int>& ids, Vector<IntPoint>& points, int actionIndex, int metaState) { - bool preventDefault = false; + int flags = 0; #if USE(ACCELERATED_COMPOSITING) GraphicsLayerAndroid* rootLayer = graphicsRootLayer(); @@ -3244,14 +3254,17 @@ bool WebViewCore::handleTouchEvent(int action, Vector<int>& ids, Vector<IntPoint } WebCore::PlatformTouchEvent te(ids, points, type, touchStates, metaState); - preventDefault = m_mainFrame->eventHandler()->handleTouchEvent(te); + if (m_mainFrame->eventHandler()->handleTouchEvent(te)) + flags |= TOUCH_FLAG_PREVENT_DEFAULT; + if (te.hitTouchHandler()) + flags |= TOUCH_FLAG_HIT_HANDLER; #endif #if USE(ACCELERATED_COMPOSITING) if (rootLayer) rootLayer->pauseDisplay(false); #endif - return preventDefault; + return flags; } bool WebViewCore::performMouseClick() @@ -4589,7 +4602,7 @@ static jstring FindAddress(JNIEnv* env, jobject obj, jstring addr, return ret; } -static jboolean HandleTouchEvent(JNIEnv* env, jobject obj, jint nativeClass, +static jint HandleTouchEvent(JNIEnv* env, jobject obj, jint nativeClass, jint action, jintArray idArray, jintArray xArray, jintArray yArray, jint count, jint actionIndex, jint metaState) { @@ -5030,7 +5043,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { (void*) SaveDocumentState }, { "nativeFindAddress", "(Ljava/lang/String;Z)Ljava/lang/String;", (void*) FindAddress }, - { "nativeHandleTouchEvent", "(II[I[I[IIII)Z", + { "nativeHandleTouchEvent", "(II[I[I[IIII)I", (void*) HandleTouchEvent }, { "nativeMouseClick", "(I)Z", (void*) MouseClick }, diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h index bfd9387..e7e97c3 100644 --- a/Source/WebKit/android/jni/WebViewCore.h +++ b/Source/WebKit/android/jni/WebViewCore.h @@ -322,8 +322,11 @@ namespace android { /** * Handle touch event + * Returns an int with the following flags: + * bit 0: hit an event handler + * bit 1: preventDefault was called */ - bool handleTouchEvent(int action, WTF::Vector<int>& ids, + int handleTouchEvent(int action, WTF::Vector<int>& ids, WTF::Vector<WebCore::IntPoint>& points, int actionIndex, int metaState); diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index a1d7fda..a730907 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -650,6 +650,84 @@ void setDrawingPaused(bool isPaused) m_viewImpl->setPrerenderingEnabled(!isPaused); } +// Finds the rectangles within world to the left, right, top, and bottom +// of rect and adds them to rects. If no intersection exists, false is returned. +static bool findMaskedRects(const FloatRect& world, + const FloatRect& rect, Vector<FloatRect>& rects) { + if (!world.intersects(rect)) + return false; // nothing to subtract + + // left rectangle + if (rect.x() > world.x()) + rects.append(FloatRect(world.x(), world.y(), + rect.x() - world.x(), world.height())); + // top rectangle + if (rect.y() > world.y()) + rects.append(FloatRect(world.x(), world.y(), + world.width(), rect.y() - world.y())); + // right rectangle + if (rect.maxX() < world.maxX()) + rects.append(FloatRect(rect.maxX(), world.y(), + world.maxX() - rect.maxX(), world.height())); + // bottom rectangle + if (rect.maxY() < world.maxY()) + rects.append(FloatRect(world.x(), rect.maxY(), + world.width(), world.maxY() - rect.maxY())); + return true; +} + +// Returns false if layerId is a fixed position layer, otherwise +// all fixed position layer rectangles are subtracted from those within +// rects. Rects will be modified to contain rectangles that don't include +// the fixed position layer rectangles. +static bool findMaskedRectsForLayer(LayerAndroid* layer, + Vector<FloatRect>& rects, int layerId) +{ + if (layer->isPositionFixed()) { + if (layerId == layer->uniqueId()) + return false; + FloatRect layerRect = layer->fullContentAreaMapped(); + for (int i = rects.size() - 1; i >= 0; i--) + if (findMaskedRects(rects[i], layerRect, rects)) + rects.remove(i); + } + + int childIndex = 0; + while (LayerAndroid* child = layer->getChild(childIndex++)) + if (!findMaskedRectsForLayer(child, rects, layerId)) + return false; + + return true; +} + +// Finds the largest rectangle not masked by any fixed layer. +void findMaxVisibleRect(int movingLayerId, SkIRect& visibleContentRect) +{ + if (!m_baseLayer) + return; + + FloatRect visibleContentFloatRect(visibleContentRect); + m_baseLayer->updatePositionsRecursive(visibleContentFloatRect); + Vector<FloatRect> rects; + rects.append(visibleContentFloatRect); + if (findMaskedRectsForLayer(m_baseLayer, rects, movingLayerId)) { + float maxSize = 0.0; + const FloatRect* largest = 0; + for (int i = 0; i < rects.size(); i++) { + const FloatRect& rect = rects[i]; + float size = rect.width() * rect.height(); + if (size > maxSize) { + maxSize = size; + largest = ▭ + } + } + if (largest) { + SkRect largeRect = *largest; + largeRect.round(&visibleContentRect); + } + } +} + private: // local state for WebView bool m_isDrawingPaused; // private to getFrameCache(); other functions operate in a different thread @@ -1194,6 +1272,16 @@ static jint nativeSetHwAccelerated(JNIEnv *env, jobject obj, jint nativeView, return webview->setHwAccelerated(hwAccelerated); } +static void nativeFindMaxVisibleRect(JNIEnv *env, jobject obj, jint nativeView, + jint movingLayerId, jobject visibleContentRect) +{ + WebView* webview = reinterpret_cast<WebView*>(nativeView); + SkIRect nativeRect; + GraphicsJNI::jrect_to_irect(env, visibleContentRect, &nativeRect); + webview->findMaxVisibleRect(movingLayerId, nativeRect); + GraphicsJNI::irect_to_jrect(nativeRect, env, visibleContentRect); +} + /* * JNI registration */ @@ -1270,6 +1358,8 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeMapLayerRect }, { "nativeSetHwAccelerated", "(IZ)I", (void*) nativeSetHwAccelerated }, + { "nativeFindMaxVisibleRect", "(IILandroid/graphics/Rect;)V", + (void*) nativeFindMaxVisibleRect }, }; int registerWebView(JNIEnv* env) |