Reviewed by Adam.
authordarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Jan 2007 00:40:55 +0000 (00:40 +0000)
committerdarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Jan 2007 00:40:55 +0000 (00:40 +0000)
        - fix http://bugs.webkit.org/show_bug.cgi?id=12273
          REGRESSION: File input value invisible after removing and re-appending

        - made more of the file chooser code cross-platform

        - fixed an Objective-C garbage collection problem in FileChooser

        - tried to remove layering violations where FileChooser in the platform
          directory knows about the rendering and DOM trees (but wasn't able to
          do it entirely)

        * platform/FileChooser.cpp: Added.
        (WebCore::FileChooser::create): Changed parameters.
        (WebCore::FileChooser::chooseFile): Changed to call chooseIcon function.
        (WebCore::FileChooser::chooseIcon): Added.

        * platform/FileChooser.h: Added FileChooserClient so this file doesn't have
        to know about RenderFileUploadControl. Used RetainPtr instead of retain/release
        so this works properly with Objective-C GC. Replaced disconnectUploadControl
        with disconnectClient, which has a simple inline implementation. Moved the
        Document parameter from the constructor to openFileChooser, along with a comment
        about why it should not be there. Added a filename parameter to the constructor
        for the initial filename. Added a font parameter to basenameForWidth so we don't
        depend on having a pointer to the renderer. Removed the uploadControl() and
        document() functions since no one calls either of them.

        * platform/mac/FileChooserMac.mm: Removed code that is now cross-platform.
        (-[OpenPanelController beginSheetWithFrame:]): Added frame parameter, instead
        of storing a document pointer in the FileChooser.
        (WebCore::FileChooser::FileChooser): Updated for changed parameters. Also added
        code to choose the icon based on the initial filename. Pass the adopt parameter
        to the constructor of the RetainPtr.
        (WebCore::FileChooser::~FileChooser): Removed the release call, since the
        RetainPtr will take care of it. Added a call to disconnectFileChooser here.
        There's no need to disconnect at disconnectClient time, and that lets us have
        one more cross-platform function.
        (WebCore::FileChooser::openFileChooser): Added document parameter. Added code
        to get the frame from the document. And added a nil check since there's no
        ironclad guarantee the document won't have outlived its frame.
        (WebCore::FileChooser::basenameForWidth): Added font parameter. Use that instead
        of going at the upload control's style. The caller can handle that now.

        * rendering/RenderFileUploadControl.h: Removed unnecessary includes.
        Made class inherit privately from FileChooserClient. Changed constructor
        parameter to HTMLInputElement rather than Node. Made protected members be
        private instead, and made a couple function members const.
        * rendering/RenderFileUploadControl.cpp: Moved constants to the top of the file,
        but after the "using namespace"
        (WebCore::RenderFileUploadControl::RenderFileUploadControl): Updated for changes
        to the FileChooser::create function and the parameter types.
        (WebCore::RenderFileUploadControl::~RenderFileUploadControl): Removed unneeded
        null check -- there's no case where the FileChooser fails to be created.
        (WebCore::RenderFileUploadControl::click): Pass document to openFileChooser.
        (WebCore::RenderFileUploadControl::updateFromElement): Tweaked code a bit by
        using updateFromElement and setValue instead of casting the renderer to a
        RenderButton and calling setText directly. Put setInputType call here.
        (WebCore::RenderFileUploadControl::maxFilenameWidth): Made const. Broke long line.
        (WebCore::RenderFileUploadControl::createButtonStyle): Made const.
        (WebCore::RenderFileUploadControl::paintObject): Moved buttonShadowHeight constant
        to the top of the file. Call isEmpty instead of checking width and height of
        IntRect for 0. Computed font to pass to FileChooser::basenameForWidth. Broke
        long lines.
        (WebCore::HTMLFileUploadInnerButtonElement::HTMLFileUploadInnerButtonElement):
        Moved the setInputType call to the caller; concept here is that this class is
        as simple as possible, rather than doing as much of the button job as possible.

        * WebCore.xcodeproj/project.pbxproj: Added FileChooser.cpp.
        * WebCore.pro: Ditto.
        * CMakeLists.txt: Ditto.
        * WebCoreSources.bkl: Ditto.

        * platform/gdk/TemporaryLinkStubs.cpp: Updated stubs.
        * platform/qt/FileChooserQt.cpp: Updated stubs.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@19035 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
