Rename rendering/RenderFileUploadControl to layout/LayoutFileUploadControl.
[chromium-blink-merge.git] / third_party / WebKit / Source / core / layout / LayoutFileUploadControl.cpp
blob6aca9cca3a6000a2b34cd1341ae26a1d6f1a3db7
1 /*
2 * Copyright (C) 2006, 2007, 2012 Apple Inc. All rights reserved.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
21 #include "config.h"
22 #include "core/layout/LayoutFileUploadControl.h"
24 #include "core/HTMLNames.h"
25 #include "core/InputTypeNames.h"
26 #include "core/dom/shadow/ElementShadow.h"
27 #include "core/dom/shadow/ShadowRoot.h"
28 #include "core/editing/PositionWithAffinity.h"
29 #include "core/fileapi/FileList.h"
30 #include "core/html/HTMLInputElement.h"
31 #include "core/layout/LayoutTheme.h"
32 #include "core/layout/PaintInfo.h"
33 #include "core/layout/TextRunConstructor.h"
34 #include "core/paint/FileUploadControlPainter.h"
35 #include "core/rendering/RenderButton.h"
36 #include "platform/fonts/Font.h"
37 #include "platform/graphics/GraphicsContextStateSaver.h"
38 #include "platform/text/PlatformLocale.h"
39 #include "platform/text/TextRun.h"
40 #include <math.h>
42 namespace blink {
44 using namespace HTMLNames;
46 const int defaultWidthNumChars = 34;
48 LayoutFileUploadControl::LayoutFileUploadControl(HTMLInputElement* input)
49 : RenderBlockFlow(input)
50 , m_canReceiveDroppedFiles(input->canReceiveDroppedFiles())
54 LayoutFileUploadControl::~LayoutFileUploadControl()
58 void LayoutFileUploadControl::updateFromElement()
60 HTMLInputElement* input = toHTMLInputElement(node());
61 ASSERT(input->type() == InputTypeNames::file);
63 if (HTMLInputElement* button = uploadButton()) {
64 bool newCanReceiveDroppedFilesState = input->canReceiveDroppedFiles();
65 if (m_canReceiveDroppedFiles != newCanReceiveDroppedFilesState) {
66 m_canReceiveDroppedFiles = newCanReceiveDroppedFilesState;
67 button->setActive(newCanReceiveDroppedFilesState);
71 // This only supports clearing out the files, but that's OK because for
72 // security reasons that's the only change the DOM is allowed to make.
73 FileList* files = input->files();
74 ASSERT(files);
75 if (files && files->isEmpty())
76 setShouldDoFullPaintInvalidation();
79 int LayoutFileUploadControl::maxFilenameWidth() const
81 int uploadButtonWidth = (uploadButton() && uploadButton()->layoutBox()) ? uploadButton()->layoutBox()->pixelSnappedWidth() : 0;
82 return std::max(0, contentBoxRect().pixelSnappedWidth() - uploadButtonWidth - afterButtonSpacing);
85 void LayoutFileUploadControl::paintObject(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
87 FileUploadControlPainter(*this).paintObject(paintInfo, paintOffset);
90 void LayoutFileUploadControl::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
92 // Figure out how big the filename space needs to be for a given number of characters
93 // (using "0" as the nominal character).
94 const UChar character = '0';
95 const String characterAsString = String(&character, 1);
96 const Font& font = style()->font();
97 // FIXME: Remove the need for this const_cast by making constructTextRun take a const LayoutObject*.
98 LayoutFileUploadControl* renderer = const_cast<LayoutFileUploadControl*>(this);
99 float minDefaultLabelWidth = defaultWidthNumChars * font.width(constructTextRun(renderer, font, characterAsString, styleRef(), TextRun::AllowTrailingExpansion));
101 const String label = toHTMLInputElement(node())->locale().queryString(WebLocalizedString::FileButtonNoFileSelectedLabel);
102 float defaultLabelWidth = font.width(constructTextRun(renderer, font, label, styleRef(), TextRun::AllowTrailingExpansion));
103 if (HTMLInputElement* button = uploadButton()) {
104 if (LayoutObject* buttonRenderer = button->renderer())
105 defaultLabelWidth += buttonRenderer->maxPreferredLogicalWidth() + afterButtonSpacing;
107 maxLogicalWidth = static_cast<int>(ceilf(std::max(minDefaultLabelWidth, defaultLabelWidth)));
109 if (!style()->width().isPercent())
110 minLogicalWidth = maxLogicalWidth;
113 void LayoutFileUploadControl::computePreferredLogicalWidths()
115 ASSERT(preferredLogicalWidthsDirty());
117 m_minPreferredLogicalWidth = 0;
118 m_maxPreferredLogicalWidth = 0;
119 const LayoutStyle& styleToUse = styleRef();
121 if (styleToUse.width().isFixed() && styleToUse.width().value() > 0)
122 m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(styleToUse.width().value());
123 else
124 computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
126 if (styleToUse.minWidth().isFixed() && styleToUse.minWidth().value() > 0) {
127 m_maxPreferredLogicalWidth = std::max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.minWidth().value()));
128 m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.minWidth().value()));
131 if (styleToUse.maxWidth().isFixed()) {
132 m_maxPreferredLogicalWidth = std::min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.maxWidth().value()));
133 m_minPreferredLogicalWidth = std::min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse.maxWidth().value()));
136 int toAdd = borderAndPaddingWidth();
137 m_minPreferredLogicalWidth += toAdd;
138 m_maxPreferredLogicalWidth += toAdd;
140 clearPreferredLogicalWidthsDirty();
143 PositionWithAffinity LayoutFileUploadControl::positionForPoint(const LayoutPoint&)
145 return PositionWithAffinity();
148 HTMLInputElement* LayoutFileUploadControl::uploadButton() const
150 // FIXME: This should be on HTMLInputElement as an API like innerButtonElement().
151 HTMLInputElement* input = toHTMLInputElement(node());
152 Node* buttonNode = input->closedShadowRoot()->firstChild();
153 return isHTMLInputElement(buttonNode) ? toHTMLInputElement(buttonNode) : 0;
156 String LayoutFileUploadControl::buttonValue()
158 if (HTMLInputElement* button = uploadButton())
159 return button->value();
161 return String();
164 String LayoutFileUploadControl::fileTextValue() const
166 HTMLInputElement* input = toHTMLInputElement(node());
167 ASSERT(input->files());
168 return LayoutTheme::theme().fileListNameForWidth(input->locale(), input->files(), style()->font(), maxFilenameWidth());
171 } // namespace blink