diff options
Diffstat (limited to 'WebCore/platform/chromium')
17 files changed, 347 insertions, 248 deletions
diff --git a/WebCore/platform/chromium/ChromiumBridge.h b/WebCore/platform/chromium/ChromiumBridge.h index dd36c1a..3e5c404 100644 --- a/WebCore/platform/chromium/ChromiumBridge.h +++ b/WebCore/platform/chromium/ChromiumBridge.h @@ -92,6 +92,7 @@ namespace WebCore { // JavaScript --------------------------------------------------------- static void notifyJSOutOfMemory(Frame*); + static bool allowScriptDespiteSettings(const KURL& documentURL); // Language ----------------------------------------------------------- static String computedDefaultLanguage(); @@ -100,11 +101,10 @@ namespace WebCore { static bool layoutTestMode(); // MimeType ----------------------------------------------------------- - static bool isSupportedImageMIMEType(const char* mimeType); - static bool isSupportedJavascriptMIMEType(const char* mimeType); - static bool isSupportedNonImageMIMEType(const char* mimeType); - static bool matchesMIMEType(const String& pattern, const String& type); - static String mimeTypeForExtension(const String& ext); + static bool isSupportedImageMIMEType(const String& mimeType); + static bool isSupportedJavaScriptMIMEType(const String& mimeType); + static bool isSupportedNonImageMIMEType(const String& mimeType); + static String mimeTypeForExtension(const String& fileExtension); static String mimeTypeFromFile(const String& filePath); static String preferredExtensionForMIMEType(const String& mimeType); @@ -114,7 +114,7 @@ namespace WebCore { static bool popupsAllowed(NPP); // Protocol ----------------------------------------------------------- - static String uiResourceProtocol(); + static String uiResourceProtocol(); // deprecated // Resources ---------------------------------------------------------- static PassRefPtr<Image> loadPlatformImageResource(const char* name); @@ -134,7 +134,6 @@ namespace WebCore { // StatsCounters ------------------------------------------------------ static void decrementStatsCounter(const char* name); static void incrementStatsCounter(const char* name); - static void initV8CounterFunction(); // SystemTime --------------------------------------------------------- static double currentTime(); @@ -153,15 +152,14 @@ namespace WebCore { GraphicsContext*, int part, int state, int classicState, const IntRect&, const IntRect& alignRect); static void paintTextField( GraphicsContext*, int part, int state, int classicState, const IntRect&, const Color&, bool fillContentArea, bool drawEdges); + static void paintTrackbar( + GraphicsContext*, int part, int state, int classicState, const IntRect&); #endif // Trace Event -------------------------------------------------------- static void traceEventBegin(const char* name, void* id, const char* extra); static void traceEventEnd(const char* name, void* id, const char* extra); - // URL ---------------------------------------------------------------- - static KURL inspectorURL(); - // Visited links ------------------------------------------------------ static LinkHash visitedLinkHash(const UChar* url, unsigned length); static LinkHash visitedLinkHash(const KURL& base, const AtomicString& attributeURL); diff --git a/WebCore/platform/chromium/ChromiumDataObject.cpp b/WebCore/platform/chromium/ChromiumDataObject.cpp index 67e9d00..dee4568 100644 --- a/WebCore/platform/chromium/ChromiumDataObject.cpp +++ b/WebCore/platform/chromium/ChromiumDataObject.cpp @@ -37,6 +37,7 @@ void ChromiumDataObject::clear() { url = KURL(); urlTitle = ""; + fileExtension = ""; filenames.clear(); plainText = ""; textHtml = ""; @@ -49,6 +50,7 @@ void ChromiumDataObject::clear() bool ChromiumDataObject::hasData() { return !url.isEmpty() + || !fileExtension.isEmpty() || !filenames.isEmpty() || !plainText.isEmpty() || !textHtml.isEmpty() diff --git a/WebCore/platform/chromium/ChromiumDataObject.h b/WebCore/platform/chromium/ChromiumDataObject.h index 448e763..19b91c4 100644 --- a/WebCore/platform/chromium/ChromiumDataObject.h +++ b/WebCore/platform/chromium/ChromiumDataObject.h @@ -54,6 +54,7 @@ namespace WebCore { KURL url; String urlTitle; + String fileExtension; Vector<String> filenames; String plainText; diff --git a/WebCore/platform/chromium/ClipboardChromium.cpp b/WebCore/platform/chromium/ClipboardChromium.cpp index 7fc156e..b28503d 100644 --- a/WebCore/platform/chromium/ClipboardChromium.cpp +++ b/WebCore/platform/chromium/ClipboardChromium.cpp @@ -268,15 +268,15 @@ static void writeImageToDataObject(ChromiumDataObject* dataObject, Element* elem // use the alt tag if one exists, otherwise we fall back on the suggested // filename in the http header, and finally we resort to using the filename // in the URL. - String extension("."); - extension += MIMETypeRegistry::getPreferredExtensionForMIMEType( + String extension = MIMETypeRegistry::getPreferredExtensionForMIMEType( cachedImage->response().mimeType()); + dataObject->fileExtension = extension.isEmpty() ? "" : "." + extension; String title = element->getAttribute(altAttr); - if (title.isEmpty()) { + if (title.isEmpty()) title = cachedImage->response().suggestedFilename(); - // FIXME: If title is empty, get the filename from the URL. - } - dataObject->fileContentFilename = title + extension; + + title = ClipboardChromium::validateFileName(title, dataObject); + dataObject->fileContentFilename = title + dataObject->fileExtension; } void ClipboardChromium::declareAndWriteDragImage(Element* element, const KURL& url, const String& title, Frame* frame) diff --git a/WebCore/platform/chromium/ClipboardChromium.h b/WebCore/platform/chromium/ClipboardChromium.h index 1864c1a..53699da 100644 --- a/WebCore/platform/chromium/ClipboardChromium.h +++ b/WebCore/platform/chromium/ClipboardChromium.h @@ -47,6 +47,12 @@ namespace WebCore { static PassRefPtr<ClipboardChromium> create( bool isForDragging, PassRefPtr<ChromiumDataObject>, ClipboardAccessPolicy); + // Returns the file name (not including the extension). This removes any + // invalid file system characters as well as making sure the + // path + extension is not bigger than allowed by the file system. + // This may change the file extension in dataObject. + static String validateFileName(const String& title, ChromiumDataObject* dataObject); + virtual void clearData(const String& type); void clearAllData(); String getData(const String& type, bool& success) const; diff --git a/WebCore/platform/chromium/ClipboardChromiumLinux.cpp b/WebCore/platform/chromium/ClipboardChromiumLinux.cpp new file mode 100644 index 0000000..2c89f6e --- /dev/null +++ b/WebCore/platform/chromium/ClipboardChromiumLinux.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2009 Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "ClipboardChromium.h" + +#include "ChromiumDataObject.h" +#include "NotImplemented.h" + +namespace WebCore { + +String ClipboardChromium::validateFileName(const String& title, ChromiumDataObject* dataObject) +{ + notImplemented(); + return title; +} + +} // namespace WebCore diff --git a/WebCore/platform/chromium/ClipboardChromiumMac.cpp b/WebCore/platform/chromium/ClipboardChromiumMac.cpp new file mode 100644 index 0000000..2c89f6e --- /dev/null +++ b/WebCore/platform/chromium/ClipboardChromiumMac.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2009 Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "ClipboardChromium.h" + +#include "ChromiumDataObject.h" +#include "NotImplemented.h" + +namespace WebCore { + +String ClipboardChromium::validateFileName(const String& title, ChromiumDataObject* dataObject) +{ + notImplemented(); + return title; +} + +} // namespace WebCore diff --git a/WebCore/platform/chromium/ClipboardChromiumWin.cpp b/WebCore/platform/chromium/ClipboardChromiumWin.cpp new file mode 100644 index 0000000..b4a2c21 --- /dev/null +++ b/WebCore/platform/chromium/ClipboardChromiumWin.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2009 Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "ClipboardChromium.h" + +#include "ChromiumDataObject.h" + +#include <shlwapi.h> + +namespace WebCore { + +// Returns true if the specified character is not valid in a file name. This +// is intended for use with removeCharacters. +static bool isInvalidFileCharacter(UChar c) +{ + return (PathGetCharType(c) & (GCT_LFNCHAR | GCT_SHORTCHAR)) == 0; +} + +String ClipboardChromium::validateFileName(const String& title, ChromiumDataObject* dataObject) +{ + // Remove any invalid file system characters. + String result = title.removeCharacters(&isInvalidFileCharacter); + if (result.length() + dataObject->fileExtension.length() + 1 >= MAX_PATH) { + if (dataObject->fileExtension.length() + 1 >= MAX_PATH) + dataObject->fileExtension = ""; + if (result.length() + dataObject->fileExtension.length() + 1 >= MAX_PATH) + result = result.substring(0, MAX_PATH - dataObject->fileExtension.length() - 1); + } + return result; +} + +} // namespace WebCore diff --git a/WebCore/platform/chromium/MimeTypeRegistryChromium.cpp b/WebCore/platform/chromium/MimeTypeRegistryChromium.cpp index 5d6f426..1aac5ec 100644 --- a/WebCore/platform/chromium/MimeTypeRegistryChromium.cpp +++ b/WebCore/platform/chromium/MimeTypeRegistryChromium.cpp @@ -83,8 +83,7 @@ String MIMETypeRegistry::getMIMETypeForPath(const String& path) bool MIMETypeRegistry::isSupportedImageMIMEType(const String& mimeType) { - return !mimeType.isEmpty() - && ChromiumBridge::isSupportedImageMIMEType(mimeType.latin1().data()); + return ChromiumBridge::isSupportedImageMIMEType(mimeType); } bool MIMETypeRegistry::isSupportedImageResourceMIMEType(const String& mimeType) @@ -100,14 +99,12 @@ bool MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(const String& mimeTyp bool MIMETypeRegistry::isSupportedJavaScriptMIMEType(const String& mimeType) { - return !mimeType.isEmpty() - && ChromiumBridge::isSupportedJavascriptMIMEType(mimeType.latin1().data()); + return ChromiumBridge::isSupportedJavaScriptMIMEType(mimeType); } bool MIMETypeRegistry::isSupportedNonImageMIMEType(const String& mimeType) { - return !mimeType.isEmpty() - && ChromiumBridge::isSupportedNonImageMIMEType(mimeType.latin1().data()); + return ChromiumBridge::isSupportedNonImageMIMEType(mimeType); } bool MIMETypeRegistry::isSupportedMediaMIMEType(const String& mimeType) diff --git a/WebCore/platform/chromium/PasteboardChromium.cpp b/WebCore/platform/chromium/PasteboardChromium.cpp index e7b2203..9b32bae 100644 --- a/WebCore/platform/chromium/PasteboardChromium.cpp +++ b/WebCore/platform/chromium/PasteboardChromium.cpp @@ -98,6 +98,15 @@ void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame) void Pasteboard::writeImage(Node* node, const KURL&, const String& title) { + ASSERT(node); + ASSERT(node->renderer()); + ASSERT(node->renderer()->isImage()); + RenderImage* renderer = static_cast<RenderImage*>(node->renderer()); + CachedImage* cachedImage = static_cast<CachedImage*>(renderer->cachedImage()); + ASSERT(cachedImage); + Image* image = cachedImage->image(); + ASSERT(image); + // If the image is wrapped in a link, |url| points to the target of the // link. This isn't useful to us, so get the actual image URL. AtomicString urlString; @@ -113,16 +122,6 @@ void Pasteboard::writeImage(Node* node, const KURL&, const String& title) } KURL url = urlString.isEmpty() ? KURL() : node->document()->completeURL(parseURL(urlString)); - ASSERT(node); - ASSERT(node->renderer()); - ASSERT(node->renderer()->isImage()); - - RenderImage* renderer = static_cast<RenderImage*>(node->renderer()); - CachedImage* cachedImage = static_cast<CachedImage*>(renderer->cachedImage()); - ASSERT(cachedImage); - Image* image = cachedImage->image(); - ASSERT(image); - NativeImageSkia* bitmap = 0; #if !PLATFORM(CG) bitmap = image->nativeImageForCurrentFrame(); diff --git a/WebCore/platform/chromium/PlatformKeyboardEventChromium.cpp b/WebCore/platform/chromium/PlatformKeyboardEventChromium.cpp index 6840bdf..ae55afe 100644 --- a/WebCore/platform/chromium/PlatformKeyboardEventChromium.cpp +++ b/WebCore/platform/chromium/PlatformKeyboardEventChromium.cpp @@ -42,7 +42,7 @@ void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardCom #if PLATFORM(WIN_OS) // No KeyDown events on Windows to disambiguate. ASSERT_NOT_REACHED(); -#elif PLATFORM(DARWIN) +#else // Can only change type from KeyDown to RawKeyDown or Char, as we lack information for other conversions. ASSERT(m_type == KeyDown); ASSERT(type == RawKeyDown || type == Char); @@ -56,6 +56,7 @@ void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardCom } else { m_keyIdentifier = String(); m_windowsVirtualKeyCode = 0; +#if PLATFORM(DARWIN) if (m_text.length() == 1 && (m_text[0U] >= 0xF700 && m_text[0U] <= 0xF7FF)) { // According to NSEvents.h, OpenStep reserves the range 0xF700-0xF8FF for function keys. However, some actual private use characters // happen to be in this range, e.g. the Apple logo (Option+Shift+K). @@ -63,6 +64,7 @@ void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool backwardCom m_text = String(); m_unmodifiedText = String(); } +#endif } #endif } diff --git a/WebCore/platform/chromium/PlatformWidget.h b/WebCore/platform/chromium/PlatformWidget.h index e4e6a18..b9dddf3 100644 --- a/WebCore/platform/chromium/PlatformWidget.h +++ b/WebCore/platform/chromium/PlatformWidget.h @@ -31,10 +31,12 @@ #ifndef PlatformWidget_h #define PlatformWidget_h +#include <wtf/StdLibExtras.h> // for intptr_t + // PlatformWidget is an opaque identifier corresponding to whatever native // view type the embedder may use. PlatformWidget CANNOT be assumed to be // a valid pointer. Some embedders may not use this identifier at all. -typedef void* PlatformWidget; +typedef intptr_t PlatformWidget; #endif diff --git a/WebCore/platform/chromium/PopupMenuChromium.cpp b/WebCore/platform/chromium/PopupMenuChromium.cpp index fad0a6b..53f565a 100644 --- a/WebCore/platform/chromium/PopupMenuChromium.cpp +++ b/WebCore/platform/chromium/PopupMenuChromium.cpp @@ -69,10 +69,24 @@ static const int kMaxHeight = 500; static const int kBorderSize = 1; static const TimeStamp kTypeAheadTimeoutMs = 1000; +// The settings used for the drop down menu. +// This is the delegate used if none is provided. +static const PopupContainerSettings dropDownSettings = { + true, // focusOnShow + true, // setTextOnIndexChange + true, // acceptOnAbandon + false // loopSelectionNavigation +}; + // This class uses WebCore code to paint and handle events for a drop-down list // box ("combobox" on Windows). class PopupListBox : public FramelessScrollView, public RefCounted<PopupListBox> { public: + static PassRefPtr<PopupListBox> create(PopupMenuClient* client, const PopupContainerSettings& settings) + { + return adoptRef(new PopupListBox(client, settings)); + } + // FramelessScrollView virtual void paint(GraphicsContext*, const IntRect&); virtual bool handleMouseDownEvent(const PlatformMouseEvent&); @@ -84,9 +98,6 @@ public: // ScrollView virtual HostWindow* hostWindow() const; - // Widget - virtual void invalidateRect(const IntRect&); - // PopupListBox methods // Shows the popup @@ -125,20 +136,6 @@ public: // Returns whether the popup wants to process events for the passed key. bool isInterestedInEventForKey(int keyCode); - // Sets whether the PopupMenuClient should be told to change its text when a - // new item is selected (by using the arrow keys). Default is true. - void setTextOnIndexChange(bool value) { m_setTextOnIndexChange = value; } - - // Sets whether we should accept the selected index when the popup is - // abandonned. - void setAcceptOnAbandon(bool value) { m_shouldAcceptOnAbandon = value; } - - // Sets whether pressing the down/up arrow when the last/first row is - // selected clears the selection on the first key press and then selects the - // first/last row on the next key press. If false, the selected row stays - // the last/first row. - void setLoopSelectionNavigation(bool value) { m_loopSelectionNavigation = value; } - private: friend class PopupContainer; friend class RefCounted<PopupListBox>; @@ -159,17 +156,15 @@ private: int y; // y offset of this item, relative to the top of the popup. }; - PopupListBox(PopupMenuClient* client) - : m_originalIndex(0) + PopupListBox(PopupMenuClient* client, const PopupContainerSettings& settings) + : m_settings(settings) + , m_originalIndex(0) , m_selectedIndex(0) - , m_shouldAcceptOnAbandon(true) , m_willAcceptOnAbandon(false) , m_visibleRows(0) , m_popupClient(client) , m_repeatingChar(0) , m_lastCharTime(0) - , m_setTextOnIndexChange(true) - , m_loopSelectionNavigation(false) { setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff); } @@ -228,6 +223,9 @@ private: void selectPreviousRow(); void selectNextRow(); + // The settings that specify the behavior for this Popup window. + PopupContainerSettings m_settings; + // This is the index of the item marked as "selected" - i.e. displayed in the widget on the // page. int m_originalIndex; @@ -237,15 +235,10 @@ private: // enter yet however. int m_selectedIndex; - // Whether we should accept the selectedIndex as chosen when the popup is - // "abandoned". This value is set through its setter and is useful as - // select popup menu and form autofill popup menu have different behaviors. - bool m_shouldAcceptOnAbandon; - // True if we should accept the selectedIndex as chosen, even if the popup // is "abandoned". This is used for keyboard navigation, where we want the - // selection to change immediately, and is only used if - // m_shouldAcceptOnAbandon is true. + // selection to change immediately, and is only used if the settings + // acceptOnAbandon field is true. bool m_willAcceptOnAbandon; // This is the number of rows visible in the popup. The maximum number visible at a time is @@ -277,10 +270,6 @@ private: // The last time the user hit a key. Used for typeAheadFind. TimeStamp m_lastCharTime; - - bool m_setTextOnIndexChange; - - bool m_loopSelectionNavigation; }; static PlatformMouseEvent constructRelativeMouseEvent(const PlatformMouseEvent& e, @@ -316,19 +305,15 @@ static PlatformWheelEvent constructRelativeWheelEvent(const PlatformWheelEvent& // static PassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client, - bool focusOnShow) + const PopupContainerSettings& settings) { - return adoptRef(new PopupContainer(client, focusOnShow)); + return adoptRef(new PopupContainer(client, settings)); } -PopupContainer::PopupContainer(PopupMenuClient* client, bool focusOnShow) - : m_listBox(new PopupListBox(client)), - m_focusOnShow(focusOnShow) +PopupContainer::PopupContainer(PopupMenuClient* client, const PopupContainerSettings& settings) + : m_listBox(PopupListBox::create(client, settings)) + , m_settings(settings) { - // FrameViews are created with a refcount of 1 so it needs releasing after we - // assign it to a RefPtr. - m_listBox->deref(); - setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff); } @@ -352,19 +337,19 @@ void PopupContainer::showPopup(FrameView* view) if (chromeClient) { // If the popup would extend past the bottom of the screen, open upwards // instead. - FloatRect screen = screenRect(view); + FloatRect screen = screenAvailableRect(view); IntRect widgetRect = chromeClient->windowToScreen(frameRect()); if (widgetRect.bottom() > static_cast<int>(screen.bottom())) widgetRect.move(0, -(widgetRect.height() + selectHeight)); - chromeClient->popupOpened(this, widgetRect, m_focusOnShow); + chromeClient->popupOpened(this, widgetRect, m_settings.focusOnShow); } - // Must get called after we have a client and containingWindow. - addChild(m_listBox.get()); + if (!m_listBox->parent()) + addChild(m_listBox.get()); - // Enable scrollbars after the listbox is inserted into the hierarchy, so - // it has a proper WidgetClient. + // Enable scrollbars after the listbox is inserted into the hierarchy, + // so it has a proper WidgetClient. m_listBox->setVerticalScrollbarMode(ScrollbarAuto); m_listBox->scrollToRevealSelection(); @@ -374,12 +359,6 @@ void PopupContainer::showPopup(FrameView* view) void PopupContainer::hidePopup() { - invalidate(); - - m_listBox->disconnectClient(); - removeChild(m_listBox.get()); - m_listBox = 0; - if (client()) client()->popupClosed(this); } @@ -495,27 +474,17 @@ void PopupContainer::show(const IntRect& r, FrameView* v, int index) showPopup(v); } -void PopupContainer::setTextOnIndexChange(bool value) -{ - listBox()->setTextOnIndexChange(value); -} - -void PopupContainer::setAcceptOnAbandon(bool value) -{ - listBox()->setAcceptOnAbandon(value); -} - -void PopupContainer::setLoopSelectionNavigation(bool value) -{ - listBox()->setLoopSelectionNavigation(value); -} - void PopupContainer::refresh() { listBox()->updateFromElement(); layout(); } +int PopupContainer::selectedIndex() const +{ + return m_listBox->selectedIndex(); +} + /////////////////////////////////////////////////////////////////////////////// // PopupListBox implementation @@ -658,13 +627,14 @@ bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event) // want to fire the onchange event until the popup is closed, to match // IE). We change the original index so we revert to that when the // popup is closed. - if (m_shouldAcceptOnAbandon) + if (m_settings.acceptOnAbandon) m_willAcceptOnAbandon = true; setOriginalIndex(m_selectedIndex); - if (m_setTextOnIndexChange) + if (m_settings.setTextOnIndexChange) m_popupClient->setTextFromItem(m_selectedIndex); - } else if (!m_setTextOnIndexChange && event.windowsVirtualKeyCode() == VKEY_TAB) { + } else if (!m_settings.setTextOnIndexChange && + 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) @@ -683,15 +653,6 @@ HostWindow* PopupListBox::hostWindow() const return parent() ? parent()->hostWindow() : 0; } -void PopupListBox::invalidateRect(const IntRect& rect) -{ - // Since we are returning the HostWindow of our parent as our own in - // hostWindow(), we need to invalidate in our parent's coordinates. - IntRect newRect(rect); - newRect.move(kBorderSize, kBorderSize); - FramelessScrollView::invalidateRect(newRect); -} - // From HTMLSelectElement.cpp static String stripLeadingWhiteSpace(const String& string) { @@ -855,12 +816,10 @@ void PopupListBox::abandon() m_selectedIndex = m_originalIndex; + m_popupClient->hidePopup(); + if (m_willAcceptOnAbandon) m_popupClient->valueChanged(m_selectedIndex); - - // valueChanged may have torn down the popup! - if (m_popupClient) - m_popupClient->hidePopup(); } int PopupListBox::pointToRowIndex(const IntPoint& point) @@ -892,12 +851,11 @@ void PopupListBox::acceptIndex(int index) if (isSelectableItem(index)) { RefPtr<PopupListBox> keepAlive(this); - // Tell the <select> PopupMenuClient what index was selected, and hide ourself. - m_popupClient->valueChanged(index); + // Hide ourselves first since valueChanged may have numerous side-effects. + m_popupClient->hidePopup(); - // valueChanged may have torn down the popup! - if (m_popupClient) - m_popupClient->hidePopup(); + // Tell the <select> PopupMenuClient what index was selected. + m_popupClient->valueChanged(index); } } @@ -940,7 +898,9 @@ void PopupListBox::invalidateRow(int index) if (index < 0) return; - invalidateRect(getRowBounds(index)); + // Invalidate in the window contents, as FramelessScrollView::invalidateRect + // paints in the window coordinates. + invalidateRect(contentsToWindow(getRowBounds(index))); } void PopupListBox::scrollToRevealRow(int index) @@ -959,7 +919,8 @@ void PopupListBox::scrollToRevealRow(int index) } } -bool PopupListBox::isSelectableItem(int index) { +bool PopupListBox::isSelectableItem(int index) +{ return m_items[index]->type == TypeOption && m_popupClient->itemIsEnabled(index); } @@ -973,7 +934,7 @@ void PopupListBox::clearSelection() void PopupListBox::selectNextRow() { - if (!m_loopSelectionNavigation || m_selectedIndex != numItems() - 1) { + if (!m_settings.loopSelectionNavigation || m_selectedIndex != numItems() - 1) { adjustSelectedIndex(1); return; } @@ -984,7 +945,7 @@ void PopupListBox::selectNextRow() void PopupListBox::selectPreviousRow() { - if (!m_loopSelectionNavigation || m_selectedIndex > 0) { + if (!m_settings.loopSelectionNavigation || m_selectedIndex > 0) { adjustSelectedIndex(-1); return; } @@ -1156,16 +1117,15 @@ PopupMenu::~PopupMenu() void PopupMenu::show(const IntRect& r, FrameView* v, int index) { - p.popup = PopupContainer::create(client(), true); + if (!p.popup) + p.popup = PopupContainer::create(client(), dropDownSettings); p.popup->show(r, v, index); } void PopupMenu::hide() { - if (p.popup) { + if (p.popup) p.popup->hidePopup(); - p.popup = 0; - } } void PopupMenu::updateFromElement() diff --git a/WebCore/platform/chromium/PopupMenuChromium.h b/WebCore/platform/chromium/PopupMenuChromium.h index a57383d..cd13c22 100644 --- a/WebCore/platform/chromium/PopupMenuChromium.h +++ b/WebCore/platform/chromium/PopupMenuChromium.h @@ -44,7 +44,7 @@ namespace WebCore { // FIXME: Our FramelessScrollView classes should probably implement HostWindow! - // This class holds a PopupListBox (see cpp file). Its sole purpose is to be + // The PopupContainer class holds a PopupListBox (see cpp file). Its sole purpose is to be // able to draw a border around its child. All its paint/event handling is // just forwarded to the child listBox (with the appropriate transforms). // NOTE: this class is exposed so it can be instantiated direcly for the @@ -52,9 +52,30 @@ namespace WebCore { // autofill popup should not be focused when shown and we want to forward the // key events to it (through handleKeyEvent). + struct PopupContainerSettings { + // Whether the popup should get the focus when displayed. + bool focusOnShow; + + // Whether the PopupMenuClient should be told to change its text when a + // new item is selected by using the arrow keys. + bool setTextOnIndexChange; + + // Whether the selection should be accepted when the popup menu is + // closed (through ESC being pressed or the focus going away). + // Note that when TAB is pressed, the selection is always accepted + // regardless of this setting. + bool acceptOnAbandon; + + // Whether the we should move the selection to the first/last item when + // the user presses down/up arrow keys and the last/first item is + // selected. + bool loopSelectionNavigation; + }; + class PopupContainer : public FramelessScrollView, public RefCounted<PopupContainer> { public: - static PassRefPtr<PopupContainer> create(PopupMenuClient*, bool focusOnShow); + static PassRefPtr<PopupContainer> create(PopupMenuClient*, + const PopupContainerSettings&); // Whether a key event should be sent to this popup. virtual bool isInterestedInEventForKey(int keyCode); @@ -84,31 +105,19 @@ namespace WebCore { // Compute size of widget and children. void layout(); - // Sets whether the PopupMenuClient should be told to change its text when a - // new item is selected (by using the arrow keys). Default is true. - void setTextOnIndexChange(bool); - - // Sets whether the selection should be accepted when the popup menu is - // closed (through ESC being pressed or the focus going away). Default - // is true. Note that when TAB is pressed, the selection is always - // accepted regardless of this setting. - void setAcceptOnAbandon(bool); - - // Sets whether we should move the selection to the first/last item - // when the user presses down/up arrow keys and the last/first item is - // selected. Default is false, causing the first/last item to stay - // selected. - void setLoopSelectionNavigation(bool); - PopupListBox* listBox() const { return m_listBox.get(); } + // Gets the index of the item that the user is currently moused-over or + // has selected with the keyboard up/down arrows. + int selectedIndex() const; + // Refresh the popup values from the PopupMenuClient. void refresh(); private: friend class WTF::RefCounted<PopupContainer>; - PopupContainer(PopupMenuClient*, bool focusOnShow); + PopupContainer(PopupMenuClient*, const PopupContainerSettings&); ~PopupContainer(); // Paint the border. @@ -116,8 +125,7 @@ namespace WebCore { RefPtr<PopupListBox> m_listBox; - // Whether the window showing this popup should be focused when shown. - bool m_focusOnShow; + PopupContainerSettings m_settings; }; } // namespace WebCore diff --git a/WebCore/platform/chromium/ScrollbarThemeChromium.cpp b/WebCore/platform/chromium/ScrollbarThemeChromium.cpp index de40572..426a078 100644 --- a/WebCore/platform/chromium/ScrollbarThemeChromium.cpp +++ b/WebCore/platform/chromium/ScrollbarThemeChromium.cpp @@ -96,7 +96,7 @@ IntRect ScrollbarThemeChromium::forwardButtonRect(Scrollbar* scrollbar, Scrollba IntRect ScrollbarThemeChromium::trackRect(Scrollbar* scrollbar, bool) { IntSize bs = buttonSize(scrollbar); - int thickness = scrollbarThickness(); + int thickness = scrollbarThickness(scrollbar->controlSize()); if (scrollbar->orientation() == HorizontalScrollbar) { if (scrollbar->width() < 2 * thickness) return IntRect(); @@ -167,26 +167,26 @@ bool ScrollbarThemeChromium::shouldCenterOnThumb(Scrollbar*, const PlatformMouse IntSize ScrollbarThemeChromium::buttonSize(Scrollbar* scrollbar) { +#if defined(__linux__) + // On Linux, we don't use buttons + return IntSize(0, 0); +#endif + // Our desired rect is essentially thickness by thickness. // Our actual rect will shrink to half the available space when we have < 2 // times thickness pixels left. This allows the scrollbar to scale down // and function even at tiny sizes. - int thickness = scrollbarThickness(); + int thickness = scrollbarThickness(scrollbar->controlSize()); -#if !defined(__linux__) // In layout test mode, we force the button "girth" (i.e., the length of // the button along the axis of the scrollbar) to be a fixed size. // FIXME: This is retarded! scrollbarThickness is already fixed in layout // test mode so that should be enough to result in repeatable results, but // preserving this hack avoids having to rebaseline pixel tests. const int kLayoutTestModeGirth = 17; - int girth = ChromiumBridge::layoutTestMode() ? kLayoutTestModeGirth : thickness; -#else - int girth = thickness; -#endif if (scrollbar->orientation() == HorizontalScrollbar) { int width = scrollbar->width() < 2 * girth ? scrollbar->width() / 2 : girth; diff --git a/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp b/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp index 95d0f78..a99d778 100644 --- a/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp +++ b/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp @@ -1,10 +1,10 @@ /* * Copyright (c) 2008, 2009, 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 @@ -14,7 +14,7 @@ * * 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 @@ -37,112 +37,106 @@ #include "Scrollbar.h" #include "TransformationMatrix.h" -#include "gtkdrawing.h" -#include <gtk/gtk.h> -#include "skia/ext/GdkSkia.h" - namespace WebCore { int ScrollbarThemeChromium::scrollbarThickness(ScrollbarControlSize controlSize) { - static int size = 0; - if (!size) { - MozGtkScrollbarMetrics metrics; - moz_gtk_get_scrollbar_metrics(&metrics); - size = metrics.slider_width; - } - return size; + return 15; } bool ScrollbarThemeChromium::invalidateOnMouseEnterExit() { - notImplemented(); return false; } -// Given an uninitialised widget state object, set the members such that it's -// sane for drawing scrollbars -static void initMozState(GtkWidgetState* mozState) +static void drawVertLine(SkCanvas* canvas, int x, int y1, int y2, const SkPaint& paint) { - mozState->active = true; - mozState->focused = false; - mozState->inHover = false; - mozState->disabled = false; - mozState->isDefault = false; - mozState->canDefault = false; - mozState->depressed = false; - mozState->curpos = 0; - mozState->maxpos = 0; + SkIRect skrect; + skrect.set(x, y1, x + 1, y2 + 1); + canvas->drawIRect(skrect, paint); } -// Paint a GTK widget -// gc: context to draw onto -// rect: the area of the widget -// widget_type: the type of widget to draw -// flags: widget dependent flags (e.g. direction of scrollbar arrows etc) -// -// See paintMozWiget in RenderThemeGtk.cpp for an explanation of the clipping. -static void paintScrollbarWidget(GraphicsContext* gc, const IntRect& rect, - GtkThemeWidgetType widget_type, gint flags) +static void drawHorizLine(SkCanvas* canvas, int x1, int x2, int y, const SkPaint& paint) { - PlatformContextSkia* pcs = gc->platformContext(); - - GdkRectangle gdkRect = { rect.x(), rect.y(), rect.width(), rect.height() }; - - const SkIRect clip_region = pcs->canvas()->getTotalClip().getBounds(); - TransformationMatrix ctm = gc->getCTM().inverse(); - IntPoint pos = ctm.mapPoint( - IntPoint(SkScalarRound(clip_region.fLeft), SkScalarRound(clip_region.fTop))); - GdkRectangle gdkClipRect; - gdkClipRect.x = pos.x(); - gdkClipRect.y = pos.y(); - gdkClipRect.width = clip_region.width(); - gdkClipRect.height = clip_region.height(); - - gdk_rectangle_intersect(&gdkRect, &gdkClipRect, &gdkClipRect); - - GtkWidgetState mozState; - initMozState(&mozState); + SkIRect skrect; + skrect.set(x1, y, x2 + 1, y + 1); + canvas->drawIRect(skrect, paint); +} - moz_gtk_widget_paint(widget_type, pcs->gdk_skia(), &gdkRect, &gdkClipRect, - &mozState, flags, GTK_TEXT_DIR_LTR); +static void drawBox(SkCanvas* canvas, const IntRect& rect, const SkPaint& paint) +{ + const int right = rect.x() + rect.width() - 1; + const int bottom = rect.y() + rect.height() - 1; + drawHorizLine(canvas, rect.x(), right, rect.y(), paint); + drawVertLine(canvas, right, rect.y(), bottom, paint); + drawHorizLine(canvas, rect.x(), right, bottom, paint); + drawVertLine(canvas, rect.x(), rect.y(), bottom, paint); } void ScrollbarThemeChromium::paintTrackPiece(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart partType) { - const bool horz = scrollbar->orientation() == HorizontalScrollbar; - const GtkThemeWidgetType track_type = - horz ? MOZ_GTK_SCROLLBAR_TRACK_HORIZONTAL : MOZ_GTK_SCROLLBAR_TRACK_VERTICAL; - paintScrollbarWidget(gc, rect, track_type, 0); + SkCanvas* const canvas = gc->platformContext()->canvas(); + SkPaint paint; + SkIRect skrect; + + skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height()); + paint.setARGB(0xff, 0xe3, 0xdd, 0xd8); + canvas->drawIRect(skrect, paint); + + paint.setARGB(0xff, 0xc5, 0xba, 0xb0); + drawBox(canvas, rect, paint); } void ScrollbarThemeChromium::paintButton(GraphicsContext* gc, Scrollbar* scrollbar, - const IntRect& rect, ScrollbarPart part) + const IntRect& rect, ScrollbarPart part) { - // FIXME: It appears the either we're upsetting GTK by forcing WebKit sizes - // on it, or the buttons expect the track to be drawn under them. Either - // way, we end up with unpainted pixels which are upsetting the pixel - // tests. Thus we paint green under the buttons to, at least, make the - // pixel output the same between debug and opt builds. - SkPaint paint; - paint.setARGB(255, 0, 255, 128); - SkRect skrect; - skrect.set(rect.x(), rect.y(), rect.x() + rect.width() - 1, rect.y() + rect.height() - 1); - gc->platformContext()->canvas()->drawRect(skrect, paint); - - const bool horz = scrollbar->orientation() == HorizontalScrollbar; - gint flags = horz ? 0 : MOZ_GTK_STEPPER_VERTICAL; - flags |= ForwardButtonEndPart == part ? MOZ_GTK_STEPPER_DOWN : 0; - paintScrollbarWidget(gc, rect, MOZ_GTK_SCROLLBAR_BUTTON, flags); + // We don't use buttons } void ScrollbarThemeChromium::paintThumb(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect) { - const bool horz = scrollbar->orientation() == HorizontalScrollbar; - const GtkThemeWidgetType thumb_type = - horz ? MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL : MOZ_GTK_SCROLLBAR_THUMB_VERTICAL; - paintScrollbarWidget(gc, rect, thumb_type, 0); + const bool hovered = scrollbar->hoveredPart() == ThumbPart; + const int midx = rect.x() + rect.width() / 2; + const int midy = rect.y() + rect.height() / 2; + const bool vertical = scrollbar->orientation() == VerticalScrollbar; + SkCanvas* const canvas = gc->platformContext()->canvas(); + + SkPaint paint; + if (hovered) + paint.setARGB(0xff, 0xff, 0xff, 0xff); + else + paint.setARGB(0xff, 0xf4, 0xf2, 0xef); + + SkIRect skrect; + if (vertical) + skrect.set(rect.x(), rect.y(), midx + 1, rect.y() + rect.height()); + else + skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), midy + 1); + + canvas->drawIRect(skrect, paint); + + if (hovered) + paint.setARGB(0xff, 0xf4, 0xf2, 0xef); + else + paint.setARGB(0xff, 0xea, 0xe5, 0xe0); + + if (vertical) + skrect.set(midx + 1, rect.y(), rect.x() + rect.width(), rect.y() + rect.height()); + else + skrect.set(rect.x(), midy + 1, rect.x() + rect.width(), rect.y() + rect.height()); + + canvas->drawIRect(skrect, paint); + + paint.setARGB(0xff, 0x9d, 0x96, 0x8e); + drawBox(canvas, rect, paint); + + if (rect.height() > 10 && rect.width() > 10) { + paint.setARGB(0xff, 0x9d, 0x96, 0x8e); + drawHorizLine(canvas, midx - 1, midx + 3, midy, paint); + drawHorizLine(canvas, midx - 1, midx + 3, midy - 3, paint); + drawHorizLine(canvas, midx - 1, midx + 3, midy + 3, paint); + } } } // namespace WebCore diff --git a/WebCore/platform/chromium/TemporaryLinkStubs.cpp b/WebCore/platform/chromium/TemporaryLinkStubs.cpp index 4a028da..f6e77d4 100644 --- a/WebCore/platform/chromium/TemporaryLinkStubs.cpp +++ b/WebCore/platform/chromium/TemporaryLinkStubs.cpp @@ -44,11 +44,3 @@ String KURL::fileSystemPath() const { notImplemented(); return String(); } PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String&) { notImplemented(); return 0; } } // namespace WebCore - -namespace WTF { - -#if !defined(__linux__) -void scheduleDispatchFunctionsOnMainThread() { notImplemented(); } -#endif - -} // namespace WTF |