WebCore/CMakeLists.txt
WebCore/ChangeLog
WebCore/WebCore.pro
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/WebCoreSources.bkl
WebCore/platform/FileChooser.cpp [new file with mode: 0644]
WebCore/platform/FileChooser.h
WebCore/platform/gdk/TemporaryLinkStubs.cpp
WebCore/platform/mac/FileChooserMac.mm
WebCore/platform/qt/FileChooserQt.cpp
WebCore/rendering/RenderFileUploadControl.cpp
WebCore/rendering/RenderFileUploadControl.h

index 9103c2c..8b88d00 100644 (file)
@@ -993,6 +993,7 @@ set(WebCore_SRCS
     platform/DeprecatedString.cpp
     platform/DeprecatedStringList.cpp
     platform/DeprecatedValueListImpl.cpp
+    platform/FileChooser.cpp
     platform/FontCache.cpp
     platform/Font.cpp
     platform/FontData.cpp
index ae19823..30d6c65 100644 (file)
@@ -1,3 +1,81 @@
+2007-01-22  Darin Adler  <darin@apple.com>
+
+        Reviewed by Adam.
+
+        - fix http://bugs.webkit.org/show_bug.cgi?id=12273
+          REGRESSION: File input value invisible after removing and re-appending
+
+        - made more of the file chooser code cross-platform
+
+        - fixed an Objective-C garbage collection problem in FileChooser
+
+        - tried to remove layering violations where FileChooser in the platform
+          directory knows about the rendering and DOM trees (but wasn't able to
+          do it entirely)
+
+        * platform/FileChooser.cpp: Added.
+        (WebCore::FileChooser::create): Changed parameters.
+        (WebCore::FileChooser::chooseFile): Changed to call chooseIcon function.
+        (WebCore::FileChooser::chooseIcon): Added.
+
+        * platform/FileChooser.h: Added FileChooserClient so this file doesn't have
+        to know about RenderFileUploadControl. Used RetainPtr instead of retain/release
+        so this works properly with Objective-C GC. Replaced disconnectUploadControl
+        with disconnectClient, which has a simple inline implementation. Moved the
+        Document parameter from the constructor to openFileChooser, along with a comment
+        about why it should not be there. Added a filename parameter to the constructor
+        for the initial filename. Added a font parameter to basenameForWidth so we don't
+        depend on having a pointer to the renderer. Removed the uploadControl() and
+        document() functions since no one calls either of them.
+
+        * platform/mac/FileChooserMac.mm: Removed code that is now cross-platform.
+        (-[OpenPanelController beginSheetWithFrame:]): Added frame parameter, instead
+        of storing a document pointer in the FileChooser.
+        (WebCore::FileChooser::FileChooser): Updated for changed parameters. Also added
+        code to choose the icon based on the initial filename. Pass the adopt parameter
+        to the constructor of the RetainPtr.
+        (WebCore::FileChooser::~FileChooser): Removed the release call, since the
+        RetainPtr will take care of it. Added a call to disconnectFileChooser here.
+        There's no need to disconnect at disconnectClient time, and that lets us have
+        one more cross-platform function.
+        (WebCore::FileChooser::openFileChooser): Added document parameter. Added code
+        to get the frame from the document. And added a nil check since there's no
+        ironclad guarantee the document won't have outlived its frame.
+        (WebCore::FileChooser::basenameForWidth): Added font parameter. Use that instead
+        of going at the upload control's style. The caller can handle that now.
+
+        * rendering/RenderFileUploadControl.h: Removed unnecessary includes.
+        Made class inherit privately from FileChooserClient. Changed constructor
+        parameter to HTMLInputElement rather than Node. Made protected members be
+        private instead, and made a couple function members const.
+        * rendering/RenderFileUploadControl.cpp: Moved constants to the top of the file,
+        but after the "using namespace"
+        (WebCore::RenderFileUploadControl::RenderFileUploadControl): Updated for changes
+        to the FileChooser::create function and the parameter types.
+        (WebCore::RenderFileUploadControl::~RenderFileUploadControl): Removed unneeded
+        null check -- there's no case where the FileChooser fails to be created.
+        (WebCore::RenderFileUploadControl::click): Pass document to openFileChooser.
+        (WebCore::RenderFileUploadControl::updateFromElement): Tweaked code a bit by
+        using updateFromElement and setValue instead of casting the renderer to a
+        RenderButton and calling setText directly. Put setInputType call here.
+        (WebCore::RenderFileUploadControl::maxFilenameWidth): Made const. Broke long line.
+        (WebCore::RenderFileUploadControl::createButtonStyle): Made const.
+        (WebCore::RenderFileUploadControl::paintObject): Moved buttonShadowHeight constant
+        to the top of the file. Call isEmpty instead of checking width and height of
+        IntRect for 0. Computed font to pass to FileChooser::basenameForWidth. Broke
+        long lines.
+        (WebCore::HTMLFileUploadInnerButtonElement::HTMLFileUploadInnerButtonElement):
+        Moved the setInputType call to the caller; concept here is that this class is
+        as simple as possible, rather than doing as much of the button job as possible.
+
+        * WebCore.xcodeproj/project.pbxproj: Added FileChooser.cpp.
+        * WebCore.pro: Ditto.
+        * CMakeLists.txt: Ditto.
+        * WebCoreSources.bkl: Ditto.
+
+        * platform/gdk/TemporaryLinkStubs.cpp: Updated stubs.
+        * platform/qt/FileChooserQt.cpp: Updated stubs.
+
 2007-01-22  Mitz Pettel  <mitz@webkit.org>
 
         Reviewed by Darin.
index e489105..9339213 100644 (file)
@@ -559,6 +559,7 @@ SOURCES += \
     platform/qt/MimeTypeRegistryQt.cpp \
     platform/qt/SoundQt.cpp \
     platform/qt/FileChooserQt.cpp \
+    platform/FileChooser.cpp \
     platform/graphics/qt/IconQt.cpp \
     platform/graphics/qt/ImageBufferQt.cpp \
     platform/graphics/qt/AffineTransformQt.cpp \
index 2b57de2..670f805 100644 (file)
                93309EA4099EB78C0056E581 /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93309EA1099EB78C0056E581 /* Timer.cpp */; };
                93354A3C0B24F8C9003F6DEA /* UIEventWithKeyState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93354A3B0B24F8C9003F6DEA /* UIEventWithKeyState.cpp */; };
                934706AB0AACD809002C1D43 /* TextDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 932CA7420AAA198E00AD1FAD /* TextDecoder.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               934FE9E50B5CA539003E4A73 /* FileChooser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 934FE9E40B5CA539003E4A73 /* FileChooser.cpp */; };
                9352071909BD3BA500F2038D /* StaticConstructors.h in Headers */ = {isa = PBXBuildFile; fileRef = 9352071709BD3BA500F2038D /* StaticConstructors.h */; };
                9352071A09BD3BA500F2038D /* TextBoundaries.h in Headers */ = {isa = PBXBuildFile; fileRef = 9352071809BD3BA500F2038D /* TextBoundaries.h */; };
                9352071D09BD3BBB00F2038D /* TextBoundaries.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9352071B09BD3BBB00F2038D /* TextBoundaries.mm */; };
                93309EA0099EB78C0056E581 /* SharedTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedTimer.h; sourceTree = "<group>"; };
                93309EA1099EB78C0056E581 /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timer.cpp; sourceTree = "<group>"; };
                93354A3B0B24F8C9003F6DEA /* UIEventWithKeyState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UIEventWithKeyState.cpp; sourceTree = "<group>"; };
+               934FE9E40B5CA539003E4A73 /* FileChooser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileChooser.cpp; sourceTree = "<group>"; };
                9352071709BD3BA500F2038D /* StaticConstructors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticConstructors.h; sourceTree = "<group>"; };
                9352071809BD3BA500F2038D /* TextBoundaries.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextBoundaries.h; sourceTree = "<group>"; };
                9352071B09BD3BBB00F2038D /* TextBoundaries.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TextBoundaries.mm; sourceTree = "<group>"; };
                                F58786C202DE3B8601EA4122 /* DeprecatedValueList.h */,
                                F587853C02DE375901EA4122 /* DeprecatedValueListImpl.cpp */,
                                F587853B02DE375901EA4122 /* DeprecatedValueListImpl.h */,
