Changeset 88115 in webkit


Ignore:
Timestamp:
Jun 4, 2011 10:14:22 AM (13 years ago)
Author:
Dimitri Glazkov
Message:

2011-06-03 Dimitri Glazkov <Dimitri Glazkov>

Reviewed by Darin Adler.

Convert file <input> to use the new shadow DOM model
https://bugs.webkit.org/show_bug.cgi?id=59005

Refactoring, covered by existing tests.

  • css/CSSSelector.cpp: (WebCore::CSSSelector::pseudoId): Removed FILE_UPLOAD_BUTTON pseudoId and all references to it. (WebCore::nameToPseudoTypeMap): Ditto. (WebCore::CSSSelector::extractPseudoType): Ditto.
  • css/CSSSelector.h: Ditto.
  • css/html.css: (input[type="button"], input[type="submit"], input[type="reset"]): Moved -webkit-file-upload-button to its own rule. (input[type="file"]::-webkit-file-upload-button): Added and moved all previously hard-coded properties there.
  • html/FileInputType.cpp: (WebCore::UploadButtonElement::create): Added. (WebCore::UploadButtonElement::UploadButtonElement): Added. (WebCore::UploadButtonElement::shadowPseudoId): Added. (WebCore::FileInputType::createShadowSubtree): Added.
  • html/FileInputType.h: Added createShadowSubtree decl.
  • page/DragController.cpp: (WebCore::asFileInput): Changed the logic to use new shadow DOM.
  • rendering/RenderFileUploadControl.cpp: Removed UploadButton class. (WebCore::RenderFileUploadControl::~RenderFileUploadControl): Removed initializer for m_button. (WebCore::RenderFileUploadControl::updateFromElement): Removed attachment logic that's no longer necessary. (WebCore::nodeWidth): Added a helper. (WebCore::RenderFileUploadControl::maxFilenameWidth): Changed to use uploadButton and nodeWidth. (WebCore::RenderFileUploadControl::paintObject): Ditto. (WebCore::RenderFileUploadControl::uploadButton): Added a helper to retrieve the button. (WebCore::RenderFileUploadControl::buttonValue): Changed to use uploadButton.
  • rendering/RenderFileUploadControl.h: Changed decls.
  • rendering/style/RenderStyleConstants.h: Removed FILE_UPLOAD_BUTTON decls.
