Diff
Modified: trunk/Source/WebCore/ChangeLog (88114 => 88115)
--- trunk/Source/WebCore/ChangeLog 2011-06-04 16:15:16 UTC (rev 88114)
+++ trunk/Source/WebCore/ChangeLog 2011-06-04 17:14:22 UTC (rev 88115)
@@ -1,3 +1,39 @@
+2011-06-03 Dimitri Glazkov <[email protected]>
+
+ 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.
+
2011-06-04 Alexey Proskuryakov <[email protected]>
Reviewed by Darin Adler.
Modified: trunk/Source/WebCore/css/CSSSelector.cpp (88114 => 88115)
--- trunk/Source/WebCore/css/CSSSelector.cpp 2011-06-04 16:15:16 UTC (rev 88114)
+++ trunk/Source/WebCore/css/CSSSelector.cpp 2011-06-04 17:14:22 UTC (rev 88115)
@@ -126,8 +126,6 @@
return BEFORE;
case PseudoAfter:
return AFTER;
- case PseudoFileUploadButton:
- return FILE_UPLOAD_BUTTON;
case PseudoInputPlaceholder:
return INPUT_PLACEHOLDER;
case PseudoScrollbar:
@@ -233,7 +231,6 @@
DEFINE_STATIC_LOCAL(AtomicString, autofill, ("-webkit-autofill"));
DEFINE_STATIC_LOCAL(AtomicString, before, ("before"));
DEFINE_STATIC_LOCAL(AtomicString, checked, ("checked"));
- DEFINE_STATIC_LOCAL(AtomicString, fileUploadButton, ("-webkit-file-upload-button"));
DEFINE_STATIC_LOCAL(AtomicString, defaultString, ("default"));
DEFINE_STATIC_LOCAL(AtomicString, disabled, ("disabled"));
DEFINE_STATIC_LOCAL(AtomicString, readOnly, ("read-only"));
@@ -314,7 +311,6 @@
nameToPseudoType->set(autofill.impl(), CSSSelector::PseudoAutofill);
nameToPseudoType->set(before.impl(), CSSSelector::PseudoBefore);
nameToPseudoType->set(checked.impl(), CSSSelector::PseudoChecked);
- nameToPseudoType->set(fileUploadButton.impl(), CSSSelector::PseudoFileUploadButton);
nameToPseudoType->set(defaultString.impl(), CSSSelector::PseudoDefault);
nameToPseudoType->set(disabled.impl(), CSSSelector::PseudoDisabled);
nameToPseudoType->set(readOnly.impl(), CSSSelector::PseudoReadOnly);
@@ -413,7 +409,6 @@
case PseudoFirstLetter:
case PseudoFirstLine:
compat = true;
- case PseudoFileUploadButton:
case PseudoInputListButton:
case PseudoInputPlaceholder:
case PseudoResizer:
Modified: trunk/Source/WebCore/css/CSSSelector.h (88114 => 88115)
--- trunk/Source/WebCore/css/CSSSelector.h 2011-06-04 16:15:16 UTC (rev 88114)
+++ trunk/Source/WebCore/css/CSSSelector.h 2011-06-04 17:14:22 UTC (rev 88115)
@@ -172,7 +172,6 @@
PseudoSingleButton,
PseudoNoButton,
PseudoSelection,
- PseudoFileUploadButton,
PseudoInputListButton,
PseudoLeftPage,
PseudoRightPage,
Modified: trunk/Source/WebCore/css/html.css (88114 => 88115)
--- trunk/Source/WebCore/css/html.css 2011-06-04 16:15:16 UTC (rev 88114)
+++ trunk/Source/WebCore/css/html.css 2011-06-04 17:14:22 UTC (rev 88115)
@@ -517,11 +517,17 @@
border: initial;
}
-input[type="button"], input[type="submit"], input[type="reset"], input[type="file"]::-webkit-file-upload-button {
+input[type="button"], input[type="submit"], input[type="reset"] {
-webkit-appearance: push-button;
white-space: pre
}
+input[type="file"]::-webkit-file-upload-button {
+ -webkit-appearance: push-button;
+ white-space: nowrap;
+ margin: 0;
+}
+
input[type="button"], input[type="submit"], input[type="reset"], input[type="file"]::-webkit-file-upload-button, button {
-webkit-box-align: center;
text-align: center;
Modified: trunk/Source/WebCore/html/FileInputType.cpp (88114 => 88115)
--- trunk/Source/WebCore/html/FileInputType.cpp 2011-06-04 16:15:16 UTC (rev 88114)
+++ trunk/Source/WebCore/html/FileInputType.cpp 2011-06-04 17:14:22 UTC (rev 88115)
@@ -31,6 +31,7 @@
#include "HTMLNames.h"
#include "LocalizedStrings.h"
#include "RenderFileUploadControl.h"
+#include "ShadowRoot.h"
#include <wtf/PassOwnPtr.h>
#include <wtf/text/WTFString.h>
@@ -38,6 +39,36 @@
using namespace HTMLNames;
+class UploadButtonElement : public HTMLInputElement {
+public:
+ static PassRefPtr<UploadButtonElement> create(Document*);
+
+private:
+ UploadButtonElement(Document*);
+
+ virtual const AtomicString& shadowPseudoId() const;
+};
+
+PassRefPtr<UploadButtonElement> UploadButtonElement::create(Document* document)
+{
+ RefPtr<UploadButtonElement> button = adoptRef(new UploadButtonElement(document));
+ button->setType("button");
+ button->setValue(fileButtonChooseFileLabel());
+ return button.release();
+}
+
+
+UploadButtonElement::UploadButtonElement(Document* document)
+ : HTMLInputElement(inputTag, document, 0, false)
+{
+}
+
+const AtomicString& UploadButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, pseudoId, ("-webkit-file-upload-button"));
+ return pseudoId;
+}
+
inline FileInputType::FileInputType(HTMLInputElement* element)
: BaseButtonInputType(element)
, m_fileList(FileList::create())
@@ -193,4 +224,10 @@
return true;
}
+void FileInputType::createShadowSubtree()
+{
+ ExceptionCode ec = 0;
+ element()->ensureShadowRoot()->appendChild(UploadButtonElement::create(element()->document()), ec);
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/html/FileInputType.h (88114 => 88115)
--- trunk/Source/WebCore/html/FileInputType.h 2011-06-04 16:15:16 UTC (rev 88114)
+++ trunk/Source/WebCore/html/FileInputType.h 2011-06-04 17:14:22 UTC (rev 88115)
@@ -59,6 +59,7 @@
virtual bool storesValueSeparateFromAttribute();
virtual void setFileList(const Vector<String>& paths);
virtual bool isFileUpload() const;
+ virtual void createShadowSubtree();
RefPtr<FileList> m_fileList;
};
Modified: trunk/Source/WebCore/page/DragController.cpp (88114 => 88115)
--- trunk/Source/WebCore/page/DragController.cpp 2011-06-04 16:15:16 UTC (rev 88114)
+++ trunk/Source/WebCore/page/DragController.cpp 2011-06-04 17:14:22 UTC (rev 88115)
@@ -253,20 +253,13 @@
{
ASSERT(node);
- // The button for a FILE input is a sub element with no set input type
- // In order to get around this problem we assume any non-FILE input element
- // is this internal button, and try querying the shadow parent node.
- if (node->hasTagName(HTMLNames::inputTag) && node->isShadowRoot() && !static_cast<HTMLInputElement*>(node)->isFileUpload())
- node = node->shadowHost();
+ HTMLInputElement* inputElement = node->toInputElement();
- if (!node || !node->hasTagName(HTMLNames::inputTag))
- return 0;
+ // If this is a button inside of the a file input, move up to the file input.
+ if (inputElement && inputElement->isTextButton() && inputElement->treeScope()->isShadowBoundary())
+ inputElement = inputElement->treeScope()->shadowHost()->toInputElement();
- HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(node);
- if (!inputElement->isFileUpload())
- return 0;
-
- return inputElement;
+ return inputElement && inputElement->isFileUpload() ? inputElement : 0;
}
// This can return null if an empty document is loaded.
Modified: trunk/Source/WebCore/rendering/RenderFileUploadControl.cpp (88114 => 88115)
--- trunk/Source/WebCore/rendering/RenderFileUploadControl.cpp 2011-06-04 16:15:16 UTC (rev 88114)
+++ trunk/Source/WebCore/rendering/RenderFileUploadControl.cpp 2011-06-04 17:14:22 UTC (rev 88115)
@@ -36,6 +36,7 @@
#include "RenderText.h"
#include "RenderTheme.h"
#include "RenderView.h"
+#include "ShadowRoot.h"
#include "TextRun.h"
#include <math.h>
@@ -52,32 +53,6 @@
const int defaultWidthNumChars = 34;
const int buttonShadowHeight = 2;
-class UploadButton : public HTMLInputElement {
-public:
- static PassRefPtr<UploadButton> create(HTMLInputElement*);
- virtual void detach();
-
-private:
- UploadButton(HTMLInputElement*);
-};
-
-PassRefPtr<UploadButton> UploadButton::create(HTMLInputElement* shadowParent)
-{
- return adoptRef(new UploadButton(shadowParent));
-}
-
-void UploadButton::detach()
-{
- HTMLInputElement::detach();
- setShadowHost(0);
-}
-
-UploadButton::UploadButton(HTMLInputElement* shadowParent)
- : HTMLInputElement(inputTag, shadowParent->document(), 0, false)
-{
- setShadowHost(shadowParent);
-}
-
RenderFileUploadControl::RenderFileUploadControl(HTMLInputElement* input)
: RenderBlock(input)
{
@@ -91,18 +66,9 @@
RenderFileUploadControl::~RenderFileUploadControl()
{
- if (m_button)
- m_button->detach();
m_fileChooser->disconnectClient();
}
-void RenderFileUploadControl::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
-{
- RenderBlock::styleDidChange(diff, oldStyle);
- if (m_button)
- m_button->renderer()->setStyle(createButtonStyle(style()));
-}
-
void RenderFileUploadControl::valueChanged()
{
// dispatchFormControlChangeEvent may destroy this renderer
@@ -177,23 +143,10 @@
{
HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(node());
ASSERT(inputElement->isFileUpload());
-
- if (!m_button) {
- m_button = UploadButton::create(inputElement);
- m_button->setType("button");
- m_button->setValue(fileButtonChooseFileLabel());
- RefPtr<RenderStyle> buttonStyle = createButtonStyle(style());
- RenderObject* renderer = m_button->createRenderer(renderArena(), buttonStyle.get());
- m_button->setRenderer(renderer);
- renderer->setStyle(buttonStyle.release());
- renderer->updateFromElement();
- m_button->setAttached();
- m_button->setInDocument();
- addChild(renderer);
- }
- m_button->setDisabled(!theme()->isEnabled(this));
+ if (HTMLInputElement* button = uploadButton())
+ button->setDisabled(!theme()->isEnabled(this));
// This only supports clearing out the files, but that's OK because for
// security reasons that's the only change the DOM is allowed to make.
@@ -205,26 +158,15 @@
}
}
-int RenderFileUploadControl::maxFilenameWidth() const
+static int nodeWidth(Node* node)
{
- return max(0, contentWidth() - m_button->renderBox()->width() - afterButtonSpacing
- - (m_fileChooser->icon() ? iconWidth + iconFilenameSpacing : 0));
+ return node ? node->renderBox()->width() : 0;
}
-PassRefPtr<RenderStyle> RenderFileUploadControl::createButtonStyle(const RenderStyle* parentStyle) const
+int RenderFileUploadControl::maxFilenameWidth() const
{
- RefPtr<RenderStyle> style = getCachedPseudoStyle(FILE_UPLOAD_BUTTON);
- if (!style) {
- style = RenderStyle::create();
- if (parentStyle)
- style->inheritFrom(parentStyle);
- }
-
- // Button text will wrap on file upload controls with widths smaller than the intrinsic button width
- // without this setWhiteSpace.
- style->setWhiteSpace(NOWRAP);
-
- return style.release();
+ return max(0, contentWidth() - nodeWidth(uploadButton()) - afterButtonSpacing
+ - (m_fileChooser->icon() ? iconWidth + iconFilenameSpacing : 0));
}
void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, const IntPoint& paintOffset)
@@ -251,7 +193,12 @@
// Determine where the filename should be placed
int contentLeft = paintOffset.x() + borderLeft() + paddingLeft();
- int buttonAndIconWidth = m_button->renderBox()->width() + afterButtonSpacing
+ HTMLInputElement* button = uploadButton();
+ if (!button)
+ return;
+
+ int buttonWidth = nodeWidth(button);
+ int buttonAndIconWidth = buttonWidth + afterButtonSpacing
+ (m_fileChooser->icon() ? iconWidth + iconFilenameSpacing : 0);
int textX;
if (style()->isLeftToRightDirection())
@@ -259,7 +206,7 @@
else
textX = contentLeft + contentWidth() - buttonAndIconWidth - font.width(textRun);
// We want to match the button's baseline
- RenderButton* buttonRenderer = toRenderButton(m_button->renderer());
+ RenderButton* buttonRenderer = toRenderButton(button->renderer());
int textY = buttonRenderer->absoluteBoundingBoxRect().y()
+ buttonRenderer->marginTop() + buttonRenderer->borderTop() + buttonRenderer->paddingTop()
+ buttonRenderer->baselinePosition(AlphabeticBaseline, true, HorizontalLine, PositionOnContainingLine);
@@ -274,9 +221,9 @@
int iconY = paintOffset.y() + borderTop() + paddingTop() + (contentHeight() - iconHeight) / 2;
int iconX;
if (style()->isLeftToRightDirection())
- iconX = contentLeft + m_button->renderBox()->width() + afterButtonSpacing;
+ iconX = contentLeft + buttonWidth + afterButtonSpacing;
else
- iconX = contentLeft + contentWidth() - m_button->renderBox()->width() - afterButtonSpacing - iconWidth;
+ iconX = contentLeft + contentWidth() - buttonWidth - afterButtonSpacing - iconWidth;
// Draw the file icon
m_fileChooser->icon()->paint(paintInfo.context, IntRect(iconX, iconY, iconWidth, iconHeight));
@@ -333,6 +280,16 @@
return VisiblePosition();
}
+HTMLInputElement* RenderFileUploadControl::uploadButton() const
+{
+ HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
+
+ ASSERT(input->shadowRoot());
+
+ Node* buttonNode = input->shadowRoot()->firstChild();
+ return buttonNode && buttonNode->isHTMLElement() && buttonNode->hasTagName(inputTag) ? static_cast<HTMLInputElement*>(buttonNode) : 0;
+}
+
void RenderFileUploadControl::receiveDroppedFiles(const Vector<String>& paths)
{
#if ENABLE(DIRECTORY_UPLOAD)
@@ -350,10 +307,10 @@
String RenderFileUploadControl::buttonValue()
{
- if (!m_button)
- return String();
+ if (HTMLInputElement* button = uploadButton())
+ return button->value();
- return m_button->value();
+ return String();
}
String RenderFileUploadControl::fileTextValue() const
Modified: trunk/Source/WebCore/rendering/RenderFileUploadControl.h (88114 => 88115)
--- trunk/Source/WebCore/rendering/RenderFileUploadControl.h 2011-06-04 16:15:16 UTC (rev 88114)
+++ trunk/Source/WebCore/rendering/RenderFileUploadControl.h 2011-06-04 17:14:22 UTC (rev 88115)
@@ -54,8 +54,6 @@
virtual void computePreferredLogicalWidths();
virtual void paintObject(PaintInfo&, const IntPoint&);
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
-
virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
// FileChooserClient methods.
@@ -75,7 +73,8 @@
virtual VisiblePosition positionForPoint(const IntPoint&);
- RefPtr<HTMLInputElement> m_button;
+ HTMLInputElement* uploadButton() const;
+
RefPtr<FileChooser> m_fileChooser;
};
Modified: trunk/Source/WebCore/rendering/style/RenderStyleConstants.h (88114 => 88115)
--- trunk/Source/WebCore/rendering/style/RenderStyleConstants.h 2011-06-04 16:15:16 UTC (rev 88114)
+++ trunk/Source/WebCore/rendering/style/RenderStyleConstants.h 2011-06-04 17:14:22 UTC (rev 88115)
@@ -74,13 +74,13 @@
// The order must be NOP ID, public IDs, and then internal IDs.
NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION, FIRST_LINE_INHERITED, SCROLLBAR,
// Internal IDs follow:
- FILE_UPLOAD_BUTTON, INPUT_PLACEHOLDER,
+ INPUT_PLACEHOLDER,
SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER,
INPUT_LIST_BUTTON, VISITED_LINK,
AFTER_LAST_INTERNAL_PSEUDOID,
FULL_SCREEN, FULL_SCREEN_DOCUMENT, FULL_SCREEN_ANCESTOR, ANIMATING_FULL_SCREEN_TRANSITION,
FIRST_PUBLIC_PSEUDOID = FIRST_LINE,
- FIRST_INTERNAL_PSEUDOID = FILE_UPLOAD_BUTTON,
+ FIRST_INTERNAL_PSEUDOID = INPUT_PLACEHOLDER,
PUBLIC_PSEUDOID_MASK = ((1 << FIRST_INTERNAL_PSEUDOID) - 1) & ~((1 << FIRST_PUBLIC_PSEUDOID) - 1)
};