+                               934FE9E40B5CA539003E4A73 /* FileChooser.cpp */,
                                066C772A0AB603B700238CC4 /* FileChooser.h */,
                                BC6D6DD009AF906600F59759 /* Font.cpp */,
                                BC6D6DD109AF906600F59759 /* Font.h */,
                                B2F273F20B5BFAC50068C956 /* SVGElementInstance.cpp in Sources */,
                                B2F273F30B5BFAC80068C956 /* SVGElementInstanceList.cpp in Sources */,
                                1A2A68230B5BEDE70002A480 /* ProgressTracker.cpp in Sources */,
+                               934FE9E50B5CA539003E4A73 /* FileChooser.cpp in Sources */,
                                A80CEBAD0B60FC49007637C1 /* SVGMPathElement.cpp in Sources */,
                                E1E6EEA40B628DA8005F2F70 /* JSHTMLSelectElement.cpp in Sources */,
                                929264770B61FC7200B41D34 /* JSDocumentCustom.cpp in Sources */,
index abb3804..d586146 100644 (file)
         platform/DeprecatedString.cpp
         platform/DeprecatedStringList.cpp
         platform/DeprecatedValueListImpl.cpp
+        platform/FileChooser.cpp
         platform/Font.cpp
         platform/FontCache.cpp
         platform/FontData.cpp