Location:
trunk/Source/WebCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r88110 r88115  
     12011-06-03  Dimitri Glazkov  <dglazkov@chromium.org>
     2
     3        Reviewed by Darin Adler.
     4
     5        Convert file <input> to use the new shadow DOM model
     6        https://bugs.webkit.org/show_bug.cgi?id=59005
     7
     8        Refactoring, covered by existing tests.
     9
     10        * css/CSSSelector.cpp:
     11        (WebCore::CSSSelector::pseudoId): Removed FILE_UPLOAD_BUTTON pseudoId and all references to it.
     12        (WebCore::nameToPseudoTypeMap): Ditto.
     13        (WebCore::CSSSelector::extractPseudoType): Ditto.
     14        * css/CSSSelector.h: Ditto.
     15        * css/html.css:
     16        (input[type="button"], input[type="submit"], input[type="reset"]): Moved -webkit-file-upload-button to its own rule.
     17        (input[type="file"]::-webkit-file-upload-button): Added and moved all previously hard-coded properties there.
     18        * html/FileInputType.cpp:
     19        (WebCore::UploadButtonElement::create): Added.
     20        (WebCore::UploadButtonElement::UploadButtonElement): Added.
     21        (WebCore::UploadButtonElement::shadowPseudoId): Added.
     22        (WebCore::FileInputType::createShadowSubtree): Added.
     23        * html/FileInputType.h: Added createShadowSubtree decl.
     24        * page/DragController.cpp:
     25        (WebCore::asFileInput): Changed the logic to use new shadow DOM.
     26        * rendering/RenderFileUploadControl.cpp: Removed UploadButton class.
     27        (WebCore::RenderFileUploadControl::~RenderFileUploadControl): Removed initializer for m_button.
     28        (WebCore::RenderFileUploadControl::updateFromElement): Removed attachment logic that's no longer necessary.
     29        (WebCore::nodeWidth): Added a helper.
     30        (WebCore::RenderFileUploadControl::maxFilenameWidth): Changed to use uploadButton and nodeWidth.
     31        (WebCore::RenderFileUploadControl::paintObject): Ditto.
     32        (WebCore::RenderFileUploadControl::uploadButton): Added a helper to retrieve the button.
     33        (WebCore::RenderFileUploadControl::buttonValue): Changed to use uploadButton.
     34        * rendering/RenderFileUploadControl.h: Changed decls.
     35        * rendering/style/RenderStyleConstants.h: Removed FILE_UPLOAD_BUTTON decls.
     36
    1372011-06-04  Alexey Proskuryakov  <ap@apple.com>
    238
  • trunk/Source/WebCore/css/CSSSelector.cpp

    r87660 r88115  
    127127    case PseudoAfter:
    128128        return AFTER;
    129     case PseudoFileUploadButton:
    130         return FILE_UPLOAD_BUTTON;
    131129    case PseudoInputPlaceholder:
    132130        return INPUT_PLACEHOLDER;
     
    234232    DEFINE_STATIC_LOCAL(AtomicString, before, ("before"));
    235233    DEFINE_STATIC_LOCAL(AtomicString, checked, ("checked"));
    236     DEFINE_STATIC_LOCAL(AtomicString, fileUploadButton, ("-webkit-file-upload-button"));
    237234    DEFINE_STATIC_LOCAL(AtomicString, defaultString, ("default"));
    238235    DEFINE_STATIC_LOCAL(AtomicString, disabled, ("disabled"));
     
    315312        nameToPseudoType->set(before.impl(), CSSSelector::PseudoBefore);
    316313        nameToPseudoType->set(checked.impl(), CSSSelector::PseudoChecked);
    317         nameToPseudoType->set(fileUploadButton.impl(), CSSSelector::PseudoFileUploadButton);
    318314        nameToPseudoType->set(defaultString.impl(), CSSSelector::PseudoDefault);
    319315        nameToPseudoType->set(disabled.impl(), CSSSelector::PseudoDisabled);
     
    414410    case PseudoFirstLine:
    415411        compat = true;
    416     case PseudoFileUploadButton:
    417412    case PseudoInputListButton:
    418413    case PseudoInputPlaceholder:
  • trunk/Source/WebCore/css/CSSSelector.h

    r87660 r88115  
    173173            PseudoNoButton,
    174174            PseudoSelection,
    175             PseudoFileUploadButton,
    176175            PseudoInputListButton,
    177176            PseudoLeftPage,
  • trunk/Source/WebCore/css/html.css

    r87881 r88115  
    518518}
    519519
    520 input[type="button"], input[type="submit"], input[type="reset"], input[type="file"]::-webkit-file-upload-button {
     520input[type="button"], input[type="submit"], input[type="reset"] {
    521521    -webkit-appearance: push-button;
    522522    white-space: pre
     523}
     524
     525input[type="file"]::-webkit-file-upload-button {
     526    -webkit-appearance: push-button;
     527    white-space: nowrap;
     528    margin: 0;
    523529}
    524530
  • trunk/Source/WebCore/html/FileInputType.cpp

    r87095 r88115  
    3232#include "LocalizedStrings.h"
    3333#include "RenderFileUploadControl.h"
     34#include "ShadowRoot.h"
    3435#include <wtf/PassOwnPtr.h>
    3536#include <wtf/text/WTFString.h>
     
    3839
    3940using namespace HTMLNames;
     41
     42class UploadButtonElement : public HTMLInputElement {
     43public:
     44    static PassRefPtr<UploadButtonElement> create(Document*);
     45
     46private:
     47    UploadButtonElement(Document*);
     48
     49    virtual const AtomicString& shadowPseudoId() const;
     50};
     51
     52PassRefPtr<UploadButtonElement> UploadButtonElement::create(Document* document)
     53{
     54    RefPtr<UploadButtonElement> button = adoptRef(new UploadButtonElement(document));
     55    button->setType("button");
     56    button->setValue(fileButtonChooseFileLabel());
     57    return button.release();
     58}
     59
     60
     61UploadButtonElement::UploadButtonElement(Document* document)
     62    : HTMLInputElement(inputTag, document, 0, false)
     63{
     64}
     65
     66const AtomicString& UploadButtonElement::shadowPseudoId() const
     67{
     68    DEFINE_STATIC_LOCAL(AtomicString, pseudoId, ("-webkit-file-upload-button"));
     69    return pseudoId;
     70}
    4071
    4172inline FileInputType::FileInputType(HTMLInputElement* element)
     
    194225}
    195226
     227void FileInputType::createShadowSubtree()
     228{
     229    ExceptionCode ec = 0;
     230    element()->ensureShadowRoot()->appendChild(UploadButtonElement::create(element()->document()), ec);
     231}
     232
    196233} // namespace WebCore
  • trunk/Source/WebCore/html/FileInputType.h

    r74895 r88115  
    6060    virtual void setFileList(const Vector<String>& paths);
    6161    virtual bool isFileUpload() const;
     62    virtual void createShadowSubtree();
    6263
    6364    RefPtr<FileList> m_fileList;
  • trunk/Source/WebCore/page/DragController.cpp

    r87878 r88115  
    254254    ASSERT(node);
    255255
    256     // The button for a FILE input is a sub element with no set input type
    257     // In order to get around this problem we assume any non-FILE input element
    258     // is this internal button, and try querying the shadow parent node.
    259     if (node->hasTagName(HTMLNames::inputTag) && node->isShadowRoot() && !static_cast<HTMLInputElement*>(node)->isFileUpload())
    260         node = node->shadowHost();
    261 
    262     if (!node || !node->hasTagName(HTMLNames::inputTag))
    263         return 0;
    264 
    265     HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(node);
    266     if (!inputElement->isFileUpload())
    267         return 0;
    268 
    269     return inputElement;
     256    HTMLInputElement* inputElement = node->toInputElement();
     257
     258    // If this is a button inside of the a file input, move up to the file input.
     259    if (inputElement && inputElement->isTextButton() && inputElement->treeScope()->isShadowBoundary())
     260        inputElement = inputElement->treeScope()->shadowHost()->toInputElement();
     261
     262    return inputElement && inputElement->isFileUpload() ? inputElement : 0;
    270263}
    271264
  • trunk/Source/WebCore/rendering/RenderFileUploadControl.cpp

    r88087 r88115  
    3737#include "RenderTheme.h"
    3838#include "RenderView.h"
     39#include "ShadowRoot.h"
    3940#include "TextRun.h"
    4041#include <math.h>
     
    5354const int buttonShadowHeight = 2;
    5455
    55 class UploadButton : public HTMLInputElement {
    56 public:
    57     static PassRefPtr<UploadButton> create(HTMLInputElement*);
    58     virtual void detach();
    59 
    60 private:
    61     UploadButton(HTMLInputElement*);
    62 };
    63 
    64 PassRefPtr<UploadButton> UploadButton::create(HTMLInputElement* shadowParent)
    65 {
    66     return adoptRef(new UploadButton(shadowParent));
    67 }
    68 
    69 void UploadButton::detach()
    70 {
    71     HTMLInputElement::detach();
    72     setShadowHost(0);
    73 }
    74 
    75 UploadButton::UploadButton(HTMLInputElement* shadowParent)
    76     : HTMLInputElement(inputTag, shadowParent->document(), 0, false)
    77 {
    78     setShadowHost(shadowParent);
    79 }
    80 
    8156RenderFileUploadControl::RenderFileUploadControl(HTMLInputElement* input)
    8257    : RenderBlock(input)
     
    9267RenderFileUploadControl::~RenderFileUploadControl()
    9368{
    94     if (m_button)
    95         m_button->detach();
    9669    m_fileChooser->disconnectClient();
    97 }
    98 
    99 void RenderFileUploadControl::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
    100 {
    101     RenderBlock::styleDidChange(diff, oldStyle);
    102     if (m_button)
    103         m_button->renderer()->setStyle(createButtonStyle(style()));
    10470}
    10571
     
    178144    HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(node());
    179145    ASSERT(inputElement->isFileUpload());
    180    
    181     if (!m_button) {
    182         m_button = UploadButton::create(inputElement);
    183         m_button->setType("button");
    184         m_button->setValue(fileButtonChooseFileLabel());
    185         RefPtr<RenderStyle> buttonStyle = createButtonStyle(style());
    186         RenderObject* renderer = m_button->createRenderer(renderArena(), buttonStyle.get());
    187         m_button->setRenderer(renderer);
    188         renderer->setStyle(buttonStyle.release());
    189         renderer->updateFromElement();
    190         m_button->setAttached();
    191         m_button->setInDocument();
    192 
    193         addChild(renderer);
    194     }
    195 
    196     m_button->setDisabled(!theme()->isEnabled(this));
     146
     147
     148    if (HTMLInputElement* button = uploadButton())
     149        button->setDisabled(!theme()->isEnabled(this));
    197150
    198151    // This only supports clearing out the files, but that's OK because for
     
    206159}
    207160
     161static int nodeWidth(Node* node)
     162{
     163    return node ? node->renderBox()->width() : 0;
     164}
     165
    208166int RenderFileUploadControl::maxFilenameWidth() const
    209167{
    210     return max(0, contentWidth() - m_button->renderBox()->width() - afterButtonSpacing
     168    return max(0, contentWidth() - nodeWidth(uploadButton()) - afterButtonSpacing
    211169        - (m_fileChooser->icon() ? iconWidth + iconFilenameSpacing : 0));
    212 }
    213 
    214 PassRefPtr<RenderStyle> RenderFileUploadControl::createButtonStyle(const RenderStyle* parentStyle) const
    215 {
    216     RefPtr<RenderStyle> style = getCachedPseudoStyle(FILE_UPLOAD_BUTTON);
    217     if (!style) {
    218         style = RenderStyle::create();
    219         if (parentStyle)
    220             style->inheritFrom(parentStyle);
    221     }
    222 
    223     // Button text will wrap on file upload controls with widths smaller than the intrinsic button width
    224     // without this setWhiteSpace.
    225     style->setWhiteSpace(NOWRAP);
    226 
    227     return style.release();
    228170}
    229171
     
    252194        // Determine where the filename should be placed
    253195        int contentLeft = paintOffset.x() + borderLeft() + paddingLeft();
    254         int buttonAndIconWidth = m_button->renderBox()->width() + afterButtonSpacing
     196        HTMLInputElement* button = uploadButton();
     197        if (!button)
     198            return;
     199
     200        int buttonWidth = nodeWidth(button);
     201        int buttonAndIconWidth = buttonWidth + afterButtonSpacing
    255202            + (m_fileChooser->icon() ? iconWidth + iconFilenameSpacing : 0);
    256203        int textX;
     
    260207            textX = contentLeft + contentWidth() - buttonAndIconWidth - font.width(textRun);
    261208        // We want to match the button's baseline
    262         RenderButton* buttonRenderer = toRenderButton(m_button->renderer());
     209        RenderButton* buttonRenderer = toRenderButton(button->renderer());
    263210        int textY = buttonRenderer->absoluteBoundingBoxRect().y()
    264211            + buttonRenderer->marginTop() + buttonRenderer->borderTop() + buttonRenderer->paddingTop()
     
    275222            int iconX;
    276223            if (style()->isLeftToRightDirection())
    277                 iconX = contentLeft + m_button->renderBox()->width() + afterButtonSpacing;
     224                iconX = contentLeft + buttonWidth + afterButtonSpacing;
    278225            else
    279                 iconX = contentLeft + contentWidth() - m_button->renderBox()->width() - afterButtonSpacing - iconWidth;
     226                iconX = contentLeft + contentWidth() - buttonWidth - afterButtonSpacing - iconWidth;
    280227
    281228            // Draw the file icon
     
    334281}
    335282
     283HTMLInputElement* RenderFileUploadControl::uploadButton() const
     284{
     285    HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
     286
     287    ASSERT(input->shadowRoot());
     288
     289    Node* buttonNode = input->shadowRoot()->firstChild();
     290    return buttonNode && buttonNode->isHTMLElement() && buttonNode->hasTagName(inputTag) ? static_cast<HTMLInputElement*>(buttonNode) : 0;
     291}
     292
    336293void RenderFileUploadControl::receiveDroppedFiles(const Vector<String>& paths)
    337294{
     
    351308String RenderFileUploadControl::buttonValue()
    352309{
    353     if (!m_button)
    354         return String();
     310    if (HTMLInputElement* button = uploadButton())
     311        return button->value();
    355312   
    356     return m_button->value();
     313    return String();
    357314}
    358315
  • trunk/Source/WebCore/rendering/RenderFileUploadControl.h

    r88087 r88115  
    5555    virtual void paintObject(PaintInfo&, const IntPoint&);
    5656
    57     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
    58 
    5957    virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
    6058
     
    7674    virtual VisiblePosition positionForPoint(const IntPoint&);
    7775
    78     RefPtr<HTMLInputElement> m_button;
     76    HTMLInputElement* uploadButton() const;
     77
    7978    RefPtr<FileChooser> m_fileChooser;
    8079};
  • trunk/Source/WebCore/rendering/style/RenderStyleConstants.h

    r87660 r88115  
    7575    NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION, FIRST_LINE_INHERITED, SCROLLBAR,
    7676    // Internal IDs follow:
    77     FILE_UPLOAD_BUTTON, INPUT_PLACEHOLDER,
     77    INPUT_PLACEHOLDER,
    7878    SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER,
    7979    INPUT_LIST_BUTTON, VISITED_LINK,
     
    8181    FULL_SCREEN, FULL_SCREEN_DOCUMENT, FULL_SCREEN_ANCESTOR, ANIMATING_FULL_SCREEN_TRANSITION,
    8282    FIRST_PUBLIC_PSEUDOID = FIRST_LINE,
    83     FIRST_INTERNAL_PSEUDOID = FILE_UPLOAD_BUTTON,
     83    FIRST_INTERNAL_PSEUDOID = INPUT_PLACEHOLDER,
    8484    PUBLIC_PSEUDOID_MASK = ((1 << FIRST_INTERNAL_PSEUDOID) - 1) & ~((1 << FIRST_PUBLIC_PSEUDOID) - 1)
    8585};
Note: See TracChangeset for help on using the changeset viewer.