summaryrefslogtreecommitdiffstats
path: root/WebCore/platform
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform')
-rw-r--r--WebCore/platform/BlobItem.cpp142
-rw-r--r--WebCore/platform/BlobItem.h25
-rw-r--r--WebCore/platform/Cursor.cpp473
-rw-r--r--WebCore/platform/Cursor.h96
-rw-r--r--WebCore/platform/FileChooser.h6
-rw-r--r--WebCore/platform/HostWindow.h5
-rw-r--r--WebCore/platform/KURLGoogle.cpp53
-rw-r--r--WebCore/platform/MIMETypeRegistry.cpp1
-rw-r--r--WebCore/platform/PopupMenuClient.h1
-rw-r--r--WebCore/platform/Widget.h4
-rw-r--r--WebCore/platform/android/TemporaryLinkStubs.cpp11
-rw-r--r--WebCore/platform/brew/PopupMenuBrew.cpp3
-rw-r--r--WebCore/platform/chromium/ChromiumBridge.h2
-rw-r--r--WebCore/platform/chromium/CursorChromium.cpp8
-rw-r--r--WebCore/platform/chromium/GLES2Context.h12
-rw-r--r--WebCore/platform/chromium/PlatformThemeChromiumGtk.cpp221
-rw-r--r--WebCore/platform/chromium/PlatformThemeChromiumGtk.h71
-rw-r--r--WebCore/platform/chromium/PopupMenuChromium.cpp54
-rw-r--r--WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp216
-rw-r--r--WebCore/platform/chromium/ThemeChromiumMac.mm132
-rw-r--r--WebCore/platform/efl/CursorEfl.cpp18
-rw-r--r--WebCore/platform/efl/PopupMenuEfl.cpp3
-rw-r--r--WebCore/platform/efl/SoundEfl.cpp4
-rw-r--r--WebCore/platform/efl/WidgetEfl.cpp24
-rw-r--r--WebCore/platform/graphics/Color.h13
-rw-r--r--WebCore/platform/graphics/FloatPoint.h22
-rw-r--r--WebCore/platform/graphics/Font.cpp3
-rw-r--r--WebCore/platform/graphics/Font.h4
-rw-r--r--WebCore/platform/graphics/GraphicsContext3D.h16
-rw-r--r--WebCore/platform/graphics/GraphicsLayer.h5
-rw-r--r--WebCore/platform/graphics/ImageBuffer.h5
-rw-r--r--WebCore/platform/graphics/MediaPlayer.cpp16
-rw-r--r--WebCore/platform/graphics/MediaPlayer.h7
-rw-r--r--WebCore/platform/graphics/MediaPlayerPrivate.h3
-rw-r--r--WebCore/platform/graphics/Path.h1
-rw-r--r--WebCore/platform/graphics/WidthIterator.cpp23
-rw-r--r--WebCore/platform/graphics/android/ImageBufferAndroid.cpp8
-rw-r--r--WebCore/platform/graphics/android/PathAndroid.cpp7
-rw-r--r--WebCore/platform/graphics/cairo/FontCairo.cpp4
-rw-r--r--WebCore/platform/graphics/cairo/PathCairo.cpp9
-rw-r--r--WebCore/platform/graphics/cg/ColorCG.cpp11
-rw-r--r--WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp37
-rw-r--r--WebCore/platform/graphics/cg/PathCG.cpp8
-rw-r--r--WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp3
-rw-r--r--WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp25
-rw-r--r--WebCore/platform/graphics/chromium/GraphicsLayerChromium.h2
-rw-r--r--WebCore/platform/graphics/chromium/LayerRendererChromium.cpp21
-rw-r--r--WebCore/platform/graphics/chromium/LayerRendererChromium.h9
-rw-r--r--WebCore/platform/graphics/chromium/VideoLayerChromium.cpp50
-rw-r--r--WebCore/platform/graphics/chromium/VideoLayerChromium.h54
-rw-r--r--WebCore/platform/graphics/haiku/PathHaiku.cpp8
-rw-r--r--WebCore/platform/graphics/mac/ComplexTextController.cpp18
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContext3DMac.mm87
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.h1
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.mm8
-rw-r--r--WebCore/platform/graphics/mac/WebLayer.h8
-rw-r--r--WebCore/platform/graphics/mac/WebLayer.mm51
-rw-r--r--WebCore/platform/graphics/mac/WebTiledLayer.mm22
-rw-r--r--WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp4
-rw-r--r--WebCore/platform/graphics/openvg/PathOpenVG.cpp7
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp13
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContextQt.cpp157
-rw-r--r--WebCore/platform/graphics/qt/ImageBufferQt.cpp15
-rw-r--r--WebCore/platform/graphics/qt/ImageQt.cpp4
-rw-r--r--WebCore/platform/graphics/qt/PathQt.cpp35
-rw-r--r--WebCore/platform/graphics/qt/StillImageQt.cpp74
-rw-r--r--WebCore/platform/graphics/qt/StillImageQt.h10
-rw-r--r--WebCore/platform/graphics/skia/ImageBufferSkia.cpp5
-rw-r--r--WebCore/platform/graphics/skia/PathSkia.cpp7
-rw-r--r--WebCore/platform/graphics/skia/SkiaUtils.cpp12
-rw-r--r--WebCore/platform/graphics/win/GraphicsLayerCACF.cpp2
-rw-r--r--WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp1
-rw-r--r--WebCore/platform/graphics/wince/PathWince.cpp7
-rw-r--r--WebCore/platform/graphics/wx/PathWx.cpp7
-rw-r--r--WebCore/platform/gtk/CursorGtk.cpp22
-rw-r--r--WebCore/platform/gtk/FileSystemGtk.cpp32
-rw-r--r--WebCore/platform/gtk/PasteboardHelper.cpp1
-rw-r--r--WebCore/platform/gtk/RenderThemeGtk.cpp7
-rw-r--r--WebCore/platform/haiku/CursorHaiku.cpp12
-rw-r--r--WebCore/platform/image-encoders/skia/PNGImageEncoder.cpp69
-rw-r--r--WebCore/platform/mac/CursorMac.mm403
-rw-r--r--WebCore/platform/mac/FileSystemMac.mm25
-rw-r--r--WebCore/platform/mac/ThemeMac.mm2
-rw-r--r--WebCore/platform/mac/WidgetMac.mm9
-rw-r--r--WebCore/platform/network/Credential.cpp2
-rw-r--r--WebCore/platform/network/Credential.h2
-rw-r--r--WebCore/platform/network/CredentialStorage.cpp5
-rw-r--r--WebCore/platform/network/CredentialStorage.h1
-rw-r--r--WebCore/platform/network/FormData.cpp5
-rw-r--r--WebCore/platform/network/NetworkStateNotifier.h2
-rw-r--r--WebCore/platform/network/ResourceHandle.cpp37
-rw-r--r--WebCore/platform/network/ResourceHandle.h15
-rw-r--r--WebCore/platform/network/ResourceHandleInternal.h8
-rw-r--r--WebCore/platform/network/ResourceResponseBase.cpp16
-rw-r--r--WebCore/platform/network/ResourceResponseBase.h6
-rw-r--r--WebCore/platform/network/android/ResourceHandleAndroid.cpp2
-rw-r--r--WebCore/platform/network/cf/ResourceErrorCF.cpp2
-rw-r--r--WebCore/platform/network/cf/ResourceHandleCFNet.cpp338
-rw-r--r--WebCore/platform/network/cf/ResourceRequestCFNet.cpp5
-rw-r--r--WebCore/platform/network/curl/FormDataStreamCurl.cpp8
-rw-r--r--WebCore/platform/network/curl/ResourceHandleManager.cpp34
-rw-r--r--WebCore/platform/network/mac/ResourceHandleMac.mm495
-rw-r--r--WebCore/platform/network/qt/QNetworkReplyHandler.cpp14
-rw-r--r--WebCore/platform/network/qt/ResourceHandleQt.cpp9
-rw-r--r--WebCore/platform/network/soup/ResourceHandleSoup.cpp18
-rw-r--r--WebCore/platform/qt/CursorQt.cpp8
-rw-r--r--WebCore/platform/qt/GeolocationServiceQt.cpp12
-rw-r--r--WebCore/platform/qt/RenderThemeQt.cpp2
-rw-r--r--WebCore/platform/qt/WidgetQt.cpp5
-rw-r--r--WebCore/platform/text/LineEnding.cpp150
-rw-r--r--WebCore/platform/text/LineEnding.h56
-rw-r--r--WebCore/platform/win/ClipboardUtilitiesWin.cpp82
-rw-r--r--WebCore/platform/win/ClipboardUtilitiesWin.h6
-rw-r--r--WebCore/platform/win/ClipboardWin.cpp25
-rw-r--r--WebCore/platform/win/ClipboardWin.h106
-rw-r--r--WebCore/platform/win/CursorWin.cpp433
-rw-r--r--WebCore/platform/win/PasteboardWin.cpp24
-rw-r--r--WebCore/platform/win/WidgetWin.cpp25
-rw-r--r--WebCore/platform/wince/CursorWince.cpp8
-rw-r--r--WebCore/platform/wx/CursorWx.cpp10
120 files changed, 3031 insertions, 2041 deletions
diff --git a/WebCore/platform/BlobItem.cpp b/WebCore/platform/BlobItem.cpp
index a12dd08..cc5e6c7 100644
--- a/WebCore/platform/BlobItem.cpp
+++ b/WebCore/platform/BlobItem.cpp
@@ -78,6 +78,20 @@ FileBlobItem::FileBlobItem(const String& path)
{
}
+#if ENABLE(DIRECTORY_UPLOAD)
+PassRefPtr<BlobItem> FileBlobItem::create(const String& path, const String& relativePath)
+{
+ return adoptRef(static_cast<BlobItem*>(new FileBlobItem(path, relativePath)));
+}
+
+FileBlobItem::FileBlobItem(const String& path, const String& relativePath)
+ : m_path(path)
+ , m_fileName(pathGetFileName(m_path))
+ , m_relativePath(relativePath)
+{
+}
+#endif
+
unsigned long long FileBlobItem::size() const
{
// FIXME: synchronized file call
@@ -105,144 +119,16 @@ PassRefPtr<BlobItem> FileBlobItem::slice(long long start, long long length)
// StringBlobItem --------------------------------------------------------------
-PassRefPtr<BlobItem> StringBlobItem::create(const String& text, LineEnding ending, TextEncoding encoding)
-{
- return adoptRef(static_cast<BlobItem*>(new StringBlobItem(text, ending, encoding)));
-}
-
PassRefPtr<BlobItem> StringBlobItem::create(const CString& text)
{
return adoptRef(static_cast<BlobItem*>(new StringBlobItem(text)));
}
-StringBlobItem::StringBlobItem(const String& text, LineEnding ending, TextEncoding encoding)
- : m_data(StringBlobItem::convertToCString(text, ending, encoding))
-{
-}
-
StringBlobItem::StringBlobItem(const CString& text)
: m_data(text)
{
}
-// Normalize all line-endings to CRLF.
-static CString convertToCRLF(const CString& from)
-{
- unsigned newLen = 0;
- const char* p = from.data();
- while (char c = *p++) {
- if (c == '\r') {
- // Safe to look ahead because of trailing '\0'.
- if (*p != '\n') {
- // Turn CR into CRLF.
- newLen += 2;
- }
- } else if (c == '\n') {
- // Turn LF into CRLF.
- newLen += 2;
- } else {
- // Leave other characters alone.
- newLen += 1;
- }
- }
- if (newLen == from.length())
- return from;
-
- // Make a copy of the string.
- p = from.data();
- char* q;
- CString result = CString::newUninitialized(newLen, q);
- while (char c = *p++) {
- if (c == '\r') {
- // Safe to look ahead because of trailing '\0'.
- if (*p != '\n') {
- // Turn CR into CRLF.
- *q++ = '\r';
- *q++ = '\n';
- }
- } else if (c == '\n') {
- // Turn LF into CRLF.
- *q++ = '\r';
- *q++ = '\n';
- } else {
- // Leave other characters alone.
- *q++ = c;
- }
- }
- return result;
-}
-
-// Normalize all line-endings to CR or LF.
-static CString convertToCROrLF(const CString& from, bool toCR)
-{
- unsigned newLen = 0;
- bool needFix = false;
- const char* p = from.data();
- char fromEndingChar = toCR ? '\n' : '\r';
- char toEndingChar = toCR ? '\r' : '\n';
- while (char c = *p++) {
- if (c == '\r' && *p == '\n') {
- // Turn CRLF into CR or LF.
- p++;
- needFix = true;
- } else if (c == fromEndingChar) {
- // Turn CR/LF into LF/CR.
- needFix = true;
- }
- newLen += 1;
- }
- if (!needFix)
- return from;
-
- // Make a copy of the string.
- p = from.data();
- char* q;
- CString result = CString::newUninitialized(newLen, q);
- while (char c = *p++) {
- if (c == '\r' && *p == '\n') {
- // Turn CRLF or CR into CR or LF.
- p++;
- *q++ = toEndingChar;
- } else if (c == fromEndingChar) {
- // Turn CR/LF into LF/CR.
- *q++ = toEndingChar;
- } else {
- // Leave other characters alone.
- *q++ = c;
- }
- }
- return result;
-}
-
-CString StringBlobItem::convertToCString(const String& text, LineEnding ending, TextEncoding encoding)
-{
- CString from = encoding.encode(text.characters(), text.length(), EntitiesForUnencodables);
-
- if (ending == EndingNative) {
-#if OS(WINDOWS)
- ending = EndingCRLF;
-#else
- ending = EndingLF;
-#endif
- }
-
- switch (ending) {
- case EndingTransparent:
- return from;
- case EndingCRLF:
- return convertToCRLF(from);
- case EndingCR:
- return convertToCROrLF(from, true);
- case EndingLF:
- return convertToCROrLF(from, false);
- default:
- ASSERT_NOT_REACHED();
- }
-
- ASSERT_NOT_REACHED();
- return from;
-}
-
// ByteArrayBlobItem ----------------------------------------------------------
PassRefPtr<BlobItem> ByteArrayBlobItem::create(const char* data, size_t size)
diff --git a/WebCore/platform/BlobItem.h b/WebCore/platform/BlobItem.h
index 1d34c59..3741f3f 100644
--- a/WebCore/platform/BlobItem.h
+++ b/WebCore/platform/BlobItem.h
@@ -32,7 +32,6 @@
#define BlobItem_h
#include "PlatformString.h"
-#include "TextEncoding.h"
#include <wtf/OwnPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -41,15 +40,6 @@
namespace WebCore {
-// String ending types.
-enum LineEnding {
- EndingTransparent = 0,
- EndingNative,
- EndingLF,
- EndingCR,
- EndingCRLF,
-};
-
class ByteArrayBlobItem;
class DataBlobItem;
class DataRangeBlobItem;
@@ -108,8 +98,14 @@ public:
class FileBlobItem : public BlobItem {
public:
static PassRefPtr<BlobItem> create(const String& path);
+#if ENABLE(DIRECTORY_UPLOAD)
+ static PassRefPtr<BlobItem> create(const String& path, const String& relativePath);
+#endif
virtual const String& name() const { return m_fileName; }
virtual const String& path() const { return m_path; }
+#if ENABLE(DIRECTORY_UPLOAD)
+ const String& relativePath() const { return m_relativePath; }
+#endif
// BlobItem methods.
virtual unsigned long long size() const;
@@ -120,13 +116,18 @@ public:
protected:
FileBlobItem(const String& path);
+#if ENABLE(DIRECTORY_UPLOAD)
+ FileBlobItem(const String& path, const String& relativePath);
+#endif
String m_path;
String m_fileName;
+#if ENABLE(DIRECTORY_UPLOAD)
+ String m_relativePath;
+#endif
};
class StringBlobItem : public DataBlobItem {
public:
- static PassRefPtr<BlobItem> create(const String&, LineEnding, TextEncoding);
static PassRefPtr<BlobItem> create(const CString&);
const CString& cstr() const { return m_data; }
@@ -138,9 +139,7 @@ public:
virtual const char* data() const { return m_data.data(); }
private:
- StringBlobItem(const String&, LineEnding, TextEncoding);
StringBlobItem(const CString&);
- static CString convertToCString(const String&, LineEnding, TextEncoding);
CString m_data;
};
diff --git a/WebCore/platform/Cursor.cpp b/WebCore/platform/Cursor.cpp
index 794a9dc..3f17ad9 100644
--- a/WebCore/platform/Cursor.cpp
+++ b/WebCore/platform/Cursor.cpp
@@ -46,4 +46,477 @@ IntPoint determineHotSpot(Image* image, const IntPoint& specifiedHotSpot)
return IntPoint();
}
+const Cursor& Cursor::fromType(Cursor::Type type)
+{
+ switch (type) {
+ case Cursor::Pointer:
+ return pointerCursor();
+ case Cursor::Cross:
+ return crossCursor();
+ case Cursor::Hand:
+ return handCursor();
+ case Cursor::IBeam:
+ return iBeamCursor();
+ case Cursor::Wait:
+ return waitCursor();
+ case Cursor::Help:
+ return helpCursor();
+ case Cursor::EastResize:
+ return eastResizeCursor();
+ case Cursor::NorthResize:
+ return northResizeCursor();
+ case Cursor::NorthEastResize:
+ return northEastResizeCursor();
+ case Cursor::NorthWestResize:
+ return northWestResizeCursor();
+ case Cursor::SouthResize:
+ return southResizeCursor();
+ case Cursor::SouthEastResize:
+ return southEastResizeCursor();
+ case Cursor::SouthWestResize:
+ return southWestResizeCursor();
+ case Cursor::WestResize:
+ return westResizeCursor();
+ case Cursor::NorthSouthResize:
+ return northSouthResizeCursor();
+ case Cursor::EastWestResize:
+ return eastWestResizeCursor();
+ case Cursor::NorthEastSouthWestResize:
+ return northEastSouthWestResizeCursor();
+ case Cursor::NorthWestSouthEastResize:
+ return northWestSouthEastResizeCursor();
+ case Cursor::ColumnResize:
+ return columnResizeCursor();
+ case Cursor::RowResize:
+ return rowResizeCursor();
+ case Cursor::MiddlePanning:
+ return middlePanningCursor();
+ case Cursor::EastPanning:
+ return eastPanningCursor();
+ case Cursor::NorthPanning:
+ return northPanningCursor();
+ case Cursor::NorthEastPanning:
+ return northEastPanningCursor();
+ case Cursor::NorthWestPanning:
+ return northWestPanningCursor();
+ case Cursor::SouthPanning:
+ return southPanningCursor();
+ case Cursor::SouthEastPanning:
+ return southEastPanningCursor();
+ case Cursor::SouthWestPanning:
+ return southWestPanningCursor();
+ case Cursor::WestPanning:
+ return westPanningCursor();
+ case Cursor::Move:
+ return moveCursor();
+ case Cursor::VerticalText:
+ return verticalTextCursor();
+ case Cursor::Cell:
+ return cellCursor();
+ case Cursor::ContextMenu:
+ return contextMenuCursor();
+ case Cursor::Alias:
+ return aliasCursor();
+ case Cursor::Progress:
+ return progressCursor();
+ case Cursor::NoDrop:
+ return noDropCursor();
+ case Cursor::Copy:
+ return copyCursor();
+ case Cursor::None:
+ return noneCursor();
+ case Cursor::NotAllowed:
+ return notAllowedCursor();
+ case Cursor::ZoomIn:
+ return zoomInCursor();
+ case Cursor::ZoomOut:
+ return zoomOutCursor();
+ case Cursor::Grab:
+ return grabCursor();
+ case Cursor::Grabbing:
+ return grabbingCursor();
+ case Cursor::Custom:
+ ASSERT_NOT_REACHED();
+ }
+ return pointerCursor();
+}
+
+const char* nameForCursorType(Cursor::Type type)
+{
+ switch (type) {
+ case Cursor::Pointer:
+ return "Pointer";
+ case Cursor::Cross:
+ return "Cross";
+ case Cursor::Hand:
+ return "Hand";
+ case Cursor::IBeam:
+ return "IBeam";
+ case Cursor::Wait:
+ return "Wait";
+ case Cursor::Help:
+ return "Help";
+ case Cursor::EastResize:
+ return "EastResize";
+ case Cursor::NorthResize:
+ return "NorthResize";
+ case Cursor::NorthEastResize:
+ return "NorthEastResize";
+ case Cursor::NorthWestResize:
+ return "NorthWestResize";
+ case Cursor::SouthResize:
+ return "SouthResize";
+ case Cursor::SouthEastResize:
+ return "SouthEastResize";
+ case Cursor::SouthWestResize:
+ return "SouthWestResize";
+ case Cursor::WestResize:
+ return "WestResize";
+ case Cursor::NorthSouthResize:
+ return "NorthSouthResize";
+ case Cursor::EastWestResize:
+ return "EastWestResize";
+ case Cursor::NorthEastSouthWestResize:
+ return "NorthEastSouthWestResize";
+ case Cursor::NorthWestSouthEastResize:
+ return "NorthWestSouthEastResize";
+ case Cursor::ColumnResize:
+ return "ColumnResize";
+ case Cursor::RowResize:
+ return "RowResize";
+ case Cursor::MiddlePanning:
+ return "MiddlePanning";
+ case Cursor::EastPanning:
+ return "EastPanning";
+ case Cursor::NorthPanning:
+ return "NorthPanning";
+ case Cursor::NorthEastPanning:
+ return "NorthEastPanning";
+ case Cursor::NorthWestPanning:
+ return "NorthWestPanning";
+ case Cursor::SouthPanning:
+ return "SouthPanning";
+ case Cursor::SouthEastPanning:
+ return "SouthEastPanning";
+ case Cursor::SouthWestPanning:
+ return "SouthWestPanning";
+ case Cursor::WestPanning:
+ return "WestPanning";
+ case Cursor::Move:
+ return "Move";
+ case Cursor::VerticalText:
+ return "VerticalText";
+ case Cursor::Cell:
+ return "Cell";
+ case Cursor::ContextMenu:
+ return "ContextMenu";
+ case Cursor::Alias:
+ return "Alias";
+ case Cursor::Progress:
+ return "Progress";
+ case Cursor::NoDrop:
+ return "NoDrop";
+ case Cursor::Copy:
+ return "Copy";
+ case Cursor::None:
+ return "None";
+ case Cursor::NotAllowed:
+ return "NotAllowed";
+ case Cursor::ZoomIn:
+ return "ZoomIn";
+ case Cursor::ZoomOut:
+ return "ZoomOut";
+ case Cursor::Grab:
+ return "Grab";
+ case Cursor::Grabbing:
+ return "Grabbing";
+ case Cursor::Custom:
+ return "Custom";
+ }
+
+ return "ERROR";
+}
+
+#if USE(LAZY_NATIVE_CURSOR)
+
+Cursor::Cursor(Image* image, const IntPoint& hotSpot)
+ : m_type(Custom)
+ , m_image(image)
+ , m_hotSpot(determineHotSpot(image, hotSpot))
+ , m_platformCursor(0)
+{
+}
+
+Cursor::Cursor(Type type)
+ : m_type(type)
+ , m_platformCursor(0)
+{
+}
+
+PlatformCursor Cursor::platformCursor() const
+{
+ ensurePlatformCursor();
+ return m_platformCursor;
+}
+
+const Cursor& pointerCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Pointer));
+ return c;
+}
+
+const Cursor& crossCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Cross));
+ return c;
+}
+
+const Cursor& handCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Hand));
+ return c;
+}
+
+const Cursor& moveCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Move));
+ return c;
+}
+
+const Cursor& verticalTextCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::VerticalText));
+ return c;
+}
+
+const Cursor& cellCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Cell));
+ return c;
+}
+
+const Cursor& contextMenuCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ContextMenu));
+ return c;
+}
+
+const Cursor& aliasCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Alias));
+ return c;
+}
+
+const Cursor& zoomInCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ZoomIn));
+ return c;
+}
+
+const Cursor& zoomOutCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ZoomOut));
+ return c;
+}
+
+const Cursor& copyCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Copy));
+ return c;
+}
+
+const Cursor& noneCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::None));
+ return c;
+}
+
+const Cursor& progressCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Progress));
+ return c;
+}
+
+const Cursor& noDropCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NoDrop));
+ return c;
+}
+
+const Cursor& notAllowedCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NotAllowed));
+ return c;
+}
+
+const Cursor& iBeamCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::IBeam));
+ return c;
+}
+
+const Cursor& waitCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Wait));
+ return c;
+}
+
+const Cursor& helpCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Help));
+ return c;
}
+
+const Cursor& eastResizeCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastResize));
+ return c;
+}
+
+const Cursor& northResizeCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthResize));
+ return c;
+}
+
+const Cursor& northEastResizeCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastResize));
+ return c;
+}
+
+const Cursor& northWestResizeCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestResize));
+ return c;
+}
+
+const Cursor& southResizeCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthResize));
+ return c;
+}
+
+const Cursor& southEastResizeCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthEastResize));
+ return c;
+}
+
+const Cursor& southWestResizeCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthWestResize));
+ return c;
+}
+
+const Cursor& westResizeCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::WestResize));
+ return c;
+}
+
+const Cursor& northSouthResizeCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthSouthResize));
+ return c;
+}
+
+const Cursor& eastWestResizeCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastWestResize));
+ return c;
+}
+
+const Cursor& northEastSouthWestResizeCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastSouthWestResize));
+ return c;
+}
+
+const Cursor& northWestSouthEastResizeCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestSouthEastResize));
+ return c;
+}
+
+const Cursor& columnResizeCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ColumnResize));
+ return c;
+}
+
+const Cursor& rowResizeCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::RowResize));
+ return c;
+}
+
+const Cursor& middlePanningCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::MiddlePanning));
+ return c;
+}
+
+const Cursor& eastPanningCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastPanning));
+ return c;
+}
+
+const Cursor& northPanningCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthPanning));
+ return c;
+}
+
+const Cursor& northEastPanningCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastPanning));
+ return c;
+}
+
+const Cursor& northWestPanningCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestPanning));
+ return c;
+}
+
+const Cursor& southPanningCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthPanning));
+ return c;
+}
+
+const Cursor& southEastPanningCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthEastPanning));
+ return c;
+}
+
+const Cursor& southWestPanningCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthWestPanning));
+ return c;
+}
+
+const Cursor& westPanningCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::WestPanning));
+ return c;
+}
+
+const Cursor& grabCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Grab));
+ return c;
+}
+
+const Cursor& grabbingCursor()
+{
+ DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Grabbing));
+ return c;
+}
+
+#endif
+
+} // namespace WebCore
diff --git a/WebCore/platform/Cursor.h b/WebCore/platform/Cursor.h
index 12b1614..98d69b9 100644
--- a/WebCore/platform/Cursor.h
+++ b/WebCore/platform/Cursor.h
@@ -26,12 +26,15 @@
#ifndef Cursor_h
#define Cursor_h
+#include "Image.h"
+#include "IntPoint.h"
+#include <wtf/RefPtr.h>
+
#if PLATFORM(WIN)
typedef struct HICON__* HICON;
typedef HICON HCURSOR;
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
#elif PLATFORM(GTK)
typedef struct _GdkCursor GdkCursor;
#elif PLATFORM(QT)
@@ -59,10 +62,13 @@ typedef struct HICON__ *HICON;
typedef HICON HCURSOR;
#endif
+#if PLATFORM(WIN) || PLATFORM(MAC)
+#define WTF_USE_LAZY_NATIVE_CURSOR 1
+#endif
+
namespace WebCore {
class Image;
- class IntPoint;
#if PLATFORM(WIN)
class SharedCursor : public RefCounted<SharedCursor> {
@@ -75,55 +81,113 @@ namespace WebCore {
HCURSOR m_nativeCursor;
};
typedef RefPtr<SharedCursor> PlatformCursor;
- typedef HCURSOR PlatformCursorHandle;
#elif PLATFORM(MAC)
typedef NSCursor* PlatformCursor;
- typedef NSCursor* PlatformCursorHandle;
#elif PLATFORM(GTK)
typedef GdkCursor* PlatformCursor;
- typedef GdkCursor* PlatformCursorHandle;
#elif PLATFORM(EFL)
typedef const char* PlatformCursor;
- typedef const char* PlatformCursorHandle;
#elif PLATFORM(QT) && !defined(QT_NO_CURSOR)
typedef QCursor PlatformCursor;
- typedef QCursor* PlatformCursorHandle;
#elif PLATFORM(WX)
typedef wxCursor* PlatformCursor;
- typedef wxCursor* PlatformCursorHandle;
#elif PLATFORM(CHROMIUM)
// See PlatformCursor.h
- typedef void* PlatformCursorHandle;
#elif PLATFORM(HAIKU)
typedef BCursor* PlatformCursor;
- typedef BCursor* PlatformCursorHandle;
#else
typedef void* PlatformCursor;
- typedef void* PlatformCursorHandle;
#endif
class Cursor {
public:
+ enum Type {
+ Pointer,
+ Cross,
+ Hand,
+ IBeam,
+ Wait,
+ Help,
+ EastResize,
+ NorthResize,
+ NorthEastResize,
+ NorthWestResize,
+ SouthResize,
+ SouthEastResize,
+ SouthWestResize,
+ WestResize,
+ NorthSouthResize,
+ EastWestResize,
+ NorthEastSouthWestResize,
+ NorthWestSouthEastResize,
+ ColumnResize,
+ RowResize,
+ MiddlePanning,
+ EastPanning,
+ NorthPanning,
+ NorthEastPanning,
+ NorthWestPanning,
+ SouthPanning,
+ SouthEastPanning,
+ SouthWestPanning,
+ WestPanning,
+ Move,
+ VerticalText,
+ Cell,
+ ContextMenu,
+ Alias,
+ Progress,
+ NoDrop,
+ Copy,
+ None,
+ NotAllowed,
+ ZoomIn,
+ ZoomOut,
+ Grab,
+ Grabbing,
+ Custom
+ };
+
+ static const Cursor& fromType(Cursor::Type);
+
Cursor()
#if !PLATFORM(QT) && !PLATFORM(EFL)
- : m_impl(0)
+ : m_platformCursor(0)
#endif
- { }
+ {
+ }
Cursor(Image*, const IntPoint& hotSpot);
Cursor(const Cursor&);
~Cursor();
Cursor& operator=(const Cursor&);
+#if USE(LAZY_NATIVE_CURSOR)
+ Cursor(Type);
+ Type type() const { return m_type; }
+ Image* image() const { return m_image.get(); }
+ const IntPoint& hotSpot() const { return m_hotSpot; }
+ PlatformCursor platformCursor() const;
+#else
Cursor(PlatformCursor);
- PlatformCursor impl() const { return m_impl; }
+ PlatformCursor impl() const { return m_platformCursor; }
+#endif
private:
- PlatformCursor m_impl;
+#if USE(LAZY_NATIVE_CURSOR)
+ void ensurePlatformCursor() const;
+
+ Type m_type;
+ RefPtr<Image> m_image;
+ IntPoint m_hotSpot;
+#endif
+
+ mutable PlatformCursor m_platformCursor;
};
IntPoint determineHotSpot(Image*, const IntPoint& specifiedHotSpot);
-
+ const char* nameForCursorType(Cursor::Type);
+
const Cursor& pointerCursor();
const Cursor& crossCursor();
const Cursor& handCursor();
diff --git a/WebCore/platform/FileChooser.h b/WebCore/platform/FileChooser.h
index e93b9ac..fa25406 100644
--- a/WebCore/platform/FileChooser.h
+++ b/WebCore/platform/FileChooser.h
@@ -44,6 +44,9 @@ public:
virtual void valueChanged() = 0;
virtual void repaint() = 0;
virtual bool allowsMultipleFiles() = 0;
+#if ENABLE(DIRECTORY_UPLOAD)
+ virtual bool allowsDirectoryUpload() = 0;
+#endif
virtual String acceptTypes() = 0;
virtual void chooseIconForFiles(FileChooser*, const Vector<String>&) = 0;
virtual ~FileChooserClient();
@@ -70,6 +73,9 @@ public:
void iconLoaded(PassRefPtr<Icon>);
bool allowsMultipleFiles() const { return m_client ? m_client->allowsMultipleFiles() : false; }
+#if ENABLE(DIRECTORY_UPLOAD)
+ bool allowsDirectoryUpload() const { return m_client ? m_client->allowsDirectoryUpload() : false; }
+#endif
// Acceptable MIME types. It's an 'accept' attribute value of the corresponding INPUT element.
String acceptTypes() const { return m_client ? m_client->acceptTypes() : String(); }
diff --git a/WebCore/platform/HostWindow.h b/WebCore/platform/HostWindow.h
index e7316a7..b0ee653 100644
--- a/WebCore/platform/HostWindow.h
+++ b/WebCore/platform/HostWindow.h
@@ -31,6 +31,8 @@
namespace WebCore {
+class Cursor;
+
class HostWindow : public Noncopyable {
public:
virtual ~HostWindow() { }
@@ -56,6 +58,9 @@ public:
// To notify WebKit of scrollbar mode changes.
virtual void scrollbarsModeDidChange() const = 0;
+
+ // Request that the cursor change.
+ virtual void setCursor(const Cursor&) = 0;
};
} // namespace WebCore
diff --git a/WebCore/platform/KURLGoogle.cpp b/WebCore/platform/KURLGoogle.cpp
index b4c84a6..ac02630 100644
--- a/WebCore/platform/KURLGoogle.cpp
+++ b/WebCore/platform/KURLGoogle.cpp
@@ -48,7 +48,6 @@
#include <wtf/StdLibExtras.h>
#include <wtf/text/CString.h>
-#include <googleurl/src/url_canon_internal.h>
#include <googleurl/src/url_util.h>
using WTF::isASCIILower;
@@ -943,55 +942,13 @@ String decodeURLEscapeSequences(const String& str, const TextEncoding& encoding)
const char* input = cstr.data();
int inputLength = cstr.length();
- url_canon::RawCanonOutputT<char> unescaped;
- for (int i = 0; i < inputLength; i++) {
- if (input[i] == '%') {
- unsigned char ch;
- if (url_canon::DecodeEscaped(input, &i, inputLength, &ch))
- unescaped.push_back(ch);
- else {
- // Invalid escape sequence, copy the percent literal.
- unescaped.push_back('%');
- }
- } else {
- // Regular non-escaped 8-bit character.
- unescaped.push_back(input[i]);
- }
- }
- // Convert that 8-bit to UTF-16. It's not clear IE does this at all to
- // JavaScript URLs, but Firefox and Safari do.
- url_canon::RawCanonOutputT<url_parse::UTF16Char> utf16;
- for (int i = 0; i < unescaped.length(); i++) {
- unsigned char uch = static_cast<unsigned char>(unescaped.at(i));
- if (uch < 0x80) {
- // Non-UTF-8, just append directly
- utf16.push_back(uch);
- } else {
- // next_ch will point to the last character of the decoded
- // character.
- int nextCharacter = i;
- unsigned codePoint;
- if (url_canon::ReadUTFChar(unescaped.data(), &nextCharacter,
- unescaped.length(), &codePoint)) {
- // Valid UTF-8 character, convert to UTF-16.
- url_canon::AppendUTF16Value(codePoint, &utf16);
- i = nextCharacter;
- } else {
- // KURL.cpp strips any sequences that are not valid UTF-8. This
- // sounds scary. Instead, we just keep those invalid code
- // points and promote to UTF-16. We copy all characters from
- // the current position to the end of the identified sqeuqnce.
- while (i < nextCharacter) {
- utf16.push_back(static_cast<unsigned char>(unescaped.at(i)));
- i++;
- }
- utf16.push_back(static_cast<unsigned char>(unescaped.at(i)));
- }
- }
- }
+ url_canon::RawCanonOutputT<url_parse::UTF16Char> unescaped;
+
+ url_util::DecodeURLEscapeSequences(input, inputLength, &unescaped);
- return String(reinterpret_cast<UChar*>(utf16.data()), utf16.length());
+ return String(reinterpret_cast<UChar*>(unescaped.data()),
+ unescaped.length());
}
bool KURL::protocolIs(const char* protocol) const
diff --git a/WebCore/platform/MIMETypeRegistry.cpp b/WebCore/platform/MIMETypeRegistry.cpp
index d6ff588..e6eb209 100644
--- a/WebCore/platform/MIMETypeRegistry.cpp
+++ b/WebCore/platform/MIMETypeRegistry.cpp
@@ -302,6 +302,7 @@ static MediaMIMETypeMap& mediaMIMETypeMap()
{ "audio/x-m4a", "m4a" },
{ "audio/x-m4b", "m4b" },
{ "audio/x-m4p", "m4p" },
+ { "audio/mp4", "m4a" },
// MP3
{ "audio/mp3", "mp3" },
diff --git a/WebCore/platform/PopupMenuClient.h b/WebCore/platform/PopupMenuClient.h
index bffde92..a1396e8 100644
--- a/WebCore/platform/PopupMenuClient.h
+++ b/WebCore/platform/PopupMenuClient.h
@@ -42,6 +42,7 @@ public:
virtual void selectionCleared() = 0;
virtual String itemText(unsigned listIndex) const = 0;
+ virtual String itemLabel(unsigned listIndex) const = 0;
virtual String itemToolTip(unsigned listIndex) const = 0;
virtual String itemAccessibilityText(unsigned listIndex) const = 0;
virtual bool itemIsEnabled(unsigned listIndex) const = 0;
diff --git a/WebCore/platform/Widget.h b/WebCore/platform/Widget.h
index 45da67a..6303c6a 100644
--- a/WebCore/platform/Widget.h
+++ b/WebCore/platform/Widget.h
@@ -187,8 +187,8 @@ public:
virtual bool isFrameView() const { return false; }
virtual bool isPluginView() const { return false; }
- // FIXME: The Mac plug-in code should inherit from PluginView. When this happens PluginWidget and PluginView can become one class.
- virtual bool isPluginWidget() const { return false; }
+ // FIXME: The Mac plug-in code should inherit from PluginView. When this happens PluginViewBase and PluginView can become one class.
+ virtual bool isPluginViewBase() const { return false; }
virtual bool isScrollbar() const { return false; }
void removeFromParent();
diff --git a/WebCore/platform/android/TemporaryLinkStubs.cpp b/WebCore/platform/android/TemporaryLinkStubs.cpp
index 302a1ed..911d849 100644
--- a/WebCore/platform/android/TemporaryLinkStubs.cpp
+++ b/WebCore/platform/android/TemporaryLinkStubs.cpp
@@ -65,7 +65,6 @@
#include "PageCache.h"
#include "Pasteboard.h"
#include "Path.h"
-#include "PluginWidget.h"
#include "ResourceError.h"
#include "ResourceHandle.h"
#include "ResourceLoader.h"
@@ -103,10 +102,6 @@ String WebCore::defaultLanguage()
namespace WebCore {
-// Needed to link with PluginWidget as a parent class of PluginToggleWidget. Mac
-// defines this in plugins/mac/PluginWidgetMac.mm
-void PluginWidget::invalidateRect(const IntRect&) { }
-
// This function tells the bridge that a resource was loaded from the cache and thus
// the app may update progress with the amount of data loaded.
void CheckCacheObjectStatus(DocLoader*, CachedResource*)
@@ -478,12 +473,6 @@ void AXObjectCache::remove(RenderObject*)
notImplemented();
}
-const AtomicString& AccessibilityObject::getAttribute(Node*, const QualifiedName&)
-{
- static const AtomicString emptyString;
- return emptyString;
-}
-
#if USE(JSC)
using namespace JSC;
diff --git a/WebCore/platform/brew/PopupMenuBrew.cpp b/WebCore/platform/brew/PopupMenuBrew.cpp
index 89f3fa1..eb03c66 100644
--- a/WebCore/platform/brew/PopupMenuBrew.cpp
+++ b/WebCore/platform/brew/PopupMenuBrew.cpp
@@ -40,6 +40,9 @@ PopupMenu::PopupMenu(PopupMenuClient* menuList)
PopupMenu::~PopupMenu()
{
+ // Tell client to destroy data related to this popup since this object is
+ // going away.
+ hide();
}
void PopupMenu::show(const IntRect& rect, FrameView* view, int index)
diff --git a/WebCore/platform/chromium/ChromiumBridge.h b/WebCore/platform/chromium/ChromiumBridge.h
index 3284aae..2d9695e 100644
--- a/WebCore/platform/chromium/ChromiumBridge.h
+++ b/WebCore/platform/chromium/ChromiumBridge.h
@@ -241,6 +241,8 @@ namespace WebCore {
GraphicsContext*, int part, int state, int classicState, const IntRect&);
static void paintScrollbarTrack(
GraphicsContext*, int part, int state, int classicState, const IntRect&, const IntRect& alignRect);
+ static void paintSpinButton(
+ GraphicsContext*, int part, int state, int classicState, const IntRect&);
static void paintTextField(
GraphicsContext*, int part, int state, int classicState, const IntRect&, const Color&, bool fillContentArea, bool drawEdges);
static void paintTrackbar(
diff --git a/WebCore/platform/chromium/CursorChromium.cpp b/WebCore/platform/chromium/CursorChromium.cpp
index 16fa634..0119f07 100644
--- a/WebCore/platform/chromium/CursorChromium.cpp
+++ b/WebCore/platform/chromium/CursorChromium.cpp
@@ -34,12 +34,12 @@
namespace WebCore {
Cursor::Cursor(const Cursor& other)
- : m_impl(other.m_impl)
+ : m_platformCursor(other.m_platformCursor)
{
}
Cursor::Cursor(Image* image, const IntPoint& hotSpot)
- : m_impl(image, hotSpot)
+ : m_platformCursor(image, hotSpot)
{
}
@@ -49,12 +49,12 @@ Cursor::~Cursor()
Cursor& Cursor::operator=(const Cursor& other)
{
- m_impl = other.m_impl;
+ m_platformCursor = other.m_platformCursor;
return *this;
}
Cursor::Cursor(PlatformCursor c)
- : m_impl(c)
+ : m_platformCursor(c)
{
}
diff --git a/WebCore/platform/chromium/GLES2Context.h b/WebCore/platform/chromium/GLES2Context.h
index b72329a..d37885a 100644
--- a/WebCore/platform/chromium/GLES2Context.h
+++ b/WebCore/platform/chromium/GLES2Context.h
@@ -43,14 +43,8 @@ class Page;
class GLES2Context : public Noncopyable {
public:
- // Creates a GL ES context that draws directly to the window associated with
- // the Page.
- static PassOwnPtr<GLES2Context> createOnscreen(Page*);
-
- // Creates a GL ES context that renders offscreen, optionally as a child
- // of the given parent if specified.
- static PassOwnPtr<GLES2Context> createOffscreen(GLES2Context* parent);
-
+ // Used by the implementation only
+ static PassOwnPtr<GLES2Context> create(PassOwnPtr<GLES2ContextInternal>);
~GLES2Context();
bool makeCurrent();
@@ -65,6 +59,8 @@ public:
unsigned getOffscreenContentParentTextureId();
private:
+ GLES2Context();
+
friend class GLES2ContextInternal;
OwnPtr<GLES2ContextInternal> m_internal;
};
diff --git a/WebCore/platform/chromium/PlatformThemeChromiumGtk.cpp b/WebCore/platform/chromium/PlatformThemeChromiumGtk.cpp
new file mode 100644
index 0000000..1f74840
--- /dev/null
+++ b/WebCore/platform/chromium/PlatformThemeChromiumGtk.cpp
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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.
+ */
+
+#include "config.h"
+#include "PlatformThemeChromiumGtk.h"
+
+namespace WebCore {
+
+unsigned PlatformThemeChromiumGtk::s_thumbInactiveColor = 0xeaeaea;
+unsigned PlatformThemeChromiumGtk::s_thumbActiveColor = 0xf4f4f4;
+unsigned PlatformThemeChromiumGtk::s_trackColor = 0xd3d3d3;
+
+void PlatformThemeChromiumGtk::setScrollbarColors(
+ SkColor inactiveColor, SkColor activeColor, SkColor trackColor)
+{
+ s_thumbInactiveColor = inactiveColor;
+ s_thumbActiveColor = activeColor;
+ s_trackColor = trackColor;
+}
+
+static SkScalar clamp(SkScalar value, SkScalar min, SkScalar max)
+{
+ return std::min(std::max(value, min), max);
+}
+
+SkColor PlatformThemeChromiumGtk::saturateAndBrighten(const SkScalar hsv[3], SkScalar saturateAmount, SkScalar brightenAmount)
+{
+ SkScalar color[3];
+ color[0] = hsv[0];
+ color[1] = clamp(hsv[1] + saturateAmount, 0.0, 1.0);
+ color[2] = clamp(hsv[2] + brightenAmount, 0.0, 1.0);
+ return SkHSVToColor(color);
+}
+
+SkColor PlatformThemeChromiumGtk::outlineColor(const SkScalar hsv1[3], const SkScalar hsv2[3])
+{
+ // GTK Theme engines have way too much control over the layout of
+ // the scrollbar. We might be able to more closely approximate its
+ // look-and-feel, if we sent whole images instead of just colors
+ // from the browser to the renderer. But even then, some themes
+ // would just break.
+ //
+ // So, instead, we don't even try to 100% replicate the look of
+ // the native scrollbar. We render our own version, but we make
+ // sure to pick colors that blend in nicely with the system GTK
+ // theme. In most cases, we can just sample a couple of pixels
+ // from the system scrollbar and use those colors to draw our
+ // scrollbar.
+ //
+ // This works fine for the track color and the overall thumb
+ // color. But it fails spectacularly for the outline color used
+ // around the thumb piece. Not all themes have a clearly defined
+ // outline. For some of them it is partially transparent, and for
+ // others the thickness is very unpredictable.
+ //
+ // So, instead of trying to approximate the system theme, we
+ // instead try to compute a reasonable looking choice based on the
+ // known color of the track and the thumb piece. This is difficult
+ // when trying to deal both with high- and low-contrast themes,
+ // and both with positive and inverted themes.
+ //
+ // The following code has been tested to look OK with all of the
+ // default GTK themes.
+ SkScalar minDiff = clamp((hsv1[1] + hsv2[1]) * 1.2, 0.28, 0.5);
+ SkScalar diff = clamp(fabs(hsv1[2] - hsv2[2]) / 2, minDiff, 0.5);
+
+ if (hsv1[2] + hsv2[2] > 1.0)
+ diff = -diff;
+
+ return saturateAndBrighten(hsv2, -0.2, diff);
+}
+
+void PlatformThemeChromiumGtk::paintArrowButton(GraphicsContext* gc, const IntRect& rect, ArrowDirection direction, ControlStates states)
+{
+ SkCanvas* const canvas = gc->platformContext()->canvas();
+ int widthMiddle, lengthMiddle;
+ SkPaint paint;
+ if (direction == North || direction == South) {
+ widthMiddle = rect.width() / 2 + 1;
+ lengthMiddle = rect.height() / 2 + 1;
+ } else {
+ lengthMiddle = rect.width() / 2 + 1;
+ widthMiddle = rect.height() / 2 + 1;
+ }
+
+ // Calculate button color.
+ SkScalar trackHSV[3];
+ SkColorToHSV(trackColor(), trackHSV);
+ SkColor buttonColor = saturateAndBrighten(trackHSV, 0, 0.2);
+ SkColor backgroundColor = buttonColor;
+ if (states & PressedState) {
+ SkScalar buttonHSV[3];
+ SkColorToHSV(buttonColor, buttonHSV);
+ buttonColor = saturateAndBrighten(buttonHSV, 0, -0.1);
+ } else if (states & HoverState) {
+ SkScalar buttonHSV[3];
+ SkColorToHSV(buttonColor, buttonHSV);
+ buttonColor = saturateAndBrighten(buttonHSV, 0, 0.05);
+ }
+
+ SkIRect skrect;
+ skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
+ // Paint the background (the area visible behind the rounded corners).
+ paint.setColor(backgroundColor);
+ canvas->drawIRect(skrect, paint);
+
+ // Paint the button's outline and fill the middle
+ SkPath outline;
+ switch (direction) {
+ case North:
+ outline.moveTo(rect.x() + 0.5, rect.y() + rect.height() + 0.5);
+ outline.rLineTo(0, -(rect.height() - 2));
+ outline.rLineTo(2, -2);
+ outline.rLineTo(rect.width() - 5, 0);
+ outline.rLineTo(2, 2);
+ outline.rLineTo(0, rect.height() - 2);
+ break;
+ case South:
+ outline.moveTo(rect.x() + 0.5, rect.y() - 0.5);
+ outline.rLineTo(0, rect.height() - 2);
+ outline.rLineTo(2, 2);
+ outline.rLineTo(rect.width() - 5, 0);
+ outline.rLineTo(2, -2);
+ outline.rLineTo(0, -(rect.height() - 2));
+ break;
+ case East:
+ outline.moveTo(rect.x() - 0.5, rect.y() + 0.5);
+ outline.rLineTo(rect.width() - 2, 0);
+ outline.rLineTo(2, 2);
+ outline.rLineTo(0, rect.height() - 5);
+ outline.rLineTo(-2, 2);
+ outline.rLineTo(-(rect.width() - 2), 0);
+ break;
+ case West:
+ outline.moveTo(rect.x() + rect.width() + 0.5, rect.y() + 0.5);
+ outline.rLineTo(-(rect.width() - 2), 0);
+ outline.rLineTo(-2, 2);
+ outline.rLineTo(0, rect.height() - 5);
+ outline.rLineTo(2, 2);
+ outline.rLineTo(rect.width() - 2, 0);
+ break;
+ }
+ outline.close();
+
+ paint.setStyle(SkPaint::kFill_Style);
+ paint.setColor(buttonColor);
+ canvas->drawPath(outline, paint);
+
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kStroke_Style);
+ SkScalar thumbHSV[3];
+ SkColorToHSV(thumbInactiveColor(), thumbHSV);
+ paint.setColor(outlineColor(trackHSV, thumbHSV));
+ canvas->drawPath(outline, paint);
+
+ // If the button is disabled, the arrow is drawn with the outline color.
+ if (states & EnabledState)
+ paint.setColor(SK_ColorBLACK);
+
+ paint.setAntiAlias(false);
+ paint.setStyle(SkPaint::kFill_Style);
+
+ SkPath path;
+ // The constants in this block of code are hand-tailored to produce good
+ // looking arrows without anti-aliasing.
+ switch (direction) {
+ case North:
+ path.moveTo(rect.x() + widthMiddle - 4, rect.y() + lengthMiddle + 2);
+ path.rLineTo(7, 0);
+ path.rLineTo(-4, -4);
+ break;
+ case South:
+ path.moveTo(rect.x() + widthMiddle - 4, rect.y() + lengthMiddle - 3);
+ path.rLineTo(7, 0);
+ path.rLineTo(-4, 4);
+ break;
+ case East:
+ path.moveTo(rect.x() + lengthMiddle - 3, rect.y() + widthMiddle - 4);
+ path.rLineTo(0, 7);
+ path.rLineTo(4, -4);
+ break;
+ case West:
+ path.moveTo(rect.x() + lengthMiddle + 1, rect.y() + widthMiddle - 5);
+ path.rLineTo(0, 9);
+ path.rLineTo(-4, -4);
+ break;
+ }
+ path.close();
+
+ canvas->drawPath(path, paint);
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/platform/chromium/PlatformThemeChromiumGtk.h b/WebCore/platform/chromium/PlatformThemeChromiumGtk.h
new file mode 100644
index 0000000..bdc2683
--- /dev/null
+++ b/WebCore/platform/chromium/PlatformThemeChromiumGtk.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 PlatformThemeChromiumGtk_h
+#define PlatformThemeChromiumGtk_h
+
+#include "PlatformContextSkia.h"
+#include "SkColor.h"
+#include "SkScalar.h"
+#include "ThemeTypes.h"
+
+namespace WebCore {
+
+class PlatformThemeChromiumGtk {
+public:
+ enum ArrowDirection {
+ North,
+ East,
+ South,
+ West,
+ };
+
+ static void setScrollbarColors(unsigned inactiveColor,
+ unsigned activeColor,
+ unsigned trackColor);
+ static unsigned thumbInactiveColor() { return s_thumbInactiveColor; }
+ static unsigned thumbActiveColor() { return s_thumbActiveColor; }
+ static unsigned trackColor() { return s_trackColor; }
+
+ static SkColor saturateAndBrighten(const SkScalar hsv[3], SkScalar saturateAmount, SkScalar brightenAmount);
+ static SkColor outlineColor(const SkScalar hsv1[3], const SkScalar hsv2[3]);
+ static void paintArrowButton(GraphicsContext*, const IntRect&, ArrowDirection, ControlStates);
+
+private:
+ PlatformThemeChromiumGtk() {}
+
+ static unsigned s_thumbInactiveColor;
+ static unsigned s_thumbActiveColor;
+ static unsigned s_trackColor;
+};
+
+} // namespace WebCore
+
+#endif // PlatformThemeChromiumGtk_h
diff --git a/WebCore/platform/chromium/PopupMenuChromium.cpp b/WebCore/platform/chromium/PopupMenuChromium.cpp
index 7e3a2a0..4701a75 100644
--- a/WebCore/platform/chromium/PopupMenuChromium.cpp
+++ b/WebCore/platform/chromium/PopupMenuChromium.cpp
@@ -70,6 +70,7 @@ typedef unsigned long long TimeStamp;
static const int kMaxVisibleRows = 20;
static const int kMaxHeight = 500;
static const int kBorderSize = 1;
+static const int kTextToLabelPadding = 10;
static const TimeStamp kTypeAheadTimeoutMs = 1000;
// The settings used for the drop down menu.
@@ -751,8 +752,11 @@ bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event)
if (event.windowsVirtualKeyCode() == VKEY_TAB) {
// TAB is a special case as it should select the current item if any and
// advance focus.
- if (m_selectedIndex >= 0)
- m_popupClient->setTextFromItem(m_selectedIndex);
+ if (m_selectedIndex >= 0) {
+ acceptIndex(m_selectedIndex); // May delete us.
+ // Return false so the TAB key event is propagated to the page.
+ return false;
+ }
// Call abandon() so we honor m_acceptedIndexOnAbandon if set.
abandon();
// Return false so the TAB key event is propagated to the page.
@@ -873,13 +877,17 @@ void PopupListBox::paintRow(GraphicsContext* gc, const IntRect& rect, int rowInd
PopupMenuStyle style = m_popupClient->itemStyle(rowIndex);
// Paint background
- Color backColor, textColor;
+ Color backColor, textColor, labelColor;
if (rowIndex == m_selectedIndex) {
backColor = RenderTheme::defaultTheme()->activeListBoxSelectionBackgroundColor();
textColor = RenderTheme::defaultTheme()->activeListBoxSelectionForegroundColor();
+ labelColor = textColor;
} else {
backColor = style.backgroundColor();
textColor = style.foregroundColor();
+ // FIXME: for now the label color is hard-coded. It should be added to
+ // the PopupMenuStyle.
+ labelColor = Color(115, 115, 115);
}
// If we have a transparent background, make sure it has a color to blend
@@ -917,10 +925,23 @@ void PopupListBox::paintRow(GraphicsContext* gc, const IntRect& rect, int rowInd
}
// Prepare text to be drawn.
String itemText = m_popupClient->itemText(rowIndex);
- if (m_settings.restrictWidthOfListBox) // truncate string to fit in.
- itemText = StringTruncator::rightTruncate(itemText, maxWidth, itemFont);
- unsigned length = itemText.length();
- const UChar* str = itemText.characters();
+ String itemLabel = m_popupClient->itemLabel(rowIndex);
+ if (m_settings.restrictWidthOfListBox) { // Truncate strings to fit in.
+ // FIXME: We should leftTruncate for the rtl case.
+ // StringTruncator::leftTruncate would have to be implemented.
+ String str = StringTruncator::rightTruncate(itemText, maxWidth, itemFont);
+ if (str != itemText) {
+ itemText = str;
+ // Don't display the label, we already don't have enough room for the
+ // item text.
+ itemLabel = "";
+ } else if (!itemLabel.isEmpty()) {
+ int availableWidth = maxWidth - kTextToLabelPadding -
+ StringTruncator::width(itemText, itemFont);
+ itemLabel = StringTruncator::rightTruncate(itemLabel, availableWidth, itemFont);
+ }
+ }
+
// Prepare the directionality to draw text.
bool rtl = false;
if (m_settings.itemTextDirectionalityHint == PopupContainerSettings::DOMElementDirection)
@@ -928,14 +949,31 @@ void PopupListBox::paintRow(GraphicsContext* gc, const IntRect& rect, int rowInd
else if (m_settings.itemTextDirectionalityHint ==
PopupContainerSettings::FirstStrongDirectionalCharacterDirection)
rtl = itemText.defaultWritingDirection() == WTF::Unicode::RightToLeft;
- TextRun textRun(str, length, false, 0, 0, rtl);
+ TextRun textRun(itemText.characters(), itemText.length(), false, 0, 0, rtl);
// If the text is right-to-left, make it right-aligned by adjusting its
// beginning position.
if (rightAligned)
textX += maxWidth - itemFont.width(textRun);
+
// Draw the item text.
int textY = rowRect.y() + itemFont.ascent() + (rowRect.height() - itemFont.height()) / 2;
gc->drawBidiText(itemFont, textRun, IntPoint(textX, textY));
+
+ // Draw the the label if applicable.
+ if (itemLabel.isEmpty())
+ return;
+ TextRun labelTextRun(itemLabel.characters(), itemLabel.length(), false, 0, 0, rtl);
+ if (rightAligned)
+ textX = max(0, m_popupClient->clientPaddingLeft() - m_popupClient->clientInsetLeft());
+ else {
+ // We are using the left padding as the right padding includes room for the scroll-bar which
+ // does not show in this case.
+ int rightPadding = max(0, m_popupClient->clientPaddingLeft() - m_popupClient->clientInsetLeft());
+ textX = rowRect.width() - rightPadding - itemFont.width(labelTextRun);
+ }
+
+ gc->setFillColor(labelColor, DeviceColorSpace);
+ gc->drawBidiText(itemFont, labelTextRun, IntPoint(textX, textY));
}
Font PopupListBox::getRowFont(int rowIndex)
diff --git a/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp b/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
index a9cff9f..19b4a54 100644
--- a/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
+++ b/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
@@ -33,8 +33,7 @@
#include "PlatformContextSkia.h"
#include "PlatformMouseEvent.h"
-#include "RenderTheme.h"
-#include "RenderThemeChromiumLinux.h"
+#include "PlatformThemeChromiumGtk.h"
#include "Scrollbar.h"
#include "TransformationMatrix.h"
@@ -78,60 +77,6 @@ static void drawBox(SkCanvas* canvas, const IntRect& rect, const SkPaint& paint)
drawVertLine(canvas, rect.x(), rect.y(), bottom, paint);
}
-static SkScalar clamp(SkScalar value, SkScalar min, SkScalar max)
-{
- return std::min(std::max(value, min), max);
-}
-
-static SkColor saturateAndBrighten(SkScalar* hsv,
- SkScalar saturateAmount,
- SkScalar brightenAmount)
-{
- SkScalar color[3];
- color[0] = hsv[0];
- color[1] = clamp(hsv[1] + saturateAmount, 0.0, 1.0);
- color[2] = clamp(hsv[2] + brightenAmount, 0.0, 1.0);
- return SkHSVToColor(color);
-}
-
-static SkColor outlineColor(SkScalar* hsv1, SkScalar* hsv2)
-{
- // GTK Theme engines have way too much control over the layout of
- // the scrollbar. We might be able to more closely approximate its
- // look-and-feel, if we sent whole images instead of just colors
- // from the browser to the renderer. But even then, some themes
- // would just break.
- //
- // So, instead, we don't even try to 100% replicate the look of
- // the native scrollbar. We render our own version, but we make
- // sure to pick colors that blend in nicely with the system GTK
- // theme. In most cases, we can just sample a couple of pixels
- // from the system scrollbar and use those colors to draw our
- // scrollbar.
- //
- // This works fine for the track color and the overall thumb
- // color. But it fails spectacularly for the outline color used
- // around the thumb piece. Not all themes have a clearly defined
- // outline. For some of them it is partially transparent, and for
- // others the thickness is very unpredictable.
- //
- // So, instead of trying to approximate the system theme, we
- // instead try to compute a reasonable looking choice based on the
- // known color of the track and the thumb piece. This is difficult
- // when trying to deal both with high- and low-contrast themes,
- // and both with positive and inverted themes.
- //
- // The following code has been tested to look OK with all of the
- // default GTK themes.
- SkScalar minDiff = clamp((hsv1[1] + hsv2[1]) * 1.2, 0.28, 0.5);
- SkScalar diff = clamp(fabs(hsv1[2] - hsv2[2]) / 2, minDiff, 0.5);
-
- if (hsv1[2] + hsv2[2] > 1.0)
- diff = -diff;
-
- return saturateAndBrighten(hsv2, -0.2, diff);
-}
-
void ScrollbarThemeChromiumLinux::paintTrackPiece(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart partType)
{
SkCanvas* const canvas = gc->platformContext()->canvas();
@@ -140,154 +85,47 @@ void ScrollbarThemeChromiumLinux::paintTrackPiece(GraphicsContext* gc, Scrollbar
skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
SkScalar trackHSV[3];
- SkColorToHSV(RenderThemeChromiumLinux::trackColor(), trackHSV);
- paint.setColor(saturateAndBrighten(trackHSV, 0, 0));
+ SkColorToHSV(PlatformThemeChromiumGtk::trackColor(), trackHSV);
+ paint.setColor(PlatformThemeChromiumGtk::saturateAndBrighten(trackHSV, 0, 0));
canvas->drawIRect(skrect, paint);
SkScalar thumbHSV[3];
- SkColorToHSV(RenderThemeChromiumLinux::thumbInactiveColor(),
+ SkColorToHSV(PlatformThemeChromiumGtk::thumbInactiveColor(),
thumbHSV);
- paint.setColor(outlineColor(trackHSV, thumbHSV));
+ paint.setColor(PlatformThemeChromiumGtk::outlineColor(trackHSV, thumbHSV));
drawBox(canvas, rect, paint);
}
void ScrollbarThemeChromiumLinux::paintButton(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part)
{
- SkCanvas* const canvas = gc->platformContext()->canvas();
- static const int widthMiddle = scrollbarThicknessValue / 2 + 1;
- static const int lengthMiddle = buttonLength / 2 + 1;
- SkPaint paint;
- enum {
- North,
- East,
- South,
- West,
- } direction;
-
+ PlatformThemeChromiumGtk::ArrowDirection direction;
if (scrollbar->orientation() == HorizontalScrollbar) {
if (part == BackButtonStartPart)
- direction = West;
+ direction = PlatformThemeChromiumGtk::West;
else
- direction = East;
+ direction = PlatformThemeChromiumGtk::East;
} else {
if (part == BackButtonStartPart)
- direction = North;
+ direction = PlatformThemeChromiumGtk::North;
else
- direction = South;
+ direction = PlatformThemeChromiumGtk::South;
}
+ ControlStates states = 0;
// Determine if the button can be pressed.
- bool enabled = false;
- if (((direction == West || direction == North) && scrollbar->currentPos())
- || (direction == East || direction == South) && scrollbar->currentPos() != scrollbar->maximum())
- enabled = true;
-
- // Calculate button color.
- SkScalar trackHSV[3];
- SkColorToHSV(RenderThemeChromiumLinux::trackColor(), trackHSV);
- SkColor buttonColor = saturateAndBrighten(trackHSV, 0, 0.2);
- SkColor backgroundColor = buttonColor;
- if (part == scrollbar->pressedPart()) {
- SkScalar buttonHSV[3];
- SkColorToHSV(buttonColor, buttonHSV);
- buttonColor = saturateAndBrighten(buttonHSV, 0, -0.1);
- } else if (part == scrollbar->hoveredPart() && enabled) {
- SkScalar buttonHSV[3];
- SkColorToHSV(buttonColor, buttonHSV);
- buttonColor = saturateAndBrighten(buttonHSV, 0, 0.05);
- }
-
- SkIRect skrect;
- skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
- // Paint the background (the area visible behind the rounded corners).
- paint.setColor(backgroundColor);
- canvas->drawIRect(skrect, paint);
-
- // Paint the button's outline and fill the middle
- SkPath outline;
- switch (direction) {
- case North:
- outline.moveTo(rect.x() + 0.5, rect.y() + rect.height() + 0.5);
- outline.rLineTo(0, -(rect.height() - 2));
- outline.rLineTo(2, -2);
- outline.rLineTo(rect.width() - 5, 0);
- outline.rLineTo(2, 2);
- outline.rLineTo(0, rect.height() - 2);
- break;
- case South:
- outline.moveTo(rect.x() + 0.5, rect.y() - 0.5);
- outline.rLineTo(0, rect.height() - 2);
- outline.rLineTo(2, 2);
- outline.rLineTo(rect.width() - 5, 0);
- outline.rLineTo(2, -2);
- outline.rLineTo(0, -(rect.height() - 2));
- break;
- case East:
- outline.moveTo(rect.x() - 0.5, rect.y() + 0.5);
- outline.rLineTo(rect.width() - 2, 0);
- outline.rLineTo(2, 2);
- outline.rLineTo(0, rect.height() - 5);
- outline.rLineTo(-2, 2);
- outline.rLineTo(-(rect.width() - 2), 0);
- break;
- case West:
- outline.moveTo(rect.x() + rect.width() + 0.5, rect.y() + 0.5);
- outline.rLineTo(-(rect.width() - 2), 0);
- outline.rLineTo(-2, 2);
- outline.rLineTo(0, rect.height() - 5);
- outline.rLineTo(2, 2);
- outline.rLineTo(rect.width() - 2, 0);
- break;
- }
- outline.close();
-
- paint.setStyle(SkPaint::kFill_Style);
- paint.setColor(buttonColor);
- canvas->drawPath(outline, paint);
-
- paint.setAntiAlias(true);
- paint.setStyle(SkPaint::kStroke_Style);
- SkScalar thumbHSV[3];
- SkColorToHSV(RenderThemeChromiumLinux::thumbInactiveColor(), thumbHSV);
- paint.setColor(outlineColor(trackHSV, thumbHSV));
- canvas->drawPath(outline, paint);
-
- // If the button is disabled, the arrow is drawn with the outline color.
- if (enabled)
- paint.setColor(SK_ColorBLACK);
-
- paint.setAntiAlias(false);
- paint.setStyle(SkPaint::kFill_Style);
-
- SkPath path;
- // The constants in this block of code are hand-tailored to produce good
- // looking arrows without anti-aliasing.
- switch (direction) {
- case North:
- path.moveTo(rect.x() + widthMiddle - 4, rect.y() + lengthMiddle + 2);
- path.rLineTo(7, 0);
- path.rLineTo(-4, -4);
- break;
- case South:
- path.moveTo(rect.x() + widthMiddle - 4, rect.y() + lengthMiddle - 3);
- path.rLineTo(7, 0);
- path.rLineTo(-4, 4);
- break;
- case East:
- path.moveTo(rect.x() + lengthMiddle - 3, rect.y() + widthMiddle - 4);
- path.rLineTo(0, 7);
- path.rLineTo(4, -4);
- break;
- case West:
- path.moveTo(rect.x() + lengthMiddle + 1, rect.y() + widthMiddle - 5);
- path.rLineTo(0, 9);
- path.rLineTo(-4, -4);
- break;
+ if (((direction == PlatformThemeChromiumGtk::West || direction == PlatformThemeChromiumGtk::North) && scrollbar->currentPos())
+ || (direction == PlatformThemeChromiumGtk::East || direction == PlatformThemeChromiumGtk::South) && scrollbar->currentPos() != scrollbar->maximum())
+ states |= EnabledState;
+
+ if (states & EnabledState) {
+ if (part == scrollbar->pressedPart())
+ states |= PressedState;
+ else if (part == scrollbar->hoveredPart())
+ states |= HoverState;
}
- path.close();
- canvas->drawPath(path, paint);
+ PlatformThemeChromiumGtk::paintArrowButton(gc, rect, direction, states);
}
void ScrollbarThemeChromiumLinux::paintThumb(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect)
@@ -300,12 +138,12 @@ void ScrollbarThemeChromiumLinux::paintThumb(GraphicsContext* gc, Scrollbar* scr
SkScalar thumb[3];
SkColorToHSV(hovered
- ? RenderThemeChromiumLinux::thumbActiveColor()
- : RenderThemeChromiumLinux::thumbInactiveColor(),
+ ? PlatformThemeChromiumGtk::thumbActiveColor()
+ : PlatformThemeChromiumGtk::thumbInactiveColor(),
thumb);
SkPaint paint;
- paint.setColor(saturateAndBrighten(thumb, 0, 0.02));
+ paint.setColor(PlatformThemeChromiumGtk::saturateAndBrighten(thumb, 0, 0.02));
SkIRect skrect;
if (vertical)
@@ -315,7 +153,7 @@ void ScrollbarThemeChromiumLinux::paintThumb(GraphicsContext* gc, Scrollbar* scr
canvas->drawIRect(skrect, paint);
- paint.setColor(saturateAndBrighten(thumb, 0, -0.02));
+ paint.setColor(PlatformThemeChromiumGtk::saturateAndBrighten(thumb, 0, -0.02));
if (vertical)
skrect.set(midx + 1, rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
@@ -325,8 +163,8 @@ void ScrollbarThemeChromiumLinux::paintThumb(GraphicsContext* gc, Scrollbar* scr
canvas->drawIRect(skrect, paint);
SkScalar track[3];
- SkColorToHSV(RenderThemeChromiumLinux::trackColor(), track);
- paint.setColor(outlineColor(track, thumb));
+ SkColorToHSV(PlatformThemeChromiumGtk::trackColor(), track);
+ paint.setColor(PlatformThemeChromiumGtk::outlineColor(track, thumb));
drawBox(canvas, rect, paint);
if (rect.height() > 10 && rect.width() > 10) {
diff --git a/WebCore/platform/chromium/ThemeChromiumMac.mm b/WebCore/platform/chromium/ThemeChromiumMac.mm
index 5769e38..68fd7b7 100644
--- a/WebCore/platform/chromium/ThemeChromiumMac.mm
+++ b/WebCore/platform/chromium/ThemeChromiumMac.mm
@@ -32,6 +32,7 @@
#import "LocalCurrentGraphicsContext.h"
#import "ScrollView.h"
#import "WebCoreSystemInterface.h"
+#import <Carbon/Carbon.h>
#include <wtf/StdLibExtras.h>
#import <objc/runtime.h>
@@ -210,9 +211,9 @@ static NSControlSize controlSizeForFont(const Font& font)
return NSMiniControlSize;
}
-static LengthSize sizeFromFont(const Font& font, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes)
+static LengthSize sizeFromNSControlSize(NSControlSize nsControlSize, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes)
{
- IntSize controlSize = sizes[controlSizeForFont(font)];
+ IntSize controlSize = sizes[nsControlSize];
if (zoomFactor != 1.0f)
controlSize = IntSize(controlSize.width() * zoomFactor, controlSize.height() * zoomFactor);
LengthSize result = zoomedSize;
@@ -223,19 +224,27 @@ static LengthSize sizeFromFont(const Font& font, const LengthSize& zoomedSize, f
return result;
}
-static void setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& minZoomedSize, float zoomFactor)
+static LengthSize sizeFromFont(const Font& font, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes)
+{
+ return sizeFromNSControlSize(controlSizeForFont(font), zoomedSize, zoomFactor, sizes);
+}
+
+static ControlSize controlSizeFromPixelSize(const IntSize* sizes, const IntSize& minZoomedSize, float zoomFactor)
{
- NSControlSize size;
if (minZoomedSize.width() >= static_cast<int>(sizes[NSRegularControlSize].width() * zoomFactor) &&
minZoomedSize.height() >= static_cast<int>(sizes[NSRegularControlSize].height() * zoomFactor))
- size = NSRegularControlSize;
- else if (minZoomedSize.width() >= static_cast<int>(sizes[NSSmallControlSize].width() * zoomFactor) &&
- minZoomedSize.height() >= static_cast<int>(sizes[NSSmallControlSize].height() * zoomFactor))
- size = NSSmallControlSize;
- else
- size = NSMiniControlSize;
+ return NSRegularControlSize;
+ if (minZoomedSize.width() >= static_cast<int>(sizes[NSSmallControlSize].width() * zoomFactor) &&
+ minZoomedSize.height() >= static_cast<int>(sizes[NSSmallControlSize].height() * zoomFactor))
+ return NSSmallControlSize;
+ return NSMiniControlSize;
+}
+
+static void setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& minZoomedSize, float zoomFactor)
+{
+ ControlSize size = controlSizeFromPixelSize(sizes, minZoomedSize, zoomFactor);
if (size != [cell controlSize]) // Only update if we have to, since AppKit does work even if the size is the same.
- [cell setControlSize:size];
+ [cell setControlSize:(NSControlSize)size];
}
static void updateStates(NSCell* cell, ControlStates states)
@@ -277,6 +286,22 @@ static void updateStates(NSCell* cell, ControlStates states)
[cell setControlTint:tint];
}
+static ThemeDrawState convertControlStatesToThemeDrawState(ThemeButtonKind kind, ControlStates states)
+{
+ if (states & ReadOnlyState)
+ return kThemeStateUnavailableInactive;
+ if (!(states & EnabledState))
+ return kThemeStateUnavailableInactive;
+
+ // Do not process PressedState if !EnabledState or ReadOnlyState.
+ if (states & PressedState) {
+ if (kind == kThemeIncDecButton || kind == kThemeIncDecButtonSmall || kind == kThemeIncDecButtonMini)
+ return states & SpinUpState ? kThemeStatePressedUp : kThemeStatePressedDown;
+ return kThemeStatePressed;
+ }
+ return kThemeStateActive;
+}
+
static IntRect inflateRect(const IntRect& zoomedRect, const IntSize& zoomedSize, const int* margins, float zoomFactor)
{
// Only do the inflation if the available width/height are too small. Otherwise try to
@@ -571,6 +596,64 @@ static void paintButton(ControlPart part, ControlStates states, GraphicsContext*
END_BLOCK_OBJC_EXCEPTIONS
}
+// Stepper
+
+static const IntSize* stepperSizes()
+{
+ static const IntSize sizes[3] = { IntSize(19, 27), IntSize(15, 22), IntSize(13, 15) };
+ return sizes;
+}
+
+// We don't use controlSizeForFont() for steppers because the stepper height
+// should be equal to or less than the corresponding text field height,
+static NSControlSize stepperControlSizeForFont(const Font& font)
+{
+ int fontSize = font.pixelSize();
+ if (fontSize >= 18)
+ return NSRegularControlSize;
+ if (fontSize >= 13)
+ return NSSmallControlSize;
+ return NSMiniControlSize;
+}
+
+static void paintStepper(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView*)
+{
+ // We don't use NSStepperCell because there are no ways to draw an
+ // NSStepperCell with the up button highlighted.
+
+ HIThemeButtonDrawInfo drawInfo;
+ drawInfo.version = 0;
+ drawInfo.state = convertControlStatesToThemeDrawState(kThemeIncDecButton, states);
+ drawInfo.adornment = kThemeAdornmentDefault;
+ ControlSize controlSize = controlSizeFromPixelSize(stepperSizes(), zoomedRect.size(), zoomFactor);
+ if (controlSize == NSSmallControlSize)
+ drawInfo.kind = kThemeIncDecButtonSmall;
+ else if (controlSize == NSMiniControlSize)
+ drawInfo.kind = kThemeIncDecButtonMini;
+ else
+ drawInfo.kind = kThemeIncDecButton;
+
+ IntRect rect(zoomedRect);
+ context->save();
+ if (zoomFactor != 1.0f) {
+ rect.setWidth(rect.width() / zoomFactor);
+ rect.setHeight(rect.height() / zoomFactor);
+ context->translate(rect.x(), rect.y());
+ context->scale(FloatSize(zoomFactor, zoomFactor));
+ context->translate(-rect.x(), -rect.y());
+ }
+ CGRect bounds(rect);
+ // Adjust 'bounds' so that HIThemeDrawButton(bounds,...) draws exactly on 'rect'.
+ CGRect backgroundBounds;
+ HIThemeGetButtonBackgroundBounds(&bounds, &drawInfo, &backgroundBounds);
+ if (bounds.origin.x != backgroundBounds.origin.x)
+ bounds.origin.x += bounds.origin.x - backgroundBounds.origin.x;
+ if (bounds.origin.y != backgroundBounds.origin.y)
+ bounds.origin.y += bounds.origin.y - backgroundBounds.origin.y;
+ HIThemeDrawButton(&bounds, &drawInfo, context->platformContext(), kHIThemeOrientationNormal, 0);
+ context->restore();
+}
+
// Theme overrides
int ThemeChromiumMac::baselinePositionAdjustment(ControlPart part) const
@@ -613,6 +696,13 @@ LengthSize ThemeChromiumMac::controlSize(ControlPart part, const Font& font, con
case ListButtonPart:
return sizeFromFont(font, LengthSize(zoomedSize.width(), Length()), zoomFactor, listButtonSizes());
#endif
+ case InnerSpinButtonPart:
+ // We don't use inner spin buttons on Mac.
+ return LengthSize(Length(Fixed), Length(Fixed));
+ case OuterSpinButtonPart:
+ if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto())
+ return zoomedSize;
+ return sizeFromNSControlSize(stepperControlSizeForFont(font), zoomedSize, zoomFactor, stepperSizes());
default:
return zoomedSize;
}
@@ -626,6 +716,14 @@ LengthSize ThemeChromiumMac::minimumControlSize(ControlPart part, const Font& fo
case ButtonPart:
case ListButtonPart:
return LengthSize(Length(0, Fixed), Length(static_cast<int>(15 * zoomFactor), Fixed));
+ case InnerSpinButtonPart:
+ // We don't use inner spin buttons on Mac.
+ return LengthSize(Length(Fixed), Length(Fixed));
+ case OuterSpinButtonPart: {
+ IntSize base = stepperSizes()[NSMiniControlSize];
+ return LengthSize(Length(static_cast<int>(base.width() * zoomFactor), Fixed),
+ Length(static_cast<int>(base.height() * zoomFactor), Fixed));
+ }
default:
return Theme::minimumControlSize(part, font, zoomFactor);
}
@@ -702,6 +800,15 @@ void ThemeChromiumMac::inflateControlPaintRect(ControlPart part, ControlStates s
}
break;
}
+ case OuterSpinButtonPart: {
+ static const int stepperMargin[4] = { 0, 0, 0, 0 };
+ ControlSize controlSize = controlSizeFromPixelSize(stepperSizes(), zoomedRect.size(), zoomFactor);
+ IntSize zoomedSize = stepperSizes()[controlSize];
+ zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
+ zoomedSize.setWidth(zoomedSize.width() * zoomFactor);
+ zoomedRect = inflateRect(zoomedRect, zoomedSize, stepperMargin, zoomFactor);
+ break;
+ }
default:
break;
}
@@ -724,6 +831,9 @@ void ThemeChromiumMac::paint(ControlPart part, ControlStates states, GraphicsCon
case ListButtonPart:
paintButton(part, states, context, zoomedRect, zoomFactor, scrollView);
break;
+ case OuterSpinButtonPart:
+ paintStepper(states, context, zoomedRect, zoomFactor, scrollView);
+ break;
default:
break;
}
diff --git a/WebCore/platform/efl/CursorEfl.cpp b/WebCore/platform/efl/CursorEfl.cpp
index c88830e..47141f9 100644
--- a/WebCore/platform/efl/CursorEfl.cpp
+++ b/WebCore/platform/efl/CursorEfl.cpp
@@ -45,33 +45,33 @@ namespace WebCore {
Cursor::Cursor(PlatformCursor p)
{
- m_impl = eina_stringshare_add(p);
+ m_platformCursor = eina_stringshare_add(p);
}
Cursor::Cursor(const Cursor& other)
{
- m_impl = eina_stringshare_ref(other.m_impl);
+ m_platformCursor = eina_stringshare_ref(other.m_platformCursor);
}
Cursor::~Cursor()
{
- if (m_impl) {
- eina_stringshare_del(m_impl);
- m_impl = 0;
+ if (m_platformCursor) {
+ eina_stringshare_del(m_platformCursor);
+ m_platformCursor = 0;
}
}
Cursor::Cursor(Image* image, const IntPoint& hotspot)
- : m_impl(0)
+ : m_platformCursor(0)
{
notImplemented();
}
Cursor& Cursor::operator=(const Cursor& other)
{
- eina_stringshare_ref(other.m_impl);
- eina_stringshare_del(m_impl);
- m_impl = other.m_impl;
+ eina_stringshare_ref(other.m_platformCursor);
+ eina_stringshare_del(m_platformCursor);
+ m_platformCursor = other.m_platformCursor;
return *this;
}
diff --git a/WebCore/platform/efl/PopupMenuEfl.cpp b/WebCore/platform/efl/PopupMenuEfl.cpp
index 4d9677b..9dc6986 100644
--- a/WebCore/platform/efl/PopupMenuEfl.cpp
+++ b/WebCore/platform/efl/PopupMenuEfl.cpp
@@ -39,6 +39,9 @@ PopupMenu::PopupMenu(PopupMenuClient* client)
PopupMenu::~PopupMenu()
{
+ // Tell client to destroy data related to this popup since this object is
+ // going away.
+ hide();
}
void PopupMenu::show(const IntRect& rect, FrameView* view, int index)
diff --git a/WebCore/platform/efl/SoundEfl.cpp b/WebCore/platform/efl/SoundEfl.cpp
index c3b1eb3..091de7a 100644
--- a/WebCore/platform/efl/SoundEfl.cpp
+++ b/WebCore/platform/efl/SoundEfl.cpp
@@ -32,7 +32,6 @@
#ifdef HAVE_ECORE_X
#include <Ecore_X.h>
-#include <X11/Xlib.h>
#endif
namespace WebCore {
@@ -40,8 +39,7 @@ namespace WebCore {
void systemBeep()
{
#ifdef HAVE_ECORE_X
- Display* display = (Display*) ecore_x_display_get();
- XBell(display, 0);
+ ecore_x_bell(0);
#endif
}
diff --git a/WebCore/platform/efl/WidgetEfl.cpp b/WebCore/platform/efl/WidgetEfl.cpp
index 725e56f..6dbf2c2 100644
--- a/WebCore/platform/efl/WidgetEfl.cpp
+++ b/WebCore/platform/efl/WidgetEfl.cpp
@@ -211,8 +211,8 @@ void Widget::applyFallbackCursor()
int shape = cursorStringMap.cursor(m_data->m_cursorGroup.utf8().data());
if (shape < ECORE_X_CURSOR_X || shape > ECORE_X_CURSOR_XTERM) {
- fprintf(stderr, "ERROR: cannot map an equivalent X cursor for"
- " cursor group %s", m_data->m_cursorGroup.utf8().data());
+ LOG_ERROR("cannot map an equivalent X cursor for"
+ " c ursor group %s", m_data->m_cursorGroup.utf8().data());
shape = ECORE_X_CURSOR_LEFT_PTR;
}
@@ -221,29 +221,23 @@ void Widget::applyFallbackCursor()
ecore_x_window_cursor_set(win, cur);
return;
}
-#else
- fprintf(stderr, "ERROR: Ooops, no fallback to set cursor %s!\n",
- m_data->m_cursorGroup.utf8().data());
#endif
+ LOG("Ooops, no fallback to set cursor %s!\n",
+ m_data->m_cursorGroup.utf8().data());
}
void Widget::applyCursor()
{
- const char *file = 0;
- Evas_Coord x, y;
-
- String theme = edjeThemeRecursive();
- if (!theme.isNull())
- file = edjeThemeRecursive().utf8().data();
+ CString file = edjeThemeRecursive().utf8();
m_data->m_cursorObject = edje_object_add(evas());
- if (file && !edje_object_file_set(m_data->m_cursorObject, file, m_data->m_cursorGroup.utf8().data())) {
+ if (!file.isNull() && !edje_object_file_set(m_data->m_cursorObject, file.data(), m_data->m_cursorGroup.utf8().data())) {
evas_object_del(m_data->m_cursorObject);
m_data->m_cursorObject = 0;
ecore_evas_object_cursor_set(ecoreEvas(), 0, 0, 0, 0);
applyFallbackCursor();
} else {
- Evas_Coord w, h;
+ Evas_Coord x, y, w, h;
const char *d;
edje_object_size_min_get(m_data->m_cursorObject, &w, &h);
@@ -266,7 +260,7 @@ void Widget::applyCursor()
void Widget::setCursor(const Cursor& cursor)
{
- if (!platformWidget() || !evas())
+ if (!evas())
return;
const char *group = cursor.impl();
@@ -347,7 +341,9 @@ void Widget::setEvasObject(Evas_Object *o)
m_data->m_evasObject = o;
if (!o) {
m_data->m_evas = 0;
+#ifdef HAVE_ECORE_X
m_data->m_isUsingEcoreX = false;
+#endif
return;
}
diff --git a/WebCore/platform/graphics/Color.h b/WebCore/platform/graphics/Color.h
index 089d061..9335bc4 100644
--- a/WebCore/platform/graphics/Color.h
+++ b/WebCore/platform/graphics/Color.h
@@ -69,6 +69,11 @@ RGBA32 makeRGBAFromCMYKA(float c, float m, float y, float k, float a);
int differenceSquared(const Color&, const Color&);
+inline int redChannel(RGBA32 color) { return (color >> 16) & 0xFF; }
+inline int greenChannel(RGBA32 color) { return (color >> 8) & 0xFF; }
+inline int blueChannel(RGBA32 color) { return color & 0xFF; }
+inline int alphaChannel(RGBA32 color) { return (color >> 24) & 0xFF; }
+
class Color : public FastAllocBase {
public:
Color() : m_color(0), m_valid(false) { }
@@ -93,10 +98,10 @@ public:
bool hasAlpha() const { return alpha() < 255; }
- int red() const { return (m_color >> 16) & 0xFF; }
- int green() const { return (m_color >> 8) & 0xFF; }
- int blue() const { return m_color & 0xFF; }
- int alpha() const { return (m_color >> 24) & 0xFF; }
+ int red() const { return redChannel(m_color); }
+ int green() const { return greenChannel(m_color); }
+ int blue() const { return blueChannel(m_color); }
+ int alpha() const { return alphaChannel(m_color); }
RGBA32 rgb() const { return m_color; } // Preserve the alpha.
void setRGB(int r, int g, int b) { m_color = makeRGB(r, g, b); m_valid = true; }
diff --git a/WebCore/platform/graphics/FloatPoint.h b/WebCore/platform/graphics/FloatPoint.h
index 7443e97..5018f1d 100644
--- a/WebCore/platform/graphics/FloatPoint.h
+++ b/WebCore/platform/graphics/FloatPoint.h
@@ -80,7 +80,16 @@ public:
void setX(float x) { m_x = x; }
void setY(float y) { m_y = y; }
- void move(float dx, float dy) { m_x += dx; m_y += dy; }
+ void move(float dx, float dy)
+ {
+ m_x += dx;
+ m_y += dy;
+ }
+ void scale(float sx, float sy)
+ {
+ m_x *= sx;
+ m_y *= sy;
+ }
#if PLATFORM(CG)
FloatPoint(const CGPoint&);
@@ -122,6 +131,12 @@ inline FloatPoint& operator+=(FloatPoint& a, const FloatSize& b)
return a;
}
+inline FloatPoint& operator+=(FloatPoint& a, const FloatPoint& b)
+{
+ a.move(b.x(), b.y());
+ return a;
+}
+
inline FloatPoint& operator-=(FloatPoint& a, const FloatSize& b)
{
a.move(-b.width(), -b.height());
@@ -133,6 +148,11 @@ inline FloatPoint operator+(const FloatPoint& a, const FloatSize& b)
return FloatPoint(a.x() + b.width(), a.y() + b.height());
}
+inline FloatPoint operator+(const FloatPoint& a, const FloatPoint& b)
+{
+ return FloatPoint(a.x() + b.x(), a.y() + b.y());
+}
+
inline FloatSize operator-(const FloatPoint& a, const FloatPoint& b)
{
return FloatSize(a.x() - b.x(), a.y() - b.y());
diff --git a/WebCore/platform/graphics/Font.cpp b/WebCore/platform/graphics/Font.cpp
index 0351f7b..61f5707 100644
--- a/WebCore/platform/graphics/Font.cpp
+++ b/WebCore/platform/graphics/Font.cpp
@@ -72,7 +72,7 @@ Font::Font(const FontDescription& fd, short letterSpacing, short wordSpacing)
{
}
-Font::Font(const FontPlatformData& fontData, bool isPrinterFont)
+Font::Font(const FontPlatformData& fontData, bool isPrinterFont, FontSmoothingMode fontSmoothingMode)
: m_fontList(FontFallbackList::create())
, m_letterSpacing(0)
, m_wordSpacing(0)
@@ -80,6 +80,7 @@ Font::Font(const FontPlatformData& fontData, bool isPrinterFont)
, m_needsTranscoding(fontTranscoder().needsTranscoding(family().family().string()))
{
m_fontDescription.setUsePrinterFont(isPrinterFont);
+ m_fontDescription.setFontSmoothing(fontSmoothingMode);
m_fontList->setPlatformFont(fontData);
}
diff --git a/WebCore/platform/graphics/Font.h b/WebCore/platform/graphics/Font.h
index ecfde98..d6cf140 100644
--- a/WebCore/platform/graphics/Font.h
+++ b/WebCore/platform/graphics/Font.h
@@ -76,7 +76,7 @@ public:
Font();
Font(const FontDescription&, short letterSpacing, short wordSpacing);
// This constructor is only used if the platform wants to start with a native font.
- Font(const FontPlatformData&, bool isPrinting);
+ Font(const FontPlatformData&, bool isPrinting, FontSmoothingMode = AutoSmoothing);
~Font();
Font(const Font&);
@@ -135,7 +135,7 @@ public:
float xHeight() const { return primaryFont()->xHeight(); }
unsigned unitsPerEm() const { return primaryFont()->unitsPerEm(); }
int spaceWidth() const { return (int)ceilf(primaryFont()->adjustedSpaceWidth() + m_letterSpacing); }
- int tabWidth() const { return 8 * spaceWidth(); }
+ float tabWidth(const SimpleFontData& fontData) const { return 8 * ceilf(fontData.adjustedSpaceWidth() + letterSpacing()); }
const SimpleFontData* primaryFont() const;
const FontData* fontDataAt(unsigned) const;
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
index 882362f..28388f4 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -68,8 +68,13 @@ typedef int Platform3DObject;
const Platform3DObject NullPlatform3DObject = 0;
#endif
+#if PLATFORM(CG)
+#include <CoreGraphics/CGContext.h>
+#endif
+
namespace WebCore {
class WebGLActiveInfo;
+ class ArrayBuffer;
class ArrayBufferView;
class WebGLBuffer;
class Uint8Array;
@@ -551,7 +556,9 @@ namespace WebCore {
void blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha);
void bufferData(unsigned long target, int size, unsigned long usage);
+ void bufferData(unsigned long target, ArrayBuffer* data, unsigned long usage);
void bufferData(unsigned long target, ArrayBufferView* data, unsigned long usage);
+ void bufferSubData(unsigned long target, long offset, ArrayBuffer* data);
void bufferSubData(unsigned long target, long offset, ArrayBufferView* data);
unsigned long checkFramebufferStatus(unsigned long target);
@@ -707,7 +714,14 @@ namespace WebCore {
void viewport(long x, long y, unsigned long width, unsigned long height);
void reshape(int width, int height);
-
+
+#if PLATFORM(CG)
+ void paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight,
+ int canvasWidth, int canvasHeight, CGContextRef context);
+#endif
+
+ void paintRenderingResultsToCanvas(WebGLRenderingContext* context);
+
// Helpers for notification about paint events
void beginPaint(WebGLRenderingContext* context);
void endPaint();
diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h
index 8fcebce..a5819f4 100644
--- a/WebCore/platform/graphics/GraphicsLayer.h
+++ b/WebCore/platform/graphics/GraphicsLayer.h
@@ -298,10 +298,11 @@ public:
virtual void setContentsToImage(Image*) { }
virtual void setContentsToMedia(PlatformLayer*) { } // video or plug-in
virtual void setContentsBackgroundColor(const Color&) { }
-
#if ENABLE(3D_CANVAS)
virtual void setContentsToWebGL(PlatformLayer*) { }
#endif
+ virtual bool hasContentsLayer() const { return false; }
+
// Callback from the underlying graphics system to draw layer contents.
void paintGraphicsLayerContents(GraphicsContext&, const IntRect& clip);
// Callback from the underlying graphics system when the layer has been displayed
@@ -351,6 +352,8 @@ public:
// pointers for the layers and timing data will be included in the returned string.
String layerTreeAsText(LayerTreeAsTextBehavior = LayerTreeAsTextBehaviorNormal) const;
+ bool usingTiledLayer() const { return m_usingTiledLayer; }
+
protected:
typedef Vector<TransformOperation::OperationType> TransformOperationList;
diff --git a/WebCore/platform/graphics/ImageBuffer.h b/WebCore/platform/graphics/ImageBuffer.h
index 9f9ba7e..cb5d63f 100644
--- a/WebCore/platform/graphics/ImageBuffer.h
+++ b/WebCore/platform/graphics/ImageBuffer.h
@@ -74,6 +74,11 @@ namespace WebCore {
GraphicsContext* context() const;
Image* image() const;
+#if PLATFORM(QT)
+ Image* imageForRendering() const;
+#else
+ Image* imageForRendering() const { return image(); }
+#endif
void clearImage() { m_image.clear(); }
diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp
index 3915713..9290dfe 100644
--- a/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/WebCore/platform/graphics/MediaPlayer.cpp
@@ -130,6 +130,7 @@ public:
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
virtual void deliverNotification(MediaPlayerProxyNotificationType) { }
virtual void setMediaPlayerProxy(WebMediaPlayerProxy*) { }
+ virtual void setControls(bool) { }
#endif
virtual bool hasSingleSecurityOrigin() const { return true; }
@@ -563,6 +564,21 @@ void MediaPlayer::setMediaPlayerProxy(WebMediaPlayerProxy* proxy)
m_playerProxy = proxy;
m_private->setMediaPlayerProxy(proxy);
}
+
+void MediaPlayer::setControls(bool controls)
+{
+ m_private->setControls(controls);
+}
+
+void MediaPlayer::enterFullscreen()
+{
+ m_private->enterFullscreen();
+}
+
+void MediaPlayer::exitFullscreen()
+{
+ m_private->exitFullscreen();
+}
#endif
#if USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/MediaPlayer.h b/WebCore/platform/graphics/MediaPlayer.h
index 87f8fb4..dea5100 100644
--- a/WebCore/platform/graphics/MediaPlayer.h
+++ b/WebCore/platform/graphics/MediaPlayer.h
@@ -55,6 +55,7 @@ class QTMovieVisualContext;
namespace WebCore {
class GStreamerGWorld;
+class MediaPlayerPrivateInterface;
// Structure that will hold every native
// types supported by the current media player.
@@ -67,6 +68,7 @@ struct PlatformMedia {
QTMovieGWorldType,
QTMovieVisualContextType,
GStreamerGWorldType,
+ ChromiumMediaPlayerType,
} type;
union {
@@ -74,6 +76,7 @@ struct PlatformMedia {
QTMovieGWorld* qtMovieGWorld;
QTMovieVisualContext* qtMovieVisualContext;
GStreamerGWorld* gstreamerGWorld;
+ MediaPlayerPrivateInterface* chromiumMediaPlayer;
} media;
};
@@ -85,7 +88,6 @@ class GraphicsContext;
class IntRect;
class IntSize;
class MediaPlayer;
-class MediaPlayerPrivateInterface;
class String;
class TimeRanges;
@@ -256,6 +258,9 @@ public:
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
void deliverNotification(MediaPlayerProxyNotificationType notification);
void setMediaPlayerProxy(WebMediaPlayerProxy* proxy);
+ void setControls(bool);
+ void enterFullscreen();
+ void exitFullscreen();
#endif
#if USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/MediaPlayerPrivate.h b/WebCore/platform/graphics/MediaPlayerPrivate.h
index 16ff543..40aeacb 100644
--- a/WebCore/platform/graphics/MediaPlayerPrivate.h
+++ b/WebCore/platform/graphics/MediaPlayerPrivate.h
@@ -107,6 +107,9 @@ public:
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
virtual void deliverNotification(MediaPlayerProxyNotificationType) = 0;
virtual void setMediaPlayerProxy(WebMediaPlayerProxy*) = 0;
+ virtual void setControls(bool) { }
+ virtual void enterFullscreen() { }
+ virtual void exitFullscreen() { }
#endif
#if USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/Path.h b/WebCore/platform/graphics/Path.h
index b69670f..f2ae2df 100644
--- a/WebCore/platform/graphics/Path.h
+++ b/WebCore/platform/graphics/Path.h
@@ -124,6 +124,7 @@ namespace WebCore {
// Gets the current point of the current path, which is conceptually the final point reached by the path so far.
// Note the Path can be empty (isEmpty() == true) and still have a current point.
bool hasCurrentPoint() const;
+ FloatPoint currentPoint() const;
void moveTo(const FloatPoint&);
void addLineTo(const FloatPoint&);
diff --git a/WebCore/platform/graphics/WidthIterator.cpp b/WebCore/platform/graphics/WidthIterator.cpp
index 827cd10..ef047e8 100644
--- a/WebCore/platform/graphics/WidthIterator.cpp
+++ b/WebCore/platform/graphics/WidthIterator.cpp
@@ -84,7 +84,10 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
bool rtl = m_run.rtl();
bool hasExtraSpacing = (m_font->letterSpacing() || m_font->wordSpacing() || m_padding) && !m_run.spacingDisabled();
- float runWidthSoFar = m_runWidthSoFar;
+ float widthSinceLastRounding = m_runWidthSoFar;
+ m_runWidthSoFar = floorf(m_runWidthSoFar);
+ widthSinceLastRounding -= m_runWidthSoFar;
+
float lastRoundingWidth = m_finalRoundingWidth;
FloatRect bounds;
@@ -130,8 +133,8 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
// Now that we have a glyph and font data, get its width.
float width;
if (c == '\t' && m_run.allowTabs()) {
- float tabWidth = m_font->tabWidth();
- width = tabWidth - fmodf(m_run.xPos() + runWidthSoFar, tabWidth);
+ float tabWidth = m_font->tabWidth(*fontData);
+ width = tabWidth - fmodf(m_run.xPos() + m_runWidthSoFar + widthSinceLastRounding, tabWidth);
} else {
width = fontData->widthForGlyph(glyph);
@@ -216,11 +219,13 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
// width so that the total run width will be on an integer boundary.
if ((m_run.applyWordRounding() && currentCharacter < m_run.length() && Font::isRoundingHackCharacter(*cp))
|| (m_run.applyRunRounding() && currentCharacter >= m_end)) {
- float totalWidth = runWidthSoFar + width;
- width += ceilf(totalWidth) - totalWidth;
- }
-
- runWidthSoFar += width;
+ float totalWidth = widthSinceLastRounding + width;
+ widthSinceLastRounding = ceilf(totalWidth);
+ width += widthSinceLastRounding - totalWidth;
+ m_runWidthSoFar += widthSinceLastRounding;
+ widthSinceLastRounding = 0;
+ } else
+ widthSinceLastRounding += width;
if (glyphBuffer)
glyphBuffer->add(glyph, fontData, (rtl ? oldWidth + lastRoundingWidth : width));
@@ -235,7 +240,7 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
}
m_currentCharacter = currentCharacter;
- m_runWidthSoFar = runWidthSoFar;
+ m_runWidthSoFar += widthSinceLastRounding;
m_finalRoundingWidth = lastRoundingWidth;
}
diff --git a/WebCore/platform/graphics/android/ImageBufferAndroid.cpp b/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
index 60e2c1c..082af3e 100644
--- a/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
+++ b/WebCore/platform/graphics/android/ImageBufferAndroid.cpp
@@ -29,8 +29,8 @@
#include "Base64.h"
#include "BitmapImage.h"
#include "ImageData.h"
-#include "android_graphics.h"
#include "GraphicsContext.h"
+#include "NotImplemented.h"
#include "PlatformGraphicsContext.h"
#include "SkBitmapRef.h"
#include "SkCanvas.h"
@@ -39,6 +39,7 @@
#include "SkImageEncoder.h"
#include "SkStream.h"
#include "SkUnPreMultiply.h"
+#include "android_graphics.h"
using namespace std;
@@ -228,4 +229,9 @@ String ImageBuffer::toDataURL(const String&, const double*) const
return String::format("data:image/png;base64,%s", base64EncodedData.data());
}
+void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookupTable)
+{
+ notImplemented();
+}
+
}
diff --git a/WebCore/platform/graphics/android/PathAndroid.cpp b/WebCore/platform/graphics/android/PathAndroid.cpp
index f7f6b19..13bd888 100644
--- a/WebCore/platform/graphics/android/PathAndroid.cpp
+++ b/WebCore/platform/graphics/android/PathAndroid.cpp
@@ -75,6 +75,13 @@ bool Path::hasCurrentPoint() const
return m_path->getPoints(0, 0) > 0;
}
+FloatPoint Path::currentPoint() const
+{
+ // FIXME: Return current point of subpath. See b/2869593
+ float quietNaN = std::numeric_limits<float>::quiet_NaN();
+ return FloatPoint(quietNaN, quietNaN);
+}
+
bool Path::contains(const FloatPoint& point, WindRule rule) const
{
SkRegion rgn, clip;
diff --git a/WebCore/platform/graphics/cairo/FontCairo.cpp b/WebCore/platform/graphics/cairo/FontCairo.cpp
index 93051cb..9217a81 100644
--- a/WebCore/platform/graphics/cairo/FontCairo.cpp
+++ b/WebCore/platform/graphics/cairo/FontCairo.cpp
@@ -73,8 +73,8 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
FloatSize shadowSize;
float shadowBlur = 0;
Color shadowColor;
- bool hasShadow = context->textDrawingMode() == cTextFill &&
- context->getShadow(shadowSize, shadowBlur, shadowColor);
+ bool hasShadow = context->textDrawingMode() & cTextFill
+ && context->getShadow(shadowSize, shadowBlur, shadowColor);
// TODO: Blur support
if (hasShadow) {
diff --git a/WebCore/platform/graphics/cairo/PathCairo.cpp b/WebCore/platform/graphics/cairo/PathCairo.cpp
index 91cecd3..d880626 100644
--- a/WebCore/platform/graphics/cairo/PathCairo.cpp
+++ b/WebCore/platform/graphics/cairo/PathCairo.cpp
@@ -86,6 +86,15 @@ bool Path::hasCurrentPoint() const
return !isEmpty();
}
+FloatPoint Path::currentPoint() const
+{
+ // FIXME: Is this the correct way?
+ double x;
+ double y;
+ cairo_get_current_point(platformPath()->m_cr, &x, &y);
+ return FloatPoint(x, y);
+}
+
void Path::translate(const FloatSize& p)
{
cairo_t* cr = platformPath()->m_cr;
diff --git a/WebCore/platform/graphics/cg/ColorCG.cpp b/WebCore/platform/graphics/cg/ColorCG.cpp
index e514fa3..9257642 100644
--- a/WebCore/platform/graphics/cg/ColorCG.cpp
+++ b/WebCore/platform/graphics/cg/ColorCG.cpp
@@ -73,10 +73,14 @@ Color::Color(CGColorRef color)
CGColorRef createCGColor(const Color& c)
{
CGColorRef color = NULL;
+#ifdef OBSOLETE_COLORSYNC_API
CMProfileRef prof = NULL;
CMGetSystemProfile(&prof);
-
RetainPtr<CGColorSpaceRef> rgbSpace(AdoptCF, CGColorSpaceCreateWithPlatformColorSpace(prof));
+#else
+ ColorSyncProfileRef prof = ColorSyncProfileCreateWithDisplayID(0);
+ RetainPtr<CGColorSpaceRef> rgbSpace(AdoptCF, CGColorSpaceCreateWithPlatformColorSpace(const_cast<void*>(reinterpret_cast<const void*>(prof))));
+#endif
if (rgbSpace) {
CGFloat components[4] = { static_cast<CGFloat>(c.red()) / 255, static_cast<CGFloat>(c.green()) / 255,
@@ -84,7 +88,12 @@ CGColorRef createCGColor(const Color& c)
color = CGColorCreate(rgbSpace.get(), components);
}
+#ifdef OBSOLETE_COLORSYNC_API
CMCloseProfile(prof);
+#else
+ if (prof)
+ CFRelease(prof);
+#endif
return color;
}
diff --git a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
index 9f0f353..8af3d0e 100644
--- a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
@@ -36,6 +36,8 @@
#include <CoreGraphics/CGContext.h>
#include <CoreGraphics/CGImage.h>
+#include <wtf/RetainPtr.h>
+
namespace WebCore {
bool GraphicsContext3D::getImageData(Image* image,
@@ -104,6 +106,41 @@ bool GraphicsContext3D::getImageData(Image* image,
format, type, neededAlphaOp, outputVector.data());
}
+void GraphicsContext3D::paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight, int canvasWidth, int canvasHeight, CGContextRef context)
+{
+ if (!imagePixels || imageWidth <= 0 || imageHeight <= 0 || canvasWidth <= 0 || canvasHeight <= 0 || !context)
+ return;
+ int rowBytes = imageWidth * 4;
+ RetainPtr<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(0, imagePixels, rowBytes * imageHeight, 0);
+ RetainPtr<CGColorSpaceRef> colorSpace = CGColorSpaceCreateDeviceRGB();
+ RetainPtr<CGImageRef> cgImage = CGImageCreate(imageWidth,
+ imageHeight,
+ 8,
+ 32,
+ rowBytes,
+ colorSpace.get(),
+ kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
+ dataProvider.get(),
+ 0,
+ false,
+ kCGRenderingIntentDefault);
+ // CSS styling may cause the canvas's content to be resized on
+ // the page. Go back to the Canvas to figure out the correct
+ // width and height to draw.
+ CGRect rect = CGRectMake(0, 0,
+ canvasWidth,
+ canvasHeight);
+ // We want to completely overwrite the previous frame's
+ // rendering results.
+ CGContextSaveGState(context);
+ CGContextSetBlendMode(context,
+ kCGBlendModeCopy);
+ CGContextSetInterpolationQuality(context,
+ kCGInterpolationNone);
+ CGContextDrawImage(context,
+ rect, cgImage.get());
+ CGContextRestoreGState(context);
+}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/cg/PathCG.cpp b/WebCore/platform/graphics/cg/PathCG.cpp
index eb196d9..90d4b8a 100644
--- a/WebCore/platform/graphics/cg/PathCG.cpp
+++ b/WebCore/platform/graphics/cg/PathCG.cpp
@@ -213,8 +213,7 @@ void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius)
void Path::closeSubpath()
{
- if (!CGPathIsEmpty(m_path)) // to silence a warning when trying to close an empty path
- CGPathCloseSubpath(m_path);
+ CGPathCloseSubpath(m_path);
}
void Path::addArc(const FloatPoint& p, float r, float sa, float ea, bool clockwise)
@@ -249,6 +248,11 @@ bool Path::hasCurrentPoint() const
{
return !isEmpty();
}
+
+FloatPoint Path::currentPoint() const
+{
+ return CGPathGetCurrentPoint(m_path);
+}
static void CGPathToCFStringApplierFunction(void* info, const CGPathElement *element)
{
diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
index dda10b7..9b54732 100644
--- a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
@@ -43,7 +43,8 @@
namespace WebCore {
static SkPaint::Hinting skiaHinting = SkPaint::kNormal_Hinting;
-static bool isSkiaAntiAlias = true, isSkiaSubpixelGlyphs;
+static bool isSkiaAntiAlias = true;
+static bool isSkiaSubpixelGlyphs = false;
void FontPlatformData::setHinting(SkPaint::Hinting hinting)
{
diff --git a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
index 9b65346..a01a17f 100644
--- a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp
@@ -363,9 +363,30 @@ void GraphicsLayerChromium::setContentsToWebGL(PlatformLayer* platformLayer)
}
#endif
-void GraphicsLayerChromium::setContentsToVideo(PlatformLayer* videoLayer)
+void GraphicsLayerChromium::setContentsToMedia(PlatformLayer* layer)
{
- // FIXME: Implement
+ bool childrenChanged = false;
+ if (layer) {
+ if (!m_contentsLayer.get() || m_contentsLayerPurpose != ContentsLayerForVideo) {
+ setupContentsLayer(layer);
+ m_contentsLayer = layer;
+ m_contentsLayerPurpose = ContentsLayerForVideo;
+ childrenChanged = true;
+ }
+ layer->setOwner(this);
+ layer->setNeedsDisplay();
+ updateContentsRect();
+ } else {
+ if (m_contentsLayer) {
+ childrenChanged = true;
+
+ // The old contents layer will be removed via updateSublayerList.
+ m_contentsLayer = 0;
+ }
+ }
+
+ if (childrenChanged)
+ updateSublayerList();
}
void GraphicsLayerChromium::setGeometryOrientation(CompositingCoordinatesOrientation orientation)
diff --git a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h
index ccd02eb..cd5e479 100644
--- a/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h
@@ -85,7 +85,7 @@ public:
virtual void setContentsRect(const IntRect&);
virtual void setContentsToImage(Image*);
- virtual void setContentsToVideo(PlatformLayer*);
+ virtual void setContentsToMedia(PlatformLayer*);
virtual void setContentsToWebGL(PlatformLayer*);
virtual PlatformLayer* platformLayer() const;
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index 9ac506c..b071385 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -37,7 +37,6 @@
#include "GLES2Context.h"
#include "LayerChromium.h"
#include "NotImplemented.h"
-#include "Page.h"
#include "TransformLayerChromium.h"
#include "WebGLLayerChromium.h"
#if PLATFORM(SKIA)
@@ -190,24 +189,24 @@ ShaderProgram::ShaderProgram()
{
}
-PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(Page* page)
+PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(PassOwnPtr<GLES2Context> gles2Context)
{
- return new LayerRendererChromium(page);
+ return new LayerRendererChromium(gles2Context);
}
-LayerRendererChromium::LayerRendererChromium(Page* page)
+LayerRendererChromium::LayerRendererChromium(PassOwnPtr<GLES2Context> gles2Context)
: m_rootLayer(0)
, m_needsDisplay(false)
, m_positionLocation(0)
, m_texCoordLocation(1)
- , m_page(page)
, m_rootLayerTextureWidth(0)
, m_rootLayerTextureHeight(0)
, m_scrollPosition(IntPoint(-1, -1))
, m_currentShaderProgramType(NumShaderProgramTypes)
+ , m_gles2Context(gles2Context)
{
m_quadVboIds[Vertices] = m_quadVboIds[LayerElements] = 0;
- m_hardwareCompositing = (initGL() && initializeSharedGLObjects());
+ m_hardwareCompositing = (m_gles2Context && initializeSharedGLObjects());
}
LayerRendererChromium::~LayerRendererChromium()
@@ -645,16 +644,6 @@ bool LayerRendererChromium::makeContextCurrent()
return m_gles2Context->makeCurrent();
}
-bool LayerRendererChromium::initGL()
-{
- m_gles2Context = GLES2Context::createOnscreen(m_page);
-
- if (!m_gles2Context)
- return false;
-
- return true;
-}
-
void LayerRendererChromium::bindCommonAttribLocations(ShaderProgramType program)
{
unsigned programId = m_shaderPrograms[program].m_shaderProgramId;
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
index dc7ea70..3b89dc6 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
@@ -45,7 +45,6 @@
namespace WebCore {
class GLES2Context;
-class Page;
class ShaderProgram {
public:
@@ -60,9 +59,9 @@ public:
// Class that handles drawing of composited render layers using GL.
class LayerRendererChromium : public Noncopyable {
public:
- static PassOwnPtr<LayerRendererChromium> create(Page* page);
+ static PassOwnPtr<LayerRendererChromium> create(PassOwnPtr<GLES2Context> gles2Context);
- LayerRendererChromium(Page* page);
+ LayerRendererChromium(PassOwnPtr<GLES2Context> gles2Context);
~LayerRendererChromium();
// Updates the contents of the root layer that fall inside the updateRect and recomposites
@@ -105,7 +104,6 @@ private:
enum VboIds { Vertices, LayerElements };
// These are here only temporarily and should be removed once we switch over to GGL
- bool initGL();
bool makeContextCurrent();
bool initializeSharedGLObjects();
@@ -151,9 +149,6 @@ private:
IntSize m_rootLayerCanvasSize;
OwnPtr<GLES2Context> m_gles2Context;
-
- // The WebCore Page that the compositor renders into.
- Page* m_page;
};
}
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
new file mode 100644
index 0000000..5ac0e57
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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.
+ */
+
+#include "config.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "VideoLayerChromium.h"
+
+namespace WebCore {
+
+PassRefPtr<VideoLayerChromium> VideoLayerChromium::create(GraphicsLayerChromium* owner)
+{
+ return adoptRef(new VideoLayerChromium(owner));
+}
+
+VideoLayerChromium::VideoLayerChromium(GraphicsLayerChromium* owner)
+ : LayerChromium(owner)
+{
+}
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.h b/WebCore/platform/graphics/chromium/VideoLayerChromium.h
new file mode 100644
index 0000000..1fa8009
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 VideoLayerChromium_h
+#define VideoLayerChromium_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "LayerChromium.h"
+
+namespace WebCore {
+
+// A Layer that contains a Video element.
+class VideoLayerChromium : public LayerChromium {
+public:
+ static PassRefPtr<VideoLayerChromium> create(GraphicsLayerChromium* owner = 0);
+ virtual bool drawsContent() { return true; }
+
+private:
+ VideoLayerChromium(GraphicsLayerChromium* owner);
+};
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif
diff --git a/WebCore/platform/graphics/haiku/PathHaiku.cpp b/WebCore/platform/graphics/haiku/PathHaiku.cpp
index d8b6932..c5b8c98 100644
--- a/WebCore/platform/graphics/haiku/PathHaiku.cpp
+++ b/WebCore/platform/graphics/haiku/PathHaiku.cpp
@@ -65,6 +65,14 @@ bool Path::hasCurrentPoint() const
return !isEmpty();
}
+FloatPoint Path::currentPoint() const
+{
+ // FIXME: implement safe way to return current point of subpath.
+ notImplemented();
+ float quietNaN = std::numeric_limits<float>::quiet_NaN();
+ return FloatPoint(quietNaN, quietNaN);
+}
+
bool Path::contains(const FloatPoint& point, WindRule rule) const
{
return m_path->Contains(point);
diff --git a/WebCore/platform/graphics/mac/ComplexTextController.cpp b/WebCore/platform/graphics/mac/ComplexTextController.cpp
index 61c9a59..da381f2 100644
--- a/WebCore/platform/graphics/mac/ComplexTextController.cpp
+++ b/WebCore/platform/graphics/mac/ComplexTextController.cpp
@@ -431,6 +431,7 @@ void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer)
void ComplexTextController::adjustGlyphsAndAdvances()
{
+ CGFloat widthSinceLastRounding = 0;
size_t runCount = m_complexTextRuns.size();
for (size_t r = 0; r < runCount; ++r) {
ComplexTextRun& complexTextRun = *m_complexTextRuns[r];
@@ -473,8 +474,8 @@ void ComplexTextController::adjustGlyphsAndAdvances()
CGSize advance = treatAsSpace ? CGSizeMake(fontData->spaceWidth(), advances[i].height) : advances[i];
if (ch == '\t' && m_run.allowTabs()) {
- float tabWidth = m_font.tabWidth();
- advance.width = tabWidth - fmodf(m_run.xPos() + m_totalWidth, tabWidth);
+ float tabWidth = m_font.tabWidth(*fontData);
+ advance.width = tabWidth - fmodf(m_run.xPos() + m_totalWidth + widthSinceLastRounding, tabWidth);
} else if (ch == zeroWidthSpace || Font::treatAsZeroWidthSpace(ch) && !treatAsSpace) {
advance.width = 0;
glyph = fontData->spaceGlyph();
@@ -532,21 +533,23 @@ void ComplexTextController::adjustGlyphsAndAdvances()
// Check to see if the next character is a "rounding hack character", if so, adjust the
// width so that the total run width will be on an integer boundary.
if (m_run.applyWordRounding() && !lastGlyph && Font::isRoundingHackCharacter(nextCh) || m_run.applyRunRounding() && lastGlyph) {
- CGFloat totalWidth = m_totalWidth + advance.width;
- CGFloat extraWidth = ceilCGFloat(totalWidth) - totalWidth;
+ CGFloat totalWidth = widthSinceLastRounding + advance.width;
+ widthSinceLastRounding = ceilCGFloat(totalWidth);
+ CGFloat extraWidth = widthSinceLastRounding - totalWidth;
if (m_run.ltr())
advance.width += extraWidth;
else {
- m_totalWidth += extraWidth;
if (m_lastRoundingGlyph)
m_adjustedAdvances[m_lastRoundingGlyph - 1].width += extraWidth;
else
m_finalRoundingWidth = extraWidth;
m_lastRoundingGlyph = m_adjustedAdvances.size() + 1;
}
- }
+ m_totalWidth += widthSinceLastRounding;
+ widthSinceLastRounding = 0;
+ } else
+ widthSinceLastRounding += advance.width;
- m_totalWidth += advance.width;
advance.height *= -1;
m_adjustedAdvances.append(advance);
m_adjustedGlyphs.append(glyph);
@@ -565,6 +568,7 @@ void ComplexTextController::adjustGlyphsAndAdvances()
if (!isMonotonic)
complexTextRun.setIsNonMonotonic();
}
+ m_totalWidth += widthSinceLastRounding;
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
index 961ec45..30c3b8e 100644
--- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
+++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm
@@ -34,14 +34,18 @@
#include "ImageBuffer.h"
#include "NotImplemented.h"
#include "WebGLActiveInfo.h"
+#include "ArrayBuffer.h"
#include "ArrayBufferView.h"
#include "WebGLBuffer.h"
#include "Float32Array.h"
#include "WebGLFramebuffer.h"
+#include "GraphicsContext.h"
+#include "HTMLCanvasElement.h"
#include "Int32Array.h"
#include "WebGLLayer.h"
#include "WebGLProgram.h"
#include "WebGLRenderbuffer.h"
+#include "WebGLRenderingContext.h"
#include "WebGLShader.h"
#include "WebGLTexture.h"
#include "Uint8Array.h"
@@ -236,6 +240,54 @@ void GraphicsContext3D::makeContextCurrent()
CGLSetCurrentContext(m_contextObj);
}
+void GraphicsContext3D::paintRenderingResultsToCanvas(WebGLRenderingContext* context)
+{
+ HTMLCanvasElement* canvas = context->canvas();
+ ImageBuffer* imageBuffer = canvas->buffer();
+
+ int rowBytes = m_currentWidth * 4;
+ int totalBytes = rowBytes * m_currentHeight;
+
+ OwnArrayPtr<unsigned char> pixels(new unsigned char[totalBytes]);
+ if (!pixels)
+ return;
+
+ CGLSetCurrentContext(m_contextObj);
+
+ bool mustRestoreFBO = false;
+ if (m_attrs.antialias) {
+ ::glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO);
+ ::glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo);
+ ::glBlitFramebufferEXT(0, 0, m_currentWidth, m_currentHeight, 0, 0, m_currentWidth, m_currentHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+ mustRestoreFBO = true;
+ } else {
+ if (m_boundFBO != m_fbo) {
+ mustRestoreFBO = true;
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
+ }
+ }
+
+ GLint packAlignment = 4;
+ bool mustRestorePackAlignment = false;
+ ::glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment);
+ if (packAlignment > 4) {
+ ::glPixelStorei(GL_PACK_ALIGNMENT, 4);
+ mustRestorePackAlignment = true;
+ }
+
+ ::glReadPixels(0, 0, m_currentWidth, m_currentHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels.get());
+
+ if (mustRestorePackAlignment)
+ ::glPixelStorei(GL_PACK_ALIGNMENT, packAlignment);
+
+ if (mustRestoreFBO)
+ ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO);
+
+ paintToCanvas(pixels.get(), m_currentWidth, m_currentHeight,
+ canvas->width(), canvas->height(), imageBuffer->context()->platformContext());
+}
+
void GraphicsContext3D::beginPaint(WebGLRenderingContext* context)
{
UNUSED_PARAM(context);
@@ -494,6 +546,16 @@ void GraphicsContext3D::bufferData(unsigned long target, int size, unsigned long
ensureContext(m_contextObj);
::glBufferData(target, size, 0, usage);
}
+
+void GraphicsContext3D::bufferData(unsigned long target, ArrayBuffer* array, unsigned long usage)
+{
+ if (!array || !array->byteLength())
+ return;
+
+ ensureContext(m_contextObj);
+ ::glBufferData(target, array->byteLength(), array->data(), usage);
+}
+
void GraphicsContext3D::bufferData(unsigned long target, ArrayBufferView* array, unsigned long usage)
{
if (!array || !array->length())
@@ -503,6 +565,15 @@ void GraphicsContext3D::bufferData(unsigned long target, ArrayBufferView* array,
::glBufferData(target, array->byteLength(), array->baseAddress(), usage);
}
+void GraphicsContext3D::bufferSubData(unsigned long target, long offset, ArrayBuffer* array)
+{
+ if (!array || !array->byteLength())
+ return;
+
+ ensureContext(m_contextObj);
+ ::glBufferSubData(target, offset, array->byteLength(), array->data());
+}
+
void GraphicsContext3D::bufferSubData(unsigned long target, long offset, ArrayBufferView* array)
{
if (!array || !array->length())
@@ -1216,6 +1287,10 @@ void GraphicsContext3D::getIntegerv(unsigned long pname, int* value)
// Need to emulate IMPLEMENTATION_COLOR_READ_FORMAT/TYPE for GL. Any valid
// combination should work, but GL_RGB/GL_UNSIGNED_BYTE might be the most
// useful for desktop WebGL users.
+ // Need to emulate MAX_FRAGMENT/VERTEX_UNIFORM_VECTORS and MAX_VARYING_VECTORS
+ // because desktop GL's corresponding queries return the number of components
+ // whereas GLES2 return the number of vectors (each vector has 4 components).
+ // Therefore, the value returned by desktop GL needs to be divided by 4.
ensureContext(m_contextObj);
switch (pname) {
case IMPLEMENTATION_COLOR_READ_FORMAT:
@@ -1224,6 +1299,18 @@ void GraphicsContext3D::getIntegerv(unsigned long pname, int* value)
case IMPLEMENTATION_COLOR_READ_TYPE:
*value = GL_UNSIGNED_BYTE;
break;
+ case MAX_FRAGMENT_UNIFORM_VECTORS:
+ ::glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, value);
+ *value /= 4;
+ break;
+ case MAX_VERTEX_UNIFORM_VECTORS:
+ ::glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, value);
+ *value /= 4;
+ break;
+ case MAX_VARYING_VECTORS:
+ ::glGetIntegerv(GL_MAX_VARYING_FLOATS, value);
+ *value /= 4;
+ break;
default:
::glGetIntegerv(pname, value);
}
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.h b/WebCore/platform/graphics/mac/GraphicsLayerCA.h
index 7d78dee..80c822c 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.h
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.h
@@ -106,6 +106,7 @@ public:
#if ENABLE(3D_CANVAS)
virtual void setContentsToWebGL(PlatformLayer*);
#endif
+ virtual bool hasContentsLayer() const { return m_contentsLayer; }
virtual PlatformLayer* platformLayer() const;
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
index 43b3f3e..9f1ac83 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
@@ -1057,11 +1057,11 @@ void GraphicsLayerCA::updateSublayerList()
void GraphicsLayerCA::updateLayerPosition()
{
- // FIXME: if constrained the size, the position will be wrong. Fixing this is not trivial.
+ FloatSize usedSize = m_usingTiledLayer ? constrainedSize() : m_size;
// Position is offset on the layer by the layer anchor point.
- CGPoint posPoint = CGPointMake(m_position.x() + m_anchorPoint.x() * m_size.width(),
- m_position.y() + m_anchorPoint.y() * m_size.height());
+ CGPoint posPoint = CGPointMake(m_position.x() + m_anchorPoint.x() * usedSize.width(),
+ m_position.y() + m_anchorPoint.y() * usedSize.height());
[primaryLayer() setPosition:posPoint];
@@ -2271,8 +2271,6 @@ void GraphicsLayerCA::updateContentsTransform()
contentsTransform = CGAffineTransformTranslate(contentsTransform, 0, -[m_layer.get() bounds].size.height);
[m_layer.get() setContentsTransform:contentsTransform];
}
-#else
- ASSERT(contentsOrientation() == CompositingCoordinatesTopDown);
#endif
}
diff --git a/WebCore/platform/graphics/mac/WebLayer.h b/WebCore/platform/graphics/mac/WebLayer.h
index af53ae6..3a91f04 100644
--- a/WebCore/platform/graphics/mac/WebLayer.h
+++ b/WebCore/platform/graphics/mac/WebLayer.h
@@ -53,12 +53,12 @@ namespace WebCore {
{
WebCore::GraphicsLayer* m_layerOwner;
}
-
-// Class method allows us to share implementation across TiledLayerMac and WebLayer
-+ (void)drawContents:(WebCore::GraphicsLayer*)layerContents ofLayer:(CALayer*)layer intoContext:(CGContextRef)context;
-
@end
+// Functions allows us to share implementation across WebTiledLayer and WebLayer
+void drawLayerContents(CGContextRef, CALayer *, WebCore::GraphicsLayer*);
+void setLayerNeedsDisplayInRect(CALayer *, WebCore::GraphicsLayer*, CGRect);
+
#endif // USE(ACCELERATED_COMPOSITING)
#endif // WebLayer_h
diff --git a/WebCore/platform/graphics/mac/WebLayer.mm b/WebCore/platform/graphics/mac/WebLayer.mm
index 0c9925e..9bb8212 100644
--- a/WebCore/platform/graphics/mac/WebLayer.mm
+++ b/WebCore/platform/graphics/mac/WebLayer.mm
@@ -31,6 +31,7 @@
#import "GraphicsContext.h"
#import "GraphicsLayer.h"
+#import <objc/objc-runtime.h>
#import <QuartzCore/QuartzCore.h>
#import <wtf/UnusedParam.h>
@@ -38,7 +39,7 @@ using namespace WebCore;
@implementation WebLayer
-+ (void)drawContents:(WebCore::GraphicsLayer*)layerContents ofLayer:(CALayer*)layer intoContext:(CGContextRef)context
+void drawLayerContents(CGContextRef context, CALayer *layer, WebCore::GraphicsLayer* layerContents)
{
if (!layerContents)
return;
@@ -110,6 +111,34 @@ using namespace WebCore;
CGContextRestoreGState(context);
}
+void setLayerNeedsDisplayInRect(CALayer *layer, WebCore::GraphicsLayer* layerContents, CGRect rect)
+{
+ if (layerContents && layerContents->client() && layerContents->drawsContent()) {
+ struct objc_super layerSuper = { layer, class_getSuperclass(object_getClass(layer)) };
+#if defined(BUILDING_ON_LEOPARD)
+ rect = CGRectApplyAffineTransform(rect, [layer contentsTransform]);
+#else
+ if (layerContents->contentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp)
+ rect.origin.y = [layer bounds].size.height - rect.origin.y - rect.size.height;
+#endif
+ objc_msgSendSuper(&layerSuper, @selector(setNeedsDisplayInRect:), rect);
+
+#ifndef NDEBUG
+ if (layerContents->showRepaintCounter()) {
+ CGRect bounds = [layer bounds];
+ CGRect indicatorRect = CGRectMake(bounds.origin.x, bounds.origin.y, 46, 25);
+#if defined(BUILDING_ON_LEOPARD)
+ indicatorRect = CGRectApplyAffineTransform(indicatorRect, [layer contentsTransform]);
+#else
+ if (layerContents->contentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp)
+ indicatorRect.origin.y = [layer bounds].size.height - indicatorRect.origin.y - indicatorRect.size.height;
+#endif
+ objc_msgSendSuper(&layerSuper, @selector(setNeedsDisplayInRect:), indicatorRect);
+ }
+#endif
+ }
+}
+
// Disable default animations
- (id<CAAction>)actionForKey:(NSString *)key
{
@@ -134,23 +163,7 @@ using namespace WebCore;
- (void)setNeedsDisplayInRect:(CGRect)dirtyRect
{
- if (m_layerOwner && m_layerOwner->client() && m_layerOwner->drawsContent()) {
-#if defined(BUILDING_ON_LEOPARD)
- dirtyRect = CGRectApplyAffineTransform(dirtyRect, [self contentsTransform]);
-#endif
- [super setNeedsDisplayInRect:dirtyRect];
-
-#ifndef NDEBUG
- if (m_layerOwner->showRepaintCounter()) {
- CGRect bounds = [self bounds];
- CGRect indicatorRect = CGRectMake(bounds.origin.x, bounds.origin.y, 46, 25);
-#if defined(BUILDING_ON_LEOPARD)
- indicatorRect = CGRectApplyAffineTransform(indicatorRect, [self contentsTransform]);
-#endif
- [super setNeedsDisplayInRect:indicatorRect];
- }
-#endif
- }
+ setLayerNeedsDisplayInRect(self, m_layerOwner, dirtyRect);
}
- (void)display
@@ -162,7 +175,7 @@ using namespace WebCore;
- (void)drawInContext:(CGContextRef)context
{
- [WebLayer drawContents:m_layerOwner ofLayer:self intoContext:context];
+ drawLayerContents(context, self, m_layerOwner);
}
@end // implementation WebLayer
diff --git a/WebCore/platform/graphics/mac/WebTiledLayer.mm b/WebCore/platform/graphics/mac/WebTiledLayer.mm
index 97ba233..72128ad 100644
--- a/WebCore/platform/graphics/mac/WebTiledLayer.mm
+++ b/WebCore/platform/graphics/mac/WebTiledLayer.mm
@@ -73,23 +73,7 @@ using namespace WebCore;
- (void)setNeedsDisplayInRect:(CGRect)dirtyRect
{
- if (m_layerOwner && m_layerOwner->client() && m_layerOwner->drawsContent()) {
-#if defined(BUILDING_ON_LEOPARD)
- dirtyRect = CGRectApplyAffineTransform(dirtyRect, [self contentsTransform]);
-#endif
- [super setNeedsDisplayInRect:dirtyRect];
-
-#ifndef NDEBUG
- if (m_layerOwner->showRepaintCounter()) {
- CGRect bounds = [self bounds];
- CGRect indicatorRect = CGRectMake(bounds.origin.x, bounds.origin.y, 46, 25);
-#if defined(BUILDING_ON_LEOPARD)
- indicatorRect = CGRectApplyAffineTransform(indicatorRect, [self contentsTransform]);
-#endif
- [super setNeedsDisplayInRect:indicatorRect];
- }
-#endif
- }
+ setLayerNeedsDisplayInRect(self, m_layerOwner, dirtyRect);
}
- (void)display
@@ -99,9 +83,9 @@ using namespace WebCore;
m_layerOwner->didDisplay(self);
}
-- (void)drawInContext:(CGContextRef)ctx
+- (void)drawInContext:(CGContextRef)context
{
- [WebLayer drawContents:m_layerOwner ofLayer:self intoContext:ctx];
+ drawLayerContents(context, self, m_layerOwner);
}
@end // implementation WebTiledLayer
diff --git a/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp b/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
index 12ae09d..7f4547d 100644
--- a/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
+++ b/WebCore/platform/graphics/opentype/OpenTypeUtilities.cpp
@@ -70,8 +70,8 @@ struct TableDirectoryEntry {
BigEndianULong length;
};
-#if !PLATFORM(CG)
-// Fixed type is not defined on non-CG platforms. |version| in sfntHeader
+#if !PLATFORM(CG) || !defined(COREGRAPHICS_INCLUDES_CORESERVICES_HEADER)
+// Fixed type is not defined on non-CG and Windows platforms. |version| in sfntHeader
// and headTable and |fontRevision| in headTable are of Fixed, but they're
// not actually refered to anywhere. Therefore, we just have to match
// the size (4 bytes). For the definition of Fixed type, see
diff --git a/WebCore/platform/graphics/openvg/PathOpenVG.cpp b/WebCore/platform/graphics/openvg/PathOpenVG.cpp
index 7e67036..e74ea57 100644
--- a/WebCore/platform/graphics/openvg/PathOpenVG.cpp
+++ b/WebCore/platform/graphics/openvg/PathOpenVG.cpp
@@ -123,6 +123,13 @@ Path& Path::operator=(const Path& other)
return *this;
}
+FloatPoint Path::currentPoint() const
+{
+ // FIXME: is this the way to return the current point of the subpath?
+ return m_currentPoint;
+}
+
+
bool Path::contains(const FloatPoint& point, WindRule rule) const
{
notImplemented();
diff --git a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
index 002765f..311d3a3 100644
--- a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
@@ -521,6 +521,15 @@ void GraphicsContext3D::makeContextCurrent()
void GraphicsContext3D::beginPaint(WebGLRenderingContext* context)
{
+ paintRenderingResultsToCanvas();
+}
+
+void GraphicsContext3D::endPaint()
+{
+}
+
+void GraphicsContext3D::paintRenderingResultsToCanvas(WebGLRenderingContext* context)
+{
m_internal->m_glWidget->makeCurrent();
HTMLCanvasElement* canvas = context->canvas();
ImageBuffer* imageBuffer = canvas->buffer();
@@ -528,10 +537,6 @@ void GraphicsContext3D::beginPaint(WebGLRenderingContext* context)
paint(painter, QRect(QPoint(0, 0), QSize(m_currentWidth, m_currentHeight)));
}
-void GraphicsContext3D::endPaint()
-{
-}
-
void GraphicsContext3D::paint(QPainter* painter, const QRect& rect) const
{
#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index 913a764..a828070 100644
--- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -358,7 +358,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
StrokeStyle style = strokeStyle();
Color color = strokeColor();
- if (style == NoStroke || !color.alpha())
+ if (style == NoStroke)
return;
float width = strokeThickness();
@@ -467,7 +467,7 @@ void GraphicsContext::drawEllipse(const IntRect& rect)
void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
{
- if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f || !strokeColor().alpha())
+ if (paintingDisabled() || strokeStyle() == NoStroke || strokeThickness() <= 0.0f)
return;
QPainter* p = m_data->p();
@@ -567,23 +567,20 @@ void GraphicsContext::fillPath()
return;
QPainter* p = m_data->p();
- QPainterPath path = m_data->currentPath;
+ QPainterPath& path = m_data->currentPath; // Avoid detaching the QPainterPath
path.setFillRule(toQtFillRule(fillRule()));
- if (m_common->state.fillPattern || m_common->state.fillGradient || fillColor().alpha()) {
- drawFilledShadowPath(this, p, path);
- if (m_common->state.fillPattern) {
- AffineTransform affine;
- p->fillPath(path, QBrush(m_common->state.fillPattern->createPlatformPattern(affine)));
- } else if (m_common->state.fillGradient) {
- QBrush brush(*m_common->state.fillGradient->platformGradient());
- brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform());
- p->fillPath(path, brush);
- } else {
- if (fillColor().alpha())
- p->fillPath(path, p->brush());
- }
- }
+ drawFilledShadowPath(this, p, path);
+ if (m_common->state.fillPattern) {
+ AffineTransform affine;
+ p->fillPath(path, QBrush(m_common->state.fillPattern->createPlatformPattern(affine)));
+ } else if (m_common->state.fillGradient) {
+ QBrush brush(*m_common->state.fillGradient->platformGradient());
+ brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform());
+ p->fillPath(path, brush);
+ } else
+ p->fillPath(path, p->brush());
+
m_data->currentPath = QPainterPath();
}
@@ -594,37 +591,33 @@ void GraphicsContext::strokePath()
QPainter* p = m_data->p();
QPen pen(p->pen());
- QPainterPath path = m_data->currentPath;
+ QPainterPath& path = m_data->currentPath; // Avoid detaching the QPainterPath
path.setFillRule(toQtFillRule(fillRule()));
- if (m_common->state.strokePattern || m_common->state.strokeGradient || strokeColor().alpha()) {
- FloatSize shadowSize;
- float shadowBlur;
- Color shadowColor;
- if (getShadow(shadowSize, shadowBlur, shadowColor)) {
- QTransform t(p->worldTransform());
- p->translate(shadowSize.width(), shadowSize.height());
- QPen shadowPen(pen);
- shadowPen.setColor(shadowColor);
- p->strokePath(path, shadowPen);
- p->setWorldTransform(t);
- }
- if (m_common->state.strokePattern) {
- AffineTransform affine;
- pen.setBrush(QBrush(m_common->state.strokePattern->createPlatformPattern(affine)));
- p->setPen(pen);
- p->strokePath(path, pen);
- } else if (m_common->state.strokeGradient) {
- QBrush brush(*m_common->state.strokeGradient->platformGradient());
- brush.setTransform(m_common->state.strokeGradient->gradientSpaceTransform());
- pen.setBrush(brush);
- p->setPen(pen);
- p->strokePath(path, pen);
- } else {
- if (strokeColor().alpha())
- p->strokePath(path, pen);
- }
+ FloatSize shadowSize;
+ float shadowBlur;
+ Color shadowColor;
+ if (getShadow(shadowSize, shadowBlur, shadowColor)) {
+ QTransform t(p->worldTransform());
+ p->translate(shadowSize.width(), shadowSize.height());
+ QPen shadowPen(pen);
+ shadowPen.setColor(shadowColor);
+ p->strokePath(path, shadowPen);
+ p->setWorldTransform(t);
}
+ if (m_common->state.strokePattern) {
+ AffineTransform affine;
+ pen.setBrush(QBrush(m_common->state.strokePattern->createPlatformPattern(affine)));
+ p->setPen(pen);
+ p->strokePath(path, pen);
+ } else if (m_common->state.strokeGradient) {
+ QBrush brush(*m_common->state.strokeGradient->platformGradient());
+ brush.setTransform(m_common->state.strokeGradient->gradientSpaceTransform());
+ pen.setBrush(brush);
+ p->setPen(pen);
+ p->strokePath(path, pen);
+ } else
+ p->strokePath(path, pen);
m_data->currentPath = QPainterPath();
}
@@ -713,28 +706,63 @@ void GraphicsContext::fillRect(const FloatRect& rect)
return;
QPainter* p = m_data->p();
+ FloatRect normalizedRect = rect.normalized();
- if (m_common->state.fillPattern || m_common->state.fillGradient || fillColor().alpha()) {
- if (m_common->state.shadowColor.isValid())
- drawBorderlessRectShadow(this, p, rect);
- if (m_common->state.fillPattern) {
- AffineTransform affine;
- FloatRect rectM(rect);
- QBrush brush(m_common->state.fillPattern->createPlatformPattern(affine));
- QPixmap* image = m_common->state.fillPattern->tileImage()->nativeImageForCurrentFrame();
-
- drawRepeatPattern(p, image, rect, m_common->state.fillPattern->repeatX(), m_common->state.fillPattern->repeatY());
- } else if (m_common->state.fillGradient) {
- QBrush brush(*m_common->state.fillGradient->platformGradient());
- brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform());
- p->fillRect(rect, brush);
- } else {
- if (fillColor().alpha())
- p->fillRect(rect, p->brush());
+ FloatSize shadowSize;
+ float shadowBlur;
+ Color shadowColor;
+ bool hasShadow = getShadow(shadowSize, shadowBlur, shadowColor);
+ FloatRect shadowDestRect;
+ QImage* shadowImage = 0;
+ QPainter* pShadow = 0;
+
+ if (hasShadow) {
+ shadowImage = new QImage(roundedIntSize(normalizedRect.size()), QImage::Format_ARGB32_Premultiplied);
+ pShadow = new QPainter(shadowImage);
+ shadowDestRect = normalizedRect;
+ shadowDestRect.move(shadowSize.width(), shadowSize.height());
+
+ pShadow->setCompositionMode(QPainter::CompositionMode_Source);
+ pShadow->fillRect(shadowImage->rect(), shadowColor);
+ pShadow->setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ }
+
+ if (m_common->state.fillPattern) {
+ AffineTransform affine;
+ FloatRect rectM(rect);
+ QBrush brush(m_common->state.fillPattern->createPlatformPattern(affine));
+ QPixmap* image = m_common->state.fillPattern->tileImage()->nativeImageForCurrentFrame();
+
+ if (hasShadow) {
+ drawRepeatPattern(pShadow, image, FloatRect(static_cast<QRectF>(shadowImage->rect())), m_common->state.fillPattern->repeatX(), m_common->state.fillPattern->repeatY());
+ pShadow->end();
+ p->drawImage(shadowDestRect, *shadowImage, shadowImage->rect());
+ }
+ drawRepeatPattern(p, image, normalizedRect, m_common->state.fillPattern->repeatX(), m_common->state.fillPattern->repeatY());
+ } else if (m_common->state.fillGradient) {
+ QBrush brush(*m_common->state.fillGradient->platformGradient());
+ brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform());
+
+ if (hasShadow) {
+ pShadow->fillRect(shadowImage->rect(), brush);
+ pShadow->end();
+ p->drawImage(shadowDestRect, *shadowImage, shadowImage->rect());
}
+ p->fillRect(normalizedRect, brush);
+ } else {
+ if (hasShadow) {
+ pShadow->fillRect(shadowImage->rect(), p->brush());
+ pShadow->end();
+ p->drawImage(shadowDestRect, *shadowImage, shadowImage->rect());
+ }
+ p->fillRect(normalizedRect, p->brush());
}
+
+ delete shadowImage;
+ delete pShadow;
}
+
void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
{
if (paintingDisabled() || !color.isValid())
@@ -749,7 +777,7 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS
void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace)
{
- if (paintingDisabled() || !color.isValid() || !color.alpha())
+ if (paintingDisabled() || !color.isValid())
return;
Path path = Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight);
@@ -1015,7 +1043,8 @@ void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
pen.setDashPattern(pattern);
pen.setDashOffset(dashOffset);
- }
+ } else
+ pen.setStyle(Qt::SolidLine);
p->setPen(pen);
}
diff --git a/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/WebCore/platform/graphics/qt/ImageBufferQt.cpp
index a546def..b4ca617 100644
--- a/WebCore/platform/graphics/qt/ImageBufferQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageBufferQt.cpp
@@ -98,6 +98,14 @@ GraphicsContext* ImageBuffer::context() const
return m_context.get();
}
+Image* ImageBuffer::imageForRendering() const
+{
+ if (!m_image)
+ m_image = StillImage::createForRendering(&m_data.m_pixmap);
+
+ return m_image.get();
+}
+
Image* ImageBuffer::image() const
{
if (!m_image) {
@@ -178,8 +186,13 @@ PassRefPtr<ImageData> getImageData(const IntRect& rect, const ImageBufferData& i
unsigned destBytesPerRow = 4 * rect.width();
unsigned char* destRows = data + desty * destBytesPerRow + destx * 4;
for (int y = 0; y < numRows; ++y) {
+#if QT_VERSION >= 0x040700
+ const quint32* scanLine = reinterpret_cast<const quint32*>(image.constScanLine(y + originy));
+#else
+ quint32* scanLine = reinterpret_cast<quint32*>(image.scanLine(y + originy));
+#endif
for (int x = 0; x < numColumns; x++) {
- QRgb value = image.pixel(x + originx, y + originy);
+ QRgb value = scanLine[x + originx];
int basex = x * 4;
destRows[basex] = qRed(value);
diff --git a/WebCore/platform/graphics/qt/ImageQt.cpp b/WebCore/platform/graphics/qt/ImageQt.cpp
index dd97873..e0ac574 100644
--- a/WebCore/platform/graphics/qt/ImageQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageQt.cpp
@@ -180,8 +180,6 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
return;
}
- IntSize selfSize = size();
-
QPainter* painter(ctxt->platformContext());
QPainter::CompositionMode compositionMode = GraphicsContext::toQtCompositionMode(op);
@@ -204,7 +202,7 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
p.setCompositionMode(QPainter::CompositionMode_Source);
p.fillRect(shadowImage.rect(), shadowColor);
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
- p.drawPixmap(normalizedDst, *image, normalizedSrc);
+ p.drawPixmap(QRect(0, 0, normalizedDst.width(), normalizedDst.height()), *image, normalizedSrc);
p.end();
painter->drawImage(shadowImageRect, shadowImage, normalizedSrc);
}
diff --git a/WebCore/platform/graphics/qt/PathQt.cpp b/WebCore/platform/graphics/qt/PathQt.cpp
index a367212..a8adb31 100644
--- a/WebCore/platform/graphics/qt/PathQt.cpp
+++ b/WebCore/platform/graphics/qt/PathQt.cpp
@@ -121,15 +121,18 @@ bool Path::contains(const FloatPoint& point, WindRule rule) const
return contains;
}
+static GraphicsContext* scratchContext()
+{
+ static ImageBuffer* scratch = ImageBuffer::create(IntSize(1, 1)).leakPtr();
+ return scratch->context();
+}
+
bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point) const
{
ASSERT(applier);
- // FIXME: We should try to use a 'shared Context' instead of creating a new ImageBuffer
- // on each call.
- OwnPtr<ImageBuffer> scratchImage = ImageBuffer::create(IntSize(1, 1));
- GraphicsContext* gc = scratchImage->context();
QPainterPathStroker stroke;
+ GraphicsContext* gc = scratchContext();
applier->strokeStyle(gc);
QPen pen = gc->pen();
@@ -157,10 +160,7 @@ FloatRect Path::boundingRect() const
FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
{
- // FIXME: We should try to use a 'shared Context' instead of creating a new ImageBuffer
- // on each call.
- OwnPtr<ImageBuffer> scratchImage = ImageBuffer::create(IntSize(1, 1));
- GraphicsContext* gc = scratchImage->context();
+ GraphicsContext* gc = scratchContext();
QPainterPathStroker stroke;
if (applier) {
applier->strokeStyle(gc);
@@ -198,22 +198,8 @@ void Path::addBezierCurveTo(const FloatPoint& cp1, const FloatPoint& cp2, const
void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius)
{
- // Make sure there is a subpath for p1, the behavior depend on the last element of the subpath.
- // When the user agent is to ensure there is a subpath for a coordinate (x, y), the user agent must
- // check to see if the context has any subpaths, and if it does not, then the user agent must create
- // a new subpath with the point (x, y) as its first (and only) point, as if the moveTo() method had been called.
- if (!m_path.elementCount()) {
- m_path.moveTo(p1);
- return;
- }
-
FloatPoint p0(m_path.currentPosition());
- if ((p1.x() == p0.x() && p1.y() == p0.y()) || (p1.x() == p2.x() && p1.y() == p2.y()) || radius == 0.f) {
- m_path.lineTo(p1);
- return;
- }
-
FloatPoint p1p0((p0.x() - p1.x()), (p0.y() - p1.y()));
FloatPoint p1p2((p2.x() - p1.x()), (p2.y() - p1.y()));
float p1p0_length = sqrtf(p1p0.x() * p1p0.x() + p1p0.y() * p1p0.y());
@@ -362,6 +348,11 @@ bool Path::hasCurrentPoint() const
return !isEmpty();
}
+FloatPoint Path::currentPoint() const
+{
+ return m_path.currentPosition();
+}
+
String Path::debugString() const
{
QString ret;
diff --git a/WebCore/platform/graphics/qt/StillImageQt.cpp b/WebCore/platform/graphics/qt/StillImageQt.cpp
index 4653c58..9c6acab 100644
--- a/WebCore/platform/graphics/qt/StillImageQt.cpp
+++ b/WebCore/platform/graphics/qt/StillImageQt.cpp
@@ -36,65 +36,65 @@
namespace WebCore {
StillImage::StillImage(const QPixmap& pixmap)
+ : m_pixmap(new QPixmap(pixmap))
+ , m_ownsPixmap(true)
+{}
+
+StillImage::StillImage(const QPixmap* pixmap)
: m_pixmap(pixmap)
+ , m_ownsPixmap(false)
{}
+StillImage::~StillImage()
+{
+ if (m_ownsPixmap)
+ delete m_pixmap;
+}
+
IntSize StillImage::size() const
{
- return IntSize(m_pixmap.width(), m_pixmap.height());
+ return IntSize(m_pixmap->width(), m_pixmap->height());
}
NativeImagePtr StillImage::nativeImageForCurrentFrame()
{
- return const_cast<NativeImagePtr>(&m_pixmap);
+ return const_cast<NativeImagePtr>(m_pixmap);
}
void StillImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
const FloatRect& src, ColorSpace, CompositeOperator op)
{
- if (m_pixmap.isNull())
+ if (m_pixmap->isNull())
return;
- ctxt->save();
- ctxt->setCompositeOperation(op);
- // To support width or height is negative
- float sx = src.x();
- float sy = src.y();
- float sw = src.width();
- float sh = src.height();
+ FloatRect normalizedSrc = src.normalized();
+ FloatRect normalizedDst = dst.normalized();
- if (sw < 0) {
- sx = sx + sw;
- sw = -sw;
- }
+ QPainter* painter = ctxt->platformContext();
+ QPainter::CompositionMode oldCompositionMode = painter->compositionMode();
- if (sh < 0) {
- sy = sy + sh;
- sh = -sh;
- }
-
- float dx = dst.x();
- float dy = dst.y();
- float dw = dst.width();
- float dh = dst.height();
-
- if (dw < 0) {
- dx = dx + dw;
- dw = -dw;
- }
+ ctxt->setCompositeOperation(op);
- if (dh < 0) {
- dy = dy + dh;
- dh = -dh;
+ FloatSize shadowSize;
+ float shadowBlur;
+ Color shadowColor;
+ if (ctxt->getShadow(shadowSize, shadowBlur, shadowColor)) {
+ FloatRect shadowImageRect(normalizedDst);
+ shadowImageRect.move(shadowSize.width(), shadowSize.height());
+
+ QImage shadowImage(QSize(static_cast<int>(normalizedSrc.width()), static_cast<int>(normalizedSrc.height())), QImage::Format_ARGB32_Premultiplied);
+ QPainter p(&shadowImage);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(shadowImage.rect(), shadowColor);
+ p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ p.drawPixmap(QRect(0, 0, normalizedDst.width(), normalizedDst.height()), *m_pixmap, normalizedSrc);
+ p.end();
+ painter->drawImage(shadowImageRect, shadowImage, normalizedSrc);
}
- FloatRect srcM(sx, sy, sw, sh);
- FloatRect dstM(dx, dy, dw, dh);
- QPainter* painter(ctxt->platformContext());
-
- painter->drawPixmap(dstM, m_pixmap, srcM);
- ctxt->restore();
+ painter->drawPixmap(normalizedDst, *m_pixmap, normalizedSrc);
+ painter->setCompositionMode(oldCompositionMode);
}
}
diff --git a/WebCore/platform/graphics/qt/StillImageQt.h b/WebCore/platform/graphics/qt/StillImageQt.h
index 7be9136..58071d9 100644
--- a/WebCore/platform/graphics/qt/StillImageQt.h
+++ b/WebCore/platform/graphics/qt/StillImageQt.h
@@ -39,6 +39,11 @@ namespace WebCore {
return adoptRef(new StillImage(pixmap));
}
+ static PassRefPtr<StillImage> createForRendering(const QPixmap* pixmap)
+ {
+ return adoptRef(new StillImage(pixmap));
+ }
+
// FIXME: StillImages are underreporting decoded sizes and will be unable
// to prune because these functions are not implemented yet.
virtual void destroyDecodedData(bool destroyAll = true) { Q_UNUSED(destroyAll); }
@@ -50,8 +55,11 @@ namespace WebCore {
private:
StillImage(const QPixmap& pixmap);
+ StillImage(const QPixmap* pixmap);
+ ~StillImage();
- QPixmap m_pixmap;
+ const QPixmap* m_pixmap;
+ bool m_ownsPixmap;
};
}
diff --git a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index 912fd12..f8192fe 100644
--- a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -74,7 +74,10 @@ ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, b
// Make the background transparent. It would be nice if this wasn't
// required, but the canvas is currently filled with the magic transparency
// color. Can we have another way to manage this?
- m_data.m_canvas.drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
+ //
+ // Avoid drawing on a zero-sized canvas. Skia can't handle it.
+ if (!size.isZero())
+ m_data.m_canvas.drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
success = true;
}
diff --git a/WebCore/platform/graphics/skia/PathSkia.cpp b/WebCore/platform/graphics/skia/PathSkia.cpp
index a0d4c79..12241f8 100644
--- a/WebCore/platform/graphics/skia/PathSkia.cpp
+++ b/WebCore/platform/graphics/skia/PathSkia.cpp
@@ -74,6 +74,13 @@ bool Path::hasCurrentPoint() const
return m_path->getPoints(NULL, 0) != 0;
}
+FloatPoint Path::currentPoint() const
+{
+ // FIXME: return current point of subpath.
+ float quietNaN = std::numeric_limits<float>::quiet_NaN();
+ return FloatPoint(quietNaN, quietNaN);
+}
+
bool Path::contains(const FloatPoint& point, WindRule rule) const
{
return SkPathContainsPoint(m_path, point,
diff --git a/WebCore/platform/graphics/skia/SkiaUtils.cpp b/WebCore/platform/graphics/skia/SkiaUtils.cpp
index 0c6b2d6..b16a344 100644
--- a/WebCore/platform/graphics/skia/SkiaUtils.cpp
+++ b/WebCore/platform/graphics/skia/SkiaUtils.cpp
@@ -129,10 +129,18 @@ static U8CPU InvScaleByte(U8CPU component, uint32_t scale)
SkColor SkPMColorToColor(SkPMColor pm)
{
- if (0 == pm)
+ if (!pm)
return 0;
-
unsigned a = SkGetPackedA32(pm);
+ if (!a) {
+ // A zero alpha value when there are non-zero R, G, or B channels is an
+ // invalid premultiplied color (since all channels should have been
+ // multiplied by 0 if a=0).
+ SkASSERT(false);
+ // In production, return 0 to protect against division by zero.
+ return 0;
+ }
+
uint32_t scale = (255 << 16) / a;
return SkColorSetARGB(a,
diff --git a/WebCore/platform/graphics/win/GraphicsLayerCACF.cpp b/WebCore/platform/graphics/win/GraphicsLayerCACF.cpp
index 20d76ef..96ac0c1 100644
--- a/WebCore/platform/graphics/win/GraphicsLayerCACF.cpp
+++ b/WebCore/platform/graphics/win/GraphicsLayerCACF.cpp
@@ -669,7 +669,7 @@ void GraphicsLayerCACF::updateLayerDrawsContent()
if (m_drawsContent)
m_layer->setNeedsDisplay();
else
- m_layer->setContents(nil);
+ m_layer->setContents(0);
updateDebugIndicators();
}
diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
index aa7bdd4..e0ecf78 100644
--- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
+++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp
@@ -46,6 +46,7 @@
#include "StringHash.h"
#include "TimeRanges.h"
#include "Timer.h"
+#include <AssertMacros.h>
#include <CoreGraphics/CGContext.h>
#include <Wininet.h>
#include <wtf/CurrentTime.h>
diff --git a/WebCore/platform/graphics/wince/PathWince.cpp b/WebCore/platform/graphics/wince/PathWince.cpp
index 00d03b1..747e650 100644
--- a/WebCore/platform/graphics/wince/PathWince.cpp
+++ b/WebCore/platform/graphics/wince/PathWince.cpp
@@ -160,4 +160,11 @@ bool Path::hasCurrentPoint() const
return !isEmpty();
}
+FloatPoint Path::currentPoint() const
+{
+ // FIXME: return current point of subpath.
+ float quietNaN = std::numeric_limits<float>::quiet_NaN();
+ return FloatPoint(quietNaN, quietNaN);
+}
+
}
diff --git a/WebCore/platform/graphics/wx/PathWx.cpp b/WebCore/platform/graphics/wx/PathWx.cpp
index 2305be0..3006e27 100644
--- a/WebCore/platform/graphics/wx/PathWx.cpp
+++ b/WebCore/platform/graphics/wx/PathWx.cpp
@@ -245,4 +245,11 @@ bool Path::hasCurrentPoint() const
return !isEmpty();
}
+FloatPoint Path::currentPoint() const
+{
+ // FIXME: return current point of subpath.
+ float quietNaN = std::numeric_limits<float>::quiet_NaN();
+ return FloatPoint(quietNaN, quietNaN);
+}
+
}
diff --git a/WebCore/platform/gtk/CursorGtk.cpp b/WebCore/platform/gtk/CursorGtk.cpp
index 017e486..a535f0c 100644
--- a/WebCore/platform/gtk/CursorGtk.cpp
+++ b/WebCore/platform/gtk/CursorGtk.cpp
@@ -57,38 +57,38 @@ static GdkCursor* customCursorNew(CustomCursorType cursorType)
Cursor::Cursor(const Cursor& other)
- : m_impl(other.m_impl)
+ : m_platformCursor(other.m_platformCursor)
{
- if (m_impl)
- gdk_cursor_ref(m_impl);
+ if (m_platformCursor)
+ gdk_cursor_ref(m_platformCursor);
}
Cursor::Cursor(Image* image, const IntPoint& hotSpot)
{
IntPoint effectiveHotSpot = determineHotSpot(image, hotSpot);
GdkPixbuf* pixbuf = image->getGdkPixbuf();
- m_impl = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pixbuf, effectiveHotSpot.x(), effectiveHotSpot.y());
+ m_platformCursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pixbuf, effectiveHotSpot.x(), effectiveHotSpot.y());
g_object_unref(pixbuf);
}
Cursor::~Cursor()
{
- if (m_impl)
- gdk_cursor_unref(m_impl);
+ if (m_platformCursor)
+ gdk_cursor_unref(m_platformCursor);
}
Cursor& Cursor::operator=(const Cursor& other)
{
- gdk_cursor_ref(other.m_impl);
- gdk_cursor_unref(m_impl);
- m_impl = other.m_impl;
+ gdk_cursor_ref(other.m_platformCursor);
+ gdk_cursor_unref(m_platformCursor);
+ m_platformCursor = other.m_platformCursor;
return *this;
}
Cursor::Cursor(GdkCursor* c)
- : m_impl(c)
+ : m_platformCursor(c)
{
- m_impl = c;
+ m_platformCursor = c;
// The GdkCursor may be NULL - the default cursor for the window.
if (c)
diff --git a/WebCore/platform/gtk/FileSystemGtk.cpp b/WebCore/platform/gtk/FileSystemGtk.cpp
index 401bd4a..7ad2a39 100644
--- a/WebCore/platform/gtk/FileSystemGtk.cpp
+++ b/WebCore/platform/gtk/FileSystemGtk.cpp
@@ -24,12 +24,13 @@
#include "GOwnPtr.h"
#include "PlatformString.h"
-#include <wtf/text/CString.h>
+#include <errno.h>
+#include <fcntl.h>
#include <glib.h>
#include <glib/gstdio.h>
-
#include <unistd.h>
+#include <wtf/text/CString.h>
namespace WebCore {
@@ -233,6 +234,22 @@ CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle)
return tempFilePath;
}
+PlatformFileHandle openFile(const String& path, FileOpenMode mode)
+{
+ CString fsRep = fileSystemRepresentation(path);
+
+ if (fsRep.isNull())
+ return invalidPlatformFileHandle;
+
+ int platformFlag = 0;
+ if (mode == OpenForRead)
+ platformFlag |= O_RDONLY;
+ else if (mode == OpenForWrite)
+ platformFlag |= (O_WRONLY | O_CREAT | O_TRUNC);
+
+ return g_open(fsRep.data(), platformFlag, 0666);
+}
+
void closeFile(PlatformFileHandle& handle)
{
if (isHandleValid(handle)) {
@@ -255,6 +272,17 @@ int writeToFile(PlatformFileHandle handle, const char* data, int length)
return totalBytesWritten;
}
+int readFromFile(PlatformFileHandle handle, char* data, int length)
+{
+ do {
+ int bytesRead = read(handle, data, static_cast<size_t>(length));
+ if (bytesRead >= 0)
+ return bytesRead;
+ } while (errno == EINTR);
+
+ return -1;
+}
+
bool unloadModule(PlatformModule module)
{
return g_module_close(module);
diff --git a/WebCore/platform/gtk/PasteboardHelper.cpp b/WebCore/platform/gtk/PasteboardHelper.cpp
index 111fb4e..2babe91 100644
--- a/WebCore/platform/gtk/PasteboardHelper.cpp
+++ b/WebCore/platform/gtk/PasteboardHelper.cpp
@@ -296,6 +296,7 @@ void PasteboardHelper::writeClipboardContents(GtkClipboard* clipboard, GClosure*
gtk_clipboard_set_with_data(clipboard, table, numberOfTargets,
getClipboardContentsCallback, clearClipboardContentsCallback, callback);
+ gtk_clipboard_set_can_store(clipboard, 0, 0);
settingClipboardDataObject = 0;
diff --git a/WebCore/platform/gtk/RenderThemeGtk.cpp b/WebCore/platform/gtk/RenderThemeGtk.cpp
index b70773e..bc0d147 100644
--- a/WebCore/platform/gtk/RenderThemeGtk.cpp
+++ b/WebCore/platform/gtk/RenderThemeGtk.cpp
@@ -762,11 +762,12 @@ bool RenderThemeGtk::paintMediaMuteButton(RenderObject* o, const PaintInfo& pain
bool RenderThemeGtk::paintMediaPlayButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
{
- HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(o);
- if (!mediaElement)
+ Node* node = o->node();
+ if (!node)
return false;
- return paintMediaButton(paintInfo.context, r, mediaElement->canPlay() ? m_playButton.get() : m_pauseButton.get(), m_panelColor, m_mediaIconSize);
+ MediaControlPlayButtonElement* button = static_cast<MediaControlPlayButtonElement*>(node);
+ return paintMediaButton(paintInfo.context, r, button->displayType() == MediaPlayButton ? m_playButton.get() : m_pauseButton.get(), m_panelColor, m_mediaIconSize);
}
bool RenderThemeGtk::paintMediaSeekBackButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
diff --git a/WebCore/platform/haiku/CursorHaiku.cpp b/WebCore/platform/haiku/CursorHaiku.cpp
index 21d678a..58833bc 100644
--- a/WebCore/platform/haiku/CursorHaiku.cpp
+++ b/WebCore/platform/haiku/CursorHaiku.cpp
@@ -34,31 +34,31 @@
namespace WebCore {
Cursor::Cursor(PlatformCursor cursor)
- : m_impl(cursor)
+ : m_platformCursor(cursor)
{
}
Cursor::Cursor(const Cursor& other)
- : m_impl(0)
+ : m_platformCursor(0)
{
*this = other;
}
Cursor::~Cursor()
{
- delete m_impl;
+ delete m_platformCursor;
}
Cursor::Cursor(Image*, const IntPoint&)
- : m_impl(0)
+ : m_platformCursor(0)
{
notImplemented();
}
Cursor& Cursor::operator=(const Cursor& other)
{
- delete m_impl;
- m_impl = other.m_impl ? new BCursor(*other.m_impl) : 0;
+ delete m_platformCursor;
+ m_platformCursor = other.m_platformCursor ? new BCursor(*other.m_platformCursor) : 0;
return *this;
}
diff --git a/WebCore/platform/image-encoders/skia/PNGImageEncoder.cpp b/WebCore/platform/image-encoders/skia/PNGImageEncoder.cpp
index 19363c8..a2e8760 100644
--- a/WebCore/platform/image-encoders/skia/PNGImageEncoder.cpp
+++ b/WebCore/platform/image-encoders/skia/PNGImageEncoder.cpp
@@ -36,6 +36,7 @@
#include "Vector.h"
#include "SkBitmap.h"
+#include "SkUnPreMultiply.h"
extern "C" {
#include "png.h"
@@ -57,6 +58,25 @@ static void convertBetweenBGRAandRGBA(const unsigned char* input, int numberOfPi
}
}
+// Converts BGRA->RGBA and RGBA->BGRA and undoes alpha premultiplication.
+static void preMultipliedBGRAtoRGBA(const unsigned char* input, int numberOfPixels,
+ unsigned char* output)
+{
+ SkBitmap inputBitmap;
+ inputBitmap.setConfig(SkBitmap::kARGB_8888_Config, numberOfPixels, 1);
+ inputBitmap.setPixels(const_cast<unsigned char*>(input));
+ for (int x = 0; x < numberOfPixels; x++) {
+ uint32_t srcPixel = *inputBitmap.getAddr32(x, 0);
+ SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(srcPixel);
+ unsigned char* pixelOut = &output[x * 4];
+ pixelOut[0] = SkColorGetR(unmultiplied);
+ pixelOut[1] = SkColorGetG(unmultiplied);
+ pixelOut[2] = SkColorGetB(unmultiplied);
+ pixelOut[3] = SkColorGetA(unmultiplied);
+ }
+}
+
+
// Encoder --------------------------------------------------------------------
//
// This section of the code is based on nsPNGEncoder.cpp in Mozilla
@@ -98,24 +118,12 @@ private:
png_info** m_pngInfo;
};
-// static
-bool PNGImageEncoder::encode(const SkBitmap& image, Vector<unsigned char>* output)
-{
- if (image.config() != SkBitmap::kARGB_8888_Config)
- return false; // Only support ARGB at 8 bpp now.
-
- image.lockPixels();
- bool result = PNGImageEncoder::encode(static_cast<unsigned char*>(
- image.getPixels()), IntSize(image.width(), image.height()),
- image.rowBytes(), output);
- image.unlockPixels();
- return result;
-}
-
-// static
-bool PNGImageEncoder::encode(const unsigned char* input, const IntSize& size,
- int bytesPerRow,
- Vector<unsigned char>* output)
+static bool encodeImpl(const unsigned char* input,
+ const IntSize& size,
+ int bytesPerRow,
+ Vector<unsigned char>* output,
+ void (*conversionFunc)(const unsigned char*, int, unsigned char*)
+ )
{
int inputColorComponents = 4;
int outputColorComponents = 4;
@@ -158,7 +166,7 @@ bool PNGImageEncoder::encode(const unsigned char* input, const IntSize& size,
OwnArrayPtr<unsigned char> rowPixels(new unsigned char[imageSize.width() * outputColorComponents]);
for (int y = 0; y < imageSize.height(); y ++) {
- convertBetweenBGRAandRGBA(&input[y * bytesPerRow], imageSize.width(), rowPixels.get());
+ conversionFunc(&input[y * bytesPerRow], imageSize.width(), rowPixels.get());
png_write_row(pngPtr, rowPixels.get());
}
@@ -166,4 +174,27 @@ bool PNGImageEncoder::encode(const unsigned char* input, const IntSize& size,
return true;
}
+
+// static
+bool PNGImageEncoder::encode(const SkBitmap& image, Vector<unsigned char>* output)
+{
+ if (image.config() != SkBitmap::kARGB_8888_Config)
+ return false; // Only support ARGB at 8 bpp now.
+
+ image.lockPixels();
+ bool result = encodeImpl(static_cast<unsigned char*>(
+ image.getPixels()), IntSize(image.width(), image.height()),
+ image.rowBytes(), output, preMultipliedBGRAtoRGBA);
+ image.unlockPixels();
+ return result;
+}
+
+// static
+bool PNGImageEncoder::encode(const unsigned char* input, const IntSize& size,
+ int bytesPerRow,
+ Vector<unsigned char>* output)
+{
+ return encodeImpl(input, size, bytesPerRow, output, convertBetweenBGRAandRGBA);
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/mac/CursorMac.mm b/WebCore/platform/mac/CursorMac.mm
index 8cd54a1..1b4c1b1 100644
--- a/WebCore/platform/mac/CursorMac.mm
+++ b/WebCore/platform/mac/CursorMac.mm
@@ -28,8 +28,6 @@
#import "BlockExceptions.h"
#import "FoundationExtras.h"
-#import "Image.h"
-#import "IntPoint.h"
#import <wtf/StdLibExtras.h>
@interface WebCoreCursorBundle : NSObject { }
@@ -50,7 +48,7 @@ static NSCursor* createCustomCursor(Image* image, const IntPoint& hotSpot)
if (!img)
return 0;
BEGIN_BLOCK_OBJC_EXCEPTIONS;
- return [[NSCursor alloc] initWithImage:img hotSpot:determineHotSpot(image, hotSpot)];
+ return [[NSCursor alloc] initWithImage:img hotSpot:hotSpot];
END_BLOCK_OBJC_EXCEPTIONS;
return 0;
}
@@ -76,281 +74,152 @@ static NSCursor* leakNamedCursor(const char* name, int x, int y)
return nil;
}
-Cursor::Cursor(Image* image, const IntPoint& hotSpot)
- : m_impl(HardRetainWithNSRelease(createCustomCursor(image, hotSpot)))
-{
+void Cursor::ensurePlatformCursor() const
+{
+ if (m_platformCursor)
+ return;
+
+ switch (m_type) {
+ case Cursor::Pointer:
+ m_platformCursor = HardRetain([NSCursor arrowCursor]);
+ break;
+ case Cursor::Cross:
+ m_platformCursor = HardRetain(leakNamedCursor("crossHairCursor", 11, 11));
+ break;
+ case Cursor::Hand:
+ m_platformCursor = HardRetain(leakNamedCursor("linkCursor", 6, 1));
+ break;
+ case Cursor::IBeam:
+ m_platformCursor = HardRetain([NSCursor IBeamCursor]);
+ break;
+ case Cursor::Wait:
+ m_platformCursor = HardRetain(leakNamedCursor("waitCursor", 7, 7));
+ break;
+ case Cursor::Help:
+ m_platformCursor = HardRetain(leakNamedCursor("helpCursor", 8, 8));
+ break;
+ case Cursor::Move:
+ case Cursor::MiddlePanning:
+ m_platformCursor = HardRetain(leakNamedCursor("moveCursor", 7, 7));
+ break;
+ case Cursor::EastResize:
+ case Cursor::EastPanning:
+ m_platformCursor = HardRetain(leakNamedCursor("eastResizeCursor", 14, 7));
+ break;
+ case Cursor::NorthResize:
+ case Cursor::NorthPanning:
+ m_platformCursor = HardRetain(leakNamedCursor("northResizeCursor", 7, 1));
+ break;
+ case Cursor::NorthEastResize:
+ case Cursor::NorthEastPanning:
+ m_platformCursor = HardRetain(leakNamedCursor("northEastResizeCursor", 14, 1));
+ break;
+ case Cursor::NorthWestResize:
+ case Cursor::NorthWestPanning:
+ m_platformCursor = HardRetain(leakNamedCursor("northWestResizeCursor", 0, 0));
+ break;
+ case Cursor::SouthResize:
+ case Cursor::SouthPanning:
+ m_platformCursor = HardRetain(leakNamedCursor("southResizeCursor", 7, 14));
+ break;
+ case Cursor::SouthEastResize:
+ case Cursor::SouthEastPanning:
+ m_platformCursor = HardRetain(leakNamedCursor("southEastResizeCursor", 14, 14));
+ break;
+ case Cursor::SouthWestResize:
+ case Cursor::SouthWestPanning:
+ m_platformCursor = HardRetain(leakNamedCursor("southWestResizeCursor", 1, 14));
+ break;
+ case Cursor::WestResize:
+ m_platformCursor = HardRetain(leakNamedCursor("westResizeCursor", 1, 7));
+ break;
+ case Cursor::NorthSouthResize:
+ m_platformCursor = HardRetain(leakNamedCursor("northSouthResizeCursor", 7, 7));
+ break;
+ case Cursor::EastWestResize:
+ case Cursor::WestPanning:
+ m_platformCursor = HardRetain(leakNamedCursor("eastWestResizeCursor", 7, 7));
+ break;
+ case Cursor::NorthEastSouthWestResize:
+ m_platformCursor = HardRetain(leakNamedCursor("northEastSouthWestResizeCursor", 7, 7));
+ break;
+ case Cursor::NorthWestSouthEastResize:
+ m_platformCursor = HardRetain(leakNamedCursor("northWestSouthEastResizeCursor", 7, 7));
+ break;
+ case Cursor::ColumnResize:
+ m_platformCursor = HardRetain([NSCursor resizeLeftRightCursor]);
+ break;
+ case Cursor::RowResize:
+ m_platformCursor = HardRetain([NSCursor resizeUpDownCursor]);
+ break;
+ case Cursor::VerticalText:
+ m_platformCursor = HardRetain(leakNamedCursor("verticalTextCursor", 7, 7));
+ break;
+ case Cursor::Cell:
+ m_platformCursor = HardRetain(leakNamedCursor("cellCursor", 7, 7));
+ break;
+ case Cursor::ContextMenu:
+ m_platformCursor = HardRetain(leakNamedCursor("contextMenuCursor", 3, 2));
+ break;
+ case Cursor::Alias:
+ m_platformCursor = HardRetain(leakNamedCursor("aliasCursor", 11, 3));
+ break;
+ case Cursor::Progress:
+ m_platformCursor = HardRetain(leakNamedCursor("progressCursor", 3, 2));
+ break;
+ case Cursor::NoDrop:
+ m_platformCursor = HardRetain(leakNamedCursor("noDropCursor", 3, 1));
+ break;
+ case Cursor::Copy:
+ m_platformCursor = HardRetain(leakNamedCursor("copyCursor", 3, 2));
+ break;
+ case Cursor::None:
+ m_platformCursor = HardRetain(leakNamedCursor("noneCursor", 7, 7));
+ break;
+ case Cursor::NotAllowed:
+ m_platformCursor = HardRetain(leakNamedCursor("notAllowedCursor", 11, 11));
+ break;
+ case Cursor::ZoomIn:
+ m_platformCursor = HardRetain(leakNamedCursor("zoomInCursor", 7, 7));
+ break;
+ case Cursor::ZoomOut:
+ m_platformCursor = HardRetain(leakNamedCursor("zoomOutCursor", 7, 7));
+ break;
+ case Cursor::Grab:
+ m_platformCursor = HardRetain([NSCursor openHandCursor]);
+ break;
+ case Cursor::Grabbing:
+ m_platformCursor = HardRetain([NSCursor closedHandCursor]);
+ break;
+ case Cursor::Custom:
+ m_platformCursor = HardRetainWithNSRelease(createCustomCursor(m_image.get(), m_hotSpot));
+ break;
+ }
}
Cursor::Cursor(const Cursor& other)
- : m_impl(HardRetain(other.m_impl))
+ : m_type(other.m_type)
+ , m_image(other.m_image)
+ , m_hotSpot(other.m_hotSpot)
+ , m_platformCursor(HardRetain(other.m_platformCursor))
{
}
-Cursor::~Cursor()
-{
- HardRelease(m_impl);
-}
-
Cursor& Cursor::operator=(const Cursor& other)
{
- HardRetain(other.m_impl);
- HardRelease(m_impl);
- m_impl = other.m_impl;
- return *this;
-}
-
-Cursor::Cursor(NSCursor* c)
- : m_impl(HardRetain(c))
-{
-}
-
-const Cursor& pointerCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor arrowCursor]));
- return c;
-}
-
-const Cursor& crossCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("crossHairCursor", 11, 11)));
- return c;
-}
-
-const Cursor& handCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("linkCursor", 6, 1)));
- return c;
-}
-
-const Cursor& moveCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("moveCursor", 7, 7)));
- return c;
-}
-
-const Cursor& verticalTextCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("verticalTextCursor", 7, 7)));
- return c;
-}
-
-const Cursor& cellCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("cellCursor", 7, 7)));
- return c;
-}
-
-const Cursor& contextMenuCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("contextMenuCursor", 3, 2)));
- return c;
-}
-
-const Cursor& aliasCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("aliasCursor", 11, 3)));
- return c;
-}
-
-const Cursor& zoomInCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("zoomInCursor", 7, 7)));
- return c;
-}
-
-const Cursor& zoomOutCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("zoomOutCursor", 7, 7)));
- return c;
-}
-
-const Cursor& copyCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("copyCursor", 3, 2)));
- return c;
-}
-
-const Cursor& noneCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("noneCursor", 7, 7)));
- return c;
-}
-
-const Cursor& progressCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("progressCursor", 3, 2)));
- return c;
-}
-
-const Cursor& noDropCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("noDropCursor", 3, 1)));
- return c;
-}
-
-const Cursor& notAllowedCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("notAllowedCursor", 11, 11)));
- return c;
-}
-
-const Cursor& iBeamCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor IBeamCursor]));
- return c;
-}
-
-const Cursor& waitCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("waitCursor", 7, 7)));
- return c;
-}
-
-const Cursor& helpCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("helpCursor", 8, 8)));
- return c;
-}
-
-const Cursor& eastResizeCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("eastResizeCursor", 14, 7)));
- return c;
-}
-
-const Cursor& northResizeCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northResizeCursor", 7, 1)));
- return c;
-}
-
-const Cursor& northEastResizeCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northEastResizeCursor", 14, 1)));
- return c;
-}
-
-const Cursor& northWestResizeCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northWestResizeCursor", 0, 0)));
- return c;
-}
-
-const Cursor& southResizeCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("southResizeCursor", 7, 14)));
- return c;
-}
-
-const Cursor& southEastResizeCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("southEastResizeCursor", 14, 14)));
- return c;
-}
-
-const Cursor& southWestResizeCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("southWestResizeCursor", 1, 14)));
- return c;
-}
-
-const Cursor& westResizeCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("westResizeCursor", 1, 7)));
- return c;
-}
-
-const Cursor& northSouthResizeCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northSouthResizeCursor", 7, 7)));
- return c;
-}
-
-const Cursor& eastWestResizeCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("eastWestResizeCursor", 7, 7)));
- return c;
-}
-
-const Cursor& northEastSouthWestResizeCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northEastSouthWestResizeCursor", 7, 7)));
- return c;
-}
+ m_type = other.m_type;
+ m_image = other.m_image;
+ m_hotSpot = other.m_hotSpot;
-const Cursor& northWestSouthEastResizeCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northWestSouthEastResizeCursor", 7, 7)));
- return c;
-}
-
-const Cursor& columnResizeCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor resizeLeftRightCursor]));
- return c;
-}
-
-const Cursor& rowResizeCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor resizeUpDownCursor]));
- return c;
-}
-
-const Cursor& middlePanningCursor()
-{
- return moveCursor();
-}
-
-const Cursor& eastPanningCursor()
-{
- return eastResizeCursor();
-}
-
-const Cursor& northPanningCursor()
-{
- return northResizeCursor();
-}
-
-const Cursor& northEastPanningCursor()
-{
- return northEastResizeCursor();
-}
-
-const Cursor& northWestPanningCursor()
-{
- return northWestResizeCursor();
-}
-
-const Cursor& southPanningCursor()
-{
- return southResizeCursor();
-}
-
-const Cursor& southEastPanningCursor()
-{
- return southEastResizeCursor();
-}
-
-const Cursor& southWestPanningCursor()
-{
- return southWestResizeCursor();
-}
-
-const Cursor& westPanningCursor()
-{
- return westResizeCursor();
-}
-
-const Cursor& grabCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor openHandCursor]));
- return c;
+ HardRetain(other.m_platformCursor);
+ HardRelease(m_platformCursor);
+ m_platformCursor = other.m_platformCursor;
+ return *this;
}
-const Cursor& grabbingCursor()
+Cursor::~Cursor()
{
- DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor closedHandCursor]));
- return c;
+ HardRelease(m_platformCursor);
}
-}
+} // namespace WebCore
diff --git a/WebCore/platform/mac/FileSystemMac.mm b/WebCore/platform/mac/FileSystemMac.mm
index 98f85bb..0df3c89 100644
--- a/WebCore/platform/mac/FileSystemMac.mm
+++ b/WebCore/platform/mac/FileSystemMac.mm
@@ -29,6 +29,7 @@
#import "FileSystem.h"
#import "PlatformString.h"
+#import <wtf/text/CString.h>
namespace WebCore {
@@ -37,4 +38,28 @@ String homeDirectoryPath()
return NSHomeDirectory();
}
+CString openTemporaryFile(const char* prefix, PlatformFileHandle& platformFileHandle)
+{
+ platformFileHandle = invalidPlatformFileHandle;
+
+ Vector<char> temporaryFilePath(PATH_MAX);
+ if (!confstr(_CS_DARWIN_USER_TEMP_DIR, temporaryFilePath.data(), temporaryFilePath.size()))
+ return CString();
+
+ // Shrink the vector.
+ temporaryFilePath.shrink(strlen(temporaryFilePath.data()));
+ ASSERT(temporaryFilePath.last() == '/');
+
+ // Append the file name.
+ temporaryFilePath.append(prefix, strlen(prefix));
+ temporaryFilePath.append("XXXXXX", 6);
+ temporaryFilePath.append('\0');
+
+ platformFileHandle = mkstemp(temporaryFilePath.data());
+ if (platformFileHandle == invalidPlatformFileHandle)
+ return CString();
+
+ return CString(temporaryFilePath.data());
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/mac/ThemeMac.mm b/WebCore/platform/mac/ThemeMac.mm
index 20b662f..c57e8df 100644
--- a/WebCore/platform/mac/ThemeMac.mm
+++ b/WebCore/platform/mac/ThemeMac.mm
@@ -687,7 +687,7 @@ void ThemeMac::inflateControlPaintRect(ControlPart part, ControlStates states, I
break;
}
case OuterSpinButtonPart: {
- static const int stepperMargin[4] = { 0, 0, 0, 0};
+ static const int stepperMargin[4] = { 0, 0, 0, 0 };
ControlSize controlSize = controlSizeFromPixelSize(stepperSizes(), zoomedRect.size(), zoomFactor);
IntSize zoomedSize = stepperSizes()[controlSize];
zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
diff --git a/WebCore/platform/mac/WidgetMac.mm b/WebCore/platform/mac/WidgetMac.mm
index 37c9e9f..2598591 100644
--- a/WebCore/platform/mac/WidgetMac.mm
+++ b/WebCore/platform/mac/WidgetMac.mm
@@ -123,11 +123,12 @@ void Widget::setFocus(bool focused)
END_BLOCK_OBJC_EXCEPTIONS;
}
- void Widget::setCursor(const Cursor& cursor)
- {
- if ([NSCursor currentCursor] == cursor.impl())
+void Widget::setCursor(const Cursor& cursor)
+{
+ ScrollView* view = root();
+ if (!view)
return;
- [cursor.impl() set];
+ view->hostWindow()->setCursor(cursor);
}
void Widget::show()
diff --git a/WebCore/platform/network/Credential.cpp b/WebCore/platform/network/Credential.cpp
index 87cd7ff..4b24403 100644
--- a/WebCore/platform/network/Credential.cpp
+++ b/WebCore/platform/network/Credential.cpp
@@ -114,7 +114,7 @@ CFArrayRef Credential::certificates() const
return m_certificates.get();
}
-const CredentialType Credential::type() const
+CredentialType Credential::type() const
{
return m_type;
}
diff --git a/WebCore/platform/network/Credential.h b/WebCore/platform/network/Credential.h
index 199817c..4fb8bfd 100644
--- a/WebCore/platform/network/Credential.h
+++ b/WebCore/platform/network/Credential.h
@@ -69,7 +69,7 @@ public:
#if CERTIFICATE_CREDENTIALS_SUPPORTED
SecIdentityRef identity() const;
CFArrayRef certificates() const;
- const CredentialType type() const;
+ CredentialType type() const;
#endif
private:
diff --git a/WebCore/platform/network/CredentialStorage.cpp b/WebCore/platform/network/CredentialStorage.cpp
index a48af77..14f4086 100644
--- a/WebCore/platform/network/CredentialStorage.cpp
+++ b/WebCore/platform/network/CredentialStorage.cpp
@@ -106,6 +106,11 @@ Credential CredentialStorage::get(const ProtectionSpace& protectionSpace)
return protectionSpaceToCredentialMap().get(protectionSpace);
}
+void CredentialStorage::remove(const ProtectionSpace& protectionSpace)
+{
+ protectionSpaceToCredentialMap().remove(protectionSpace);
+}
+
static PathToDefaultProtectionSpaceMap::iterator findDefaultProtectionSpaceForURL(const KURL& url)
{
ASSERT(url.protocolInHTTPFamily());
diff --git a/WebCore/platform/network/CredentialStorage.h b/WebCore/platform/network/CredentialStorage.h
index ff7b5ee..d11384d 100644
--- a/WebCore/platform/network/CredentialStorage.h
+++ b/WebCore/platform/network/CredentialStorage.h
@@ -37,6 +37,7 @@ public:
// WebCore session credential storage.
static void set(const Credential&, const ProtectionSpace&, const KURL&);
static Credential get(const ProtectionSpace&);
+ static void remove(const ProtectionSpace&);
// OS persistent storage.
static Credential getFromPersistentStorage(const ProtectionSpace&);
diff --git a/WebCore/platform/network/FormData.cpp b/WebCore/platform/network/FormData.cpp
index 9e4a227..80f17da 100644
--- a/WebCore/platform/network/FormData.cpp
+++ b/WebCore/platform/network/FormData.cpp
@@ -224,7 +224,12 @@ void FormData::appendKeyValuePairItems(const BlobItemList& items, const TextEnco
const FileBlobItem* fileItem = value->toFileBlobItem();
if (fileItem) {
const String& path = fileItem->path();
+
+#if ENABLE(DIRECTORY_UPLOAD)
+ String fileName = !fileItem->relativePath().isEmpty() ? fileItem->relativePath() : fileItem->name();
+#else
String fileName = fileItem->name();
+#endif
// Let the application specify a filename if it's going to generate a replacement file for the upload.
if (!path.isEmpty()) {
diff --git a/WebCore/platform/network/NetworkStateNotifier.h b/WebCore/platform/network/NetworkStateNotifier.h
index ade27fd..21d0067 100644
--- a/WebCore/platform/network/NetworkStateNotifier.h
+++ b/WebCore/platform/network/NetworkStateNotifier.h
@@ -129,7 +129,7 @@ inline NetworkStateNotifier::NetworkStateNotifier()
: m_isOnLine(true)
#if PLATFORM(ANDROID)
// TODO: Upstream to webkit.org
- , m_type(Connection::Unknown)
+ , m_type(Connection::UNKNOWN)
#endif
, m_networkStateChangedFunction(0)
{
diff --git a/WebCore/platform/network/ResourceHandle.cpp b/WebCore/platform/network/ResourceHandle.cpp
index d3ee3f2..0575523 100644
--- a/WebCore/platform/network/ResourceHandle.cpp
+++ b/WebCore/platform/network/ResourceHandle.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,30 +37,28 @@ namespace WebCore {
static bool shouldForceContentSniffing;
-ResourceHandle::ResourceHandle(const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading,
- bool shouldContentSniff)
- : d(new ResourceHandleInternal(this, request, client, defersLoading, shouldContentSniff))
+ResourceHandle::ResourceHandle(const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading, bool shouldContentSniff)
+ : d(new ResourceHandleInternal(this, request, client, defersLoading, shouldContentSniff && shouldContentSniffURL(request.url())))
{
+ if (!request.url().isValid()) {
+ scheduleFailure(InvalidURLFailure);
+ return;
+ }
+
+ if (!portAllowed(request.url())) {
+ scheduleFailure(BlockedFailure);
+ return;
+ }
}
PassRefPtr<ResourceHandle> ResourceHandle::create(const ResourceRequest& request, ResourceHandleClient* client,
Frame* frame, bool defersLoading, bool shouldContentSniff)
{
- if (shouldContentSniff)
- shouldContentSniff = shouldContentSniffURL(request.url());
-
RefPtr<ResourceHandle> newHandle(adoptRef(new ResourceHandle(request, client, defersLoading, shouldContentSniff)));
- if (!request.url().isValid()) {
- newHandle->scheduleFailure(InvalidURLFailure);
+ if (newHandle->d->m_scheduledFailureType != NoFailure)
return newHandle.release();
- }
- if (!portAllowed(request.url())) {
- newHandle->scheduleFailure(BlockedFailure);
- return newHandle.release();
- }
-
if (newHandle->start(frame))
return newHandle.release();
@@ -105,9 +103,9 @@ void ResourceHandle::setClient(ResourceHandleClient* client)
d->m_client = client;
}
-const ResourceRequest& ResourceHandle::request() const
+ResourceRequest& ResourceHandle::firstRequest()
{
- return d->m_request;
+ return d->m_firstRequest;
}
const String& ResourceHandle::lastHTTPMethod() const
@@ -115,6 +113,11 @@ const String& ResourceHandle::lastHTTPMethod() const
return d->m_lastHTTPMethod;
}
+bool ResourceHandle::hasAuthenticationChallenge() const
+{
+ return !d->m_currentWebChallenge.isNull();
+}
+
void ResourceHandle::clearAuthentication()
{
#if PLATFORM(MAC)
diff --git a/WebCore/platform/network/ResourceHandle.h b/WebCore/platform/network/ResourceHandle.h
index e1c889a..3dc38f8 100644
--- a/WebCore/platform/network/ResourceHandle.h
+++ b/WebCore/platform/network/ResourceHandle.h
@@ -110,8 +110,8 @@ private:
public:
// FIXME: should not need the Frame
static PassRefPtr<ResourceHandle> create(const ResourceRequest&, ResourceHandleClient*, Frame*, bool defersLoading, bool shouldContentSniff);
-
static void loadResourceSynchronously(const ResourceRequest&, StoredCredentials, ResourceError&, ResourceResponse&, Vector<char>& data, Frame* frame);
+
static void prepareForURL(const KURL&);
static bool willLoadFromCache(ResourceRequest&, Frame*);
static void cacheMetadata(const ResourceResponse&, const Vector<char>&);
@@ -187,7 +187,8 @@ public:
// Used to work around the fact that you don't get any more NSURLConnection callbacks until you return from the one you're in.
static bool loadsBlocked();
-
+
+ bool hasAuthenticationChallenge() const;
void clearAuthentication();
void cancel();
@@ -200,8 +201,8 @@ public:
// TODO: this needs upstreaming.
void pauseLoad(bool);
#endif
-
- const ResourceRequest& request() const;
+
+ ResourceRequest& firstRequest();
const String& lastHTTPMethod() const;
void fireFailure(Timer<ResourceHandle>*);
@@ -219,6 +220,12 @@ private:
virtual void refAuthenticationClient() { ref(); }
virtual void derefAuthenticationClient() { deref(); }
+#if PLATFORM(MAC)
+ void createNSURLConnection(id delegate, bool shouldUseCredentialStorage, bool shouldContentSniff);
+#elif PLATFORM(CF)
+ void createCFURLConnection(bool shouldUseCredentialStorage, bool shouldContentSniff);
+#endif
+
friend class ResourceHandleInternal;
OwnPtr<ResourceHandleInternal> d;
};
diff --git a/WebCore/platform/network/ResourceHandleInternal.h b/WebCore/platform/network/ResourceHandleInternal.h
index 92b24cb..7b6e960 100644
--- a/WebCore/platform/network/ResourceHandleInternal.h
+++ b/WebCore/platform/network/ResourceHandleInternal.h
@@ -83,7 +83,7 @@ namespace WebCore {
public:
ResourceHandleInternal(ResourceHandle* loader, const ResourceRequest& request, ResourceHandleClient* c, bool defersLoading, bool shouldContentSniff)
: m_client(c)
- , m_request(request)
+ , m_firstRequest(request)
, m_lastHTTPMethod(request.httpMethod())
, status(0)
, m_defersLoading(defersLoading)
@@ -136,10 +136,10 @@ namespace WebCore {
, m_scheduledFailureType(ResourceHandle::NoFailure)
, m_failureTimer(loader, &ResourceHandle::fireFailure)
{
- const KURL& url = m_request.url();
+ const KURL& url = m_firstRequest.url();
m_user = url.user();
m_pass = url.pass();
- m_request.removeCredentials();
+ m_firstRequest.removeCredentials();
}
~ResourceHandleInternal();
@@ -147,7 +147,7 @@ namespace WebCore {
ResourceHandleClient* client() { return m_client; }
ResourceHandleClient* m_client;
- ResourceRequest m_request;
+ ResourceRequest m_firstRequest;
String m_lastHTTPMethod;
// Suggested credentials for the current redirection step.
diff --git a/WebCore/platform/network/ResourceResponseBase.cpp b/WebCore/platform/network/ResourceResponseBase.cpp
index 89d31d7..f30344e 100644
--- a/WebCore/platform/network/ResourceResponseBase.cpp
+++ b/WebCore/platform/network/ResourceResponseBase.cpp
@@ -45,6 +45,7 @@ ResourceResponseBase::ResourceResponseBase()
, m_lastModifiedDate(0)
, m_wasCached(false)
, m_connectionID(0)
+ , m_connectionReused(false)
, m_isNull(true)
, m_haveParsedCacheControlHeader(false)
, m_haveParsedAgeHeader(false)
@@ -72,6 +73,7 @@ ResourceResponseBase::ResourceResponseBase(const KURL& url, const String& mimeTy
, m_lastModifiedDate(0)
, m_wasCached(false)
, m_connectionID(0)
+ , m_connectionReused(false)
, m_isNull(false)
, m_haveParsedCacheControlHeader(false)
, m_haveParsedAgeHeader(false)
@@ -471,6 +473,20 @@ void ResourceResponseBase::setWasCached(bool value)
m_wasCached = value;
}
+bool ResourceResponseBase::connectionReused() const
+{
+ lazyInit();
+
+ return m_connectionReused;
+}
+
+void ResourceResponseBase::setConnectionReused(bool connectionReused)
+{
+ lazyInit();
+
+ m_connectionReused = connectionReused;
+}
+
unsigned ResourceResponseBase::connectionID() const
{
lazyInit();
diff --git a/WebCore/platform/network/ResourceResponseBase.h b/WebCore/platform/network/ResourceResponseBase.h
index 858a612..65e24ad 100644
--- a/WebCore/platform/network/ResourceResponseBase.h
+++ b/WebCore/platform/network/ResourceResponseBase.h
@@ -100,6 +100,9 @@ public:
unsigned connectionID() const;
void setConnectionID(unsigned);
+ bool connectionReused() const;
+ void setConnectionReused(bool);
+
bool wasCached() const;
void setWasCached(bool);
@@ -136,8 +139,9 @@ protected:
String m_httpStatusText;
HTTPHeaderMap m_httpHeaderFields;
time_t m_lastModifiedDate;
- bool m_wasCached;
+ bool m_wasCached : 1;
unsigned m_connectionID;
+ bool m_connectionReused : 1;
RefPtr<ResourceLoadTiming> m_resourceLoadTiming;
bool m_isNull : 1;
diff --git a/WebCore/platform/network/android/ResourceHandleAndroid.cpp b/WebCore/platform/network/android/ResourceHandleAndroid.cpp
index b8bc6da..fbafd6d 100644
--- a/WebCore/platform/network/android/ResourceHandleAndroid.cpp
+++ b/WebCore/platform/network/android/ResourceHandleAndroid.cpp
@@ -55,7 +55,7 @@ bool ResourceHandle::start(Frame* frame)
bool isMainResource =
static_cast<void*>(mainLoader) == static_cast<void*>(client());
- PassRefPtr<ResourceLoaderAndroid> loader = ResourceLoaderAndroid::start(this, d->m_request, frame->loader()->client(), isMainResource, false);
+ PassRefPtr<ResourceLoaderAndroid> loader = ResourceLoaderAndroid::start(this, d->m_firstRequest, frame->loader()->client(), isMainResource, false);
if (loader) {
d->m_loader = loader;
diff --git a/WebCore/platform/network/cf/ResourceErrorCF.cpp b/WebCore/platform/network/cf/ResourceErrorCF.cpp
index dacc68b..1eba97e 100644
--- a/WebCore/platform/network/cf/ResourceErrorCF.cpp
+++ b/WebCore/platform/network/cf/ResourceErrorCF.cpp
@@ -115,7 +115,7 @@ ResourceError::operator CFErrorRef() const
{
if (m_isNull) {
ASSERT(!m_platformError);
- return nil;
+ return 0;
}
if (!m_platformError) {
diff --git a/WebCore/platform/network/cf/ResourceHandleCFNet.cpp b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
index 1139126..419e397 100644
--- a/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
+++ b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
@@ -66,36 +66,40 @@ namespace WebCore {
static CFStringRef WebCoreSynchronousLoaderRunLoopMode = CFSTR("WebCoreSynchronousLoaderRunLoopMode");
-class WebCoreSynchronousLoader {
+class WebCoreSynchronousLoaderClient : public ResourceHandleClient {
public:
- static RetainPtr<CFDataRef> load(const ResourceRequest&, StoredCredentials, ResourceResponse&, ResourceError&);
+ static PassOwnPtr<WebCoreSynchronousLoaderClient> create(ResourceResponse& response, ResourceError& error)
+ {
+ return adoptPtr(new WebCoreSynchronousLoaderClient(response, error));
+ }
+
+ void setAllowStoredCredentials(bool allow) { m_allowStoredCredentials = allow; }
+ bool isDone() { return m_isDone; }
+
+ CFMutableDataRef data() { return m_data.get(); }
private:
- WebCoreSynchronousLoader(ResourceResponse& response, ResourceError& error)
- : m_isDone(false)
+ WebCoreSynchronousLoaderClient(ResourceResponse& response, ResourceError& error)
+ : m_allowStoredCredentials(false)
, m_response(response)
, m_error(error)
+ , m_isDone(false)
{
}
- static CFURLRequestRef willSendRequest(CFURLConnectionRef, CFURLRequestRef, CFURLResponseRef, const void* clientInfo);
- static void didReceiveResponse(CFURLConnectionRef, CFURLResponseRef, const void* clientInfo);
- static void didReceiveData(CFURLConnectionRef, CFDataRef, CFIndex, const void* clientInfo);
- static void didFinishLoading(CFURLConnectionRef, const void* clientInfo);
- static void didFail(CFURLConnectionRef, CFErrorRef, const void* clientInfo);
- static void didReceiveChallenge(CFURLConnectionRef, CFURLAuthChallengeRef, const void* clientInfo);
- static Boolean shouldUseCredentialStorage(CFURLConnectionRef, const void* clientInfo);
+ virtual void willSendRequest(ResourceHandle*, ResourceRequest&, const ResourceResponse& /*redirectResponse*/);
+ virtual bool shouldUseCredentialStorage(ResourceHandle*);
+ virtual void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&);
+ virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
+ virtual void didReceiveData(ResourceHandle*, const char*, int, int /*lengthReceived*/);
+ virtual void didFinishLoading(ResourceHandle*);
+ virtual void didFail(ResourceHandle*, const ResourceError&);
- bool m_isDone;
- RetainPtr<CFURLRef> m_url;
- RetainPtr<CFStringRef> m_user;
- RetainPtr<CFStringRef> m_pass;
- // Store the preemptively used initial credential so that if we get an authentication challenge, we won't use the same one again.
- Credential m_initialCredential;
bool m_allowStoredCredentials;
ResourceResponse& m_response;
RetainPtr<CFMutableDataRef> m_data;
ResourceError& m_error;
+ bool m_isDone;
};
static HashSet<String>& allowsAnyHTTPSCertificateHosts()
@@ -137,7 +141,7 @@ CFURLRequestRef willSendRequest(CFURLConnectionRef conn, CFURLRequestRef cfReque
return cfRequest;
}
- LOG(Network, "CFNet - willSendRequest(conn=%p, handle=%p) (%s)", conn, handle, handle->request().url().string().utf8().data());
+ LOG(Network, "CFNet - willSendRequest(conn=%p, handle=%p) (%s)", conn, handle, handle->firstRequest().url().string().utf8().data());
ResourceRequest request;
if (cfRedirectResponse) {
@@ -149,11 +153,11 @@ CFURLRequestRef willSendRequest(CFURLConnectionRef conn, CFURLRequestRef cfReque
RetainPtr<CFMutableURLRequestRef> mutableRequest(AdoptCF, CFURLRequestCreateMutableCopy(0, cfRequest));
CFURLRequestSetHTTPRequestMethod(mutableRequest.get(), lastHTTPMethod.get());
- FormData* body = handle->request().httpBody();
- if (!equalIgnoringCase(handle->request().httpMethod(), "GET") && body && !body->isEmpty())
+ FormData* body = handle->firstRequest().httpBody();
+ if (!equalIgnoringCase(handle->firstRequest().httpMethod(), "GET") && body && !body->isEmpty())
WebCore::setHTTPBody(mutableRequest.get(), body);
- String originalContentType = handle->request().httpContentType();
+ String originalContentType = handle->firstRequest().httpContentType();
RetainPtr<CFStringRef> originalContentTypeCF(AdoptCF, originalContentType.createCFString());
if (!originalContentType.isEmpty())
CFURLRequestSetHTTPHeaderFieldValue(mutableRequest.get(), CFSTR("Content-Type"), originalContentTypeCF.get());
@@ -184,7 +188,7 @@ void didReceiveResponse(CFURLConnectionRef conn, CFURLResponseRef cfResponse, co
{
ResourceHandle* handle = static_cast<ResourceHandle*>(const_cast<void*>(clientInfo));
- LOG(Network, "CFNet - didReceiveResponse(conn=%p, handle=%p) (%s)", conn, handle, handle->request().url().string().utf8().data());
+ LOG(Network, "CFNet - didReceiveResponse(conn=%p, handle=%p) (%s)", conn, handle, handle->firstRequest().url().string().utf8().data());
if (!handle->client())
return;
@@ -204,7 +208,7 @@ void didReceiveData(CFURLConnectionRef conn, CFDataRef data, CFIndex originalLen
const UInt8* bytes = CFDataGetBytePtr(data);
CFIndex length = CFDataGetLength(data);
- LOG(Network, "CFNet - didReceiveData(conn=%p, handle=%p, bytes=%d) (%s)", conn, handle, length, handle->request().url().string().utf8().data());
+ LOG(Network, "CFNet - didReceiveData(conn=%p, handle=%p, bytes=%d) (%s)", conn, handle, length, handle->firstRequest().url().string().utf8().data());
if (handle->client())
handle->client()->didReceiveData(handle, (const char*)bytes, length, originalLength);
@@ -222,7 +226,7 @@ static Boolean shouldUseCredentialStorageCallback(CFURLConnectionRef conn, const
{
ResourceHandle* handle = const_cast<ResourceHandle*>(static_cast<const ResourceHandle*>(clientInfo));
- LOG(Network, "CFNet - shouldUseCredentialStorage(conn=%p, handle=%p) (%s)", conn, handle, handle->request().url().string().utf8().data());
+ LOG(Network, "CFNet - shouldUseCredentialStorage(conn=%p, handle=%p) (%s)", conn, handle, handle->firstRequest().url().string().utf8().data());
if (!handle)
return false;
@@ -234,7 +238,7 @@ void didFinishLoading(CFURLConnectionRef conn, const void* clientInfo)
{
ResourceHandle* handle = static_cast<ResourceHandle*>(const_cast<void*>(clientInfo));
- LOG(Network, "CFNet - didFinishLoading(conn=%p, handle=%p) (%s)", conn, handle, handle->request().url().string().utf8().data());
+ LOG(Network, "CFNet - didFinishLoading(conn=%p, handle=%p) (%s)", conn, handle, handle->firstRequest().url().string().utf8().data());
if (handle->client())
handle->client()->didFinishLoading(handle);
@@ -244,7 +248,7 @@ void didFail(CFURLConnectionRef conn, CFErrorRef error, const void* clientInfo)
{
ResourceHandle* handle = static_cast<ResourceHandle*>(const_cast<void*>(clientInfo));
- LOG(Network, "CFNet - didFail(conn=%p, handle=%p, error = %p) (%s)", conn, handle, error, handle->request().url().string().utf8().data());
+ LOG(Network, "CFNet - didFail(conn=%p, handle=%p, error = %p) (%s)", conn, handle, error, handle->firstRequest().url().string().utf8().data());
if (handle->client())
handle->client()->didFail(handle, ResourceError(error));
@@ -277,7 +281,7 @@ void didReceiveChallenge(CFURLConnectionRef conn, CFURLAuthChallengeRef challeng
{
ResourceHandle* handle = static_cast<ResourceHandle*>(const_cast<void*>(clientInfo));
ASSERT(handle);
- LOG(Network, "CFNet - didReceiveChallenge(conn=%p, handle=%p (%s)", conn, handle, handle->request().url().string().utf8().data());
+ LOG(Network, "CFNet - didReceiveChallenge(conn=%p, handle=%p (%s)", conn, handle, handle->firstRequest().url().string().utf8().data());
handle->didReceiveAuthenticationChallenge(AuthenticationChallenge(challenge, handle));
}
@@ -300,14 +304,14 @@ void addHeadersFromHashMap(CFMutableURLRequestRef request, const HTTPHeaderMap&
ResourceHandleInternal::~ResourceHandleInternal()
{
if (m_connection) {
- LOG(Network, "CFNet - Cancelling connection %p (%s)", m_connection, m_request.url().string().utf8().data());
+ LOG(Network, "CFNet - Cancelling connection %p (%s)", m_connection, m_firstRequest.url().string().utf8().data());
CFURLConnectionCancel(m_connection.get());
}
}
ResourceHandle::~ResourceHandle()
{
- LOG(Network, "CFNet - Destroying job %p (%s)", this, d->m_request.url().string().utf8().data());
+ LOG(Network, "CFNet - Destroying job %p (%s)", this, d->m_firstRequest.url().string().utf8().data());
}
CFArrayRef arrayFromFormData(const FormData& d)
@@ -390,56 +394,60 @@ static CFDictionaryRef createConnectionProperties(bool shouldUseCredentialStorag
return propertiesDictionary;
}
-bool ResourceHandle::start(Frame* frame)
+void ResourceHandle::createCFURLConnection(bool shouldUseCredentialStorage, bool shouldContentSniff)
{
- // If we are no longer attached to a Page, this must be an attempted load from an
- // onUnload handler, so let's just block it.
- if (!frame->page())
- return false;
-
- if ((!d->m_user.isEmpty() || !d->m_pass.isEmpty()) && !d->m_request.url().protocolInHTTPFamily()) {
+ if ((!d->m_user.isEmpty() || !d->m_pass.isEmpty()) && !firstRequest().url().protocolInHTTPFamily()) {
// Credentials for ftp can only be passed in URL, the didReceiveAuthenticationChallenge delegate call won't be made.
- KURL urlWithCredentials(d->m_request.url());
+ KURL urlWithCredentials(firstRequest().url());
urlWithCredentials.setUser(d->m_user);
urlWithCredentials.setPass(d->m_pass);
- d->m_request.setURL(urlWithCredentials);
+ firstRequest().setURL(urlWithCredentials);
}
- bool shouldUseCredentialStorage = !client() || client()->shouldUseCredentialStorage(this);
-
// <rdar://problem/7174050> - For URLs that match the paths of those previously challenged for HTTP Basic authentication,
// try and reuse the credential preemptively, as allowed by RFC 2617.
- if (shouldUseCredentialStorage && d->m_request.url().protocolInHTTPFamily()) {
+ if (shouldUseCredentialStorage && firstRequest().url().protocolInHTTPFamily()) {
if (d->m_user.isEmpty() && d->m_pass.isEmpty()) {
// <rdar://problem/7174050> - For URLs that match the paths of those previously challenged for HTTP Basic authentication,
// try and reuse the credential preemptively, as allowed by RFC 2617.
- d->m_initialCredential = CredentialStorage::get(d->m_request.url());
+ d->m_initialCredential = CredentialStorage::get(firstRequest().url());
} else {
// If there is already a protection space known for the URL, update stored credentials before sending a request.
// This makes it possible to implement logout by sending an XMLHttpRequest with known incorrect credentials, and aborting it immediately
// (so that an authentication dialog doesn't pop up).
- CredentialStorage::set(Credential(d->m_user, d->m_pass, CredentialPersistenceNone), d->m_request.url());
+ CredentialStorage::set(Credential(d->m_user, d->m_pass, CredentialPersistenceNone), firstRequest().url());
}
}
if (!d->m_initialCredential.isEmpty()) {
String authHeader = "Basic " + encodeBasicAuthorization(d->m_initialCredential.user(), d->m_initialCredential.password());
- d->m_request.addHTTPHeaderField("Authorization", authHeader);
+ firstRequest().addHTTPHeaderField("Authorization", authHeader);
}
- RetainPtr<CFURLRequestRef> request(AdoptCF, makeFinalRequest(d->m_request, d->m_shouldContentSniff));
-
- CFURLConnectionClient_V3 client = { 3, this, 0, 0, 0, WebCore::willSendRequest, didReceiveResponse, didReceiveData, NULL, didFinishLoading, didFail, willCacheResponse, didReceiveChallenge, didSendBodyData, shouldUseCredentialStorageCallback, 0};
+ RetainPtr<CFURLRequestRef> request(AdoptCF, makeFinalRequest(firstRequest(), shouldContentSniff));
+ CFURLConnectionClient_V3 client = { 3, this, 0, 0, 0, WebCore::willSendRequest, didReceiveResponse, didReceiveData, 0, didFinishLoading, didFail, willCacheResponse, didReceiveChallenge, didSendBodyData, shouldUseCredentialStorageCallback, 0};
RetainPtr<CFDictionaryRef> connectionProperties(AdoptCF, createConnectionProperties(shouldUseCredentialStorage));
d->m_connection.adoptCF(CFURLConnectionCreateWithProperties(0, request.get(), reinterpret_cast<CFURLConnectionClient*>(&client), connectionProperties.get()));
+}
+
+bool ResourceHandle::start(Frame* frame)
+{
+ // If we are no longer attached to a Page, this must be an attempted load from an
+ // onUnload handler, so let's just block it.
+ if (!frame->page())
+ return false;
+
+ bool shouldUseCredentialStorage = !client() || client()->shouldUseCredentialStorage(this);
+
+ createCFURLConnection(shouldUseCredentialStorage, d->m_shouldContentSniff);
CFURLConnectionScheduleWithCurrentMessageQueue(d->m_connection.get());
CFURLConnectionScheduleDownloadWithRunLoop(d->m_connection.get(), loaderRunLoop(), kCFRunLoopDefaultMode);
CFURLConnectionStart(d->m_connection.get());
- LOG(Network, "CFNet - Starting URL %s (handle=%p, conn=%p)", d->m_request.url().string().utf8().data(), this, d->m_connection);
+ LOG(Network, "CFNet - Starting URL %s (handle=%p, conn=%p)", firstRequest().url().string().utf8().data(), this, d->m_connection);
return true;
}
@@ -500,7 +508,7 @@ void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChall
KURL urlToStore;
if (challenge.failureResponse().httpStatusCode() == 401)
- urlToStore = d->m_request.url();
+ urlToStore = firstRequest().url();
CredentialStorage::set(core(credential.get()), challenge.protectionSpace(), urlToStore);
CFURLConnectionUseCredential(d->m_connection.get(), credential.get(), challenge.cfURLAuthChallengeRef());
@@ -510,17 +518,26 @@ void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChall
return;
}
- if (!challenge.previousFailureCount() && (!client() || client()->shouldUseCredentialStorage(this))) {
- Credential credential = CredentialStorage::get(challenge.protectionSpace());
- if (!credential.isEmpty() && credential != d->m_initialCredential) {
- ASSERT(credential.persistence() == CredentialPersistenceNone);
- if (challenge.failureResponse().httpStatusCode() == 401) {
- // Store the credential back, possibly adding it as a default for this directory.
- CredentialStorage::set(credential, challenge.protectionSpace(), d->m_request.url());
+ if (!client() || client()->shouldUseCredentialStorage(this)) {
+ if (!d->m_initialCredential.isEmpty() || challenge.previousFailureCount()) {
+ // The stored credential wasn't accepted, stop using it.
+ // There is a race condition here, since a different credential might have already been stored by another ResourceHandle,
+ // but the observable effect should be very minor, if any.
+ CredentialStorage::remove(challenge.protectionSpace());
+ }
+
+ if (!challenge.previousFailureCount()) {
+ Credential credential = CredentialStorage::get(challenge.protectionSpace());
+ if (!credential.isEmpty() && credential != d->m_initialCredential) {
+ ASSERT(credential.persistence() == CredentialPersistenceNone);
+ if (challenge.failureResponse().httpStatusCode() == 401) {
+ // Store the credential back, possibly adding it as a default for this directory.
+ CredentialStorage::set(credential, challenge.protectionSpace(), firstRequest().url());
+ }
+ RetainPtr<CFURLCredentialRef> cfCredential(AdoptCF, createCF(credential));
+ CFURLConnectionUseCredential(d->m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef());
+ return;
}
- RetainPtr<CFURLCredentialRef> cfCredential(AdoptCF, createCF(credential));
- CFURLConnectionUseCredential(d->m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef());
- return;
}
}
@@ -552,7 +569,7 @@ void ResourceHandle::receivedCredential(const AuthenticationChallenge& challenge
KURL urlToStore;
if (challenge.failureResponse().httpStatusCode() == 401)
- urlToStore = d->m_request.url();
+ urlToStore = firstRequest().url();
CredentialStorage::set(webCredential, challenge.protectionSpace(), urlToStore);
CFURLConnectionUseCredential(d->m_connection.get(), cfCredential.get(), challenge.cfURLAuthChallengeRef());
@@ -598,12 +615,43 @@ CFURLConnectionRef ResourceHandle::releaseConnectionForDownload()
return d->m_connection.releaseRef();
}
-void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& vector, Frame*)
+void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& vector, Frame* frame)
{
+ LOG(Network, "ResourceHandle::loadResourceSynchronously:%s allowStoredCredentials:%u", request.url().string().utf8().data(), storedCredentials);
+
ASSERT(!request.isEmpty());
- RetainPtr<CFDataRef> data = WebCoreSynchronousLoader::load(request, storedCredentials, response, error);
+ ASSERT(response.isNull());
+ ASSERT(error.isNull());
+
+ OwnPtr<WebCoreSynchronousLoaderClient> client = WebCoreSynchronousLoaderClient::create(response, error);
+ client->setAllowStoredCredentials(storedCredentials == AllowStoredCredentials);
+
+ RefPtr<ResourceHandle> handle = adoptRef(new ResourceHandle(request, client.get(), false /*defersLoading*/, true /*shouldContentSniff*/));
+
+ if (handle->d->m_scheduledFailureType != NoFailure) {
+ error = frame->loader()->blockedError(request);
+ return;
+ }
+
+ RetainPtr<CFDictionaryRef> connectionProperties(AdoptCF, createConnectionProperties(storedCredentials == AllowStoredCredentials));
+ handle->createCFURLConnection(storedCredentials == AllowStoredCredentials, ResourceHandle::shouldContentSniffURL(request.url()));
+
+ CFURLConnectionScheduleWithRunLoop(handle->connection(), CFRunLoopGetCurrent(), WebCoreSynchronousLoaderRunLoopMode);
+ CFURLConnectionScheduleDownloadWithRunLoop(handle->connection(), CFRunLoopGetCurrent(), WebCoreSynchronousLoaderRunLoopMode);
+ CFURLConnectionStart(handle->connection());
+
+ while (!client->isDone())
+ CFRunLoopRunInMode(WebCoreSynchronousLoaderRunLoopMode, UINT_MAX, true);
+
+ CFURLConnectionCancel(handle->connection());
+
+ if (error.isNull() && response.mimeType().isNull())
+ setDefaultMIMEType(response.cfURLResponse());
+
+ RetainPtr<CFDataRef> data = client->data();
+
if (!error.isNull()) {
response = ResourceResponse(request.url(), String(), 0, String(), String());
@@ -666,173 +714,51 @@ bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame* frame)
return cached;
}
-CFURLRequestRef WebCoreSynchronousLoader::willSendRequest(CFURLConnectionRef, CFURLRequestRef cfRequest, CFURLResponseRef cfRedirectResponse, const void* clientInfo)
+void WebCoreSynchronousLoaderClient::willSendRequest(ResourceHandle* handle, ResourceRequest& request, const ResourceResponse& /*redirectResponse*/)
{
- WebCoreSynchronousLoader* loader = static_cast<WebCoreSynchronousLoader*>(const_cast<void*>(clientInfo));
-
// FIXME: This needs to be fixed to follow the redirect correctly even for cross-domain requests.
- if (loader->m_url && !protocolHostAndPortAreEqual(loader->m_url.get(), CFURLRequestGetURL(cfRequest))) {
+ if (!protocolHostAndPortAreEqual(handle->firstRequest().url(), request.url())) {
+ ASSERT(!m_error);
RetainPtr<CFErrorRef> cfError(AdoptCF, CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainCFNetwork, kCFURLErrorBadServerResponse, 0));
- loader->m_error = cfError.get();
- loader->m_isDone = true;
- return 0;
- }
-
- loader->m_url = CFURLRequestGetURL(cfRequest);
-
- if (cfRedirectResponse) {
- // Take user/pass out of the URL.
- loader->m_user.adoptCF(CFURLCopyUserName(loader->m_url.get()));
- loader->m_pass.adoptCF(CFURLCopyPassword(loader->m_url.get()));
- if (loader->m_user || loader->m_pass) {
- ResourceRequest requestWithoutCredentials = cfRequest;
- requestWithoutCredentials.removeCredentials();
- cfRequest = requestWithoutCredentials.cfURLRequest();
- }
+ m_error = cfError.get();
+ m_isDone = true;
+ request = 0;
+ return;
}
-
- CFRetain(cfRequest);
- return cfRequest;
}
-
-void WebCoreSynchronousLoader::didReceiveResponse(CFURLConnectionRef, CFURLResponseRef cfResponse, const void* clientInfo)
+void WebCoreSynchronousLoaderClient::didReceiveResponse(ResourceHandle*, const ResourceResponse& response)
{
- WebCoreSynchronousLoader* loader = static_cast<WebCoreSynchronousLoader*>(const_cast<void*>(clientInfo));
-
- loader->m_response = cfResponse;
+ m_response = response;
}
-void WebCoreSynchronousLoader::didReceiveData(CFURLConnectionRef, CFDataRef data, CFIndex originalLength, const void* clientInfo)
+void WebCoreSynchronousLoaderClient::didReceiveData(ResourceHandle*, const char* data, int length, int /*lengthReceived*/)
{
- WebCoreSynchronousLoader* loader = static_cast<WebCoreSynchronousLoader*>(const_cast<void*>(clientInfo));
-
- if (!loader->m_data)
- loader->m_data.adoptCF(CFDataCreateMutable(kCFAllocatorDefault, 0));
-
- const UInt8* bytes = CFDataGetBytePtr(data);
- CFIndex length = CFDataGetLength(data);
-
- CFDataAppendBytes(loader->m_data.get(), bytes, length);
+ if (!m_data)
+ m_data.adoptCF(CFDataCreateMutable(kCFAllocatorDefault, 0));
+ CFDataAppendBytes(m_data.get(), reinterpret_cast<const UInt8*>(data), length);
}
-void WebCoreSynchronousLoader::didFinishLoading(CFURLConnectionRef, const void* clientInfo)
+void WebCoreSynchronousLoaderClient::didFinishLoading(ResourceHandle*)
{
- WebCoreSynchronousLoader* loader = static_cast<WebCoreSynchronousLoader*>(const_cast<void*>(clientInfo));
-
- loader->m_isDone = true;
+ m_isDone = true;
}
-void WebCoreSynchronousLoader::didFail(CFURLConnectionRef, CFErrorRef error, const void* clientInfo)
+void WebCoreSynchronousLoaderClient::didFail(ResourceHandle*, const ResourceError& error)
{
- WebCoreSynchronousLoader* loader = static_cast<WebCoreSynchronousLoader*>(const_cast<void*>(clientInfo));
-
- loader->m_error = error;
- loader->m_isDone = true;
+ m_error = error;
+ m_isDone = true;
}
-void WebCoreSynchronousLoader::didReceiveChallenge(CFURLConnectionRef conn, CFURLAuthChallengeRef challenge, const void* clientInfo)
+void WebCoreSynchronousLoaderClient::didReceiveAuthenticationChallenge(ResourceHandle* handle, const AuthenticationChallenge& challenge)
{
- WebCoreSynchronousLoader* loader = static_cast<WebCoreSynchronousLoader*>(const_cast<void*>(clientInfo));
-
- CFURLResponseRef urlResponse = (CFURLResponseRef)CFURLAuthChallengeGetFailureResponse(challenge);
- CFHTTPMessageRef httpResponse = urlResponse ? CFURLResponseGetHTTPResponse(urlResponse) : 0;
-
- if (loader->m_user && loader->m_pass) {
- Credential credential(loader->m_user.get(), loader->m_pass.get(), CredentialPersistenceNone);
- RetainPtr<CFURLCredentialRef> cfCredential(AdoptCF, createCF(credential));
-
- KURL urlToStore;
- if (httpResponse && CFHTTPMessageGetResponseStatusCode(httpResponse) == 401)
- urlToStore = loader->m_url.get();
-
- CredentialStorage::set(credential, core(CFURLAuthChallengeGetProtectionSpace(challenge)), urlToStore);
-
- CFURLConnectionUseCredential(conn, cfCredential.get(), challenge);
- loader->m_user = 0;
- loader->m_pass = 0;
- return;
- }
- if (!CFURLAuthChallengeGetPreviousFailureCount(challenge) && loader->m_allowStoredCredentials) {
- Credential credential = CredentialStorage::get(core(CFURLAuthChallengeGetProtectionSpace(challenge)));
- if (!credential.isEmpty() && credential != loader->m_initialCredential) {
- ASSERT(credential.persistence() == CredentialPersistenceNone);
- if (httpResponse && CFHTTPMessageGetResponseStatusCode(httpResponse) == 401) {
- // Store the credential back, possibly adding it as a default for this directory.
- CredentialStorage::set(credential, core(CFURLAuthChallengeGetProtectionSpace(challenge)), loader->m_url.get());
- }
- RetainPtr<CFURLCredentialRef> cfCredential(AdoptCF, createCF(credential));
- CFURLConnectionUseCredential(conn, cfCredential.get(), challenge);
- return;
- }
- }
// FIXME: The user should be asked for credentials, as in async case.
- CFURLConnectionUseCredential(conn, 0, challenge);
+ CFURLConnectionUseCredential(handle->connection(), 0, challenge.cfURLAuthChallengeRef());
}
-Boolean WebCoreSynchronousLoader::shouldUseCredentialStorage(CFURLConnectionRef, const void* clientInfo)
+bool WebCoreSynchronousLoaderClient::shouldUseCredentialStorage(ResourceHandle*)
{
- WebCoreSynchronousLoader* loader = static_cast<WebCoreSynchronousLoader*>(const_cast<void*>(clientInfo));
-
// FIXME: We should ask FrameLoaderClient whether using credential storage is globally forbidden.
- return loader->m_allowStoredCredentials;
-}
-
-RetainPtr<CFDataRef> WebCoreSynchronousLoader::load(const ResourceRequest& request, StoredCredentials storedCredentials, ResourceResponse& response, ResourceError& error)
-{
- ASSERT(response.isNull());
- ASSERT(error.isNull());
-
- WebCoreSynchronousLoader loader(response, error);
-
- KURL url = request.url();
-
- if (url.user().length())
- loader.m_user.adoptCF(url.user().createCFString());
- if (url.pass().length())
- loader.m_pass.adoptCF(url.pass().createCFString());
- loader.m_allowStoredCredentials = (storedCredentials == AllowStoredCredentials);
-
- // Take user/pass out of the URL.
- // Credentials for ftp can only be passed in URL, the didReceiveAuthenticationChallenge delegate call won't be made.
- RetainPtr<CFURLRequestRef> cfRequest;
- if ((loader.m_user || loader.m_pass) && url.protocolInHTTPFamily()) {
- ResourceRequest requestWithoutCredentials(request);
- requestWithoutCredentials.removeCredentials();
- cfRequest.adoptCF(makeFinalRequest(requestWithoutCredentials, ResourceHandle::shouldContentSniffURL(requestWithoutCredentials.url())));
- } else {
- // <rdar://problem/7174050> - For URLs that match the paths of those previously challenged for HTTP Basic authentication,
- // try and reuse the credential preemptively, as allowed by RFC 2617.
- ResourceRequest requestWithInitialCredential(request);
- if (loader.m_allowStoredCredentials && url.protocolInHTTPFamily())
- loader.m_initialCredential = CredentialStorage::get(url);
-
- if (!loader.m_initialCredential.isEmpty()) {
- String authHeader = "Basic " + encodeBasicAuthorization(loader.m_initialCredential.user(), loader.m_initialCredential.password());
- requestWithInitialCredential.addHTTPHeaderField("Authorization", authHeader);
- }
-
- cfRequest.adoptCF(makeFinalRequest(requestWithInitialCredential, ResourceHandle::shouldContentSniffURL(requestWithInitialCredential.url())));
- }
-
- CFURLConnectionClient_V3 client = { 3, &loader, 0, 0, 0, willSendRequest, didReceiveResponse, didReceiveData, 0, didFinishLoading, didFail, 0, didReceiveChallenge, 0, shouldUseCredentialStorage, 0 };
-
- RetainPtr<CFDictionaryRef> connectionProperties(AdoptCF, createConnectionProperties(loader.m_allowStoredCredentials));
-
- RetainPtr<CFURLConnectionRef> connection(AdoptCF, CFURLConnectionCreateWithProperties(kCFAllocatorDefault, cfRequest.get(), reinterpret_cast<CFURLConnectionClient*>(&client), connectionProperties.get()));
-
- CFURLConnectionScheduleWithRunLoop(connection.get(), CFRunLoopGetCurrent(), WebCoreSynchronousLoaderRunLoopMode);
- CFURLConnectionScheduleDownloadWithRunLoop(connection.get(), CFRunLoopGetCurrent(), WebCoreSynchronousLoaderRunLoopMode);
- CFURLConnectionStart(connection.get());
-
- while (!loader.m_isDone)
- CFRunLoopRunInMode(WebCoreSynchronousLoaderRunLoopMode, UINT_MAX, true);
-
- CFURLConnectionCancel(connection.get());
-
- if (error.isNull() && loader.m_response.mimeType().isNull())
- setDefaultMIMEType(loader.m_response.cfURLResponse());
-
- return loader.m_data;
+ return m_allowStoredCredentials;
}
} // namespace WebCore
diff --git a/WebCore/platform/network/cf/ResourceRequestCFNet.cpp b/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
index cc0220e..8e15040 100644
--- a/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
+++ b/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
@@ -146,6 +146,11 @@ void ResourceRequest::doUpdatePlatformRequest()
void ResourceRequest::doUpdateResourceRequest()
{
+ if (!m_cfRequest) {
+ *this = ResourceRequest();
+ return;
+ }
+
m_url = CFURLRequestGetURL(m_cfRequest.get());
m_cachePolicy = (ResourceRequestCachePolicy)CFURLRequestGetCachePolicy(m_cfRequest.get());
diff --git a/WebCore/platform/network/curl/FormDataStreamCurl.cpp b/WebCore/platform/network/curl/FormDataStreamCurl.cpp
index 0f94d63..e47eb07 100644
--- a/WebCore/platform/network/curl/FormDataStreamCurl.cpp
+++ b/WebCore/platform/network/curl/FormDataStreamCurl.cpp
@@ -50,8 +50,8 @@ size_t FormDataStream::read(void* ptr, size_t blockSize, size_t numberOfBlocks)
return 0;
Vector<FormDataElement> elements;
- if (m_resourceHandle->request().httpBody())
- elements = m_resourceHandle->request().httpBody()->elements();
+ if (m_resourceHandle->firstRequest().httpBody())
+ elements = m_resourceHandle->firstRequest().httpBody()->elements();
if (m_formDataElementIndex >= elements.size())
return 0;
@@ -104,8 +104,8 @@ size_t FormDataStream::read(void* ptr, size_t blockSize, size_t numberOfBlocks)
bool FormDataStream::hasMoreElements() const
{
Vector<FormDataElement> elements;
- if (m_resourceHandle->request().httpBody())
- elements = m_resourceHandle->request().httpBody()->elements();
+ if (m_resourceHandle->firstRequest().httpBody())
+ elements = m_resourceHandle->firstRequest().httpBody()->elements();
return m_formDataElementIndex < elements.size();
}
diff --git a/WebCore/platform/network/curl/ResourceHandleManager.cpp b/WebCore/platform/network/curl/ResourceHandleManager.cpp
index c621d5c..ba68351 100644
--- a/WebCore/platform/network/curl/ResourceHandleManager.cpp
+++ b/WebCore/platform/network/curl/ResourceHandleManager.cpp
@@ -264,14 +264,14 @@ static size_t headerCallback(char* ptr, size_t size, size_t nmemb, void* data)
if (httpCode >= 300 && httpCode < 400) {
String location = d->m_response.httpHeaderField("location");
if (!location.isEmpty()) {
- KURL newURL = KURL(job->request().url(), location);
+ KURL newURL = KURL(job->firstRequest().url(), location);
- ResourceRequest redirectedRequest = job->request();
+ ResourceRequest redirectedRequest = job->firstRequest();
redirectedRequest.setURL(newURL);
if (client)
client->willSendRequest(job, redirectedRequest, d->m_response);
- d->m_request.setURL(newURL);
+ d->m_firstRequest.setURL(newURL);
return totalSize;
}
@@ -463,17 +463,17 @@ void ResourceHandleManager::setupPOST(ResourceHandle* job, struct curl_slist** h
curl_easy_setopt(d->m_handle, CURLOPT_POST, TRUE);
curl_easy_setopt(d->m_handle, CURLOPT_POSTFIELDSIZE, 0);
- if (!job->request().httpBody())
+ if (!job->firstRequest().httpBody())
return;
- Vector<FormDataElement> elements = job->request().httpBody()->elements();
+ Vector<FormDataElement> elements = job->firstRequest().httpBody()->elements();
size_t numElements = elements.size();
if (!numElements)
return;
// Do not stream for simple POST data
if (numElements == 1) {
- job->request().httpBody()->flatten(d->m_postBytes);
+ job->firstRequest().httpBody()->flatten(d->m_postBytes);
if (d->m_postBytes.size() != 0) {
curl_easy_setopt(d->m_handle, CURLOPT_POSTFIELDSIZE, d->m_postBytes.size());
curl_easy_setopt(d->m_handle, CURLOPT_POSTFIELDS, d->m_postBytes.data());
@@ -580,7 +580,7 @@ static void parseDataUrl(ResourceHandle* handle)
if (!client)
return;
- String url = handle->request().url().string();
+ String url = handle->firstRequest().url().string();
ASSERT(url.startsWith("data:", false));
int index = url.find(',');
@@ -628,7 +628,7 @@ static void parseDataUrl(ResourceHandle* handle)
void ResourceHandleManager::dispatchSynchronousJob(ResourceHandle* job)
{
- KURL kurl = job->request().url();
+ KURL kurl = job->firstRequest().url();
if (kurl.protocolIs("data")) {
parseDataUrl(job);
@@ -659,7 +659,7 @@ void ResourceHandleManager::dispatchSynchronousJob(ResourceHandle* job)
void ResourceHandleManager::startJob(ResourceHandle* job)
{
- KURL kurl = job->request().url();
+ KURL kurl = job->firstRequest().url();
if (kurl.protocolIs("data")) {
parseDataUrl(job);
@@ -674,7 +674,7 @@ void ResourceHandleManager::startJob(ResourceHandle* job)
// timeout will occur and do curl_multi_perform
if (ret && ret != CURLM_CALL_MULTI_PERFORM) {
#ifndef NDEBUG
- fprintf(stderr, "Error %d starting job %s\n", ret, encodeWithURLEscapeSequences(job->request().url().string()).latin1().data());
+ fprintf(stderr, "Error %d starting job %s\n", ret, encodeWithURLEscapeSequences(job->firstRequest().url().string()).latin1().data());
#endif
job->cancel();
return;
@@ -683,7 +683,7 @@ void ResourceHandleManager::startJob(ResourceHandle* job)
void ResourceHandleManager::initializeHandle(ResourceHandle* job)
{
- KURL kurl = job->request().url();
+ KURL kurl = job->firstRequest().url();
// Remove any fragment part, otherwise curl will send it as part of the request.
kurl.removeFragmentIdentifier();
@@ -753,8 +753,8 @@ void ResourceHandleManager::initializeHandle(ResourceHandle* job)
}
struct curl_slist* headers = 0;
- if (job->request().httpHeaderFields().size() > 0) {
- HTTPHeaderMap customHeaders = job->request().httpHeaderFields();
+ if (job->firstRequest().httpHeaderFields().size() > 0) {
+ HTTPHeaderMap customHeaders = job->firstRequest().httpHeaderFields();
HTTPHeaderMap::const_iterator end = customHeaders.end();
for (HTTPHeaderMap::const_iterator it = customHeaders.begin(); it != end; ++it) {
String key = it->first;
@@ -767,13 +767,13 @@ void ResourceHandleManager::initializeHandle(ResourceHandle* job)
}
}
- if ("GET" == job->request().httpMethod())
+ if ("GET" == job->firstRequest().httpMethod())
curl_easy_setopt(d->m_handle, CURLOPT_HTTPGET, TRUE);
- else if ("POST" == job->request().httpMethod())
+ else if ("POST" == job->firstRequest().httpMethod())
setupPOST(job, &headers);
- else if ("PUT" == job->request().httpMethod())
+ else if ("PUT" == job->firstRequest().httpMethod())
setupPUT(job, &headers);
- else if ("HEAD" == job->request().httpMethod())
+ else if ("HEAD" == job->firstRequest().httpMethod())
curl_easy_setopt(d->m_handle, CURLOPT_NOBODY, TRUE);
if (headers) {
diff --git a/WebCore/platform/network/mac/ResourceHandleMac.mm b/WebCore/platform/network/mac/ResourceHandleMac.mm
index 9f64d4e..f7161ec 100644
--- a/WebCore/platform/network/mac/ResourceHandleMac.mm
+++ b/WebCore/platform/network/mac/ResourceHandleMac.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006-2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -56,8 +56,7 @@ typedef int NSInteger;
using namespace WebCore;
-@interface WebCoreResourceHandleAsDelegate : NSObject <NSURLConnectionDelegate>
-{
+@interface WebCoreResourceHandleAsDelegate : NSObject <NSURLConnectionDelegate> {
ResourceHandle* m_handle;
}
- (id)initWithHandle:(ResourceHandle*)handle;
@@ -85,20 +84,48 @@ using namespace WebCore;
#ifndef BUILDING_ON_TIGER
-@interface WebCoreSynchronousLoader : NSObject <NSURLConnectionDelegate> {
- NSURL *m_url;
- NSString *m_user;
- NSString *m_pass;
- // Store the preemptively used initial credential so that if we get an authentication challenge, we won't use the same one again.
- Credential m_initialCredential;
- BOOL m_allowStoredCredentials;
+class WebCoreSynchronousLoaderClient : public ResourceHandleClient {
+public:
+ static PassOwnPtr<WebCoreSynchronousLoaderClient> create()
+ {
+ return adoptPtr(new WebCoreSynchronousLoaderClient);
+ }
+
+ virtual ~WebCoreSynchronousLoaderClient();
+
+ void setAllowStoredCredentials(bool allow) { m_allowStoredCredentials = allow; }
+ NSURLResponse *response() { return m_response; }
+ NSMutableData *data() { return m_data; }
+ NSError *error() { return m_error; }
+ bool isDone() { return m_isDone; }
+
+private:
+ WebCoreSynchronousLoaderClient()
+ : m_allowStoredCredentials(false)
+ , m_response(0)
+ , m_data(0)
+ , m_error(0)
+ , m_isDone(false)
+ {
+ }
+
+ virtual void willSendRequest(ResourceHandle*, ResourceRequest&, const ResourceResponse& /*redirectResponse*/);
+ virtual bool shouldUseCredentialStorage(ResourceHandle*);
+ virtual void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&);
+ virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
+ virtual void didReceiveData(ResourceHandle*, const char*, int, int /*lengthReceived*/);
+ virtual void didFinishLoading(ResourceHandle*);
+ virtual void didFail(ResourceHandle*, const ResourceError&);
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+ virtual bool canAuthenticateAgainstProtectionSpace(ResourceHandle*, const ProtectionSpace&);
+#endif
+
+ bool m_allowStoredCredentials;
NSURLResponse *m_response;
NSMutableData *m_data;
NSError *m_error;
- BOOL m_isDone;
-}
-+ (NSData *)loadRequest:(NSURLRequest *)request allowStoredCredentials:(BOOL)allowStoredCredentials returningResponse:(NSURLResponse **)response error:(NSError **)error;
-@end
+ bool m_isDone;
+};
static NSString *WebCoreSynchronousLoaderRunLoopMode = @"WebCoreSynchronousLoaderRunLoopMode";
@@ -161,12 +188,51 @@ bool ResourceHandle::didSendBodyDataDelegateExists()
return NSFoundationVersionNumber > MaxFoundationVersionWithoutdidSendBodyDataDelegate;
}
-static NSURLConnection *createNSURLConnection(NSURLRequest *request, id delegate, bool shouldUseCredentialStorage)
+void ResourceHandle::createNSURLConnection(id delegate, bool shouldUseCredentialStorage, bool shouldContentSniff)
{
-#if defined(BUILDING_ON_TIGER)
- UNUSED_PARAM(shouldUseCredentialStorage);
- return [[NSURLConnection alloc] initWithRequest:request delegate:delegate];
-#else
+ // Credentials for ftp can only be passed in URL, the connection:didReceiveAuthenticationChallenge: delegate call won't be made.
+ if ((!d->m_user.isEmpty() || !d->m_pass.isEmpty())
+#ifndef BUILDING_ON_TIGER
+ && !firstRequest().url().protocolInHTTPFamily() // On Tiger, always pass credentials in URL, so that they get stored even if the request gets cancelled right away.
+#endif
+ ) {
+ KURL urlWithCredentials(firstRequest().url());
+ urlWithCredentials.setUser(d->m_user);
+ urlWithCredentials.setPass(d->m_pass);
+ firstRequest().setURL(urlWithCredentials);
+ }
+
+ // If a URL already has cookies, then we'll relax the 3rd party cookie policy and accept new cookies.
+ NSHTTPCookieStorage *sharedStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
+ if ([sharedStorage cookieAcceptPolicy] == NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain && [[sharedStorage cookiesForURL:firstRequest().url()] count])
+ firstRequest().setFirstPartyForCookies(firstRequest().url());
+
+#if !defined(BUILDING_ON_TIGER)
+ if (shouldUseCredentialStorage && firstRequest().url().protocolInHTTPFamily()) {
+ if (d->m_user.isEmpty() && d->m_pass.isEmpty()) {
+ // <rdar://problem/7174050> - For URLs that match the paths of those previously challenged for HTTP Basic authentication,
+ // try and reuse the credential preemptively, as allowed by RFC 2617.
+ d->m_initialCredential = CredentialStorage::get(firstRequest().url());
+ } else {
+ // If there is already a protection space known for the URL, update stored credentials before sending a request.
+ // This makes it possible to implement logout by sending an XMLHttpRequest with known incorrect credentials, and aborting it immediately
+ // (so that an authentication dialog doesn't pop up).
+ CredentialStorage::set(Credential(d->m_user, d->m_pass, CredentialPersistenceNone), firstRequest().url());
+ }
+ }
+
+ if (!d->m_initialCredential.isEmpty()) {
+ // FIXME: Support Digest authentication, and Proxy-Authorization.
+ String authHeader = "Basic " + encodeBasicAuthorization(d->m_initialCredential.user(), d->m_initialCredential.password());
+ firstRequest().addHTTPHeaderField("Authorization", authHeader);
+ }
+
+ NSURLRequest *nsRequest = firstRequest().nsURLRequest();
+ if (!shouldContentSniff) {
+ NSMutableURLRequest *mutableRequest = [[nsRequest copy] autorelease];
+ wkSetNSURLRequestShouldContentSniff(mutableRequest, NO);
+ nsRequest = mutableRequest;
+ }
#if !defined(BUILDING_ON_LEOPARD)
ASSERT([NSURLConnection instancesRespondToSelector:@selector(_initWithRequest:delegate:usesCache:maxContentLength:startImmediately:connectionProperties:)]);
@@ -178,10 +244,18 @@ static NSURLConnection *createNSURLConnection(NSURLRequest *request, id delegate
if (supportsSettingConnectionProperties) {
NSDictionary *sessionID = shouldUseCredentialStorage ? [NSDictionary dictionary] : [NSDictionary dictionaryWithObject:@"WebKitPrivateSession" forKey:@"_kCFURLConnectionSessionID"];
NSDictionary *propertyDictionary = [NSDictionary dictionaryWithObject:sessionID forKey:@"kCFURLConnectionSocketStreamProperties"];
- return [[NSURLConnection alloc] _initWithRequest:request delegate:delegate usesCache:YES maxContentLength:0 startImmediately:NO connectionProperties:propertyDictionary];
+ d->m_connection.adoptNS([[NSURLConnection alloc] _initWithRequest:nsRequest delegate:delegate usesCache:YES maxContentLength:0 startImmediately:NO connectionProperties:propertyDictionary]);
+ return;
}
- return [[NSURLConnection alloc] initWithRequest:request delegate:delegate startImmediately:NO];
+ d->m_connection.adoptNS([[NSURLConnection alloc] initWithRequest:nsRequest delegate:delegate startImmediately:NO]);
+ return;
+
+#else
+ // Building on Tiger. Don't use WebCore credential storage, don't try to disable content sniffing.
+ UNUSED_PARAM(shouldUseCredentialStorage);
+ UNUSED_PARAM(shouldContentSniff);
+ d->m_connection.adoptNS([[NSURLConnection alloc] initWithRequest:firstRequest().nsURLRequest() delegate:delegate]);
#endif
}
@@ -206,69 +280,24 @@ bool ResourceHandle::start(Frame* frame)
d->m_proxy.adoptNS(wkCreateNSURLConnectionDelegateProxy());
[static_cast<WebCoreNSURLConnectionDelegateProxy*>(d->m_proxy.get()) setDelegate:ResourceHandle::delegate()];
- if ((!d->m_user.isEmpty() || !d->m_pass.isEmpty())
-#ifndef BUILDING_ON_TIGER
- && !d->m_request.url().protocolInHTTPFamily() // On Tiger, always pass credentials in URL, so that they get stored even if the request gets cancelled right away.
-#endif
- ) {
- // Credentials for ftp can only be passed in URL, the connection:didReceiveAuthenticationChallenge: delegate call won't be made.
- KURL urlWithCredentials(d->m_request.url());
- urlWithCredentials.setUser(d->m_user);
- urlWithCredentials.setPass(d->m_pass);
- d->m_request.setURL(urlWithCredentials);
- }
-
bool shouldUseCredentialStorage = !client() || client()->shouldUseCredentialStorage(this);
-#ifndef BUILDING_ON_TIGER
- if (shouldUseCredentialStorage && d->m_request.url().protocolInHTTPFamily()) {
- if (d->m_user.isEmpty() && d->m_pass.isEmpty()) {
- // <rdar://problem/7174050> - For URLs that match the paths of those previously challenged for HTTP Basic authentication,
- // try and reuse the credential preemptively, as allowed by RFC 2617.
- d->m_initialCredential = CredentialStorage::get(d->m_request.url());
- } else {
- // If there is already a protection space known for the URL, update stored credentials before sending a request.
- // This makes it possible to implement logout by sending an XMLHttpRequest with known incorrect credentials, and aborting it immediately
- // (so that an authentication dialog doesn't pop up).
- CredentialStorage::set(Credential(d->m_user, d->m_pass, CredentialPersistenceNone), d->m_request.url());
- }
- }
-
- if (!d->m_initialCredential.isEmpty()) {
- // FIXME: Support Digest authentication, and Proxy-Authorization.
- String authHeader = "Basic " + encodeBasicAuthorization(d->m_initialCredential.user(), d->m_initialCredential.password());
- d->m_request.addHTTPHeaderField("Authorization", authHeader);
- }
-#endif
-
if (!ResourceHandle::didSendBodyDataDelegateExists())
- associateStreamWithResourceHandle([d->m_request.nsURLRequest() HTTPBodyStream], this);
+ associateStreamWithResourceHandle([firstRequest().nsURLRequest() HTTPBodyStream], this);
#ifdef BUILDING_ON_TIGER
// A conditional request sent by WebCore (e.g. to update appcache) can be for a resource that is not cacheable by NSURLConnection,
// which can get confused and fail to load it in this case.
- if (d->m_request.isConditional())
- d->m_request.setCachePolicy(ReloadIgnoringCacheData);
+ if (firstRequest().isConditional())
+ firstRequest().setCachePolicy(ReloadIgnoringCacheData);
#endif
d->m_needsSiteSpecificQuirks = frame->settings() && frame->settings()->needsSiteSpecificQuirks();
- // If a URL already has cookies, then we'll relax the 3rd party cookie policy and accept new cookies.
- NSHTTPCookieStorage *sharedStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
- if ([sharedStorage cookieAcceptPolicy] == NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
- && [[sharedStorage cookiesForURL:d->m_request.url()] count])
- d->m_request.setFirstPartyForCookies(d->m_request.url());
-
- NSURLConnection *connection;
-
- if (d->m_shouldContentSniff || frame->settings()->localFileContentSniffingEnabled())
- connection = createNSURLConnection(d->m_request.nsURLRequest(), d->m_proxy.get(), shouldUseCredentialStorage);
- else {
- NSMutableURLRequest *request = [d->m_request.nsURLRequest() mutableCopy];
- wkSetNSURLRequestShouldContentSniff(request, NO);
- connection = createNSURLConnection(request, d->m_proxy.get(), shouldUseCredentialStorage);
- [request release];
- }
+ createNSURLConnection(
+ d->m_proxy.get(),
+ shouldUseCredentialStorage,
+ d->m_shouldContentSniff || frame->settings()->localFileContentSniffingEnabled());
#ifndef BUILDING_ON_TIGER
bool scheduled = false;
@@ -276,7 +305,7 @@ bool ResourceHandle::start(Frame* frame)
SchedulePairHashSet::iterator end = scheduledPairs->end();
for (SchedulePairHashSet::iterator it = scheduledPairs->begin(); it != end; ++it) {
if (NSRunLoop *runLoop = (*it)->nsRunLoop()) {
- [connection scheduleInRunLoop:runLoop forMode:(NSString *)(*it)->mode()];
+ [connection() scheduleInRunLoop:runLoop forMode:(NSString *)(*it)->mode()];
scheduled = true;
}
}
@@ -285,7 +314,7 @@ bool ResourceHandle::start(Frame* frame)
// Start the connection if we did schedule with at least one runloop.
// We can't start the connection until we have one runloop scheduled.
if (scheduled)
- [connection start];
+ [connection() start];
else
d->m_startWhenScheduled = true;
#endif
@@ -294,15 +323,11 @@ bool ResourceHandle::start(Frame* frame)
isInitializingConnection = NO;
#endif
- LOG(Network, "Handle %p starting connection %p for %@", this, connection, d->m_request.nsURLRequest());
+ LOG(Network, "Handle %p starting connection %p for %@", this, connection(), firstRequest().nsURLRequest());
- d->m_connection = connection;
-
if (d->m_connection) {
- [connection release];
-
if (d->m_defersLoading)
- wkSetNSURLConnectionDefersCallbacks(d->m_connection.get(), YES);
+ wkSetNSURLConnectionDefersCallbacks(connection(), YES);
return true;
}
@@ -321,7 +346,7 @@ void ResourceHandle::cancel()
[[d->m_currentMacChallenge sender] cancelAuthenticationChallenge:d->m_currentMacChallenge];
if (!ResourceHandle::didSendBodyDataDelegateExists())
- disassociateStreamWithResourceHandle([d->m_request.nsURLRequest() HTTPBodyStream]);
+ disassociateStreamWithResourceHandle([firstRequest().nsURLRequest() HTTPBodyStream]);
[d->m_connection.get() cancel];
}
@@ -435,43 +460,63 @@ bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame*)
#endif
}
-void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data, Frame*)
+void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, StoredCredentials storedCredentials, ResourceError& error, ResourceResponse& response, Vector<char>& data, Frame* frame)
{
+ LOG(Network, "ResourceHandle::loadResourceSynchronously:%@ allowStoredCredentials:%u", request.nsURLRequest(), storedCredentials);
+
NSError *nsError = nil;
-
NSURLResponse *nsURLResponse = nil;
NSData *result = nil;
ASSERT(!request.isEmpty());
- NSMutableURLRequest *mutableRequest = nil;
- if (!shouldContentSniffURL(request.url())) {
- mutableRequest = [[request.nsURLRequest() mutableCopy] autorelease];
- wkSetNSURLRequestShouldContentSniff(mutableRequest, NO);
- }
+#ifndef BUILDING_ON_TIGER
+ OwnPtr<WebCoreSynchronousLoaderClient> client = WebCoreSynchronousLoaderClient::create();
+ client->setAllowStoredCredentials(storedCredentials == AllowStoredCredentials);
- // If a URL already has cookies, then we'll ignore the 3rd party cookie policy and accept new cookies.
- NSHTTPCookieStorage *sharedStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
- if ([sharedStorage cookieAcceptPolicy] == NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
- && [[sharedStorage cookiesForURL:request.url()] count]) {
- if (!mutableRequest)
- mutableRequest = [[request.nsURLRequest() mutableCopy] autorelease];
- [mutableRequest setMainDocumentURL:[mutableRequest URL]];
+ RefPtr<ResourceHandle> handle = adoptRef(new ResourceHandle(request, client.get(), false /*defersLoading*/, true /*shouldContentSniff*/));
+
+ if (handle->d->m_scheduledFailureType != NoFailure) {
+ error = frame->loader()->blockedError(request);
+ return;
}
+
+ handle->createNSURLConnection(
+ handle->delegate(), // A synchronous request cannot turn into a download, so there is no need to proxy the delegate.
+ storedCredentials == AllowStoredCredentials,
+ handle->shouldContentSniff() || frame->settings()->localFileContentSniffingEnabled());
+
+ [handle->connection() scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:WebCoreSynchronousLoaderRunLoopMode];
+ [handle->connection() start];
- NSURLRequest *nsRequest = mutableRequest ? mutableRequest : request.nsURLRequest();
-
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ while (!client->isDone())
+ [[NSRunLoop currentRunLoop] runMode:WebCoreSynchronousLoaderRunLoopMode beforeDate:[NSDate distantFuture]];
+
+ result = client->data();
+ nsURLResponse = client->response();
+ nsError = client->error();
-#ifndef BUILDING_ON_TIGER
- result = [WebCoreSynchronousLoader loadRequest:nsRequest allowStoredCredentials:(storedCredentials == AllowStoredCredentials) returningResponse:&nsURLResponse error:&nsError];
+ [handle->connection() cancel];
+
#else
UNUSED_PARAM(storedCredentials);
- result = [NSURLConnection sendSynchronousRequest:nsRequest returningResponse:&nsURLResponse error:&nsError];
-#endif
+ UNUSED_PARAM(frame);
+ NSURLRequest *firstRequest = request.nsURLRequest();
+
+ // If a URL already has cookies, then we'll relax the 3rd party cookie policy and accept new cookies.
+ NSHTTPCookieStorage *sharedStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
+ if ([sharedStorage cookieAcceptPolicy] == NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain && [[sharedStorage cookiesForURL:[firstRequest URL]] count]) {
+ NSMutableURLRequest *mutableRequest = [[firstRequest mutableCopy] autorelease];
+ [mutableRequest setMainDocumentURL:[mutableRequest URL]];
+ firstRequest = mutableRequest;
+ }
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ result = [NSURLConnection sendSynchronousRequest:firstRequest returningResponse:&nsURLResponse error:&nsError];
END_BLOCK_OBJC_EXCEPTIONS;
+#endif
- if (nsError == nil)
+ if (!nsError)
response = nsURLResponse;
else {
response = ResourceResponse(request.url(), String(), 0, String(), String());
@@ -536,16 +581,25 @@ void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChall
}
#ifndef BUILDING_ON_TIGER
- if (!challenge.previousFailureCount() && (!client() || client()->shouldUseCredentialStorage(this))) {
- Credential credential = CredentialStorage::get(challenge.protectionSpace());
- if (!credential.isEmpty() && credential != d->m_initialCredential) {
- ASSERT(credential.persistence() == CredentialPersistenceNone);
- if (challenge.failureResponse().httpStatusCode() == 401) {
- // Store the credential back, possibly adding it as a default for this directory.
- CredentialStorage::set(credential, challenge.protectionSpace(), d->m_request.url());
+ if (!client() || client()->shouldUseCredentialStorage(this)) {
+ if (!d->m_initialCredential.isEmpty() || challenge.previousFailureCount()) {
+ // The stored credential wasn't accepted, stop using it.
+ // There is a race condition here, since a different credential might have already been stored by another ResourceHandle,
+ // but the observable effect should be very minor, if any.
+ CredentialStorage::remove(challenge.protectionSpace());
+ }
+
+ if (!challenge.previousFailureCount()) {
+ Credential credential = CredentialStorage::get(challenge.protectionSpace());
+ if (!credential.isEmpty() && credential != d->m_initialCredential) {
+ ASSERT(credential.persistence() == CredentialPersistenceNone);
+ if (challenge.failureResponse().httpStatusCode() == 401) {
+ // Store the credential back, possibly adding it as a default for this directory.
+ CredentialStorage::set(credential, challenge.protectionSpace(), firstRequest().url());
+ }
+ [challenge.sender() useCredential:mac(credential) forAuthenticationChallenge:mac(challenge)];
+ return;
}
- [challenge.sender() useCredential:mac(credential) forAuthenticationChallenge:mac(challenge)];
- return;
}
}
#endif
@@ -604,7 +658,7 @@ void ResourceHandle::receivedCredential(const AuthenticationChallenge& challenge
Credential webCredential(credential, CredentialPersistenceNone);
KURL urlToStore;
if (challenge.failureResponse().httpStatusCode() == 401)
- urlToStore = d->m_request.url();
+ urlToStore = firstRequest().url();
CredentialStorage::set(webCredential, core([d->m_currentMacChallenge protectionSpace]), urlToStore);
[[d->m_currentMacChallenge sender] useCredential:mac(webCredential) forAuthenticationChallenge:d->m_currentMacChallenge];
} else
@@ -679,11 +733,11 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
NSMutableURLRequest *mutableRequest = [newRequest mutableCopy];
[mutableRequest setHTTPMethod:lastHTTPMethod];
- FormData* body = m_handle->request().httpBody();
+ FormData* body = m_handle->firstRequest().httpBody();
if (!equalIgnoringCase(lastHTTPMethod, "GET") && body && !body->isEmpty())
WebCore::setHTTPBody(mutableRequest, body);
- String originalContentType = m_handle->request().httpContentType();
+ String originalContentType = m_handle->firstRequest().httpContentType();
if (!originalContentType.isEmpty())
[mutableRequest setValue:originalContentType forHTTPHeaderField:@"Content-Type"];
@@ -779,7 +833,7 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
if (statusCode != 304)
[r adjustMIMETypeIfNecessary];
- if ([m_handle->request().nsURLRequest() _propertyForKey:@"ForceHTMLMIMEType"])
+ if ([m_handle->firstRequest().nsURLRequest() _propertyForKey:@"ForceHTMLMIMEType"])
[r _setMIMEType:@"text/html"];
#if ENABLE(WML)
@@ -855,7 +909,7 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
CallbackGuard guard;
if (!ResourceHandle::didSendBodyDataDelegateExists())
- disassociateStreamWithResourceHandle([m_handle->request().nsURLRequest() HTTPBodyStream]);
+ disassociateStreamWithResourceHandle([m_handle->firstRequest().nsURLRequest() HTTPBodyStream]);
m_handle->client()->didFinishLoading(m_handle);
}
@@ -871,7 +925,7 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
CallbackGuard guard;
if (!ResourceHandle::didSendBodyDataDelegateExists())
- disassociateStreamWithResourceHandle([m_handle->request().nsURLRequest() HTTPBodyStream]);
+ disassociateStreamWithResourceHandle([m_handle->firstRequest().nsURLRequest() HTTPBodyStream]);
m_handle->client()->didFail(m_handle, error);
}
@@ -947,220 +1001,69 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
#ifndef BUILDING_ON_TIGER
-@implementation WebCoreSynchronousLoader
-
-- (BOOL)_isDone
-{
- return m_isDone;
-}
-
-- (void)dealloc
+WebCoreSynchronousLoaderClient::~WebCoreSynchronousLoaderClient()
{
- [m_url release];
- [m_user release];
- [m_pass release];
[m_response release];
[m_data release];
[m_error release];
-
- [super dealloc];
}
-- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)newRequest redirectResponse:(NSURLResponse *)redirectResponse
+void WebCoreSynchronousLoaderClient::willSendRequest(ResourceHandle* handle, ResourceRequest& request, const ResourceResponse& /*redirectResponse*/)
{
- UNUSED_PARAM(connection);
-
- LOG(Network, "WebCoreSynchronousLoader delegate connection:%p willSendRequest:%@ redirectResponse:%p", connection, [newRequest description], redirectResponse);
-
// FIXME: This needs to be fixed to follow the redirect correctly even for cross-domain requests.
- if (m_url && !protocolHostAndPortAreEqual(m_url, [newRequest URL])) {
+ if (!protocolHostAndPortAreEqual(handle->firstRequest().url(), request.url())) {
+ ASSERT(!m_error);
m_error = [[NSError alloc] initWithDomain:NSURLErrorDomain code:NSURLErrorBadServerResponse userInfo:nil];
- m_isDone = YES;
- return nil;
- }
-
- NSURL *copy = [[newRequest URL] copy];
- [m_url release];
- m_url = copy;
-
- if (redirectResponse) {
- // Take user/pass out of the URL.
- [m_user release];
- [m_pass release];
- m_user = [[m_url user] copy];
- m_pass = [[m_url password] copy];
- if (m_user || m_pass) {
- ResourceRequest requestWithoutCredentials = newRequest;
- requestWithoutCredentials.removeCredentials();
- return requestWithoutCredentials.nsURLRequest();
- }
+ m_isDone = true;
+ request = 0;
+ return;
}
-
- return newRequest;
}
-- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection
+bool WebCoreSynchronousLoaderClient::shouldUseCredentialStorage(ResourceHandle*)
{
- UNUSED_PARAM(connection);
-
- LOG(Network, "WebCoreSynchronousLoader delegate connectionShouldUseCredentialStorage:%p", connection);
-
// FIXME: We should ask FrameLoaderClient whether using credential storage is globally forbidden.
return m_allowStoredCredentials;
}
-- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+bool WebCoreSynchronousLoaderClient::canAuthenticateAgainstProtectionSpace(ResourceHandle*, const ProtectionSpace&)
{
- UNUSED_PARAM(connection);
-
- LOG(Network, "WebCoreSynchronousLoader delegate connection:%p didReceiveAuthenticationChallenge:%p", connection, challenge);
+ // FIXME: We should ask FrameLoaderClient.
+ return true;
+}
+#endif
- if (m_user && m_pass) {
- NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:m_user
- password:m_pass
- persistence:NSURLCredentialPersistenceNone];
- KURL urlToStore;
- if ([[challenge failureResponse] isKindOfClass:[NSHTTPURLResponse class]] && [(NSHTTPURLResponse*)[challenge failureResponse] statusCode] == 401)
- urlToStore = m_url;
- CredentialStorage::set(core(credential), core([challenge protectionSpace]), urlToStore);
-
- [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
- [credential release];
- [m_user release];
- [m_pass release];
- m_user = 0;
- m_pass = 0;
- return;
- }
- if ([challenge previousFailureCount] == 0 && m_allowStoredCredentials) {
- Credential credential = CredentialStorage::get(core([challenge protectionSpace]));
- if (!credential.isEmpty() && credential != m_initialCredential) {
- ASSERT(credential.persistence() == CredentialPersistenceNone);
- if ([[challenge failureResponse] isKindOfClass:[NSHTTPURLResponse class]] && [(NSHTTPURLResponse *)[challenge failureResponse] statusCode] == 401) {
- // Store the credential back, possibly adding it as a default for this directory.
- CredentialStorage::set(credential, core([challenge protectionSpace]), m_url);
- }
- [[challenge sender] useCredential:mac(credential) forAuthenticationChallenge:challenge];
- return;
- }
- }
+void WebCoreSynchronousLoaderClient::didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge& challenge)
+{
// FIXME: The user should be asked for credentials, as in async case.
- [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
+ [challenge.sender() continueWithoutCredentialForAuthenticationChallenge:challenge.nsURLAuthenticationChallenge()];
}
-- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
+void WebCoreSynchronousLoaderClient::didReceiveResponse(ResourceHandle*, const ResourceResponse& response)
{
- UNUSED_PARAM(connection);
-
- LOG(Network, "WebCoreSynchronousLoader delegate connection:%p didReceiveResponse:%p (HTTP status %d, reported MIMEType '%s')", connection, response, [response respondsToSelector:@selector(statusCode)] ? [(id)response statusCode] : 0, [[response MIMEType] UTF8String]);
-
- NSURLResponse *r = [response copy];
-
[m_response release];
- m_response = r;
+ m_response = [response.nsURLResponse() copy];
}
-- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
+void WebCoreSynchronousLoaderClient::didReceiveData(ResourceHandle*, const char* data, int length, int /*lengthReceived*/)
{
- UNUSED_PARAM(connection);
-
- LOG(Network, "WebCoreSynchronousLoader delegate connection:%p didReceiveData:%p", connection, data);
-
if (!m_data)
m_data = [[NSMutableData alloc] init];
-
- [m_data appendData:data];
+ [m_data appendBytes:data length:length];
}
-- (void)connectionDidFinishLoading:(NSURLConnection *)connection
+void WebCoreSynchronousLoaderClient::didFinishLoading(ResourceHandle*)
{
- UNUSED_PARAM(connection);
-
- LOG(Network, "WebCoreSynchronousLoader delegate connectionDidFinishLoading:%p", connection);
-
- m_isDone = YES;
+ m_isDone = true;
}
-- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
+void WebCoreSynchronousLoaderClient::didFail(ResourceHandle*, const ResourceError& error)
{
- UNUSED_PARAM(connection);
-
- LOG(Network, "WebCoreSynchronousLoader delegate connection:%p didFailWithError:%@", connection, error);
-
ASSERT(!m_error);
-
- m_error = [error retain];
- m_isDone = YES;
-}
-
-- (NSData *)_data
-{
- return [[m_data retain] autorelease];
-}
-
-- (NSURLResponse *)_response
-{
- return [[m_response retain] autorelease];
-}
-- (NSError *)_error
-{
- return [[m_error retain] autorelease];
+ m_error = [error copy];
+ m_isDone = true;
}
-+ (NSData *)loadRequest:(NSURLRequest *)request allowStoredCredentials:(BOOL)allowStoredCredentials returningResponse:(NSURLResponse **)response error:(NSError **)error
-{
- LOG(Network, "WebCoreSynchronousLoader loadRequest:%@ allowStoredCredentials:%u", request, allowStoredCredentials);
-
- WebCoreSynchronousLoader *delegate = [[WebCoreSynchronousLoader alloc] init];
-
- KURL url([request URL]);
- delegate->m_user = [nsStringNilIfEmpty(url.user()) retain];
- delegate->m_pass = [nsStringNilIfEmpty(url.pass()) retain];
- delegate->m_allowStoredCredentials = allowStoredCredentials;
-
- NSURLConnection *connection;
-
- // Take user/pass out of the URL.
- // Credentials for ftp can only be passed in URL, the connection:didReceiveAuthenticationChallenge: delegate call won't be made.
- if ((delegate->m_user || delegate->m_pass) && url.protocolInHTTPFamily()) {
- ResourceRequest requestWithoutCredentials = request;
- requestWithoutCredentials.removeCredentials();
- connection = createNSURLConnection(requestWithoutCredentials.nsURLRequest(), delegate, allowStoredCredentials);
- } else {
- // <rdar://problem/7174050> - For URLs that match the paths of those previously challenged for HTTP Basic authentication,
- // try and reuse the credential preemptively, as allowed by RFC 2617.
- ResourceRequest requestWithInitialCredentials = request;
- if (allowStoredCredentials && url.protocolInHTTPFamily())
- delegate->m_initialCredential = CredentialStorage::get(url);
-
- if (!delegate->m_initialCredential.isEmpty()) {
- String authHeader = "Basic " + encodeBasicAuthorization(delegate->m_initialCredential.user(), delegate->m_initialCredential.password());
- requestWithInitialCredentials.addHTTPHeaderField("Authorization", authHeader);
- }
- connection = createNSURLConnection(requestWithInitialCredentials.nsURLRequest(), delegate, allowStoredCredentials);
- }
-
- [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:WebCoreSynchronousLoaderRunLoopMode];
- [connection start];
-
- while (![delegate _isDone])
- [[NSRunLoop currentRunLoop] runMode:WebCoreSynchronousLoaderRunLoopMode beforeDate:[NSDate distantFuture]];
-
- NSData *data = [delegate _data];
- *response = [delegate _response];
- *error = [delegate _error];
-
- [connection cancel];
-
- [connection release];
- [delegate release];
-
- LOG(Network, "WebCoreSynchronousLoader done");
-
- return data;
-}
-
-@end
-
#endif
diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
index 1ae24ff..131f924 100644
--- a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
+++ b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
@@ -150,7 +150,7 @@ QNetworkReplyHandler::QNetworkReplyHandler(ResourceHandle* handle, LoadMode load
, m_shouldForwardData(false)
, m_redirectionTries(gMaxRecursionLimit)
{
- const ResourceRequest &r = m_resourceHandle->request();
+ const ResourceRequest &r = m_resourceHandle->firstRequest();
if (r.httpMethod() == "GET")
m_method = QNetworkAccessManager::GetOperation;
@@ -309,7 +309,7 @@ void QNetworkReplyHandler::sendResponseIfNeeded()
}
KURL url(m_reply->url());
- ResourceResponse response(url, mimeType,
+ ResourceResponse response(url, mimeType.lower(),
m_reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(),
encoding, String());
@@ -358,7 +358,7 @@ void QNetworkReplyHandler::sendResponseIfNeeded()
}
m_redirected = true;
- ResourceRequest newRequest = m_resourceHandle->request();
+ ResourceRequest newRequest = m_resourceHandle->firstRequest();
newRequest.setURL(newUrl);
if (((statusCode >= 301 && statusCode <= 303) || statusCode == 307) && newRequest.httpMethod() == "POST") {
@@ -442,7 +442,7 @@ void QNetworkReplyHandler::start()
m_reply = manager->get(m_request);
break;
case QNetworkAccessManager::PostOperation: {
- FormDataIODevice* postDevice = new FormDataIODevice(d->m_request.httpBody());
+ FormDataIODevice* postDevice = new FormDataIODevice(d->m_firstRequest.httpBody());
m_reply = manager->post(m_request, postDevice);
postDevice->setParent(m_reply);
break;
@@ -451,7 +451,7 @@ void QNetworkReplyHandler::start()
m_reply = manager->head(m_request);
break;
case QNetworkAccessManager::PutOperation: {
- FormDataIODevice* putDevice = new FormDataIODevice(d->m_request.httpBody());
+ FormDataIODevice* putDevice = new FormDataIODevice(d->m_firstRequest.httpBody());
m_reply = manager->put(m_request, putDevice);
putDevice->setParent(m_reply);
break;
@@ -464,7 +464,7 @@ void QNetworkReplyHandler::start()
#endif
#if QT_VERSION >= 0x040700
case QNetworkAccessManager::CustomOperation:
- m_reply = manager->sendCustomRequest(m_request, m_resourceHandle->request().httpMethod().latin1().data());
+ m_reply = manager->sendCustomRequest(m_request, m_resourceHandle->firstRequest().httpMethod().latin1().data());
break;
#endif
case QNetworkAccessManager::UnknownOperation: {
@@ -494,7 +494,7 @@ void QNetworkReplyHandler::start()
connect(m_reply, SIGNAL(readyRead()),
this, SLOT(forwardData()), SIGNAL_CONN);
- if (m_resourceHandle->request().reportUploadProgress()) {
+ if (m_resourceHandle->firstRequest().reportUploadProgress()) {
connect(m_reply, SIGNAL(uploadProgress(qint64, qint64)),
this, SLOT(uploadProgress(qint64, qint64)), SIGNAL_CONN);
}
diff --git a/WebCore/platform/network/qt/ResourceHandleQt.cpp b/WebCore/platform/network/qt/ResourceHandleQt.cpp
index ff75a94..f91eecb 100644
--- a/WebCore/platform/network/qt/ResourceHandleQt.cpp
+++ b/WebCore/platform/network/qt/ResourceHandleQt.cpp
@@ -43,7 +43,6 @@
// FIXME: WebCore including these headers from WebKit is a massive layering violation.
#include "qwebframe_p.h"
-#include "qwebpage_p.h"
#include <QAbstractNetworkCache>
#include <QCoreApplication>
@@ -130,10 +129,10 @@ bool ResourceHandle::start(Frame* frame)
if (!(d->m_user.isEmpty() || d->m_pass.isEmpty())) {
// If credentials were specified for this request, add them to the url,
// so that they will be passed to QNetworkRequest.
- KURL urlWithCredentials(d->m_request.url());
+ KURL urlWithCredentials(firstRequest().url());
urlWithCredentials.setUser(d->m_user);
urlWithCredentials.setPass(d->m_pass);
- d->m_request.setURL(urlWithCredentials);
+ d->m_firstRequest.setURL(urlWithCredentials);
}
getInternal()->m_frame = static_cast<FrameLoaderClientQt*>(frame->loader()->client())->webFrame();
@@ -195,10 +194,10 @@ void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, S
if (!(d->m_user.isEmpty() || d->m_pass.isEmpty())) {
// If credentials were specified for this request, add them to the url,
// so that they will be passed to QNetworkRequest.
- KURL urlWithCredentials(d->m_request.url());
+ KURL urlWithCredentials(d->m_firstRequest.url());
urlWithCredentials.setUser(d->m_user);
urlWithCredentials.setPass(d->m_pass);
- d->m_request.setURL(urlWithCredentials);
+ d->m_firstRequest.setURL(urlWithCredentials);
}
d->m_frame = static_cast<FrameLoaderClientQt*>(frame->loader()->client())->webFrame();
d->m_job = new QNetworkReplyHandler(handle.get(), QNetworkReplyHandler::LoadNormal);
diff --git a/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
index e4f2a4b..96a2f25 100644
--- a/WebCore/platform/network/soup/ResourceHandleSoup.cpp
+++ b/WebCore/platform/network/soup/ResourceHandleSoup.cpp
@@ -188,9 +188,9 @@ static void restartedCallback(SoupMessage* msg, gpointer data)
char* uri = soup_uri_to_string(soup_message_get_uri(msg), false);
String location = String(uri);
g_free(uri);
- KURL newURL = KURL(handle->request().url(), location);
+ KURL newURL = KURL(handle->firstRequest().url(), location);
- ResourceRequest request = handle->request();
+ ResourceRequest request = handle->firstRequest();
ResourceResponse response;
request.setURL(newURL);
request.setHTTPMethod(msg->method);
@@ -354,7 +354,7 @@ static gboolean parseDataUrl(gpointer callbackData)
if (!client)
return false;
- String url = handle->request().url().string();
+ String url = handle->firstRequest().url().string();
ASSERT(url.startsWith("data:", false));
int index = url.find(',');
@@ -377,7 +377,7 @@ static gboolean parseDataUrl(gpointer callbackData)
String charset = extractCharsetFromMediaType(mediaType);
ResourceResponse response;
- response.setURL(handle->request().url());
+ response.setURL(handle->firstRequest().url());
response.setMimeType(mimeType);
if (isBase64) {
@@ -478,7 +478,7 @@ static bool startHttp(ResourceHandle* handle)
ResourceHandleInternal* d = handle->getInternal();
- ResourceRequest request(handle->request());
+ ResourceRequest request(handle->firstRequest());
KURL url(request.url());
url.removeFragmentIdentifier();
request.setURL(url);
@@ -504,7 +504,7 @@ static bool startHttp(ResourceHandle* handle)
#endif
g_object_set_data(G_OBJECT(d->m_msg), "resourceHandle", reinterpret_cast<void*>(handle));
- FormData* httpBody = d->m_request.httpBody();
+ FormData* httpBody = d->m_firstRequest.httpBody();
if (httpBody && !httpBody->isEmpty()) {
size_t numElements = httpBody->elements().size();
@@ -512,7 +512,7 @@ static bool startHttp(ResourceHandle* handle)
if (numElements < 2) {
Vector<char> body;
httpBody->flatten(body);
- soup_message_set_request(d->m_msg, d->m_request.httpContentType().utf8().data(),
+ soup_message_set_request(d->m_msg, d->m_firstRequest.httpContentType().utf8().data(),
SOUP_MEMORY_COPY, body.data(), body.size());
} else {
/*
@@ -590,7 +590,7 @@ bool ResourceHandle::start(Frame* frame)
if (frame && !frame->page())
return false;
- KURL url = request().url();
+ KURL url = firstRequest().url();
String urlString = url.string();
String protocol = url.protocol();
@@ -889,7 +889,7 @@ static bool startGio(ResourceHandle* handle, KURL url)
ResourceHandleInternal* d = handle->getInternal();
- if (handle->request().httpMethod() != "GET" && handle->request().httpMethod() != "POST")
+ if (handle->firstRequest().httpMethod() != "GET" && handle->firstRequest().httpMethod() != "POST")
return false;
// GIO doesn't know how to handle refs and queries, so remove them
diff --git a/WebCore/platform/qt/CursorQt.cpp b/WebCore/platform/qt/CursorQt.cpp
index 2e495e7..6017daa 100644
--- a/WebCore/platform/qt/CursorQt.cpp
+++ b/WebCore/platform/qt/CursorQt.cpp
@@ -44,12 +44,12 @@
namespace WebCore {
Cursor::Cursor(PlatformCursor p)
- : m_impl(p)
+ : m_platformCursor(p)
{
}
Cursor::Cursor(const Cursor& other)
- : m_impl(other.m_impl)
+ : m_platformCursor(other.m_platformCursor)
{
}
@@ -61,13 +61,13 @@ Cursor::Cursor(Image* image, const IntPoint& hotSpot)
{
#ifndef QT_NO_CURSOR
IntPoint effectiveHotSpot = determineHotSpot(image, hotSpot);
- m_impl = QCursor(*(image->nativeImageForCurrentFrame()), effectiveHotSpot.x(), effectiveHotSpot.y());
+ m_platformCursor = QCursor(*(image->nativeImageForCurrentFrame()), effectiveHotSpot.x(), effectiveHotSpot.y());
#endif
}
Cursor& Cursor::operator=(const Cursor& other)
{
- m_impl = other.m_impl;
+ m_platformCursor = other.m_platformCursor;
return *this;
}
diff --git a/WebCore/platform/qt/GeolocationServiceQt.cpp b/WebCore/platform/qt/GeolocationServiceQt.cpp
index e24d497..3562eb9 100644
--- a/WebCore/platform/qt/GeolocationServiceQt.cpp
+++ b/WebCore/platform/qt/GeolocationServiceQt.cpp
@@ -55,6 +55,7 @@ GeolocationServiceQt::GeolocationServiceQt(GeolocationServiceClient* client)
GeolocationServiceQt::~GeolocationServiceQt()
{
+ delete m_location;
}
void GeolocationServiceQt::positionUpdated(const QGeoPositionInfo &geoPosition)
@@ -65,20 +66,19 @@ void GeolocationServiceQt::positionUpdated(const QGeoPositionInfo &geoPosition)
QGeoCoordinate coord = geoPosition.coordinate();
double latitude = coord.latitude();
double longitude = coord.longitude();
- bool providesAltitude = true;
+ bool providesAltitude = (geoPosition.coordinate().type() == QGeoCoordinate::Coordinate3D);
double altitude = coord.altitude();
- double accuracy = geoPosition.hasAttribute(QGeoPositionInfo::HorizontalAccuracy) ?
- geoPosition.attribute(QGeoPositionInfo::HorizontalAccuracy) : 0.0;
+ double accuracy = geoPosition.attribute(QGeoPositionInfo::HorizontalAccuracy);
bool providesAltitudeAccuracy = geoPosition.hasAttribute(QGeoPositionInfo::VerticalAccuracy);
- double altitudeAccuracy = providesAltitudeAccuracy ? geoPosition.attribute(QGeoPositionInfo::VerticalAccuracy) : 0.0;
+ double altitudeAccuracy = geoPosition.attribute(QGeoPositionInfo::VerticalAccuracy);
bool providesHeading = geoPosition.hasAttribute(QGeoPositionInfo::Direction);
- double heading = providesHeading ? geoPosition.attribute(QGeoPositionInfo::Direction) : 0.0;
+ double heading = geoPosition.attribute(QGeoPositionInfo::Direction);
bool providesSpeed = geoPosition.hasAttribute(QGeoPositionInfo::GroundSpeed);
- double speed = providesSpeed ? geoPosition.attribute(QGeoPositionInfo::GroundSpeed) : 0.0;
+ double speed = geoPosition.attribute(QGeoPositionInfo::GroundSpeed);
RefPtr<Coordinates> coordinates = Coordinates::create(latitude, longitude, providesAltitude, altitude,
accuracy, providesAltitudeAccuracy, altitudeAccuracy,
diff --git a/WebCore/platform/qt/RenderThemeQt.cpp b/WebCore/platform/qt/RenderThemeQt.cpp
index deb9037..22d99a1 100644
--- a/WebCore/platform/qt/RenderThemeQt.cpp
+++ b/WebCore/platform/qt/RenderThemeQt.cpp
@@ -58,8 +58,6 @@
#include "ScrollbarThemeQt.h"
#include "TimeRanges.h"
#include "UserAgentStyleSheets.h"
-#include "qwebpage.h"
-
#include <QApplication>
#include <QColor>
diff --git a/WebCore/platform/qt/WidgetQt.cpp b/WebCore/platform/qt/WidgetQt.cpp
index 00a58a4..0903b6e 100644
--- a/WebCore/platform/qt/WidgetQt.cpp
+++ b/WebCore/platform/qt/WidgetQt.cpp
@@ -41,14 +41,11 @@
#include "QWebPageClient.h"
#include "ScrollView.h"
-#include "qwebframe.h"
-#include "qwebframe_p.h"
-#include "qwebpage.h"
-
#include <QCoreApplication>
#include <QDebug>
#include <QPaintEngine>
#include <QPainter>
+#include <QWidget>
namespace WebCore {
diff --git a/WebCore/platform/text/LineEnding.cpp b/WebCore/platform/text/LineEnding.cpp
new file mode 100644
index 0000000..545f22b
--- /dev/null
+++ b/WebCore/platform/text/LineEnding.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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.
+ */
+
+#include "config.h"
+#include "LineEnding.h"
+
+#include "PlatformString.h"
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+// Normalize all line-endings to CRLF.
+CString normalizeLineEndingsToCRLF(const CString& from)
+{
+ unsigned newLen = 0;
+ const char* p = from.data();
+ while (char c = *p++) {
+ if (c == '\r') {
+ // Safe to look ahead because of trailing '\0'.
+ if (*p != '\n') {
+ // Turn CR into CRLF.
+ newLen += 2;
+ }
+ } else if (c == '\n') {
+ // Turn LF into CRLF.
+ newLen += 2;
+ } else {
+ // Leave other characters alone.
+ newLen += 1;
+ }
+ }
+ if (newLen == from.length())
+ return from;
+
+ // Make a copy of the string.
+ p = from.data();
+ char* q;
+ CString result = CString::newUninitialized(newLen, q);
+ while (char c = *p++) {
+ if (c == '\r') {
+ // Safe to look ahead because of trailing '\0'.
+ if (*p != '\n') {
+ // Turn CR into CRLF.
+ *q++ = '\r';
+ *q++ = '\n';
+ }
+ } else if (c == '\n') {
+ // Turn LF into CRLF.
+ *q++ = '\r';
+ *q++ = '\n';
+ } else {
+ // Leave other characters alone.
+ *q++ = c;
+ }
+ }
+ return result;
+}
+
+// Normalize all line-endings to CR or LF.
+static CString normalizeToCROrLF(const CString& from, bool toCR)
+{
+ unsigned newLen = 0;
+ bool needFix = false;
+ const char* p = from.data();
+ char fromEndingChar = toCR ? '\n' : '\r';
+ char toEndingChar = toCR ? '\r' : '\n';
+ while (char c = *p++) {
+ if (c == '\r' && *p == '\n') {
+ // Turn CRLF into CR or LF.
+ p++;
+ needFix = true;
+ } else if (c == fromEndingChar) {
+ // Turn CR/LF into LF/CR.
+ needFix = true;
+ }
+ newLen += 1;
+ }
+ if (!needFix)
+ return from;
+
+ // Make a copy of the string.
+ p = from.data();
+ char* q;
+ CString result = CString::newUninitialized(newLen, q);
+ while (char c = *p++) {
+ if (c == '\r' && *p == '\n') {
+ // Turn CRLF or CR into CR or LF.
+ p++;
+ *q++ = toEndingChar;
+ } else if (c == fromEndingChar) {
+ // Turn CR/LF into LF/CR.
+ *q++ = toEndingChar;
+ } else {
+ // Leave other characters alone.
+ *q++ = c;
+ }
+ }
+ return result;
+}
+
+// Normalize all line-endings to CR.
+CString normalizeLineEndingsToCR(const CString& from)
+{
+ return normalizeToCROrLF(from, true);
+}
+
+// Normalize all line-endings to LF.
+CString normalizeLineEndingsToLF(const CString& from)
+{
+ return normalizeToCROrLF(from, false);
+}
+
+CString normalizeLineEndingsToNative(const CString& from)
+{
+#if OS(WINDOWS)
+ return normalizeLineEndingsToCRLF(from);
+#else
+ return normalizeLineEndingsToLF(from);
+#endif
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/text/LineEnding.h b/WebCore/platform/text/LineEnding.h
new file mode 100644
index 0000000..9c3e2aa
--- /dev/null
+++ b/WebCore/platform/text/LineEnding.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 LineEnding_h
+#define LineEnding_h
+
+namespace WTF {
+class CString;
+}
+
+namespace WebCore {
+
+// Normalize all line-endings in the given string to CRLF.
+WTF::CString normalizeLineEndingsToCRLF(const WTF::CString&);
+
+// Normalize all line-endings in the given string to CR.
+WTF::CString normalizeLineEndingsToCR(const WTF::CString&);
+
+// Normalize all line-endings in the given string to LF.
+WTF::CString normalizeLineEndingsToLF(const WTF::CString&);
+
+// Normalize all line-endings in the given string to the native line-endings.
+// (Normalize to CRLF on Windows and normalize to LF on all other platforms.)
+WTF::CString normalizeLineEndingsToNative(const WTF::CString&);
+
+} // namespace WebCore
+
+#endif // LineEnding_h
diff --git a/WebCore/platform/win/ClipboardUtilitiesWin.cpp b/WebCore/platform/win/ClipboardUtilitiesWin.cpp
index fbd0011..e6af7ef 100644
--- a/WebCore/platform/win/ClipboardUtilitiesWin.cpp
+++ b/WebCore/platform/win/ClipboardUtilitiesWin.cpp
@@ -32,10 +32,10 @@
#include "TextEncoding.h"
#include "markup.h"
#include <CoreFoundation/CoreFoundation.h>
+#include <shlwapi.h>
+#include <wininet.h> // for INTERNET_MAX_URL_LENGTH
#include <wtf/RetainPtr.h>
#include <wtf/text/CString.h>
-#include <shlwapi.h>
-#include <wininet.h> // for INTERNET_MAX_URL_LENGTH
namespace WebCore {
@@ -97,7 +97,7 @@ static String extractURL(const String &inURL, String* title)
return url;
}
-//Firefox text/html
+// Firefox text/html
static FORMATETC* texthtmlFormat()
{
static UINT cf = RegisterClipboardFormat(L"text/html");
@@ -109,7 +109,7 @@ HGLOBAL createGlobalData(const KURL& url, const String& title)
{
String mutableURL(url.string());
String mutableTitle(title);
- SIZE_T size = mutableURL.length() + mutableTitle.length() + 2; // +1 for "\n" and +1 for null terminator
+ SIZE_T size = mutableURL.length() + mutableTitle.length() + 2; // +1 for "\n" and +1 for null terminator
HGLOBAL cbData = ::GlobalAlloc(GPTR, size * sizeof(UChar));
if (cbData) {
@@ -155,7 +155,7 @@ static void append(Vector<char>& vector, const CString& string)
}
// Documentation for the CF_HTML format is available at http://msdn.microsoft.com/workshop/networking/clipboard/htmlclipboard.asp
-void markupToCF_HTML(const String& markup, const String& srcURL, Vector<char>& result)
+void markupToCFHTML(const String& markup, const String& srcURL, Vector<char>& result)
{
if (markup.isEmpty())
return;
@@ -256,7 +256,7 @@ FORMATETC* filenameFormat()
return &urlFormat;
}
-//MSIE HTML Format
+// MSIE HTML Format
FORMATETC* htmlFormat()
{
static UINT cf = RegisterClipboardFormat(L"HTML Format");
@@ -294,18 +294,17 @@ String getURL(IDataObject* dataObject, DragData::FilenameConversionPolicy filena
STGMEDIUM store;
String url;
success = false;
- if (getWebLocData(dataObject, url, title)) {
+ if (getWebLocData(dataObject, url, title))
success = true;
- return url;
- } else if (SUCCEEDED(dataObject->GetData(urlWFormat(), &store))) {
- //URL using unicode
+ else if (SUCCEEDED(dataObject->GetData(urlWFormat(), &store))) {
+ // URL using Unicode
UChar* data = (UChar*)GlobalLock(store.hGlobal);
url = extractURL(String(data), title);
GlobalUnlock(store.hGlobal);
ReleaseStgMedium(&store);
success = true;
} else if (SUCCEEDED(dataObject->GetData(urlFormat(), &store))) {
- //URL using ascii
+ // URL using ASCII
char* data = (char*)GlobalLock(store.hGlobal);
url = extractURL(String(data), title);
GlobalUnlock(store.hGlobal);
@@ -349,14 +348,14 @@ String getPlainText(IDataObject* dataObject, bool& success)
String text;
success = false;
if (SUCCEEDED(dataObject->GetData(plainTextWFormat(), &store))) {
- //unicode text
+ // Unicode text
UChar* data = (UChar*)GlobalLock(store.hGlobal);
text = String(data);
GlobalUnlock(store.hGlobal);
ReleaseStgMedium(&store);
success = true;
} else if (SUCCEEDED(dataObject->GetData(plainTextFormat(), &store))) {
- //ascii text
+ // ASCII text
char* data = (char*)GlobalLock(store.hGlobal);
text = String(data);
GlobalUnlock(store.hGlobal);
@@ -372,40 +371,55 @@ String getPlainText(IDataObject* dataObject, bool& success)
return text;
}
+String getTextHTML(IDataObject* data, bool& success)
+{
+ STGMEDIUM store;
+ String html;
+ success = false;
+ if (SUCCEEDED(data->GetData(texthtmlFormat(), &store))) {
+ UChar* data = static_cast<UChar*>(GlobalLock(store.hGlobal));
+ html = String(data);
+ GlobalUnlock(store.hGlobal);
+ ReleaseStgMedium(&store);
+ success = true;
+ }
+ return html;
+}
+
PassRefPtr<DocumentFragment> fragmentFromFilenames(Document*, const IDataObject*)
{
- //FIXME: We should be able to create fragments from files
+ // FIXME: We should be able to create fragments from files
return 0;
}
bool containsFilenames(const IDataObject*)
{
- //FIXME: We'll want to update this once we can produce fragments from files
+ // FIXME: We'll want to update this once we can produce fragments from files
return false;
}
-//Convert a String containing CF_HTML formatted text to a DocumentFragment
-PassRefPtr<DocumentFragment> fragmentFromCF_HTML(Document* doc, const String& cf_html)
+// Convert a String containing CF_HTML formatted text to a DocumentFragment
+PassRefPtr<DocumentFragment> fragmentFromCFHTML(Document* doc, const String& cfhtml)
{
// obtain baseURL if present
String srcURLStr("sourceURL:");
String srcURL;
- unsigned lineStart = cf_html.find(srcURLStr, 0, false);
+ unsigned lineStart = cfhtml.find(srcURLStr, 0, false);
if (lineStart != -1) {
- unsigned srcEnd = cf_html.find("\n", lineStart, false);
+ unsigned srcEnd = cfhtml.find("\n", lineStart, false);
unsigned srcStart = lineStart+srcURLStr.length();
- String rawSrcURL = cf_html.substring(srcStart, srcEnd-srcStart);
+ String rawSrcURL = cfhtml.substring(srcStart, srcEnd-srcStart);
replaceNBSPWithSpace(rawSrcURL);
srcURL = rawSrcURL.stripWhiteSpace();
}
// find the markup between "<!--StartFragment -->" and "<!--EndFragment -->", accounting for browser quirks
- unsigned markupStart = cf_html.find("<html", 0, false);
- unsigned tagStart = cf_html.find("startfragment", markupStart, false);
- unsigned fragmentStart = cf_html.find('>', tagStart) + 1;
- unsigned tagEnd = cf_html.find("endfragment", fragmentStart, false);
- unsigned fragmentEnd = cf_html.reverseFind('<', tagEnd);
- String markup = cf_html.substring(fragmentStart, fragmentEnd - fragmentStart).stripWhiteSpace();
+ unsigned markupStart = cfhtml.find("<html", 0, false);
+ unsigned tagStart = cfhtml.find("startfragment", markupStart, false);
+ unsigned fragmentStart = cfhtml.find('>', tagStart) + 1;
+ unsigned tagEnd = cfhtml.find("endfragment", fragmentStart, false);
+ unsigned fragmentEnd = cfhtml.reverseFind('<', tagEnd);
+ String markup = cfhtml.substring(fragmentStart, fragmentEnd - fragmentStart).stripWhiteSpace();
return createFragmentFromMarkup(doc, markup, srcURL, FragmentScriptingNotAllowed);
}
@@ -420,23 +434,19 @@ PassRefPtr<DocumentFragment> fragmentFromHTML(Document* doc, IDataObject* data)
String html;
String srcURL;
if (SUCCEEDED(data->GetData(htmlFormat(), &store))) {
- //MS HTML Format parsing
+ // MS HTML Format parsing
char* data = (char*)GlobalLock(store.hGlobal);
SIZE_T dataSize = ::GlobalSize(store.hGlobal);
- String cf_html(UTF8Encoding().decode(data, dataSize));
+ String cfhtml(UTF8Encoding().decode(data, dataSize));
GlobalUnlock(store.hGlobal);
ReleaseStgMedium(&store);
- if (PassRefPtr<DocumentFragment> fragment = fragmentFromCF_HTML(doc, cf_html))
+ if (PassRefPtr<DocumentFragment> fragment = fragmentFromCFHTML(doc, cfhtml))
return fragment;
}
- if (SUCCEEDED(data->GetData(texthtmlFormat(), &store))) {
- //raw html
- UChar* data = (UChar*)GlobalLock(store.hGlobal);
- html = String(data);
- GlobalUnlock(store.hGlobal);
- ReleaseStgMedium(&store);
+ bool success = false;
+ html = getTextHTML(data, success);
+ if (success)
return createFragmentFromMarkup(doc, html, srcURL, FragmentScriptingNotAllowed);
- }
return 0;
}
diff --git a/WebCore/platform/win/ClipboardUtilitiesWin.h b/WebCore/platform/win/ClipboardUtilitiesWin.h
index ac5efd8..4ca46f9 100644
--- a/WebCore/platform/win/ClipboardUtilitiesWin.h
+++ b/WebCore/platform/win/ClipboardUtilitiesWin.h
@@ -49,7 +49,7 @@ FORMATETC* htmlFormat();
FORMATETC* cfHDropFormat();
FORMATETC* smartPasteFormat();
-void markupToCF_HTML(const String& markup, const String& srcURL, Vector<char>& result);
+void markupToCFHTML(const String& markup, const String& srcURL, Vector<char>& result);
void replaceNewlinesWithWindowsStyleNewlines(String&);
void replaceNBSPWithSpace(String&);
@@ -59,12 +59,12 @@ bool containsHTML(IDataObject*);
PassRefPtr<DocumentFragment> fragmentFromFilenames(Document*, const IDataObject*);
PassRefPtr<DocumentFragment> fragmentFromHTML(Document*, IDataObject*);
-PassRefPtr<DocumentFragment> fragmentFromCF_HTML(Document*, const String& cf_html);
+PassRefPtr<DocumentFragment> fragmentFromCFHTML(Document*, const String& cfhtml);
String getURL(IDataObject*, DragData::FilenameConversionPolicy, bool& success, String* title = 0);
String getPlainText(IDataObject*, bool& success);
+String getTextHTML(IDataObject*, bool& success);
} // namespace WebCore
#endif // ClipboardUtilitiesWin_h
-
diff --git a/WebCore/platform/win/ClipboardWin.cpp b/WebCore/platform/win/ClipboardWin.cpp
index 3c3a205..2cd6feb 100644
--- a/WebCore/platform/win/ClipboardWin.cpp
+++ b/WebCore/platform/win/ClipboardWin.cpp
@@ -105,9 +105,8 @@ static inline void pathRemoveBadFSCharacters(PWSTR psz, size_t length)
size_t readFrom = 0;
while (readFrom < length) {
UINT type = PathGetCharType(psz[readFrom]);
- if (psz[readFrom] == 0 || type & (GCT_LFNCHAR | GCT_SHORTCHAR)) {
+ if (!psz[readFrom] || type & (GCT_LFNCHAR | GCT_SHORTCHAR))
psz[writeTo++] = psz[readFrom];
- }
readFrom++;
}
@@ -215,7 +214,7 @@ static HGLOBAL createGlobalImageFileContent(SharedBuffer* data)
static HGLOBAL createGlobalHDropContent(const KURL& url, String& fileName, SharedBuffer* data)
{
- if (fileName.isEmpty() || !data )
+ if (fileName.isEmpty() || !data)
return 0;
WCHAR filePath[MAX_PATH];
@@ -290,7 +289,7 @@ static HGLOBAL createGlobalUrlFileDescriptor(const String& url, const String& ti
fgd->cItems = 1;
fgd->fgd[0].dwFlags = FD_FILESIZE;
int fileSize = ::WideCharToMultiByte(CP_ACP, 0, url.characters(), url.length(), 0, 0, 0, 0);
- fileSize += strlen(szShellDotUrlTemplate) - 2; // -2 is for getting rid of %s in the template string
+ fileSize += strlen(szShellDotUrlTemplate) - 2; // -2 is for getting rid of %s in the template string
fgd->fgd[0].nFileSizeLow = fileSize;
estimatedSize = fileSize;
fsPath = filesystemPathFromUrlOrTitle(url, title, L".URL", true);
@@ -437,7 +436,7 @@ static bool writeURL(WCDataObject *data, const KURL& url, String title, bool wit
if (withHTML) {
Vector<char> cfhtmlData;
- markupToCF_HTML(urlToMarkup(url, title), "", cfhtmlData);
+ markupToCFHTML(urlToMarkup(url, title), "", cfhtmlData);
medium.hGlobal = createGlobalData(cfhtmlData);
if (medium.hGlobal && FAILED(data->SetData(htmlFormat(), &medium, TRUE)))
::GlobalFree(medium.hGlobal);
@@ -458,7 +457,7 @@ static bool writeURL(WCDataObject *data, const KURL& url, String title, bool wit
void ClipboardWin::clearData(const String& type)
{
- //FIXME: Need to be able to write to the system clipboard <rdar://problem/5015941>
+ // FIXME: Need to be able to write to the system clipboard <rdar://problem/5015941>
ASSERT(isForDragging());
if (policy() != ClipboardWritable || !m_writableDataObject)
return;
@@ -478,7 +477,7 @@ void ClipboardWin::clearData(const String& type)
void ClipboardWin::clearAllData()
{
- //FIXME: Need to be able to write to the system clipboard <rdar://problem/5015941>
+ // FIXME: Need to be able to write to the system clipboard <rdar://problem/5015941>
ASSERT(isForDragging());
if (policy() != ClipboardWritable)
return;
@@ -491,14 +490,13 @@ void ClipboardWin::clearAllData()
String ClipboardWin::getData(const String& type, bool& success) const
{
success = false;
- if (policy() != ClipboardReadable || !m_dataObject) {
+ if (policy() != ClipboardReadable || !m_dataObject)
return "";
- }
ClipboardDataType dataType = clipboardTypeFromMIMEType(type);
if (dataType == ClipboardDataTypeText)
return getPlainText(m_dataObject.get(), success);
- else if (dataType == ClipboardDataTypeURL)
+ if (dataType == ClipboardDataTypeURL)
return getURL(m_dataObject.get(), DragData::DoNotConvertFilenames, success);
return "";
@@ -568,9 +566,8 @@ HashSet<String> ClipboardWin::types() const
FORMATETC data;
// IEnumFORMATETC::Next returns S_FALSE if there are no more items.
- while (itr->Next(1, &data, 0) == S_OK) {
+ while (itr->Next(1, &data, 0) == S_OK)
addMimeTypesForFormat(results, data);
- }
return results;
}
@@ -720,7 +717,7 @@ void ClipboardWin::declareAndWriteDragImage(Element* element, const KURL& url, c
// Put img tag on the clipboard referencing the image
Vector<char> data;
- markupToCF_HTML(imageToMarkup(fullURL), "", data);
+ markupToCFHTML(imageToMarkup(fullURL), "", data);
medium.hGlobal = createGlobalData(data);
if (medium.hGlobal && FAILED(m_writableDataObject->SetData(htmlFormat(), &medium, TRUE)))
::GlobalFree(medium.hGlobal);
@@ -757,7 +754,7 @@ void ClipboardWin::writeRange(Range* selectedRange, Frame* frame)
ExceptionCode ec = 0;
Vector<char> data;
- markupToCF_HTML(createMarkup(selectedRange, 0, AnnotateForInterchange),
+ markupToCFHTML(createMarkup(selectedRange, 0, AnnotateForInterchange),
selectedRange->startContainer(ec)->document()->url().string(), data);
medium.hGlobal = createGlobalData(data);
if (medium.hGlobal && FAILED(m_writableDataObject->SetData(htmlFormat(), &medium, TRUE)))
diff --git a/WebCore/platform/win/ClipboardWin.h b/WebCore/platform/win/ClipboardWin.h
index 49fdcfe..1b139ed 100644
--- a/WebCore/platform/win/ClipboardWin.h
+++ b/WebCore/platform/win/ClipboardWin.h
@@ -26,66 +26,66 @@
#ifndef ClipboardWin_h
#define ClipboardWin_h
+#include "COMPtr.h"
#include "CachedResourceClient.h"
#include "Clipboard.h"
-#include "COMPtr.h"
struct IDataObject;
namespace WebCore {
- class CachedImage;
- class IntPoint;
- class WCDataObject;
-
- // State available during IE's events for drag and drop and copy/paste
- class ClipboardWin : public Clipboard, public CachedResourceClient {
- public:
- static PassRefPtr<ClipboardWin> create(bool isForDragging, IDataObject* dataObject, ClipboardAccessPolicy policy)
- {
- return adoptRef(new ClipboardWin(isForDragging, dataObject, policy));
- }
- static PassRefPtr<ClipboardWin> create(bool isForDragging, WCDataObject* dataObject, ClipboardAccessPolicy policy)
- {
- return adoptRef(new ClipboardWin(isForDragging, dataObject, policy));
- }
- ~ClipboardWin();
-
- void clearData(const String& type);
- void clearAllData();
- String getData(const String& type, bool& success) const;
- bool setData(const String& type, const String& data);
-
- // extensions beyond IE's API
- virtual HashSet<String> types() const;
- virtual PassRefPtr<FileList> files() const;
-
- void setDragImage(CachedImage*, const IntPoint&);
- void setDragImageElement(Node*, const IntPoint&);
-
- virtual DragImageRef createDragImage(IntPoint& dragLoc) const;
- virtual void declareAndWriteDragImage(Element*, const KURL&, const String& title, Frame*);
- virtual void writeURL(const KURL&, const String&, Frame*);
- virtual void writeRange(Range*, Frame*);
- virtual void writePlainText(const String&);
-
- virtual bool hasData();
-
- COMPtr<IDataObject> dataObject() { return m_dataObject; }
-
- void setExternalDataObject(IDataObject *dataObject);
-
- private:
- ClipboardWin(bool isForDragging, IDataObject*, ClipboardAccessPolicy);
- ClipboardWin(bool isForDragging, WCDataObject*, ClipboardAccessPolicy);
-
- void resetFromClipboard();
- void setDragImage(CachedImage*, Node*, const IntPoint&);
-
- COMPtr<IDataObject> m_dataObject;
- COMPtr<WCDataObject> m_writableDataObject;
- Frame* m_frame;
- };
+class CachedImage;
+class IntPoint;
+class WCDataObject;
+
+// State available during IE's events for drag and drop and copy/paste
+class ClipboardWin : public Clipboard, public CachedResourceClient {
+public:
+ static PassRefPtr<ClipboardWin> create(bool isForDragging, IDataObject* dataObject, ClipboardAccessPolicy policy)
+ {
+ return adoptRef(new ClipboardWin(isForDragging, dataObject, policy));
+ }
+ static PassRefPtr<ClipboardWin> create(bool isForDragging, WCDataObject* dataObject, ClipboardAccessPolicy policy)
+ {
+ return adoptRef(new ClipboardWin(isForDragging, dataObject, policy));
+ }
+ ~ClipboardWin();
+
+ void clearData(const String& type);
+ void clearAllData();
+ String getData(const String& type, bool& success) const;
+ bool setData(const String& type, const String& data);
+
+ // extensions beyond IE's API
+ virtual HashSet<String> types() const;
+ virtual PassRefPtr<FileList> files() const;
+
+ void setDragImage(CachedImage*, const IntPoint&);
+ void setDragImageElement(Node*, const IntPoint&);
+
+ virtual DragImageRef createDragImage(IntPoint& dragLoc) const;
+ virtual void declareAndWriteDragImage(Element*, const KURL&, const String& title, Frame*);
+ virtual void writeURL(const KURL&, const String&, Frame*);
+ virtual void writeRange(Range*, Frame*);
+ virtual void writePlainText(const String&);
+
+ virtual bool hasData();
+
+ COMPtr<IDataObject> dataObject() { return m_dataObject; }
+
+ void setExternalDataObject(IDataObject *dataObject);
+
+private:
+ ClipboardWin(bool isForDragging, IDataObject*, ClipboardAccessPolicy);
+ ClipboardWin(bool isForDragging, WCDataObject*, ClipboardAccessPolicy);
+
+ void resetFromClipboard();
+ void setDragImage(CachedImage*, Node*, const IntPoint&);
+
+ COMPtr<IDataObject> m_dataObject;
+ COMPtr<WCDataObject> m_writableDataObject;
+ Frame* m_frame;
+};
} // namespace WebCore
diff --git a/WebCore/platform/win/CursorWin.cpp b/WebCore/platform/win/CursorWin.cpp
index 22a535d..2dd1452 100644
--- a/WebCore/platform/win/CursorWin.cpp
+++ b/WebCore/platform/win/CursorWin.cpp
@@ -39,11 +39,6 @@
namespace WebCore {
-Cursor::Cursor(const Cursor& other)
- : m_impl(other.m_impl)
-{
-}
-
static inline bool supportsAlphaCursors()
{
OSVERSIONINFO osinfo = {0};
@@ -52,8 +47,10 @@ static inline bool supportsAlphaCursors()
return osinfo.dwMajorVersion > 5 || (osinfo.dwMajorVersion == 5 && osinfo.dwMinorVersion > 0);
}
-Cursor::Cursor(Image* img, const IntPoint& hotSpot)
+static PassRefPtr<SharedCursor> createSharedCursor(Image* img, const IntPoint& hotSpot)
{
+ RefPtr<SharedCursor> impl;
+
IntPoint effectiveHotSpot = determineHotSpot(img, hotSpot);
static bool doAlpha = supportsAlphaCursors();
BitmapInfo cursorImage = BitmapInfo::create(IntSize(img->width(), img->height()));
@@ -80,7 +77,7 @@ Cursor::Cursor(Image* img, const IntPoint& hotSpot)
ii.hbmMask = hMask.get();
ii.hbmColor = hCursor.get();
- m_impl = SharedCursor::create(CreateIconIndirect(&ii));
+ impl = SharedCursor::create(CreateIconIndirect(&ii));
} else {
// Platform doesn't support alpha blended cursors, so we need
// to create the mask manually
@@ -115,303 +112,183 @@ Cursor::Cursor(Image* img, const IntPoint& hotSpot)
icon.yHotspot = effectiveHotSpot.y();
icon.hbmMask = andMask.get();
icon.hbmColor = xorMask.get();
- m_impl = SharedCursor::create(CreateIconIndirect(&icon));
+ impl = SharedCursor::create(CreateIconIndirect(&icon));
DeleteDC(xorMaskDC);
DeleteDC(andMaskDC);
}
DeleteDC(workingDC);
ReleaseDC(0, dc);
-}
-Cursor::~Cursor()
-{
+ return impl.release();
}
-Cursor& Cursor::operator=(const Cursor& other)
-{
- m_impl = other.m_impl;
- return *this;
-}
-
-Cursor::Cursor(PlatformCursor c)
- : m_impl(c)
+static PassRefPtr<SharedCursor> loadSharedCursor(HINSTANCE hInstance, LPCTSTR lpCursorName)
{
+ return SharedCursor::create(::LoadCursor(hInstance, lpCursorName));
}
-static Cursor loadCursorByName(char* name, int x, int y)
+static PassRefPtr<SharedCursor> loadCursorByName(char* name, int x, int y)
{
IntPoint hotSpot(x, y);
- Cursor c;
RefPtr<Image> cursorImage(Image::loadPlatformResource(name));
- if (cursorImage && !cursorImage->isNull())
- c = Cursor(cursorImage.get(), hotSpot);
- else
- c = pointerCursor();
- return c;
-}
-
-static PassRefPtr<SharedCursor> loadSharedCursor(HINSTANCE hInstance, LPCTSTR lpCursorName)
-{
- return SharedCursor::create(LoadCursor(hInstance, lpCursorName));
-}
-
-const Cursor& pointerCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_ARROW);
- return c;
-}
-
-const Cursor& crossCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_CROSS);
- return c;
-}
-
-const Cursor& handCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_HAND);
- return c;
-}
-
-const Cursor& iBeamCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_IBEAM);
- return c;
-}
-
-const Cursor& waitCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_WAIT);
- return c;
-}
-
-const Cursor& helpCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_HELP);
- return c;
-}
-
-const Cursor& eastResizeCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_SIZEWE);
- return c;
-}
-
-const Cursor& northResizeCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_SIZENS);
- return c;
-}
-
-const Cursor& northEastResizeCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_SIZENESW);
- return c;
-}
-
-const Cursor& northWestResizeCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_SIZENWSE);
- return c;
-}
-
-const Cursor& southResizeCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_SIZENS);
- return c;
-}
-
-const Cursor& southEastResizeCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_SIZENWSE);
- return c;
-}
-
-const Cursor& southWestResizeCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_SIZENESW);
- return c;
-}
-
-const Cursor& westResizeCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_SIZEWE);
- return c;
-}
-
-const Cursor& northSouthResizeCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_SIZENS);
- return c;
-}
-
-const Cursor& eastWestResizeCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_SIZEWE);
- return c;
-}
-
-const Cursor& northEastSouthWestResizeCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_SIZENESW);
- return c;
-}
-
-const Cursor& northWestSouthEastResizeCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_SIZENWSE);
- return c;
-}
-
-const Cursor& columnResizeCursor()
-{
- // FIXME: Windows does not have a standard column resize cursor <rdar://problem/5018591>
- static Cursor c = loadSharedCursor(0, IDC_SIZEWE);
- return c;
-}
-
-const Cursor& rowResizeCursor()
-{
- // FIXME: Windows does not have a standard row resize cursor <rdar://problem/5018591>
- static Cursor c = loadSharedCursor(0, IDC_SIZENS);
- return c;
-}
-
-const Cursor& middlePanningCursor()
-{
- static const Cursor c = loadCursorByName("panIcon", 8, 8);
- return c;
-}
-
-const Cursor& eastPanningCursor()
-{
- static const Cursor c = loadCursorByName("panEastCursor", 7, 7);
- return c;
-}
-
-const Cursor& northPanningCursor()
-{
- static const Cursor c = loadCursorByName("panNorthCursor", 7, 7);
- return c;
-}
-
-const Cursor& northEastPanningCursor()
-{
- static const Cursor c = loadCursorByName("panNorthEastCursor", 7, 7);
- return c;
-}
-
-const Cursor& northWestPanningCursor()
-{
- static const Cursor c = loadCursorByName("panNorthWestCursor", 7, 7);
- return c;
-}
-
-const Cursor& southPanningCursor()
-{
- static const Cursor c = loadCursorByName("panSouthCursor", 7, 7);
- return c;
-}
-
-const Cursor& southEastPanningCursor()
-{
- static const Cursor c = loadCursorByName("panSouthEastCursor", 7, 7);
- return c;
-}
-
-const Cursor& southWestPanningCursor()
-{
- static const Cursor c = loadCursorByName("panSouthWestCursor", 7, 7);
- return c;
-}
-
-const Cursor& westPanningCursor()
-{
- static const Cursor c = loadCursorByName("panWestCursor", 7, 7);
- return c;
-}
-
-const Cursor& moveCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_SIZEALL);
- return c;
-}
-
-const Cursor& verticalTextCursor()
-{
- static const Cursor c = loadCursorByName("verticalTextCursor", 7, 7);
- return c;
-}
-
-const Cursor& cellCursor()
-{
- return pointerCursor();
-}
-
-const Cursor& contextMenuCursor()
-{
- return pointerCursor();
-}
-
-const Cursor& aliasCursor()
-{
- return pointerCursor();
-}
-
-const Cursor& progressCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_APPSTARTING);
- return c;
-}
-
-const Cursor& noDropCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_NO);
- return c;
-}
-
-const Cursor& copyCursor()
-{
- return pointerCursor();
-}
-
-const Cursor& noneCursor()
-{
- return pointerCursor();
-}
-
-const Cursor& notAllowedCursor()
-{
- static Cursor c = loadSharedCursor(0, IDC_NO);
- return c;
-}
-
-const Cursor& zoomInCursor()
-{
- static const Cursor c = loadCursorByName("zoomInCursor", 7, 7);
- return c;
+ if (cursorImage && !cursorImage->isNull())
+ return createSharedCursor(cursorImage.get(), hotSpot);
+ return loadSharedCursor(0, IDC_ARROW);
+}
+
+void Cursor::ensurePlatformCursor() const
+{
+ if (m_platformCursor)
+ return;
+
+ switch (m_type) {
+ case Cursor::Pointer:
+ case Cursor::Cell:
+ case Cursor::ContextMenu:
+ case Cursor::Alias:
+ case Cursor::Copy:
+ case Cursor::None:
+ case Cursor::Grab:
+ case Cursor::Grabbing:
+ m_platformCursor = loadSharedCursor(0, IDC_ARROW);
+ break;
+ case Cursor::Cross:
+ m_platformCursor = loadSharedCursor(0, IDC_CROSS);
+ break;
+ case Cursor::Hand:
+ m_platformCursor = loadSharedCursor(0, IDC_HAND);
+ break;
+ case Cursor::IBeam:
+ m_platformCursor = loadSharedCursor(0, IDC_IBEAM);
+ break;
+ case Cursor::Wait:
+ m_platformCursor = loadSharedCursor(0, IDC_WAIT);
+ break;
+ case Cursor::Help:
+ m_platformCursor = loadSharedCursor(0, IDC_HELP);
+ break;
+ case Cursor::Move:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZEALL);
+ break;
+ case Cursor::MiddlePanning:
+ m_platformCursor = loadCursorByName("panIcon", 8, 8);
+ break;
+ case Cursor::EastResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZEWE);
+ break;
+ case Cursor::EastPanning:
+ m_platformCursor = loadCursorByName("panEastCursor", 7, 7);
+ break;
+ case Cursor::NorthResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENS);
+ break;
+ case Cursor::NorthPanning:
+ m_platformCursor = loadCursorByName("panNorthCursor", 7, 7);
+ break;
+ case Cursor::NorthEastResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENESW);
+ break;
+ case Cursor::NorthEastPanning:
+ m_platformCursor = loadCursorByName("panNorthEastCursor", 7, 7);
+ break;
+ case Cursor::NorthWestResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENWSE);
+ break;
+ case Cursor::NorthWestPanning:
+ m_platformCursor = loadCursorByName("panNorthWestCursor", 7, 7);
+ break;
+ case Cursor::SouthResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENS);
+ break;
+ case Cursor::SouthPanning:
+ m_platformCursor = loadCursorByName("panSouthCursor", 7, 7);
+ break;
+ case Cursor::SouthEastResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENWSE);
+ break;
+ case Cursor::SouthEastPanning:
+ m_platformCursor = loadCursorByName("panSouthEastCursor", 7, 7);
+ break;
+ case Cursor::SouthWestResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENESW);
+ break;
+ case Cursor::SouthWestPanning:
+ m_platformCursor = loadCursorByName("panSouthWestCursor", 7, 7);
+ break;
+ case Cursor::WestResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZEWE);
+ break;
+ case Cursor::NorthSouthResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENS);
+ break;
+ case Cursor::EastWestResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZEWE);
+ break;
+ case Cursor::WestPanning:
+ m_platformCursor = loadCursorByName("panWestCursor", 7, 7);
+ break;
+ case Cursor::NorthEastSouthWestResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENESW);
+ break;
+ case Cursor::NorthWestSouthEastResize:
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENWSE);
+ break;
+ case Cursor::ColumnResize:
+ // FIXME: Windows does not have a standard column resize cursor <rdar://problem/5018591>
+ m_platformCursor = loadSharedCursor(0, IDC_SIZEWE);
+ break;
+ case Cursor::RowResize:
+ // FIXME: Windows does not have a standard row resize cursor <rdar://problem/5018591>
+ m_platformCursor = loadSharedCursor(0, IDC_SIZENS);
+ break;
+ case Cursor::VerticalText:
+ m_platformCursor = loadCursorByName("verticalTextCursor", 7, 7);
+ break;
+ case Cursor::Progress:
+ m_platformCursor = loadSharedCursor(0, IDC_APPSTARTING);
+ break;
+ case Cursor::NoDrop:
+ break;
+ case Cursor::NotAllowed:
+ m_platformCursor = loadSharedCursor(0, IDC_NO);
+ break;
+ case Cursor::ZoomIn:
+ m_platformCursor = loadCursorByName("zoomInCursor", 7, 7);
+ break;
+ case Cursor::ZoomOut:
+ m_platformCursor = loadCursorByName("zoomOutCursor", 7, 7);
+ break;
+ case Cursor::Custom:
+ m_platformCursor = createSharedCursor(m_image.get(), m_hotSpot);
+ break;
+ }
}
-const Cursor& zoomOutCursor()
+SharedCursor::~SharedCursor()
{
- static const Cursor c = loadCursorByName("zoomOutCursor", 7, 7);
- return c;
+ DestroyIcon(m_nativeCursor);
}
-const Cursor& grabCursor()
+Cursor::Cursor(const Cursor& other)
+ : m_type(other.m_type)
+ , m_image(other.m_image)
+ , m_hotSpot(other.m_hotSpot)
+ , m_platformCursor(other.m_platformCursor)
{
- return pointerCursor();
}
-const Cursor& grabbingCursor()
+Cursor& Cursor::operator=(const Cursor& other)
{
- return pointerCursor();
+ m_type = other.m_type;
+ m_image = other.m_image;
+ m_hotSpot = other.m_hotSpot;
+ m_platformCursor = other.m_platformCursor;
+ return *this;
}
-SharedCursor::~SharedCursor()
+Cursor::~Cursor()
{
- DestroyIcon(m_nativeCursor);
}
-}
+} // namespace WebCore
diff --git a/WebCore/platform/win/PasteboardWin.cpp b/WebCore/platform/win/PasteboardWin.cpp
index 512f6cf..808c863 100644
--- a/WebCore/platform/win/PasteboardWin.cpp
+++ b/WebCore/platform/win/PasteboardWin.cpp
@@ -54,7 +54,7 @@ static LRESULT CALLBACK PasteboardOwnerWndProc(HWND hWnd, UINT message, WPARAM w
LRESULT lresult = 0;
LONG_PTR longPtr = GetWindowLongPtr(hWnd, 0);
- switch(message) {
+ switch (message) {
case WM_RENDERFORMAT:
// This message comes when SetClipboardData was sent a null data handle
// and now it's come time to put the data on the clipboard.
@@ -117,7 +117,7 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
if (::OpenClipboard(m_owner)) {
ExceptionCode ec = 0;
Vector<char> data;
- markupToCF_HTML(createMarkup(selectedRange, 0, AnnotateForInterchange),
+ markupToCFHTML(createMarkup(selectedRange, 0, AnnotateForInterchange),
selectedRange->startContainer(ec)->document()->url().string(), data);
HGLOBAL cbData = createGlobalData(data);
if (!::SetClipboardData(HTMLClipboardFormat, cbData))
@@ -139,7 +139,7 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete,
// enable smart-replacing later on by putting dummy data on the pasteboard
if (canSmartCopyOrDelete) {
if (::OpenClipboard(m_owner)) {
- ::SetClipboardData(WebSmartPasteFormat, NULL);
+ ::SetClipboardData(WebSmartPasteFormat, 0);
::CloseClipboard();
}
@@ -185,7 +185,7 @@ void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame)
// write to clipboard in format CF_HTML to be able to paste into contenteditable areas as a link
if (::OpenClipboard(m_owner)) {
Vector<char> data;
- markupToCF_HTML(urlToMarkup(url, title), "", data);
+ markupToCFHTML(urlToMarkup(url, title), "", data);
HGLOBAL cbData = createGlobalData(data);
if (!::SetClipboardData(HTMLClipboardFormat, cbData))
::GlobalFree(cbData);
@@ -260,8 +260,8 @@ String Pasteboard::plainText(Frame* frame)
::GlobalUnlock(cbData);
::CloseClipboard();
return fromClipboard;
- } else
- ::CloseClipboard();
+ }
+ ::CloseClipboard();
}
if (::IsClipboardFormatAvailable(CF_TEXT) && ::OpenClipboard(m_owner)) {
@@ -272,8 +272,8 @@ String Pasteboard::plainText(Frame* frame)
::GlobalUnlock(cbData);
::CloseClipboard();
return fromClipboard;
- } else
- ::CloseClipboard();
+ }
+ ::CloseClipboard();
}
return String();
@@ -288,11 +288,11 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
HANDLE cbData = ::GetClipboardData(HTMLClipboardFormat);
if (cbData) {
SIZE_T dataSize = ::GlobalSize(cbData);
- String cf_html(UTF8Encoding().decode((char*)::GlobalLock(cbData), dataSize));
+ String cfhtml(UTF8Encoding().decode((char*)::GlobalLock(cbData), dataSize));
::GlobalUnlock(cbData);
::CloseClipboard();
- PassRefPtr<DocumentFragment> fragment = fragmentFromCF_HTML(frame->document(), cf_html);
+ PassRefPtr<DocumentFragment> fragment = fragmentFromCFHTML(frame->document(), cfhtml);
if (fragment)
return fragment;
} else
@@ -306,7 +306,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
if (cbData) {
UChar* buffer = (UChar*)GlobalLock(cbData);
String str(buffer);
- ::GlobalUnlock( cbData );
+ ::GlobalUnlock(cbData);
::CloseClipboard();
RefPtr<DocumentFragment> fragment = createFragmentFromText(context.get(), str);
if (fragment)
@@ -323,7 +323,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
if (cbData) {
char* buffer = (char*)GlobalLock(cbData);
String str(buffer);
- ::GlobalUnlock( cbData );
+ ::GlobalUnlock(cbData);
::CloseClipboard();
RefPtr<DocumentFragment> fragment = createFragmentFromText(context.get(), str);
if (fragment)
diff --git a/WebCore/platform/win/WidgetWin.cpp b/WebCore/platform/win/WidgetWin.cpp
index 607c0d8..416260b 100644
--- a/WebCore/platform/win/WidgetWin.cpp
+++ b/WebCore/platform/win/WidgetWin.cpp
@@ -59,7 +59,6 @@ void Widget::hide()
{
}
-HCURSOR lastSetCursor = 0;
bool ignoreNextSetCursor = false;
void Widget::setCursor(const Cursor& cursor)
@@ -71,30 +70,10 @@ void Widget::setCursor(const Cursor& cursor)
return;
}
- if (!cursor.impl()->nativeCursor())
- return;
-
- lastSetCursor = cursor.impl()->nativeCursor();
-
ScrollView* view = root();
- if (!view || !view->isFrameView()) {
- SetCursor(lastSetCursor);
- return;
- }
-
- Frame* frame = static_cast<FrameView*>(view)->frame();
- if (!frame) {
- SetCursor(lastSetCursor);
+ if (!view)
return;
- }
-
- Page* page = frame->page();
- if (!page) {
- SetCursor(lastSetCursor);
- return;
- }
-
- page->chrome()->setCursor(lastSetCursor);
+ view->hostWindow()->setCursor(cursor);
}
void Widget::paint(GraphicsContext*, const IntRect&)
diff --git a/WebCore/platform/wince/CursorWince.cpp b/WebCore/platform/wince/CursorWince.cpp
index e35f1f9..d7dcfb4 100644
--- a/WebCore/platform/wince/CursorWince.cpp
+++ b/WebCore/platform/wince/CursorWince.cpp
@@ -38,12 +38,12 @@ static const Cursor& getCursor(CursorType type)
}
Cursor::Cursor(const Cursor& other)
-: m_impl(other.m_impl)
+: m_platformCursor(other.m_platformCursor)
{
}
Cursor::Cursor(Image* img, const IntPoint& hotspot)
-: m_impl(CursorNone)
+: m_platformCursor(CursorNone)
{
}
@@ -53,12 +53,12 @@ Cursor::~Cursor()
Cursor& Cursor::operator=(const Cursor& other)
{
- m_impl = other.m_impl;
+ m_platformCursor = other.m_platformCursor;
return *this;
}
Cursor::Cursor(PlatformCursor c)
-: m_impl(c)
+: m_platformCursor(c)
{
}
diff --git a/WebCore/platform/wx/CursorWx.cpp b/WebCore/platform/wx/CursorWx.cpp
index ed7f86b..dd61f1e 100644
--- a/WebCore/platform/wx/CursorWx.cpp
+++ b/WebCore/platform/wx/CursorWx.cpp
@@ -34,15 +34,15 @@
namespace WebCore {
Cursor::Cursor(const Cursor& other)
- : m_impl(other.m_impl)
+ : m_platformCursor(other.m_platformCursor)
{
}
Cursor::Cursor(Image* image, const IntPoint&)
{
- m_impl = 0;
+ m_platformCursor = 0;
// FIXME: figure out why the below code causes a crash
- //m_impl = new wxCursor( image->getWxBitmap()->ConvertToImage() );
+ //m_platformCursor = new wxCursor( image->getWxBitmap()->ConvertToImage() );
}
Cursor::~Cursor()
@@ -51,12 +51,12 @@ Cursor::~Cursor()
Cursor& Cursor::operator=(const Cursor& other)
{
- m_impl = other.m_impl;
+ m_platformCursor = other.m_platformCursor;
return *this;
}
Cursor::Cursor(wxCursor* c)
- : m_impl(c)
+ : m_platformCursor(c)
{
}