diff --git a/WebCore/platform/FileChooser.cpp b/WebCore/platform/FileChooser.cpp
new file mode 100644 (file)
index 0000000..2ac7342
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2007 Apple 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:
+ *
+ * 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. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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 "FileChooser.h"
+
+#include "Icon.h"
+
+namespace WebCore {
+    
+PassRefPtr<FileChooser> FileChooser::create(FileChooserClient* client, const String& filename)
+{
+    return new FileChooser(client, filename);
+}
+
+void FileChooser::chooseFile(const String& filename)
+{
+    if (m_filename == filename)
+        return;
+    m_filename = filename;
+    m_icon = chooseIcon(filename);
+    if (m_client)
+        m_client->valueChanged();
+}
+
+PassRefPtr<Icon> FileChooser::chooseIcon(const String& filename)
+{
+    // FIXME: Should the special cases be in Icon::newIconForFile?
+    // Need unsigned 0 here to disambiguate String::operator[] from operator(NSString*, int)[]
+    if (filename.isEmpty() || filename[0U] != '/')
+        return 0;
+    return Icon::newIconForFile(filename);
+}
+
+}
index f75ddb9..63f9d73 100644 (file)
@@ -1,31 +1,40 @@
 /*
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006, 2007 Apple Inc.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
  *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
+ * 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. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
  *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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 FileChooser_h
 #define FileChooser_h
 
-#include "Icon.h"
 #include "PlatformString.h"
 #include <wtf/RefPtr.h>
 
 #if PLATFORM(MAC)
+#include "RetainPtr.h"
 #ifdef __OBJC__
 @class OpenPanelController;
 #else
@@ -36,37 +45,45 @@ class OpenPanelController;
 namespace WebCore {
 
 class Document;
-class RenderFileUploadControl;
-class String;
+class Font;
+class Icon;
+
+class FileChooserClient {
+public:
+    virtual ~FileChooserClient() { }
+    virtual void valueChanged() = 0;
+};
 
 class FileChooser : public Shared<FileChooser> {
 public:
-    static PassRefPtr<FileChooser> create(Document*, RenderFileUploadControl*);
+    static PassRefPtr<FileChooser> create(FileChooserClient*, const String& initialFilename);
     ~FileChooser();
-    
-    void openFileChooser();
-    
+
+    void disconnectClient() { m_client = 0; }
+
+    // FIXME: It's a layering violation that we pass a Document in here.
+    // The platform directory is underneath the DOM, so it can't use the DOM.
+    // Because of UI delegates, it's not clear that this class belongs in the platform
+    // layer at all. It might need to go alongside the Chrome class instead.
+    void openFileChooser(Document*);
+
     const String& filename() const { return m_filename; }
-    String basenameForWidth(int width) const;
-    
+    String basenameForWidth(const Font&, int width) const;
+
     Icon* icon() const { return m_icon.get(); }
-    RenderFileUploadControl* uploadControl() const { return m_uploadControl; }
-    Document* document() { return m_document; }
-    
-    void disconnectUploadControl();
 
     void chooseFile(const String& filename);
-    
+
 private:
-    Document* m_document;
+    FileChooser(FileChooserClient*, const String& initialFilename);
+    static PassRefPtr<Icon> chooseIcon(const String& filename);
+
+    FileChooserClient* m_client;
     String m_filename;
     RefPtr<Icon> m_icon;
-    RenderFileUploadControl* m_uploadControl;
 
-    FileChooser(Document*, RenderFileUploadControl*);
-    
 #if PLATFORM(MAC)
-    OpenPanelController* m_controller;
+    RetainPtr<OpenPanelController> m_controller;
 #endif
 };
 
index ccd688e..53c3c88 100644 (file)
@@ -331,13 +331,10 @@ void PlatformScrollbar::updateThumbPosition() { }
 void PlatformScrollbar::updateThumbProportion() { }
 void PlatformScrollbar::setRect(const IntRect&) { }
 
-FileChooser::FileChooser(Document*, RenderFileUploadControl*) { notImplemented(); }
+FileChooser::FileChooser(FileChooserClient*, const String&) { notImplemented(); }
 FileChooser::~FileChooser() { notImplemented(); }
-PassRefPtr<FileChooser> FileChooser::create(Document*, RenderFileUploadControl*) { notImplemented(); return 0; }
-void FileChooser::openFileChooser() { notImplemented(); }
-String FileChooser::basenameForWidth(int width) const { notImplemented(); return String(); }
-void FileChooser::disconnectUploadControl() { notImplemented(); }
-void FileChooser::chooseFile(const String& filename) { notImplemented(); }
+void FileChooser::openFileChooser(Document*) { notImplemented(); }
+String FileChooser::basenameForWidth(const Font&, int width) const { notImplemented(); return String(); }
 
 Color WebCore::focusRingColor() { return 0xFF0000FF; }
 void WebCore::setFocusRingColorChangeFunction(void (*)()) { }
index 854baf6..c5e948e 100644 (file)
@@ -1,33 +1,40 @@
 /*
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006, 2007 Apple Inc.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
  *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
+ * 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. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
  *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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.
  *
  */
 
 #import "config.h"
 #import "FileChooser.h"
 
