summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebCore/bindings/generic/BindingDOMWindow.h2
-rw-r--r--WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp2
-rw-r--r--WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp4
-rw-r--r--WebCore/dom/EventListener.h3
-rw-r--r--WebCore/loader/FrameLoader.cpp7
-rw-r--r--WebCore/page/Geolocation.cpp48
-rw-r--r--WebCore/page/Geolocation.h15
-rw-r--r--WebCore/platform/android/FileChooserAndroid.cpp16
-rw-r--r--WebCore/platform/android/FileSystemAndroid.cpp11
-rw-r--r--WebCore/platform/android/LocalizedStringsAndroid.cpp4
-rw-r--r--WebCore/platform/android/PlatformBridge.h6
-rw-r--r--WebCore/platform/android/ScrollViewAndroid.cpp4
-rw-r--r--WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp28
-rw-r--r--WebCore/platform/graphics/android/ImageBufferAndroid.cpp28
-rw-r--r--WebCore/platform/graphics/android/ImageSourceAndroid.cpp2
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.cpp54
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.h16
-rw-r--r--WebCore/platform/posix/FileSystemPOSIX.cpp2
-rw-r--r--WebCore/plugins/PluginView.cpp42
-rw-r--r--WebCore/plugins/PluginView.h6
-rw-r--r--WebCore/rendering/RenderIFrame.cpp12
-rw-r--r--WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp10
-rw-r--r--WebKit/android/WebCoreSupport/ChromeClientAndroid.h8
-rw-r--r--WebKit/android/WebCoreSupport/FileSystemClient.h41
-rw-r--r--WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp4
-rw-r--r--WebKit/android/WebCoreSupport/PlatformBridge.cpp20
-rw-r--r--WebKit/android/jni/JavaBridge.cpp19
-rw-r--r--WebKit/android/jni/JavaSharedClient.cpp12
-rw-r--r--WebKit/android/jni/JavaSharedClient.h4
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.cpp24
-rw-r--r--WebKit/android/jni/WebViewCore.cpp23
-rw-r--r--WebKit/android/nav/SelectText.cpp104
-rw-r--r--WebKit/android/nav/SelectText.h6
33 files changed, 381 insertions, 206 deletions
diff --git a/WebCore/bindings/generic/BindingDOMWindow.h b/WebCore/bindings/generic/BindingDOMWindow.h
index b46bdf9..f883d11 100644
--- a/WebCore/bindings/generic/BindingDOMWindow.h
+++ b/WebCore/bindings/generic/BindingDOMWindow.h
@@ -109,7 +109,7 @@ Frame* BindingDOMWindow<Binding>::createWindow(State<Binding>* state,
if (created)
newFrame->loader()->changeLocation(completedUrl, referrer, false, false, userGesture);
else if (!url.isEmpty())
- newFrame->redirectScheduler()->scheduleLocationChange(completedUrl.string(), referrer, false, userGesture);
+ newFrame->redirectScheduler()->scheduleLocationChange(completedUrl.string(), referrer, false, false, userGesture);
}
return newFrame;
diff --git a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
index 6a53a1f..ff2be37 100644
--- a/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
@@ -574,7 +574,7 @@ v8::Handle<v8::Value> V8DOMWindow::openCallback(const v8::Arguments& args)
// the outgoingReferrer. We replicate that behavior here.
String referrer = enteredFrame->loader()->outgoingReferrer();
- frame->redirectScheduler()->scheduleLocationChange(completedUrl, referrer, false, userGesture);
+ frame->redirectScheduler()->scheduleLocationChange(completedUrl, referrer, false, false, userGesture);
}
return toV8(frame->domWindow());
}
diff --git a/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp b/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp
index 008d1ab..8959189 100644
--- a/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp
+++ b/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp
@@ -198,7 +198,9 @@ JSValue JavaInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod
}
}
-#ifdef BUILDING_ON_TIGER
+// This is a deprecated code path which should not be required on Android.
+// Remove this guard once Bug 39476 is fixed.
+#if PLATFORM(ANDROID) || defined(BUILDING_ON_TIGER)
if (!handled) {
jobject obj = m_instance->m_instance;
switch (jMethod->JNIReturnType()) {
diff --git a/WebCore/dom/EventListener.h b/WebCore/dom/EventListener.h
index 249d3eb..d7c950f 100644
--- a/WebCore/dom/EventListener.h
+++ b/WebCore/dom/EventListener.h
@@ -41,8 +41,7 @@ namespace WebCore {
InspectorDOMAgentType,
InspectorDOMStorageResourceType,
ObjCEventListenerType,
- ConditionEventListenerType,
- GeolocationEventListenerType };
+ ConditionEventListenerType };
virtual ~EventListener() { }
virtual bool operator==(const EventListener&) = 0;
diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp
index 125ee9b..f6b8f52 100644
--- a/WebCore/loader/FrameLoader.cpp
+++ b/WebCore/loader/FrameLoader.cpp
@@ -59,6 +59,7 @@
#include "FrameLoaderClient.h"
#include "FrameTree.h"
#include "FrameView.h"
+#include "Geolocation.h"
#include "HTMLAnchorElement.h"
#include "HTMLAppletElement.h"
#include "HTMLFormElement.h"
@@ -76,6 +77,7 @@
#include "Logging.h"
#include "MIMETypeRegistry.h"
#include "MainResourceLoader.h"
+#include "Navigator.h"
#include "Page.h"
#include "PageCache.h"
#include "PageGroup.h"
@@ -605,6 +607,11 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy, DatabasePolic
#endif
}
+ // Stop the Geolocation object, if present. This call is made after the unload
+ // event has fired, so no new Geolocation activity is possible.
+ if (m_frame->domWindow()->navigator()->optionalGeolocation())
+ m_frame->domWindow()->navigator()->optionalGeolocation()->stop();
+
// tell all subframes to stop as well
for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling())
child->loader()->stopLoading(unloadEventPolicy);
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
index 88e8941..49a4d84 100644
--- a/WebCore/page/Geolocation.cpp
+++ b/WebCore/page/Geolocation.cpp
@@ -31,10 +31,6 @@
#if ENABLE(GEOLOCATION)
#include "Chrome.h"
-// ANDROID
-#include "DOMWindow.h"
-#include "EventNames.h"
-// END ANDROID
#include "Frame.h"
#include "Page.h"
#if PLATFORM(ANDROID)
@@ -208,10 +204,7 @@ void Geolocation::Watchers::getNotifiersVector(Vector<RefPtr<GeoNotifier> >& cop
}
Geolocation::Geolocation(Frame* frame)
-// ANDROID
- : EventListener(GeolocationEventListenerType)
- , m_frame(frame)
-// END ANDROID
+ : m_frame(frame)
#if !ENABLE(CLIENT_BASED_GEOLOCATION)
, m_service(GeolocationService::create(this))
#endif
@@ -222,26 +215,23 @@ Geolocation::Geolocation(Frame* frame)
return;
ASSERT(m_frame->document());
m_frame->document()->setUsingGeolocation(true);
-
-// ANDROID
- if (m_frame->domWindow())
- m_frame->domWindow()->addEventListener(eventNames().unloadEvent, this, false);
-// END ANDROID
}
Geolocation::~Geolocation()
{
-// ANDROID
- if (m_frame && m_frame->domWindow())
- m_frame->domWindow()->removeEventListener(eventNames().unloadEvent, this, false);
-// END ANDROID
+}
+
+void Geolocation::stop()
+{
+ m_oneShots.clear();
+ m_watchers.clear();
+ stopUpdating();
}
void Geolocation::disconnectFrame()
{
if (m_frame && m_frame->page() && m_allowGeolocation == InProgress)
m_frame->page()->chrome()->cancelGeolocationPermissionRequestForFrame(m_frame, this);
- stopUpdating();
if (m_frame && m_frame->document())
m_frame->document()->setUsingGeolocation(false);
m_frame = 0;
@@ -684,26 +674,6 @@ void Geolocation::stopUpdating()
}
-// ANDROID
-bool Geolocation::operator==(const EventListener& listener)
-{
- if (listener.type() != GeolocationEventListenerType)
- return false;
- const Geolocation* geolocation = static_cast<const Geolocation*>(&listener);
- return m_frame == geolocation->m_frame;
-}
-
-void Geolocation::handleEvent(ScriptExecutionContext*, Event* event)
-{
- ASSERT_UNUSED(event, event->type() == eventNames().unloadEvent);
- // Cancel any ongoing requests on page unload. This is required to release
- // references to JS callbacks in the page, to allow the frame to be cleaned up
- // by WebKit.
- m_oneShots.clear();
- m_watchers.clear();
-}
-// END ANDROID
-
} // namespace WebCore
#else
@@ -720,6 +690,8 @@ Geolocation::~Geolocation() {}
void Geolocation::setIsAllowed(bool) {}
+void Geolocation::stop() {}
+
}
#endif // ENABLE(GEOLOCATION)
diff --git a/WebCore/page/Geolocation.h b/WebCore/page/Geolocation.h
index ba4f149..8803703 100644
--- a/WebCore/page/Geolocation.h
+++ b/WebCore/page/Geolocation.h
@@ -27,9 +27,6 @@
#ifndef Geolocation_h
#define Geolocation_h
-// ANDROID
-#include "EventListener.h"
-// END ANDROID
#include "GeolocationPositionCache.h"
#include "GeolocationService.h"
#include "Geoposition.h"
@@ -48,9 +45,7 @@ class GeolocationPosition;
class GeolocationError;
#endif
-// ANDROID
-class Geolocation : public EventListener
-// END ANDROID
+class Geolocation : public RefCounted<Geolocation>
#if !ENABLE(CLIENT_BASED_GEOLOCATION) && ENABLE(GEOLOCATION)
, public GeolocationServiceClient
#endif
@@ -70,6 +65,8 @@ public:
void suspend();
void resume();
+ void stop();
+
void setIsAllowed(bool);
Frame* frame() const { return m_frame; }
@@ -154,12 +151,6 @@ private:
PassRefPtr<GeoNotifier> startRequest(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
-// ANDROID
- // EventListener
- virtual bool operator==(const EventListener&);
- virtual void handleEvent(ScriptExecutionContext*, Event*);
-// END ANDROID
-
void fatalErrorOccurred(GeoNotifier*);
void requestTimedOut(GeoNotifier*);
void requestUsesCachedPosition(GeoNotifier*);
diff --git a/WebCore/platform/android/FileChooserAndroid.cpp b/WebCore/platform/android/FileChooserAndroid.cpp
index 1f8200f..f2ad3b9 100644
--- a/WebCore/platform/android/FileChooserAndroid.cpp
+++ b/WebCore/platform/android/FileChooserAndroid.cpp
@@ -25,22 +25,20 @@
#include "config.h"
#include "FileChooser.h"
+#include "FileSystem.h"
#include "Font.h"
+#include "LocalizedStrings.h"
+#include "StringTruncator.h"
namespace WebCore {
String FileChooser::basenameForWidth(const Font& font, int width) const
{
if (!m_filenames.size())
- return String();
- // FIXME: This could be a lot faster, but assuming the data will not
- // often be much longer than the provided width, this may be fast enough.
- // If this does not need to be threadsafe, we can use crossThreadString().
- // See http://trac.webkit.org/changeset/49160.
- String output = m_filenames[0].threadsafeCopy();
- while (font.width(TextRun(output.impl())) > width && output.length() > 4)
- output = output.replace(0, 4, String("..."));
- return output;
+ return fileButtonNoFileSelectedLabel();
+
+ String output = pathGetFileName(m_filenames[0]);
+ return StringTruncator::centerTruncate(output, static_cast<float>(width), font, false);
}
} // namespace WebCore
diff --git a/WebCore/platform/android/FileSystemAndroid.cpp b/WebCore/platform/android/FileSystemAndroid.cpp
index 3d841d7..cf9830e 100644
--- a/WebCore/platform/android/FileSystemAndroid.cpp
+++ b/WebCore/platform/android/FileSystemAndroid.cpp
@@ -28,6 +28,7 @@
#include "config.h"
#include "FileSystem.h"
+#include "PlatformBridge.h"
#include "StringBuilder.h"
#include "cutils/log.h"
#include <dirent.h>
@@ -106,4 +107,14 @@ Vector<String> listDirectory(const String& path, const String& filter)
return entries;
}
+String pathGetFileName(const String& path)
+{
+ // If the path is a content:// URI then ask Java to resolve it for us.
+ if (path.startsWith("content://"))
+ return PlatformBridge::resolveFileNameForContentUri(path);
+ else
+ return path.substring(path.reverseFind('/') + 1);
+}
+
+
} // namespace WebCore
diff --git a/WebCore/platform/android/LocalizedStringsAndroid.cpp b/WebCore/platform/android/LocalizedStringsAndroid.cpp
index e0db88d..5ca7fa2 100644
--- a/WebCore/platform/android/LocalizedStringsAndroid.cpp
+++ b/WebCore/platform/android/LocalizedStringsAndroid.cpp
@@ -48,8 +48,8 @@ String fileButtonChooseFileLabel()
String fileButtonNoFileSelectedLabel()
{
- notImplemented();
- return String();
+ return *(PlatformBridge::globalLocalizedName(
+ PlatformBridge::FileUploadNoFileChosenLabel));
}
String contextMenuItemTagInspectElement()
diff --git a/WebCore/platform/android/PlatformBridge.h b/WebCore/platform/android/PlatformBridge.h
index 43313a5..33f8697 100644
--- a/WebCore/platform/android/PlatformBridge.h
+++ b/WebCore/platform/android/PlatformBridge.h
@@ -119,7 +119,8 @@ public:
DrawableDir,
FileUploadLabel,
ResetLabel,
- SubmitLabel
+ SubmitLabel,
+ FileUploadNoFileChosenLabel
};
static String* globalLocalizedName(rawResId resId);
@@ -135,6 +136,9 @@ public:
// ANDROID
// TODO: Upstream to webkit.org. See https://bugs.webkit.org/show_bug.cgi?id=34082
static bool isWebViewPaused(const FrameView*);
+
+ static bool canScroll(const FrameView*);
+ static String resolveFileNameForContentUri(const String&);
};
}
diff --git a/WebCore/platform/android/ScrollViewAndroid.cpp b/WebCore/platform/android/ScrollViewAndroid.cpp
index f9e4285..7efc8c1 100644
--- a/WebCore/platform/android/ScrollViewAndroid.cpp
+++ b/WebCore/platform/android/ScrollViewAndroid.cpp
@@ -30,8 +30,8 @@
#include "FloatRect.h"
#include "FrameView.h"
#include "IntRect.h"
+#include "PlatformBridge.h"
#include "SkRegion.h"
-#include "WebCoreFrameBridge.h"
#include "WebCoreViewBridge.h"
#include "WebViewCore.h"
@@ -70,6 +70,8 @@ void ScrollView::platformSetScrollPosition(const WebCore::IntPoint& pt)
{
if (parent()) // don't attempt to scroll subframes; they're fully visible
return;
+ if (isFrameView() && !PlatformBridge::canScroll(static_cast<FrameView*>(this)))
+ return;
android::WebViewCore::getWebViewCore(this)->scrollTo(pt.x(), pt.y());
}
diff --git a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 0d22719..c3df943 100644
--- a/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -229,30 +229,39 @@ void GraphicsLayerAndroid::updateFixedPosition()
// If we are a fixed position layer, just set it
if (view->isPositioned() && view->style()->position() == FixedPosition) {
+ // We need to get the passed CSS properties for the element
SkLength left, top, right, bottom;
left = convertLength(view->style()->left());
top = convertLength(view->style()->top());
right = convertLength(view->style()->right());
bottom = convertLength(view->style()->bottom());
- // We need to pass the size of the element to compute the final fixed
- // position -- we can't use the layer's size as it could possibly differs.
- // We also have to use the visible overflow and not just the size,
- // as some child elements could be overflowing.
- int w = view->rightVisibleOverflow() - view->leftVisibleOverflow();
- int h = view->bottomVisibleOverflow() - view->topVisibleOverflow();
+ // We also need to get the margin...
SkLength marginLeft, marginTop, marginRight, marginBottom;
marginLeft = convertLength(view->style()->marginLeft());
marginTop = convertLength(view->style()->marginTop());
marginRight = convertLength(view->style()->marginRight());
marginBottom = convertLength(view->style()->marginBottom());
+ // The layer can be bigger than the element we want to draw;
+ // not only that, the layout rect of the element might also be
+ // different from the visible rect of that element (i.e. the element
+ // has a CSS shadow property -- the shadow is "outside" the element).
+ // We thus need to:
+ // 1/ get the size of the element (w,h), using the layoutOverflow rect
+ // 2/ pass the current offset of the painting relative to the layer
+ int w = view->rightLayoutOverflow() - view->leftLayoutOverflow();
+ int h = view->bottomLayoutOverflow() - view->topLayoutOverflow();
+ int paintingOffsetX = - offsetFromRenderer().width();
+ int paintingOffsetY = - offsetFromRenderer().height();
+
+ SkRect viewRect;
+ viewRect.set(paintingOffsetX, paintingOffsetY, paintingOffsetX + w, paintingOffsetY + h);
+
m_contentLayer->setFixedPosition(left, top, right, bottom,
marginLeft, marginTop,
marginRight, marginBottom,
- offsetFromRenderer().width(),
- offsetFromRenderer().height(),
- w, h);
+ viewRect);
}
}
@@ -283,6 +292,7 @@ void GraphicsLayerAndroid::setSize(const FloatSize& size)
MLOG("(%x) setSize (%.2f,%.2f)", this, size.width(), size.height());
GraphicsLayer::setSize(size);
m_contentLayer->setSize(size.width(), size.height());
+ updateFixedPosition();
askForSync();
}
}
diff --git a/WebCore/platform/graphics/android/ImageBufferAndroid.cpp b/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
index 6efccfe..92c585f 100644
--- a/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
+++ b/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
@@ -24,11 +24,11 @@
*/
#include "config.h"
-#include "BitmapImage.h"
#include "ImageBuffer.h"
-#include "ImageData.h"
-#include "NotImplemented.h"
+#include "Base64.h"
+#include "BitmapImage.h"
+#include "ImageData.h"
#include "android_graphics.h"
#include "GraphicsContext.h"
#include "PlatformGraphicsContext.h"
@@ -36,6 +36,8 @@
#include "SkCanvas.h"
#include "SkColorPriv.h"
#include "SkDevice.h"
+#include "SkImageEncoder.h"
+#include "SkStream.h"
#include "SkUnPreMultiply.h"
using namespace std;
@@ -208,10 +210,22 @@ void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sou
String ImageBuffer::toDataURL(const String&) const
-{
- // leaving this unimplemented, until I understand what its for (and what it
- // really is).
- return "data:,"; // I think this means we couldn't make the data url
+{
+ // Encode the image into a vector.
+ SkDynamicMemoryWStream pngStream;
+ const SkBitmap& dst = android_gc2canvas(context())->getDevice()->accessBitmap(true);
+ SkImageEncoder::EncodeStream(&pngStream, dst, SkImageEncoder::kPNG_Type, 100);
+
+ // Convert it into base64.
+ Vector<char> pngEncodedData;
+ pngEncodedData.append(pngStream.getStream(), pngStream.getOffset());
+ Vector<char> base64EncodedData;
+ base64Encode(pngEncodedData, base64EncodedData);
+ // Append with a \0 so that it's a valid string.
+ base64EncodedData.append('\0');
+
+ // And the resulting string.
+ return String::format("data:image/png;base64,%s", base64EncodedData.data());
}
}
diff --git a/WebCore/platform/graphics/android/ImageSourceAndroid.cpp b/WebCore/platform/graphics/android/ImageSourceAndroid.cpp
index 914a9d6..c0ef611 100644
--- a/WebCore/platform/graphics/android/ImageSourceAndroid.cpp
+++ b/WebCore/platform/graphics/android/ImageSourceAndroid.cpp
@@ -303,7 +303,7 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
}
PrivateAndroidImageSourceRec* decoder = m_decoder.m_image;
- if (allDataReceived && !decoder->fAllDataReceived) {
+ if (allDataReceived && decoder && !decoder->fAllDataReceived) {
decoder->fAllDataReceived = true;
SkBitmap* bm = &decoder->bitmap();
diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp
index 2f10d33..5aaa243 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -87,9 +87,7 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
m_fixedMarginTop = layer.m_fixedMarginTop;
m_fixedMarginRight = layer.m_fixedMarginRight;
m_fixedMarginBottom = layer.m_fixedMarginBottom;
- m_fixedOffset = layer.m_fixedOffset;
- m_fixedWidth = layer.m_fixedWidth;
- m_fixedHeight = layer.m_fixedHeight;
+ m_fixedRect = layer.m_fixedRect;
m_recordingPicture = layer.m_recordingPicture;
SkSafeRef(m_recordingPicture);
@@ -256,20 +254,6 @@ const LayerAndroid* LayerAndroid::find(int x, int y) const
///////////////////////////////////////////////////////////////////////////////
-// The Layer bounds and the renderview bounds are not always indentical.
-// We need to compute the intersection to correctly compute the
-// positiong...
-static SkRect computeLayerRect(LayerAndroid* layer) {
- SkRect layerRect, viewRect;
- SkScalar fX, fY;
- fX = layer->getOffset().fX;
- fY = layer->getOffset().fY;
- layerRect.set(0, 0, layer->getSize().width(), layer->getSize().height());
- viewRect.set(-fX, -fY, -fX + layer->getFixedWidth(), -fY + layer->getFixedHeight());
- layerRect.intersect(viewRect);
- return layerRect;
-}
-
void LayerAndroid::updateFixedLayersPositions(const SkRect& viewport)
{
if (m_isFixed) {
@@ -280,23 +264,21 @@ void LayerAndroid::updateFixedLayersPositions(const SkRect& viewport)
float x = dx;
float y = dy;
- SkRect layerRect = computeLayerRect(this);
-
// Not defined corresponds to 'auto';
- // so if right is auto, and left is auto, the w3c says we should set
- // left to zero (in left-to-right layout). So basically, if right is not
- // defined, we always apply auto.
- if (m_fixedRight.defined())
- x += w - m_fixedMarginRight.calcFloatValue(w) - m_fixedRight.calcFloatValue(w) - layerRect.width();
+ // If both left and right are auto, the w3c says we should set left
+ // to zero (in left-to-right layout). So we use left if it's defined
+ // or if right isn't defined.
+ if (m_fixedLeft.defined() || !m_fixedRight.defined())
+ x += m_fixedMarginLeft.calcFloatValue(w) + m_fixedLeft.calcFloatValue(w) - m_fixedRect.fLeft;
else
- x += m_fixedMarginLeft.calcFloatValue(w) + m_fixedLeft.calcFloatValue(w) - layerRect.fLeft;
+ x += w - m_fixedMarginRight.calcFloatValue(w) - m_fixedRight.calcFloatValue(w) - m_fixedRect.fRight;
// Following the same reason as above, if bottom isn't defined, we apply
// top regardless of it being defined or not.
- if (m_fixedBottom.defined())
- y += h - m_fixedMarginBottom.calcFloatValue(h) - m_fixedBottom.calcFloatValue(h) - layerRect.fTop - layerRect.height();
+ if (m_fixedTop.defined() || !m_fixedBottom.defined())
+ y += m_fixedMarginTop.calcFloatValue(h) + m_fixedTop.calcFloatValue(h) - m_fixedRect.fTop;
else
- y += m_fixedMarginTop.calcFloatValue(h) + m_fixedTop.calcFloatValue(h) - layerRect.fTop;
+ y += h - m_fixedMarginBottom.calcFloatValue(h) - m_fixedBottom.calcFloatValue(h) - m_fixedRect.fBottom;
this->setPosition(x, y);
}
@@ -375,10 +357,9 @@ void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity) {
canvas->drawLine(w, 0, 0, 0, paint);
if (m_isFixed) {
- SkRect layerRect = computeLayerRect(this);
SkPaint paint;
- paint.setARGB(128, 0, 0, 255);
- canvas->drawRect(layerRect, paint);
+ paint.setARGB(80, 255, 0, 0);
+ canvas->drawRect(m_fixedRect, paint);
}
#endif
}
@@ -513,6 +494,13 @@ void writeSize(FILE* file, int indentLevel, const char* str, SkSize size)
fprintf(file, "%s = { w = %.3f; h = %.3f; };\n", str, size.width(), size.height());
}
+void writeRect(FILE* file, int indentLevel, const char* str, SkRect rect)
+{
+ writeIndent(file, indentLevel);
+ fprintf(file, "%s = { x = %.3f; y = %.3f; w = %.3f; h = %.3f; };\n",
+ str, rect.fLeft, rect.fTop, rect.width(), rect.height());
+}
+
void writeLength(FILE* file, int indentLevel, const char* str, SkLength length)
{
if (!length.defined()) return;
@@ -549,9 +537,7 @@ void LayerAndroid::dumpLayers(FILE* file, int indentLevel) const
writeLength(file, indentLevel + 1, "fixedMarginTop", m_fixedMarginTop);
writeLength(file, indentLevel + 1, "fixedMarginRight", m_fixedMarginRight);
writeLength(file, indentLevel + 1, "fixedMarginBottom", m_fixedMarginBottom);
- writePoint(file, indentLevel + 1, "fixedOffset", m_fixedOffset);
- writeIntVal(file, indentLevel + 1, "fixedWidth", m_fixedWidth);
- writeIntVal(file, indentLevel + 1, "fixedHeight", m_fixedHeight);
+ writeRect(file, indentLevel + 1, "fixedRect", m_fixedRect);
}
if (m_recordingPicture) {
diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h
index 2b106d1..b6b6f70 100644
--- a/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/WebCore/platform/graphics/android/LayerAndroid.h
@@ -104,10 +104,7 @@ public:
SkLength marginTop, // CSS margin-top property
SkLength marginRight, // CSS margin-right property
SkLength marginBottom, // CSS margin-bottom property
- int offsetX, // X Offset from the renderer
- int offsetY, // Y Offset from the renderer
- int width, // visible overflow width
- int height) { // visible overflow height
+ SkRect viewRect) { // view rect, can be smaller than the layer's
m_fixedLeft = left;
m_fixedTop = top;
m_fixedRight = right;
@@ -116,9 +113,7 @@ public:
m_fixedMarginTop = marginTop;
m_fixedMarginRight = marginRight;
m_fixedMarginBottom = marginBottom;
- m_fixedOffset.set(offsetX, offsetY);
- m_fixedWidth = width;
- m_fixedHeight = height;
+ m_fixedRect = viewRect;
m_isFixed = true;
setInheritFromRootTransform(true);
}
@@ -171,9 +166,6 @@ public:
void setExtra(DrawExtra* extra); // does not assign ownership
int uniqueId() const { return m_uniqueId; }
bool isFixed() { return m_isFixed; }
- const SkPoint& getOffset() const { return m_fixedOffset; }
- int getFixedWidth() { return m_fixedWidth; }
- int getFixedHeight() { return m_fixedHeight; }
/** This sets a content image -- calling it means we will use
the image directly when drawing the layer instead of using
@@ -208,9 +200,7 @@ private:
SkLength m_fixedMarginTop;
SkLength m_fixedMarginRight;
SkLength m_fixedMarginBottom;
- SkPoint m_fixedOffset;
- int m_fixedWidth;
- int m_fixedHeight;
+ SkRect m_fixedRect;
SkPoint m_translation;
SkPoint m_scale;
diff --git a/WebCore/platform/posix/FileSystemPOSIX.cpp b/WebCore/platform/posix/FileSystemPOSIX.cpp
index ac8c7fa..b7fcd71 100644
--- a/WebCore/platform/posix/FileSystemPOSIX.cpp
+++ b/WebCore/platform/posix/FileSystemPOSIX.cpp
@@ -213,10 +213,12 @@ bool makeAllDirectories(const String& path)
return true;
}
+#if !PLATFORM(ANDROID)
String pathGetFileName(const String& path)
{
return path.substring(path.reverseFind('/') + 1);
}
+#endif
String directoryName(const String& path)
{
diff --git a/WebCore/plugins/PluginView.cpp b/WebCore/plugins/PluginView.cpp
index fe24109..73ac220 100644
--- a/WebCore/plugins/PluginView.cpp
+++ b/WebCore/plugins/PluginView.cpp
@@ -69,8 +69,6 @@
#include "TouchEvent.h"
#endif
-// ANDROID
-// TODO: Upstream to webkit.org
#if USE(JSC)
#include "JSDOMBinding.h"
#include "JSDOMWindow.h"
@@ -233,7 +231,6 @@ bool PluginView::startOrAddToUnstartedList()
return start();
}
-
bool PluginView::start()
{
if (m_isStarted)
@@ -249,7 +246,7 @@ bool PluginView::start()
NPError npErr;
{
PluginView::setCurrentPluginView(this);
-#if USE(JSC)
+#if USE(JSC)
JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
#endif
setCallingPlugin(true);
@@ -362,6 +359,7 @@ void PluginView::stop()
ASSERT(m_streams.isEmpty());
m_isStarted = false;
+
#if USE(JSC)
JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
#endif
@@ -447,22 +445,6 @@ static char* createUTF8String(const String& str)
return result;
}
-#if USE(JSC)
-static bool getString(ScriptController* proxy, JSValue result, String& string)
-{
- if (!proxy || !result || result.isUndefined())
- return false;
- JSLock lock(JSC::SilenceAssertionsOnly);
-
- ExecState* exec = proxy->globalObject(pluginWorld())->globalExec();
- UString ustring = result.toString(exec);
- exec->clearException();
-
- string = ustringToString(ustring);
- return true;
-}
-#endif
-
void PluginView::performRequest(PluginRequest* request)
{
if (!m_isStarted)
@@ -495,7 +477,7 @@ void PluginView::performRequest(PluginRequest* request)
// FIXME: <rdar://problem/4807469> This should be sent when the document has finished loading
if (request->sendNotification()) {
PluginView::setCurrentPluginView(this);
-#if USE(JSC)
+#if USE(JSC)
JSC::JSLock::DropAllLocks dropAllLocks(JSC::SilenceAssertionsOnly);
#endif
setCallingPlugin(true);
@@ -510,7 +492,7 @@ void PluginView::performRequest(PluginRequest* request)
// Targeted JavaScript requests are only allowed on the frame that contains the JavaScript plugin
// and this has been made sure in ::load.
ASSERT(targetFrameName.isEmpty() || m_parentFrame->tree()->find(targetFrameName) == m_parentFrame);
-
+
// Executing a script can cause the plugin view to be destroyed, so we keep a reference to the parent frame.
RefPtr<Frame> parentFrame = m_parentFrame;
ScriptValue result = m_parentFrame->script()->executeScript(jsString, request->shouldAllowPopups());
@@ -518,19 +500,14 @@ void PluginView::performRequest(PluginRequest* request)
if (targetFrameName.isNull()) {
String resultString;
- CString cstr;
#if USE(JSC)
- if (getString(parentFrame->script(), result.jsValue(), resultString))
- cstr = resultString.utf8();
+ ScriptState* scriptState = parentFrame->script()->globalObject(pluginWorld())->globalExec();
#elif USE(V8)
- // #if PLATFORM(ANDROID)
- // TODO. When upstreaming this, we could re-visit whether the JSC getString function in this file
- // could be removed, and this code re-factored to call ScriptValue::getString(ScriptState* scriptState, String& result)
- // in both cases, thus getting rid of the #ifs
- // #endif
- if (result.getString(resultString))
- cstr = resultString.utf8();
+ ScriptState* scriptState = 0; // Not used with V8
#endif
+ CString cstr;
+ if (result.getString(scriptState, resultString))
+ cstr = resultString.utf8();
RefPtr<PluginStream> stream = PluginStream::create(this, m_parentFrame.get(), request->frameLoadRequest().resourceRequest(), request->sendNotification(), request->notifyData(), plugin()->pluginFuncs(), instance(), m_plugin->quirks());
m_streams.add(stream);
@@ -787,7 +764,6 @@ void PluginView::setJavaScriptPaused(bool paused)
m_requestTimer.startOneShot(0);
}
-
#if USE(JSC)
PassRefPtr<JSC::Bindings::Instance> PluginView::bindingInstance()
{
diff --git a/WebCore/plugins/PluginView.h b/WebCore/plugins/PluginView.h
index 88136e3..b685bbf 100644
--- a/WebCore/plugins/PluginView.h
+++ b/WebCore/plugins/PluginView.h
@@ -1,4 +1,3 @@
-
/*
* Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2008 Collabora Ltd. All rights reserved.
@@ -140,8 +139,6 @@ namespace WebCore {
#if USE(JSC)
PassRefPtr<JSC::Bindings::Instance> bindingInstance();
-#elif USE(V8)
- NPObject* getNPObject();
#endif
PluginStatus status() const { return m_status; }
@@ -175,6 +172,9 @@ namespace WebCore {
void (*timerFunc)(NPP, uint32_t timerID));
void unscheduleTimer(NPP, uint32_t timerID);
#endif
+#if USE(V8)
+ NPObject* getNPObject();
+#endif
virtual void invalidateRect(const IntRect&);
diff --git a/WebCore/rendering/RenderIFrame.cpp b/WebCore/rendering/RenderIFrame.cpp
index 90cac14..146e028 100644
--- a/WebCore/rendering/RenderIFrame.cpp
+++ b/WebCore/rendering/RenderIFrame.cpp
@@ -58,9 +58,7 @@ void RenderIFrame::calcHeight()
updateWidgetPosition();
// Layout to get the content height
- do {
- view->layout();
- } while (view->layoutPending() || root->needsLayout());
+ view->layout();
int extraHeight = paddingTop() + paddingBottom() + borderTop() + borderBottom();
setHeight(max(width(), view->contentsHeight() + extraHeight));
@@ -110,9 +108,7 @@ void RenderIFrame::calcWidth()
updateWidgetPosition();
// Layout to get the content width
- do {
- view->layout();
- } while (view->layoutPending() || root->needsLayout());
+ view->layout();
setWidth(max(width(), view->contentsWidth() + extraWidth));
@@ -208,9 +204,7 @@ void RenderIFrame::layout()
}
// Layout the view.
- do {
- view->layout();
- } while (view->layoutPending() || root->needsLayout());
+ view->layout();
int contentHeight = view->contentsHeight();
int contentWidth = view->contentsWidth();
diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
index b59689d..ead81e0 100644
--- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
@@ -57,11 +57,16 @@ static unsigned long long tryToReclaimDatabaseQuota(SecurityOrigin* originNeedin
#if USE(ACCELERATED_COMPOSITING)
-void ChromeClientAndroid::syncTimerFired(Timer<ChromeClientAndroid>* client)
+void ChromeClientAndroid::layersSync()
{
if (!m_rootGraphicsLayer)
return;
+ if (!m_needsLayerSync)
+ return;
+
+ m_needsLayerSync = false;
+
if (m_webFrame) {
FrameView* frameView = m_webFrame->page()->mainFrame()->view();
if (frameView && frameView->syncCompositingStateRecursive()) {
@@ -77,8 +82,7 @@ void ChromeClientAndroid::syncTimerFired(Timer<ChromeClientAndroid>* client)
void ChromeClientAndroid::scheduleCompositingLayerSync()
{
- if (!m_syncTimer.isActive())
- m_syncTimer.startOneShot(0);
+ m_needsLayerSync = true;
}
void ChromeClientAndroid::setNeedsOneShotDrawingSynchronization()
diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h b/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
index 902d84c..28f2546 100644
--- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
+++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
@@ -46,8 +46,7 @@ namespace android {
ChromeClientAndroid() : m_webFrame(0), m_geolocationPermissions(0)
#if USE(ACCELERATED_COMPOSITING)
, m_rootGraphicsLayer(0)
- , m_askToDrawAgain(false)
- , m_syncTimer(this, &ChromeClientAndroid::syncTimerFired)
+ , m_needsLayerSync(false)
#endif
, m_triedToReclaimDBQuota(false)
{ }
@@ -170,7 +169,7 @@ namespace android {
virtual void attachRootGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer* g);
virtual void setNeedsOneShotDrawingSynchronization();
virtual void scheduleCompositingLayerSync();
- void syncTimerFired(Timer<ChromeClientAndroid>*);
+ void layersSync();
#endif
private:
@@ -179,8 +178,7 @@ namespace android {
OwnPtr<GeolocationPermissions> m_geolocationPermissions;
#if USE(ACCELERATED_COMPOSITING)
WebCore::GraphicsLayer* m_rootGraphicsLayer;
- bool m_askToDrawAgain;
- Timer<ChromeClientAndroid> m_syncTimer;
+ bool m_needsLayerSync;
#endif
WTF::ThreadCondition m_quotaThreadCondition;
WTF::Mutex m_quotaThreadLock;
diff --git a/WebKit/android/WebCoreSupport/FileSystemClient.h b/WebKit/android/WebCoreSupport/FileSystemClient.h
new file mode 100644
index 0000000..8847bda
--- /dev/null
+++ b/WebKit/android/WebCoreSupport/FileSystemClient.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FILESYSTEM_CLIENT_H
+#define FILESYSTEM_CLIENT_H
+
+#include "PlatformString.h"
+
+using namespace WebCore;
+
+namespace android {
+
+class FileSystemClient {
+public:
+ virtual ~FileSystemClient() { }
+ virtual String resolveFileNameForContentUri(const String&) = 0;
+};
+}
+#endif
diff --git a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
index 697f7b9..79c64fd 100644
--- a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp
@@ -395,7 +395,9 @@ void FrameLoaderClientAndroid::dispatchDidFinishLoad() {
void FrameLoaderClientAndroid::dispatchDidFirstLayout() {
ASSERT(m_frame);
- m_frame->document()->setExtraLayoutDelay(EXTRA_LAYOUT_DELAY);
+ // set EXTRA_LAYOUT_DELAY if the loader is not completed yet
+ if (!m_frame->loader()->isComplete())
+ m_frame->document()->setExtraLayoutDelay(EXTRA_LAYOUT_DELAY);
// we need to do this here instead of dispatchDidFirstVisuallyNonEmptyLayout
// so that about:blank will update the screen.
if (!m_frame->tree()->parent()) {
diff --git a/WebKit/android/WebCoreSupport/PlatformBridge.cpp b/WebKit/android/WebCoreSupport/PlatformBridge.cpp
index 05aa42b..c64bb9d 100644
--- a/WebKit/android/WebCoreSupport/PlatformBridge.cpp
+++ b/WebKit/android/WebCoreSupport/PlatformBridge.cpp
@@ -27,9 +27,12 @@
#include <PlatformBridge.h>
#include "CookieClient.h"
+#include "FileSystemClient.h"
+#include "FrameView.h"
#include "JavaSharedClient.h"
#include "KeyGeneratorClient.h"
#include "PluginView.h"
+#include "WebCoreFrameBridge.h"
#include "WebViewCore.h"
#include "npruntime.h"
#include <wtf/android/AndroidThreading.h>
@@ -135,11 +138,28 @@ bool PlatformBridge::isWebViewPaused(const WebCore::FrameView* frameView)
return webViewCore->isPaused();
}
+bool PlatformBridge::canScroll(const WebCore::FrameView* frameView)
+{
+ // We want to ignore requests to scroll that were not initiated by the
+ // user. An example of this is when text is inserted into a
+ // textfield/area, which results in a scroll. We ignore this because
+ // we know how to do this ourselves in the UI thread.
+ // An example of it being initiated by the user is if the user clicks
+ // an anchor element which simply scrolls the page.
+ return android::WebFrame::getWebFrame(frameView->frame())->userInitiatedClick();
+}
+
bool PlatformBridge::popupsAllowed(NPP)
{
return false;
}
+String PlatformBridge::resolveFileNameForContentUri(const String& contentUri)
+{
+ FileSystemClient* client = JavaSharedClient::GetFileSystemClient();
+ return client->resolveFileNameForContentUri(contentUri);
+}
+
} // namespace WebCore
diff --git a/WebKit/android/jni/JavaBridge.cpp b/WebKit/android/jni/JavaBridge.cpp
index 0e65e1c..2d95f87 100644
--- a/WebKit/android/jni/JavaBridge.cpp
+++ b/WebKit/android/jni/JavaBridge.cpp
@@ -31,6 +31,7 @@
#include "Cache.h"
#include "Connection.h"
#include "CookieClient.h"
+#include "FileSystemClient.h"
#include "JavaSharedClient.h"
#include "KeyGeneratorClient.h"
#include "KURL.h"
@@ -62,7 +63,7 @@ static jfieldID gJavaBridge_ObjectID;
// ----------------------------------------------------------------------------
-class JavaBridge : public TimerClient, public CookieClient, public PluginClient, public KeyGeneratorClient
+class JavaBridge : public TimerClient, public CookieClient, public PluginClient, public KeyGeneratorClient, public FileSystemClient
{
public:
JavaBridge(JNIEnv* env, jobject obj);
@@ -84,6 +85,7 @@ public:
virtual WTF::Vector<String> getSupportedKeyStrengthList();
virtual WebCore::String getSignedPublicKeyAndChallengeString(unsigned index,
const WebCore::String& challenge, const WebCore::KURL& url);
+ virtual WebCore::String resolveFileNameForContentUri(const WebCore::String& uri);
////////////////////////////////////////////
@@ -120,6 +122,7 @@ private:
jmethodID mSignalFuncPtrQueue;
jmethodID mGetKeyStrengthList;
jmethodID mGetSignedPublicKey;
+ jmethodID mResolveFileNameForContentUri;
};
static void (*sSharedTimerFiredCallback)();
@@ -139,6 +142,7 @@ JavaBridge::JavaBridge(JNIEnv* env, jobject obj)
mSignalFuncPtrQueue = env->GetMethodID(clazz, "signalServiceFuncPtrQueue", "()V");
mGetKeyStrengthList = env->GetMethodID(clazz, "getKeyStrengthList", "()[Ljava/lang/String;");
mGetSignedPublicKey = env->GetMethodID(clazz, "getSignedPublicKey", "(ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
+ mResolveFileNameForContentUri = env->GetMethodID(clazz, "resolveFileNameForContentUri", "(Ljava/lang/String;)Ljava/lang/String;");
LOG_ASSERT(mSetSharedTimer, "Could not find method setSharedTimer");
LOG_ASSERT(mStopSharedTimer, "Could not find method stopSharedTimer");
@@ -154,6 +158,7 @@ JavaBridge::JavaBridge(JNIEnv* env, jobject obj)
JavaSharedClient::SetCookieClient(this);
JavaSharedClient::SetPluginClient(this);
JavaSharedClient::SetKeyGeneratorClient(this);
+ JavaSharedClient::SetFileSystemClient(this);
}
JavaBridge::~JavaBridge()
@@ -168,6 +173,7 @@ JavaBridge::~JavaBridge()
JavaSharedClient::SetCookieClient(NULL);
JavaSharedClient::SetPluginClient(NULL);
JavaSharedClient::SetKeyGeneratorClient(NULL);
+ JavaSharedClient::SetFileSystemClient(NULL);
}
void
@@ -308,6 +314,17 @@ WebCore::String JavaBridge::getSignedPublicKeyAndChallengeString(unsigned index,
return ret;
}
+WebCore::String JavaBridge::resolveFileNameForContentUri(const WebCore::String& uri) {
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ jstring jUri = env->NewString(uri.characters(), uri.length());
+ AutoJObject obj = getRealObject(env, mJavaObject);
+ jstring path = static_cast<jstring>(env->CallObjectMethod(obj.get(), mResolveFileNameForContentUri, jUri));
+ WebCore::String ret = to_string(env, path);
+ env->DeleteLocalRef(jUri);
+ env->DeleteLocalRef(path);
+ return ret;
+}
+
// ----------------------------------------------------------------------------
void JavaBridge::Constructor(JNIEnv* env, jobject obj)
diff --git a/WebKit/android/jni/JavaSharedClient.cpp b/WebKit/android/jni/JavaSharedClient.cpp
index ce46570..e884c99 100644
--- a/WebKit/android/jni/JavaSharedClient.cpp
+++ b/WebKit/android/jni/JavaSharedClient.cpp
@@ -24,6 +24,7 @@
*/
#include "config.h"
+#include "FileSystemClient.h"
#include "JavaSharedClient.h"
#include "TimerClient.h"
#include "SkDeque.h"
@@ -50,6 +51,11 @@ namespace android {
return gKeyGeneratorClient;
}
+ FileSystemClient* JavaSharedClient::GetFileSystemClient()
+ {
+ return gFileSystemClient;
+ }
+
void JavaSharedClient::SetTimerClient(TimerClient* client)
{
gTimerClient = client;
@@ -70,10 +76,16 @@ namespace android {
gKeyGeneratorClient = client;
}
+ void JavaSharedClient::SetFileSystemClient(FileSystemClient* client)
+ {
+ gFileSystemClient = client;
+ }
+
TimerClient* JavaSharedClient::gTimerClient = NULL;
CookieClient* JavaSharedClient::gCookieClient = NULL;
PluginClient* JavaSharedClient::gPluginClient = NULL;
KeyGeneratorClient* JavaSharedClient::gKeyGeneratorClient = NULL;
+ FileSystemClient* JavaSharedClient::gFileSystemClient = NULL;
///////////////////////////////////////////////////////////////////////////
diff --git a/WebKit/android/jni/JavaSharedClient.h b/WebKit/android/jni/JavaSharedClient.h
index d33df67..9a09280 100644
--- a/WebKit/android/jni/JavaSharedClient.h
+++ b/WebKit/android/jni/JavaSharedClient.h
@@ -32,6 +32,7 @@ namespace android {
class CookieClient;
class PluginClient;
class KeyGeneratorClient;
+ class FileSystemClient;
class JavaSharedClient
{
@@ -40,11 +41,13 @@ namespace android {
static CookieClient* GetCookieClient();
static PluginClient* GetPluginClient();
static KeyGeneratorClient* GetKeyGeneratorClient();
+ static FileSystemClient* GetFileSystemClient();
static void SetTimerClient(TimerClient* client);
static void SetCookieClient(CookieClient* client);
static void SetPluginClient(PluginClient* client);
static void SetKeyGeneratorClient(KeyGeneratorClient* client);
+ static void SetFileSystemClient(FileSystemClient* client);
// can be called from any thread, to be executed in webkit thread
static void EnqueueFunctionPtr(void (*proc)(void*), void* payload);
@@ -56,6 +59,7 @@ namespace android {
static CookieClient* gCookieClient;
static PluginClient* gPluginClient;
static KeyGeneratorClient* gKeyGeneratorClient;
+ static FileSystemClient* gFileSystemClient;
};
}
#endif
diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp
index 9ecb121..de172cd 100644
--- a/WebKit/android/jni/WebCoreFrameBridge.cpp
+++ b/WebKit/android/jni/WebCoreFrameBridge.cpp
@@ -116,6 +116,7 @@ using namespace JSC::Bindings;
static String* gUploadFileLabel;
static String* gResetLabel;
static String* gSubmitLabel;
+static String* gNoFileChosenLabel;
String* WebCore::PlatformBridge::globalLocalizedName(
WebCore::PlatformBridge::rawResId resId)
@@ -127,6 +128,9 @@ String* WebCore::PlatformBridge::globalLocalizedName(
return gResetLabel;
case WebCore::PlatformBridge::SubmitLabel:
return gSubmitLabel;
+ case WebCore::PlatformBridge::FileUploadNoFileChosenLabel:
+ return gNoFileChosenLabel;
+
default:
return 0;
}
@@ -148,6 +152,9 @@ void initGlobalLocalizedName(WebCore::PlatformBridge::rawResId resId,
case WebCore::PlatformBridge::SubmitLabel:
pointer = &gSubmitLabel;
break;
+ case WebCore::PlatformBridge::FileUploadNoFileChosenLabel:
+ pointer = &gNoFileChosenLabel;
+ break;
default:
return;
}
@@ -320,19 +327,6 @@ static jobject createJavaMapFromHTTPHeaders(JNIEnv* env, const WebCore::HTTPHead
return hashMap;
}
-// In WebViewCore.java, we artificially append the filename to the URI so that
-// webkit treats the actual display name of the file as the filename, rather
-// than the last segment of the URI (which will simply be a number). When we
-// pass the URI up to BrowserFrame, we no longer need the appended name (in fact
-// it causes problems), so remove it here.
-// FIXME: If we rewrite pathGetFileName (the current version is in
-// FileSystemPOSIX), we can get the filename that way rather than appending it.
-static jstring uriFromUriFileName(JNIEnv* env, const WebCore::String& name)
-{
- const WebCore::String fileName = name.left(name.reverseFind('/'));
- return env->NewString(fileName.characters(), fileName.length());
-}
-
// This class stores the URI and the size of each file for upload. The URI is
// stored so we do not have to create it again. The size is stored so we can
// compare the actual size of the file with the stated size. If the actual size
@@ -341,7 +335,7 @@ static jstring uriFromUriFileName(JNIEnv* env, const WebCore::String& name)
class FileInfo {
public:
FileInfo(JNIEnv* env, const WebCore::String& name) {
- m_uri = uriFromUriFileName(env, name);
+ m_uri = env->NewString(name.characters(), name.length());
checkException(env);
m_size = 0;
m_env = env;
@@ -940,7 +934,7 @@ static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAss
WebCore::RenderSkinAndroid::Init(am, directory);
}
for (int i = WebCore::PlatformBridge::FileUploadLabel;
- i <= WebCore::PlatformBridge::SubmitLabel; i++)
+ i <= WebCore::PlatformBridge::FileUploadNoFileChosenLabel; i++)
initGlobalLocalizedName(
static_cast<WebCore::PlatformBridge::rawResId>(i), webFrame);
}
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 50611c7..45356f8 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -308,7 +308,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_javaGlue->m_scrollBy = GetJMethod(env, clazz, "contentScrollBy", "(IIZ)V");
m_javaGlue->m_contentDraw = GetJMethod(env, clazz, "contentDraw", "()V");
m_javaGlue->m_requestListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[I[I)V");
- m_javaGlue->m_openFileChooser = GetJMethod(env, clazz, "openFileChooser", "()Ljava/lang/String;");
+ m_javaGlue->m_openFileChooser = GetJMethod(env, clazz, "openFileChooser", "(Ljava/lang/String;)Ljava/lang/String;");
m_javaGlue->m_requestSingleListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[II)V");
m_javaGlue->m_jsAlert = GetJMethod(env, clazz, "jsAlert", "(Ljava/lang/String;Ljava/lang/String;)V");
m_javaGlue->m_jsConfirm = GetJMethod(env, clazz, "jsConfirm", "(Ljava/lang/String;Ljava/lang/String;)Z");
@@ -884,6 +884,12 @@ bool WebViewCore::recordContent(SkRegion* region, SkIPoint* point)
region->getBounds().fTop, region->getBounds().fRight,
region->getBounds().fBottom);
DBG_SET_LOG("end");
+
+#if USE(ACCELERATED_COMPOSITING)
+ // We update the layers
+ ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>(m_mainFrame->page()->chrome()->client());
+ chromeC->layersSync();
+#endif
return true;
}
@@ -1969,15 +1975,24 @@ void WebViewCore::openFileChooser(PassRefPtr<WebCore::FileChooser> chooser) {
if (!chooser)
return;
JNIEnv* env = JSC::Bindings::getJNIEnv();
+
+ WebCore::String acceptType = chooser->acceptTypes();
+ jstring jAcceptType = env->NewString(const_cast<unsigned short*>(acceptType.characters()), acceptType.length());
jstring jName = (jstring) env->CallObjectMethod(
- m_javaGlue->object(env).get(), m_javaGlue->m_openFileChooser);
+ m_javaGlue->object(env).get(), m_javaGlue->m_openFileChooser, jAcceptType);
checkException(env);
- const UChar* string = (const UChar*) env->GetStringChars(jName, NULL);
+ env->DeleteLocalRef(jAcceptType);
+
+ const UChar* string = static_cast<const UChar*>(env->GetStringChars(jName, NULL));
+
if (!string)
return;
+
WebCore::String webcoreString = to_string(env, jName);
env->ReleaseStringChars(jName, string);
- chooser->chooseFile(webcoreString);
+
+ if (webcoreString.length())
+ chooser->chooseFile(webcoreString);
}
void WebViewCore::listBoxRequest(WebCoreReply* reply, const uint16_t** labels, size_t count, const int enabled[], size_t enabledCount,
diff --git a/WebKit/android/nav/SelectText.cpp b/WebKit/android/nav/SelectText.cpp
index 0fcbe95..29d47e5 100644
--- a/WebKit/android/nav/SelectText.cpp
+++ b/WebKit/android/nav/SelectText.cpp
@@ -26,6 +26,7 @@
#define LOG_TAG "webcoreglue"
#include "CachedPrefix.h"
+#include "BidiResolver.h"
#include "CachedRoot.h"
#include "LayerAndroid.h"
#include "SelectText.h"
@@ -39,11 +40,101 @@
#include "SkRect.h"
#include "SkRegion.h"
#include "SkUtils.h"
+#include "TextRun.h"
#ifdef DEBUG_NAV_UI
#include <wtf/text/CString.h>
#endif
+// TextRunIterator has been copied verbatim from GraphicsContext.cpp
+namespace WebCore {
+
+class TextRunIterator {
+public:
+ TextRunIterator()
+ : m_textRun(0)
+ , m_offset(0)
+ {
+ }
+
+ TextRunIterator(const TextRun* textRun, unsigned offset)
+ : m_textRun(textRun)
+ , m_offset(offset)
+ {
+ }
+
+ TextRunIterator(const TextRunIterator& other)
+ : m_textRun(other.m_textRun)
+ , m_offset(other.m_offset)
+ {
+ }
+
+ unsigned offset() const { return m_offset; }
+ void increment() { m_offset++; }
+ bool atEnd() const { return !m_textRun || m_offset >= m_textRun->length(); }
+ UChar current() const { return (*m_textRun)[m_offset]; }
+ WTF::Unicode::Direction direction() const { return atEnd() ? WTF::Unicode::OtherNeutral : WTF::Unicode::direction(current()); }
+
+ bool operator==(const TextRunIterator& other)
+ {
+ return m_offset == other.m_offset && m_textRun == other.m_textRun;
+ }
+
+ bool operator!=(const TextRunIterator& other) { return !operator==(other); }
+
+private:
+ const TextRun* m_textRun;
+ int m_offset;
+};
+
+// ReverseBidi is a trimmed-down version of GraphicsContext::drawBidiText()
+void ReverseBidi(UChar* chars, int len) {
+ using namespace WTF::Unicode;
+ WTF::Vector<UChar> result;
+ result.reserveCapacity(len);
+ TextRun run(chars, len);
+ BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver;
+ bidiResolver.setStatus(BidiStatus(LeftToRight, LeftToRight, LeftToRight,
+ BidiContext::create(0, LeftToRight, false)));
+ bidiResolver.setPosition(TextRunIterator(&run, 0));
+ bidiResolver.createBidiRunsForLine(TextRunIterator(&run, len));
+ if (!bidiResolver.runCount())
+ return;
+ BidiCharacterRun* bidiRun = bidiResolver.firstRun();
+ while (bidiRun) {
+ int bidiStart = bidiRun->start();
+ int bidiStop = bidiRun->stop();
+ int size = result.size();
+ int bidiCount = bidiStop - bidiStart;
+ result.append(chars + bidiStart, bidiCount);
+ if (bidiRun->level() % 2) {
+ UChar* start = &result[size];
+ UChar* end = start + bidiCount;
+ // reverse the order of any RTL substrings
+ while (start < end) {
+ UChar temp = *start;
+ *start++ = *--end;
+ *end = temp;
+ }
+ start = &result[size];
+ end = start + bidiCount - 1;
+ // if the RTL substring had a surrogate pair, restore its order
+ while (start < end) {
+ UChar trail = *start++;
+ if (!U16_IS_SURROGATE(trail))
+ continue;
+ start[-1] = *start; // lead
+ *start++ = trail;
+ }
+ }
+ bidiRun = bidiRun->next();
+ }
+ bidiResolver.deleteRuns();
+ memcpy(chars, &result[0], len * sizeof(UChar));
+}
+
+}
+
namespace android {
class CommonCheck : public SkBounder {
@@ -264,6 +355,19 @@ public:
}
WebCore::String text() {
+ // the text has been copied in visual order. Reverse as needed if
+ // result contains right-to-left characters.
+ const uint16_t* start = mSelectText.begin();
+ const uint16_t* end = mSelectText.end();
+ while (start < end) {
+ SkUnichar ch = SkUTF16_NextUnichar(&start);
+ WTF::Unicode::Direction charDirection = WTF::Unicode::direction(ch);
+ if (WTF::Unicode::RightToLeftArabic == charDirection
+ || WTF::Unicode::RightToLeft == charDirection) {
+ WebCore::ReverseBidi(mSelectText.begin(), mSelectText.count());
+ break;
+ }
+ }
return WebCore::String(mSelectText.begin(), mSelectText.count());
}
diff --git a/WebKit/android/nav/SelectText.h b/WebKit/android/nav/SelectText.h
index 8174046..2e17a74 100644
--- a/WebKit/android/nav/SelectText.h
+++ b/WebKit/android/nav/SelectText.h
@@ -81,4 +81,10 @@ private:
}
+namespace WebCore {
+
+void ReverseBidi(UChar* chars, int len);
+
+}
+
#endif