Changeset 89535 in webkit


Ignore:
Timestamp:
Jun 22, 2011 11:04:50 PM (13 years ago)
Author:
Dimitri Glazkov
Message:

2011-06-22 Dimitri Glazkov <Dimitri Glazkov>

Reviewed by Kent Tamura.

Move file-choosing and icon-loading management to FileInputType
https://bugs.webkit.org/show_bug.cgi?id=62069

1) Moved the duties of FileChooserClient and FileIconLoaderClient from
RenderFileUploadControl to FileInputType, along with all of the
supporting functions.

2) Moved Icon ownership to FileInputType and exposed accessor on
HTMInputElement to allow RenderFileUploadControl to query current icon.

As a result, RenderFileUploadControl is now completely stateless, which is
neat and clean.

Refactoring, covered by existing tests.

  • html/FileInputType.cpp: (WebCore::FileInputType::handleDOMActivateEvent): Moved logic here from RenderFileUploadControl. (WebCore::FileInputType::requestIcon): Ditto. (WebCore::FileInputType::filesChosen): Ditto. (WebCore::FileInputType::receiveDropForDirectoryUpload): Ditto. (WebCore::FileInputType::updateRendering): Ditto. (WebCore::FileInputType::chrome): Ditto. (WebCore::FileInputType::receiveDroppedFiles): Ditto. (WebCore::FileInputType::icon): Added.
  • html/FileInputType.h:
  • html/HTMLInputElement.cpp: (WebCore::HTMLInputElement::setValueFromRenderer): Updated comment. (WebCore::HTMLInputElement::receiveDroppedFiles): Added to replace setFileListFromRenderer. (WebCore::HTMLInputElement::icon): Added.
  • html/HTMLInputElement.h:
  • html/InputType.cpp: (WebCore::InputType::receiveDroppedFiles): Added. (WebCore::InputType::icon): Added.
  • html/InputType.h:
  • page/DragController.cpp: (WebCore::DragController::concludeEditDrag): Changed to use HTMLInputElement. Ahh, nice and clean!
  • rendering/RenderFileUploadControl.cpp: (WebCore::RenderFileUploadControl::RenderFileUploadControl): Removed code that is no longer necessary. (WebCore::RenderFileUploadControl::updateFromElement): Ditto. (WebCore::RenderFileUploadControl::maxFilenameWidth): Changed to use HTMLInputElement icon accessor. (WebCore::RenderFileUploadControl::paintObject): Ditto.
  • rendering/RenderFileUploadControl.h:
Location:
trunk/Source/WebCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r89534 r89535  
     12011-06-22  Dimitri Glazkov  <dglazkov@chromium.org>
     2
     3        Reviewed by Kent Tamura.
     4
     5        Move file-choosing and icon-loading management to FileInputType
     6        https://bugs.webkit.org/show_bug.cgi?id=62069
     7
     8        1) Moved the duties of FileChooserClient and FileIconLoaderClient from
     9        RenderFileUploadControl to FileInputType, along with all of the
     10        supporting functions.
     11
     12        2) Moved Icon ownership to FileInputType and exposed accessor on
     13        HTMInputElement to allow RenderFileUploadControl to query current icon.
     14
     15        As a result, RenderFileUploadControl is now completely stateless, which is
     16        neat and clean.
     17
     18        Refactoring, covered by existing tests.
     19
     20        * html/FileInputType.cpp:
     21        (WebCore::FileInputType::handleDOMActivateEvent): Moved logic here from RenderFileUploadControl.
     22        (WebCore::FileInputType::requestIcon): Ditto.
     23        (WebCore::FileInputType::filesChosen): Ditto.
     24        (WebCore::FileInputType::receiveDropForDirectoryUpload): Ditto.
     25        (WebCore::FileInputType::updateRendering): Ditto.
     26        (WebCore::FileInputType::chrome): Ditto.
     27        (WebCore::FileInputType::receiveDroppedFiles): Ditto.
     28        (WebCore::FileInputType::icon): Added.
     29        * html/FileInputType.h:
     30        * html/HTMLInputElement.cpp:
     31        (WebCore::HTMLInputElement::setValueFromRenderer): Updated comment.
     32        (WebCore::HTMLInputElement::receiveDroppedFiles): Added to replace setFileListFromRenderer.
     33        (WebCore::HTMLInputElement::icon): Added.
     34        * html/HTMLInputElement.h:
     35        * html/InputType.cpp:
     36        (WebCore::InputType::receiveDroppedFiles): Added.
     37        (WebCore::InputType::icon): Added.
     38        * html/InputType.h:
     39        * page/DragController.cpp:
     40        (WebCore::DragController::concludeEditDrag): Changed to use HTMLInputElement. Ahh, nice and clean!
     41        * rendering/RenderFileUploadControl.cpp:
     42        (WebCore::RenderFileUploadControl::RenderFileUploadControl): Removed code that is no longer necessary.
     43        (WebCore::RenderFileUploadControl::updateFromElement): Ditto.
     44        (WebCore::RenderFileUploadControl::maxFilenameWidth): Changed to use HTMLInputElement icon accessor.
     45        (WebCore::RenderFileUploadControl::paintObject): Ditto.
     46        * rendering/RenderFileUploadControl.h:
     47
    1482011-06-22  Pratik Solanki  <psolanki@apple.com>
    249
  • trunk/Source/WebCore/html/FileInputType.cpp

    r88115 r89535  
    2323#include "FileInputType.h"
    2424
     25#include "Chrome.h"
    2526#include "Event.h"
    2627#include "File.h"
     
    2829#include "FileSystem.h"
    2930#include "FormDataList.h"
     31#include "Frame.h"
    3032#include "HTMLInputElement.h"
    3133#include "HTMLNames.h"
     34#include "Icon.h"
    3235#include "LocalizedStrings.h"
     36#include "Page.h"
    3337#include "RenderFileUploadControl.h"
     38#include "ScriptController.h"
    3439#include "ShadowRoot.h"
    3540#include <wtf/PassOwnPtr.h>
     
    129134    if (element()->disabled() || !element()->renderer())
    130135        return;
    131     toRenderFileUploadControl(element()->renderer())->click();
     136
     137    if (!ScriptController::processingUserGesture())
     138        return;
     139
     140    if (Chrome* chrome = this->chrome()) {
     141        FileChooserSettings settings;
     142        HTMLInputElement* input = element();
     143#if ENABLE(DIRECTORY_UPLOAD)
     144        settings.allowsDirectoryUpload = input->fastHasAttribute(webkitdirectoryAttr);
     145        settings.allowsMultipleFiles = settings.allowsDirectoryUpload || input->fastHasAttribute(multipleAttr);
     146#else
     147        settings.allowsMultipleFiles = input->fastHasAttribute(multipleAttr);
     148#endif
     149        settings.acceptTypes = input->accept();
     150        ASSERT(input->files());
     151        settings.selectedFiles = input->files()->filenames();
     152        chrome->runOpenPanel(input->document()->frame(), newFileChooser(settings));
     153    }
    132154    event->setDefaultHandled();
    133155}
     
    231253}
    232254
     255void FileInputType::requestIcon(const Vector<String>& filenames)
     256{
     257    if (!filenames.size())
     258        return;
     259
     260    if (Chrome* chrome = this->chrome())
     261        chrome->loadIconForFiles(filenames, newFileIconLoader());
     262}
     263
     264void FileInputType::filesChosen(const Vector<String>& filenames)
     265{
     266    HTMLInputElement* input = element();
     267    setFileList(filenames);
     268
     269    input->setFormControlValueMatchesRenderer(true);
     270    input->notifyFormStateChanged();
     271    input->setNeedsValidityCheck();
     272
     273    requestIcon(filenames);
     274
     275    if (input->renderer())
     276        input->renderer()->repaint();
     277    // This call may cause destruction of this instance and thus must always be last in the function.
     278    input->dispatchFormControlChangeEvent();
     279}
     280
     281#if ENABLE(DIRECTORY_UPLOAD)
     282void FileInputType::receiveDropForDirectoryUpload(const Vector<String>& paths)
     283{
     284    if (Chrome* chrome = this->chrome()) {
     285        FileChooserSettings settings;
     286        settings.allowsDirectoryUpload = true;
     287        settings.allowsMultipleFiles = true;
     288        settings.selectedFiles.append(paths[0]);
     289        chrome->enumerateChosenDirectory(newFileChooser(settings));
     290    }
     291}
     292#endif
     293
     294void FileInputType::updateRendering(PassRefPtr<Icon> icon)
     295{
     296    if (m_icon == icon)
     297        return;
     298
     299    m_icon = icon;
     300    if (element()->renderer())
     301        element()->renderer()->repaint();
     302}
     303
     304Chrome* FileInputType::chrome() const
     305{
     306    if (Page* page = element()->document()->page())
     307        return page->chrome();
     308    return 0;
     309}
     310
     311void FileInputType::receiveDroppedFiles(const Vector<String>& paths)
     312{
     313    HTMLInputElement* input = element();
     314#if ENABLE(DIRECTORY_UPLOAD)
     315    if (input->fastHasAttribute(webkitdirectoryAttr)) {
     316        receiveDropForDirectoryUpload(paths);
     317        return;
     318    }
     319#endif
     320
     321    if (input->fastHasAttribute(multipleAttr))
     322        filesChosen(paths);
     323    else {
     324        Vector<String> firstPathOnly;
     325        firstPathOnly.append(paths[0]);
     326        filesChosen(firstPathOnly);
     327    }
     328}
     329
     330Icon* FileInputType::icon() const
     331{
     332    return m_icon.get();
     333}
     334
    233335} // namespace WebCore
  • trunk/Source/WebCore/html/FileInputType.h

    r88115 r89535  
    3434
    3535#include "BaseButtonInputType.h"
     36#include "FileChooser.h"
     37#include "FileIconLoader.h"
    3638#include <wtf/RefPtr.h>
    3739
    3840namespace WebCore {
    3941
     42class Chrome;
    4043class FileList;
    4144
    42 class FileInputType : public BaseButtonInputType {
     45class FileInputType : public BaseButtonInputType, private FileChooserClient, private FileIconLoaderClient {
    4346public:
    4447    static PassOwnPtr<InputType> create(HTMLInputElement*);
     
    5861    virtual bool getTypeSpecificValue(String&); // Checked first, before internal storage or the value attribute.
    5962    virtual bool storesValueSeparateFromAttribute();
    60     virtual void setFileList(const Vector<String>& paths);
     63    virtual void receiveDroppedFiles(const Vector<String>&);
     64    virtual Icon* icon() const;
    6165    virtual bool isFileUpload() const;
    6266    virtual void createShadowSubtree();
    6367
     68    // FileChooserClient implementation.
     69    virtual void filesChosen(const Vector<String>&);
     70
     71    // FileIconLoaderClient implementation.
     72    virtual void updateRendering(PassRefPtr<Icon>);
     73
     74    void setFileList(const Vector<String>& paths);
     75#if ENABLE(DIRECTORY_UPLOAD)
     76    void receiveDropForDirectoryUpload(const Vector<String>&);
     77#endif
     78    void requestIcon(const Vector<String>&);
     79    Chrome* chrome() const;
     80
    6481    RefPtr<FileList> m_fileList;
     82    RefPtr<Icon> m_icon;
    6583};
    6684
  • trunk/Source/WebCore/html/HTMLInputElement.cpp

    r89460 r89535  
    4646#include "HTMLOptionElement.h"
    4747#include "HTMLParserIdioms.h"
     48#include "Icon.h"
    4849#include "InputType.h"
    4950#include "KeyboardEvent.h"
     
    10581059void HTMLInputElement::setValueFromRenderer(const String& value)
    10591060{
    1060     // File upload controls will always use setFileListFromRenderer.
     1061    // File upload controls will never use this.
    10611062    ASSERT(!isFileUpload());
    10621063
     
    10841085    // Clear autofill flag (and yellow background) on user edit.
    10851086    setAutofilled(false);
    1086 }
    1087 
    1088 void HTMLInputElement::setFileListFromRenderer(const Vector<String>& paths)
    1089 {
    1090     m_inputType->setFileList(paths);
    1091 
    1092     setFormControlValueMatchesRenderer(true);
    1093     notifyFormStateChanged();
    1094     setNeedsValidityCheck();
    10951087}
    10961088
     
    12741266{
    12751267    return m_inputType->files();
     1268}
     1269
     1270void HTMLInputElement::receiveDroppedFiles(const Vector<String>& filenames)
     1271{
     1272    m_inputType->receiveDroppedFiles(filenames);
     1273}
     1274
     1275Icon* HTMLInputElement::icon() const
     1276{
     1277    return m_inputType->icon();
    12761278}
    12771279
  • trunk/Source/WebCore/html/HTMLInputElement.h

    r89460 r89535  
    3232class HTMLDataListElement;
    3333class HTMLOptionElement;
     34class Icon;
    3435class InputType;
    3536class KURL;
     
    164165
    165166    void setValueFromRenderer(const String&);
    166     void setFileListFromRenderer(const Vector<String>&);
    167167
    168168    bool canHaveSelection() const;
     
    203203
    204204    FileList* files();
     205    void receiveDroppedFiles(const Vector<String>&);
     206    Icon* icon() const;
    205207
    206208    void addSearchResult();
     
    227229    bool lastChangeWasUserEdit() const;
    228230    void cacheSelection(int start, int end);
     231    void notifyFormStateChanged();
    229232
    230233    static const int maximumLength;
     
    319322    HTMLDataListElement* dataList() const;
    320323#endif
    321     void notifyFormStateChanged();
    322324    void parseMaxLengthAttribute(Attribute*);
    323325    void updateValueIfNeeded();
  • trunk/Source/WebCore/html/InputType.cpp

    r89194 r89535  
    538538}
    539539
    540 void InputType::setFileList(const Vector<String>&)
     540void InputType::receiveDroppedFiles(const Vector<String>&)
    541541{
    542542    ASSERT_NOT_REACHED();
     543}
     544
     545Icon* InputType::icon() const
     546{
     547    ASSERT_NOT_REACHED();
     548    return 0;
    543549}
    544550
  • trunk/Source/WebCore/html/InputType.h

    r89460 r89535  
    4949class HTMLFormElement;
    5050class HTMLInputElement;
     51class Icon;
    5152class KeyboardEvent;
    5253class MouseEvent;
     
    210211    virtual bool shouldRespectAlignAttribute();
    211212    virtual FileList* files();
     213    virtual void receiveDroppedFiles(const Vector<String>&);
     214    virtual Icon* icon() const;
    212215    // Should return true if the corresponding renderer for a type can display a suggested value.
    213216    virtual bool canSetSuggestedValue();
     
    215218    virtual bool canSetValue(const String&);
    216219    virtual bool storesValueSeparateFromAttribute();
    217     virtual void setFileList(const Vector<String>& paths);
    218220    virtual bool shouldResetOnDocumentActivation();
    219221    virtual bool shouldRespectListAttribute();
  • trunk/Source/WebCore/page/DragController.cpp

    r88476 r89535  
    421421            return false;
    422422
    423         // Ugly. For security none of the APIs available to us can set the input value
    424         // on file inputs. Even forcing a change in HTMLInputElement doesn't work as
    425         // RenderFileUploadControl clears the file when doing updateFromElement().
    426         RenderFileUploadControl* renderer = toRenderFileUploadControl(fileInput->renderer());
    427         if (!renderer)
    428             return false;
    429 
    430         renderer->receiveDroppedFiles(filenames);
     423        fileInput->receiveDroppedFiles(filenames);
    431424        return true;
    432425    }
  • trunk/Source/WebCore/rendering/RenderFileUploadControl.cpp

    r89526 r89535  
    2222#include "RenderFileUploadControl.h"
    2323
    24 #include "Chrome.h"
    2524#include "FileList.h"
    26 #include "Frame.h"
    27 #include "FrameView.h"
    2825#include "GraphicsContext.h"
    2926#include "HTMLInputElement.h"
     
    3128#include "Icon.h"
    3229#include "LocalizedStrings.h"
    33 #include "Page.h"
    3430#include "PaintInfo.h"
    3531#include "RenderButton.h"
    3632#include "RenderText.h"
    3733#include "RenderTheme.h"
    38 #include "RenderView.h"
    39 #include "ScriptController.h"
    4034#include "ShadowRoot.h"
    4135#include "TextRun.h"
     36#include "VisiblePosition.h"
    4237#include <math.h>
    4338
     
    5853    : RenderBlock(input)
    5954{
    60     ASSERT(input->files());
    61     requestIcon(input->files()->filenames());
    6255}
    6356
     
    6659}
    6760
    68 void RenderFileUploadControl::requestIcon(const Vector<String>& filenames)
    69 {
    70     if (!filenames.size())
    71         return;
    72 
    73     if (Chrome* chrome = this->chrome())
    74         chrome->loadIconForFiles(filenames, newFileIconLoader());
    75 }
    76 
    77 void RenderFileUploadControl::filesChosen(const Vector<String>& filenames)
    78 {
    79     HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(node());
    80     inputElement->setFileListFromRenderer(filenames);
    81     requestIcon(filenames);
    82 
    83     repaint();
    84     // This call may cause destruction of this instance and thus must always be last in the function.
    85     inputElement->dispatchFormControlChangeEvent();
    86 }
    87 
    88 #if ENABLE(DIRECTORY_UPLOAD)
    89 void RenderFileUploadControl::receiveDropForDirectoryUpload(const Vector<String>& paths)
    90 {
    91     if (Chrome* chrome = this->chrome()) {
    92         FileChooserSettings settings;
    93         settings.allowsDirectoryUpload = true;
    94         settings.allowsMultipleFiles = true;
    95         settings.selectedFiles.append(paths[0]);
    96         chrome->enumerateChosenDirectory(newFileChooser(settings));
    97     }
    98 }
    99 #endif
    100 
    101 
    102 void RenderFileUploadControl::updateRendering(PassRefPtr<Icon> icon)
    103 {
    104     if (m_icon == icon)
    105         return;
    106 
    107     m_icon = icon;
    108     repaint();
    109 }
    110 
    111 void RenderFileUploadControl::click()
    112 {
    113     if (!ScriptController::processingUserGesture())
    114         return;
    115 
    116     if (Chrome* chrome = this->chrome()) {
    117         FileChooserSettings settings;
    118         HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
    119 #if ENABLE(DIRECTORY_UPLOAD)
    120         settings.allowsDirectoryUpload = input->fastHasAttribute(webkitdirectoryAttr);
    121         settings.allowsMultipleFiles = settings.allowsDirectoryUpload || input->fastHasAttribute(multipleAttr);
    122 #else
    123         settings.allowsMultipleFiles = input->fastHasAttribute(multipleAttr);
    124 #endif
    125         settings.acceptTypes = input->accept();
    126         ASSERT(input->files());
    127         settings.selectedFiles = input->files()->filenames();
    128         chrome->runOpenPanel(frame(), newFileChooser(settings));
    129     }
    130 }
    131 
    132 Chrome* RenderFileUploadControl::chrome() const
    133 {
    134     Frame* frame = node()->document()->frame();
    135     if (!frame)
    136         return 0;
    137     Page* page = frame->page();
    138     if (!page)
    139         return 0;
    140     return page->chrome();
    141 }
    142 
    14361void RenderFileUploadControl::updateFromElement()
    14462{
    145     HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(node());
    146     ASSERT(inputElement->isFileUpload());
    147 
    148 
    14963    if (HTMLInputElement* button = uploadButton())
    15064        button->setDisabled(!theme()->isEnabled(this));
    151 
    152     // This only supports clearing out the files, but that's OK because for
    153     // security reasons that's the only change the DOM is allowed to make.
    154     FileList* files = inputElement->files();
    155     ASSERT(files);
    156     if (files && files->isEmpty() && m_icon) {
    157         m_icon = 0;
    158         repaint();
    159     }
    16065}
    16166
     
    16772int RenderFileUploadControl::maxFilenameWidth() const
    16873{
     74    HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
    16975    return max(0, contentWidth() - nodeWidth(uploadButton()) - afterButtonSpacing
    170         - (m_icon ? iconWidth + iconFilenameSpacing : 0));
     76        - (input->icon() ? iconWidth + iconFilenameSpacing : 0));
    17177}
    17278
     
    198104            return;
    199105
     106        HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
    200107        int buttonWidth = nodeWidth(button);
    201108        int buttonAndIconWidth = buttonWidth + afterButtonSpacing
    202             + (m_icon ? iconWidth + iconFilenameSpacing : 0);
     109            + (input->icon() ? iconWidth + iconFilenameSpacing : 0);
    203110        int textX;
    204111        if (style()->isLeftToRightDirection())
     
    217124        paintInfo.context->drawBidiText(font, textRun, IntPoint(textX, textY));
    218125       
    219         if (m_icon) {
     126        if (input->icon()) {
    220127            // Determine where the icon should be placed
    221128            int iconY = paintOffset.y() + borderTop() + paddingTop() + (contentHeight() - iconHeight) / 2;
     
    227134
    228135            // Draw the file icon
    229             m_icon->paint(paintInfo.context, IntRect(iconX, iconY, iconWidth, iconHeight));
     136            input->icon()->paint(paintInfo.context, IntRect(iconX, iconY, iconWidth, iconHeight));
    230137        }
    231138    }
     
    291198}
    292199
    293 void RenderFileUploadControl::receiveDroppedFiles(const Vector<String>& paths)
    294 {
    295     HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
    296 #if ENABLE(DIRECTORY_UPLOAD)
    297     if (input->fastHasAttribute(webkitdirectoryAttr)) {
    298         receiveDropForDirectoryUpload(paths);
    299         return;
    300     }
    301 #endif
    302 
    303     if (input->fastHasAttribute(multipleAttr))
    304         filesChosen(paths);
    305     else {
    306         Vector<String> firstPathOnly;
    307         firstPathOnly.append(paths[0]);
    308         filesChosen(firstPathOnly);
    309     }
    310 }
    311 
    312200String RenderFileUploadControl::buttonValue()
    313201{
  • trunk/Source/WebCore/rendering/RenderFileUploadControl.h

    r89526 r89535  
    2222#define RenderFileUploadControl_h
    2323
    24 #include "FileChooser.h"
    25 #include "FileIconLoader.h"
    2624#include "RenderBlock.h"
    2725
    2826namespace WebCore {
    2927
    30 class Chrome;
    3128class HTMLInputElement;
    3229
     
    3532// associated with it to receive click/hover events.
    3633
    37 class RenderFileUploadControl : public RenderBlock, private FileChooserClient, private FileIconLoaderClient {
     34class RenderFileUploadControl : public RenderBlock {
    3835public:
    3936    RenderFileUploadControl(HTMLInputElement*);
     
    4138
    4239    virtual bool isFileUploadControl() const { return true; }
    43 
    44     void click();
    45 
    46     void receiveDroppedFiles(const Vector<String>&);
    4740
    4841    String buttonValue();
     
    5851    virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
    5952
    60     // FileChooserClient implementation.
    61     virtual void filesChosen(const Vector<String>&);
    62 
    63     // FileIconLoaderClient implementation.
    64     virtual void updateRendering(PassRefPtr<Icon>);
    65 
    66 #if ENABLE(DIRECTORY_UPLOAD)
    67     void receiveDropForDirectoryUpload(const Vector<String>&);
    68 #endif
    69 
    70     Chrome* chrome() const;
    7153    int maxFilenameWidth() const;
    7254   
     
    7456
    7557    HTMLInputElement* uploadButton() const;
    76     void requestIcon(const Vector<String>&);
    77 
    78     RefPtr<Icon> m_icon;
    7958};
    8059
Note: See TracChangeset for help on using the changeset viewer.