-#import <AppKit/NSOpenPanel.h>
 #import "Document.h"
 #import "FontData.h"
 #import "FrameMac.h"
 #import "Icon.h"
 #import "LocalizedStrings.h"
-#import "RenderFileUploadControl.h"
 #import "WebCoreFrameBridge.h"
 #import "WebCoreStringTruncator.h"
 
@@ -39,7 +46,7 @@ using namespace WebCore;
 }
 - (id)initWithFileChooser:(FileChooser *)fileChooser;
 - (void)disconnectFileChooser;
-- (void)beginSheet;
+- (void)beginSheetWithFrame:(Frame*)frame;
 @end
 
 @implementation OpenPanelController
@@ -49,7 +56,7 @@ using namespace WebCore;
     self = [super init];
     if (!self)
         return nil;
-    
+
     _fileChooser = fileChooser;
     return self;
 }
@@ -59,12 +66,12 @@ using namespace WebCore;
     _fileChooser = 0;
 }
 
-- (void)beginSheet
+- (void)beginSheetWithFrame:(Frame*)frame
 {
     if (!_fileChooser)
         return;
     
-    _bridge = Mac(_fileChooser->document()->frame())->bridge();
+    _bridge = Mac(frame)->bridge();
     [_bridge retain];
     [_bridge runOpenPanelForFileButtonWithResultListener:self];
 }
@@ -85,64 +92,38 @@ using namespace WebCore;
 
 namespace WebCore {
     
-PassRefPtr<FileChooser> FileChooser::create(Document* document, RenderFileUploadControl* uploadControl)
-{
-    return new FileChooser(document, uploadControl);
-}
-
-FileChooser::FileChooser(Document* document, RenderFileUploadControl* uploadControl)
-    : m_document(document)
-    , m_icon(0)
-    , m_uploadControl(uploadControl)
-    , m_controller([[OpenPanelController alloc] initWithFileChooser:this])
+FileChooser::FileChooser(FileChooserClient* client, const String& filename)
+    : m_client(client)
+    , m_filename(filename)
+    , m_icon(chooseIcon(filename))
+    , m_controller(Adopt, [[OpenPanelController alloc] initWithFileChooser:this])
 {
 }
 
 FileChooser::~FileChooser()
 {
-    [m_controller release];
+    [m_controller.get() disconnectFileChooser];
 }
 
-void FileChooser::openFileChooser()
+void FileChooser::openFileChooser(Document* document)
 {
-    [m_controller beginSheet];
+    if (Frame* frame = document->frame())
+        [m_controller.get() beginSheetWithFrame:frame];
 }
 
-String FileChooser::basenameForWidth(int width) const
+String FileChooser::basenameForWidth(const Font& font, int width) const
 {
     if (width <= 0)
         return String();
-    
+
     String strToTruncate;
     if (m_filename.isEmpty())
         strToTruncate = fileButtonNoFileSelectedLabel();
     else
         strToTruncate = [[NSFileManager defaultManager] displayNameAtPath:m_filename];
-    
-    return [WebCoreStringTruncator centerTruncateString:strToTruncate
-            toWidth:width withFont:m_uploadControl->style()->font().primaryFont()->getNSFont()];
-}
 
-void FileChooser::disconnectUploadControl()
-{
-    if (m_controller)
-        [m_controller disconnectFileChooser];
-}
-
-void FileChooser::chooseFile(const String& filename)
-{
-    if (m_filename == filename)
-        return;
-    
-    m_filename = filename;
-    
-    // Need unsigned 0 here to disambiguate String::operator[] from operator(NSString*, int)[]
-    if (!m_filename.length() || m_filename[0U] != '/')
-        m_icon = 0;
-    else
-        m_icon = Icon::newIconForFile(m_filename);
-    
-    uploadControl()->valueChanged();
+    return [WebCoreStringTruncator centerTruncateString:strToTruncate
+        toWidth:width withFont:font.primaryFont()->getNSFont()];
 }
 
 }
index 90965bd..35db56e 100644 (file)
 
 namespace WebCore {
 
-FileChooser::FileChooser(Document*, RenderFileUploadControl*)
+FileChooser::FileChooser(FileChooserClient* client, const String& filename)
+    : m_client(client)
+    , m_filename(filename)
+    , m_icon(chooseIcon(filename))
 {
-    notImplemented();
 }
 
 FileChooser::~FileChooser()
 {
-    notImplemented();
 }
 
-PassRefPtr<FileChooser> FileChooser::create(Document*, RenderFileUploadControl*)
+void FileChooser::openFileChooser(Document*)
 {
     notImplemented();
-    return 0;
 }
 
-void FileChooser::openFileChooser()
-{
-    notImplemented();
-}
-
-String FileChooser::basenameForWidth(int width) const
+String FileChooser::basenameForWidth(const Font&, int width) const
 {
     notImplemented();
     return String();
 }
 
-void FileChooser::disconnectUploadControl()
-{
-    notImplemented();
-}
-
-void FileChooser::chooseFile(const String& filename)
-{
-    notImplemented();
-}
-
 }
 
 // vim: ts=4 sw=4 et
index 0f645f1..1103d50 100644 (file)
@@ -1,6 +1,5 @@
-/**
- *
- * Copyright (C) 2006 Apple Computer, Inc.
+/*
+ * Copyright (C) 2006, 2007 Apple Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -39,32 +38,30 @@ using namespace std;
 
 namespace WebCore {
 
+using namespace HTMLNames;
+
 const int afterButtonSpacing = 4;
 const int iconHeight = 16;
 const int iconWidth = 16;
 const int iconFilenameSpacing = 2;
 const int defaultWidthNumChars = 34;
-
-using namespace HTMLNames;
+const int buttonShadowHeight = 2;
 
 class HTMLFileUploadInnerButtonElement : public HTMLInputElement {
 public:
-    HTMLFileUploadInnerButtonElement(Document*, Node* shadowParent = 0);
-    
-    virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
-    
+    HTMLFileUploadInnerButtonElement(Document*, Node* shadowParent);
+
     virtual bool isShadowNode() const { return true; }
-    
     virtual Node* shadowParentNode() { return m_shadowParent; }
-    
+
 private:
     Node* m_shadowParent;    
 };
 
-RenderFileUploadControl::RenderFileUploadControl(Node* node)
-    : RenderBlock(node)
+RenderFileUploadControl::RenderFileUploadControl(HTMLInputElement* input)
+    : RenderBlock(input)
     , m_button(0)
-    , m_fileChooser(FileChooser::create(document(), this))
+    , m_fileChooser(FileChooser::create(this, input->value()))
 {
 }
 
@@ -72,8 +69,7 @@ RenderFileUploadControl::~RenderFileUploadControl()
 {
     if (m_button)
         m_button->detach();
-    if (m_fileChooser)
-        m_fileChooser->disconnectUploadControl();
+    m_fileChooser->disconnectClient();
 }
 
 void RenderFileUploadControl::setStyle(RenderStyle* newStyle)
@@ -100,35 +96,39 @@ void RenderFileUploadControl::valueChanged()
 
 void RenderFileUploadControl::click()
 {
-    m_fileChooser->openFileChooser();
+     m_fileChooser->openFileChooser(node()->document());
 }
 
 void RenderFileUploadControl::updateFromElement()
 {
     if (!m_button) {
         m_button = new HTMLFileUploadInnerButtonElement(document(), node());
+        m_button->setInputType("button");
+        m_button->setValue(fileButtonChooseFileLabel());
         RenderStyle* buttonStyle = createButtonStyle(style());
-        m_button->setRenderer(m_button->createRenderer(renderArena(), buttonStyle));
-        m_button->renderer()->setStyle(buttonStyle);
-        static_cast<RenderButton*>(m_button->renderer())->setText(fileButtonChooseFileLabel());
+        RenderObject* renderer = m_button->createRenderer(renderArena(), buttonStyle);
+        m_button->setRenderer(renderer);
+        renderer->setStyle(buttonStyle);
+        renderer->updateFromElement();
         m_button->setAttached();
         m_button->setInDocument(true);
-        
+
         addChild(m_button->renderer());
     }
     m_button->setDisabled(!theme()->isEnabled(this));
 }
 
-int RenderFileUploadControl::maxFilenameWidth()
+int RenderFileUploadControl::maxFilenameWidth() const
 {
-    return max(0, contentWidth() - m_button->renderer()->width() - afterButtonSpacing - (m_fileChooser->icon() ? iconWidth + iconFilenameSpacing : 0));
+    return max(0, contentWidth() - m_button->renderer()->width() - afterButtonSpacing
+        - (m_fileChooser->icon() ? iconWidth + iconFilenameSpacing : 0));
 }
 
-RenderStyle* RenderFileUploadControl::createButtonStyle(RenderStyle* parentStyle)
+RenderStyle* RenderFileUploadControl::createButtonStyle(RenderStyle* parentStyle) const
 {
     RenderStyle* style = getPseudoStyle(RenderStyle::FILE_UPLOAD_BUTTON);
     if (!style) {
-        style = new (renderArena()) RenderStyle();
+        style = new (renderArena()) RenderStyle;
         if (parentStyle)
             style->inheritFrom(parentStyle);
     }
@@ -142,25 +142,24 @@ RenderStyle* RenderFileUploadControl::createButtonStyle(RenderStyle* parentStyle
 
 void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
 {
-    const int buttonShadowHeight = 2;
-    
     // Push a clip.
     if (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseChildBlockBackgrounds) {
         IntRect clipRect(tx + borderLeft(), ty + borderTop(),
                          width() - borderLeft() - borderRight(), height() - borderBottom() - borderTop() + buttonShadowHeight);
-        if (clipRect.width() == 0 || clipRect.height() == 0)
+        if (clipRect.isEmpty())
             return;
         paintInfo.context->save();
         paintInfo.context->clip(clipRect);
     }
 
     if (paintInfo.phase == PaintPhaseForeground) {
-        const String& displayedFilename = m_fileChooser->basenameForWidth(maxFilenameWidth());
+        const String& displayedFilename = m_fileChooser->basenameForWidth(style()->font(), maxFilenameWidth());
         TextRun textRun(displayedFilename.characters(), displayedFilename.length());
 
         // Determine where the filename should be placed
         int contentLeft = tx + borderLeft() + paddingLeft();
-        int buttonAndIconWidth = m_button->renderer()->width() + afterButtonSpacing + (m_fileChooser->icon() ? iconWidth + iconFilenameSpacing : 0);
+        int buttonAndIconWidth = m_button->renderer()->width() + afterButtonSpacing
+            + (m_fileChooser->icon() ? iconWidth + iconFilenameSpacing : 0);
         int textX;
         if (style()->direction() == LTR)
             textX = contentLeft + buttonAndIconWidth;
@@ -168,7 +167,9 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
             textX = contentLeft + contentWidth() - buttonAndIconWidth - style()->font().width(textRun);
         // We want to match the button's baseline
         RenderButton* buttonRenderer = static_cast<RenderButton*>(m_button->renderer());
-        int textY = buttonRenderer->absoluteBoundingBoxRect().y() + buttonRenderer->marginTop() + buttonRenderer->borderTop() + buttonRenderer->paddingTop() + buttonRenderer->baselinePosition(true, false);
+        int textY = buttonRenderer->absoluteBoundingBoxRect().y()
+            + buttonRenderer->marginTop() + buttonRenderer->borderTop() + buttonRenderer->paddingTop()
+            + buttonRenderer->baselinePosition(true, false);
 
         paintInfo.context->setFont(style()->font());
         paintInfo.context->setFillColor(style()->color());
@@ -237,12 +238,6 @@ HTMLFileUploadInnerButtonElement::HTMLFileUploadInnerButtonElement(Document* doc
     : HTMLInputElement(doc)
     , m_shadowParent(shadowParent)
 {
-    setInputType("button");
-}
-
-RenderObject* HTMLFileUploadInnerButtonElement::createRenderer(RenderArena* arena, RenderStyle* style)
-{
-    return HTMLInputElement::createRenderer(arena, style);
 }
 
 } // namespace WebCore
index aaa6f1b..31b8294 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Apple Computer
+ * Copyright (C) 2006, 2007 Apple Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 #define RenderFileUploadControl_h
 
 #include "FileChooser.h"
-#include "HTMLInputElement.h"
 #include "RenderBlock.h"
-#include "Shared.h"
 
 namespace WebCore {
 
-class HTMLFileUploadInnerButtonElement;
-//class RenderFileUploadInnerFileBlock;
+class HTMLInputElement;
     
-// RenderFileUploadControls contain a RenderButton (for opening the file chooser), and
-// sufficient space to draw a file icon and filename. The RenderButton has an
-// HTMLFileUploadInnerButtonElement shadow node associated with it to receive click/hover events.
+// Each RenderFileUploadControl contains a RenderButton (for opening the file chooser), and
+// sufficient space to draw a file icon and filename. The RenderButton has a shadow node
+// associated with it to receive click/hover events.
 
-class RenderFileUploadControl : public RenderBlock {
+class RenderFileUploadControl : public RenderBlock, private FileChooserClient {
 public:
-    RenderFileUploadControl(Node*);
+    RenderFileUploadControl(HTMLInputElement*);
     ~RenderFileUploadControl();
 
     virtual const char* renderName() const { return "RenderFileUploadControl"; }
@@ -51,11 +48,11 @@ public:
 
     void valueChanged();
 
-protected:
-    int maxFilenameWidth();
-    RenderStyle* createButtonStyle(RenderStyle* parentStyle = 0);
+private:
+    int maxFilenameWidth() const;
+    RenderStyle* createButtonStyle(RenderStyle* parentStyle) const;
 
-    RefPtr<HTMLFileUploadInnerButtonElement> m_button;
+    RefPtr<HTMLInputElement> m_button;
     RefPtr<FileChooser> m_fileChooser;
 };