blob: f4e3d2fa0be8177da9fc008a8313eb31de2bdfe4 [file] [log] [blame]
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +00001/**
joepeck@webkit.org1fbeab32010-05-01 02:54:08 +00002 * Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +00003 * (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
jorlow@chromium.org777bf4b2010-06-24 10:40:28 +00004 * Copyright (C) 2010 Google Inc. All rights reserved.
luiz@webkit.org260550a2010-08-03 00:39:44 +00005 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +00006 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#include "config.h"
25#include "RenderTextControlSingleLine.h"
26
tonyg@chromium.org8d183cb2011-05-10 08:19:52 +000027#include "CSSFontSelector.h"
jonlee@apple.com666eb272012-01-19 22:56:14 +000028#include "CSSValueKeywords.h"
tonyg@chromium.org8d183cb2011-05-10 08:19:52 +000029#include "Chrome.h"
antti@apple.com5a8f7942015-01-22 21:57:04 +000030#include "Font.h"
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +000031#include "Frame.h"
rniwa@webkit.org78bbc942011-05-05 18:14:43 +000032#include "FrameSelection.h"
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +000033#include "FrameView.h"
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +000034#include "HTMLNames.h"
eric@webkit.orgb35848a2010-06-10 08:33:22 +000035#include "HitTestResult.h"
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +000036#include "LocalizedStrings.h"
weinig@apple.comc5b2001d2011-05-13 19:09:09 +000037#include "Page.h"
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +000038#include "PlatformKeyboardEvent.h"
eric@webkit.orgb35848a2010-06-10 08:33:22 +000039#include "RenderLayer.h"
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +000040#include "RenderScrollbar.h"
41#include "RenderTheme.h"
akling@apple.com836b22b2013-08-25 21:22:06 +000042#include "RenderView.h"
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +000043#include "Settings.h"
alexis.menard@openbossa.orge6db2f62012-04-25 15:49:08 +000044#include "StyleResolver.h"
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +000045#include "TextControlInnerElements.h"
andersca@apple.coma5fb7da2013-04-16 19:57:36 +000046#include <wtf/StackStats.h>
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +000047
dbates@webkit.org395fca72013-12-06 19:59:38 +000048#if PLATFORM(IOS)
49#include "RenderThemeIOS.h"
50#endif
51
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +000052namespace WebCore {
53
54using namespace HTMLNames;
55
akling@apple.com689f7612014-12-14 08:21:05 +000056RenderTextControlSingleLine::RenderTextControlSingleLine(HTMLInputElement& element, Ref<RenderStyle>&& style)
dbates@webkit.org0cefe4f2014-07-03 22:13:54 +000057 : RenderTextControl(element, WTF::move(style))
hyatt@apple.comfce3dc72013-03-11 20:00:37 +000058 , m_desiredInnerTextLogicalHeight(-1)
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +000059{
60}
61
62RenderTextControlSingleLine::~RenderTextControlSingleLine()
63{
tkent@chromium.org72e4ae92011-05-23 10:10:38 +000064}
65
66inline HTMLElement* RenderTextControlSingleLine::innerSpinButtonElement() const
67{
akling@apple.comca97cfb2013-09-13 05:32:54 +000068 return inputElement().innerSpinButtonElement();
tkent@chromium.org72e4ae92011-05-23 10:10:38 +000069}
70
hyatt@apple.comfce3dc72013-03-11 20:00:37 +000071LayoutUnit RenderTextControlSingleLine::computeLogicalHeightLimit() const
yosin@chromium.orgf5c62432012-06-18 04:57:05 +000072{
hyatt@apple.comfce3dc72013-03-11 20:00:37 +000073 return containerElement() ? contentLogicalHeight() : logicalHeight();
yosin@chromium.orgf5c62432012-06-18 04:57:05 +000074}
75
zalan@apple.com70c7f312014-01-26 01:27:28 +000076void RenderTextControlSingleLine::centerRenderer(RenderBox& renderer) const
77{
78 LayoutUnit logicalHeightDiff = renderer.logicalHeight() - contentLogicalHeight();
79 float center = logicalHeightDiff / 2;
80 renderer.setLogicalTop(renderer.logicalTop() - LayoutUnit(round(center)));
81}
82
rniwa@webkit.org45ad2e52013-08-14 01:44:51 +000083static void setNeedsLayoutOnAncestors(RenderObject* start, RenderObject* ancestor)
84{
85 ASSERT(start != ancestor);
86 for (RenderObject* renderer = start; renderer != ancestor; renderer = renderer->parent()) {
87 ASSERT(renderer);
antti@apple.comca2a8ff2013-10-04 04:04:35 +000088 renderer->setNeedsLayout(MarkOnlyThis);
rniwa@webkit.org45ad2e52013-08-14 01:44:51 +000089 }
90}
91
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +000092void RenderTextControlSingleLine::layout()
93{
mark.lam@apple.com6df1a802012-10-19 20:09:36 +000094 StackStats::LayoutCheckPoint layoutCheckPoint;
95
tkent@chromium.org99e49d82011-06-30 06:30:23 +000096 // FIXME: We should remove the height-related hacks in layout() and
97 // styleDidChange(). We need them because
98 // - Center the inner elements vertically if the input height is taller than
99 // the intrinsic height of the inner elements.
100 // - Shrink the inner elment heights if the input height is samller than the
101 // intrinsic heights of the inner elements.
102
103 // We don't honor paddings and borders for textfields without decorations
104 // and type=search if the text height is taller than the contentHeight()
105 // because of compability.
106
weinig@apple.comeac56f72013-10-20 04:55:32 +0000107 RenderTextControlInnerBlock* innerTextRenderer = innerTextElement()->renderer();
tkent@chromium.org99e49d82011-06-30 06:30:23 +0000108 RenderBox* innerBlockRenderer = innerBlockElement() ? innerBlockElement()->renderBox() : 0;
jchaffraix@webkit.orga9428222012-07-11 03:11:30 +0000109
110 // To ensure consistency between layouts, we need to reset any conditionally overriden height.
akling@apple.com827be9c2013-10-29 02:58:43 +0000111 if (innerTextRenderer && !innerTextRenderer->style().logicalHeight().isAuto()) {
112 innerTextRenderer->style().setLogicalHeight(Length(Auto));
rniwa@webkit.org45ad2e52013-08-14 01:44:51 +0000113 setNeedsLayoutOnAncestors(innerTextRenderer, this);
commit-queue@webkit.orga3934902013-03-16 02:27:56 +0000114 }
akling@apple.com827be9c2013-10-29 02:58:43 +0000115 if (innerBlockRenderer && !innerBlockRenderer->style().logicalHeight().isAuto()) {
116 innerBlockRenderer->style().setLogicalHeight(Length(Auto));
rniwa@webkit.org45ad2e52013-08-14 01:44:51 +0000117 setNeedsLayoutOnAncestors(innerBlockRenderer, this);
commit-queue@webkit.orga3934902013-03-16 02:27:56 +0000118 }
jchaffraix@webkit.orga9428222012-07-11 03:11:30 +0000119
hyatt@apple.comc9b1aef2013-09-09 20:23:21 +0000120 RenderBlockFlow::layoutBlock(false);
jchaffraix@webkit.orga9428222012-07-11 03:11:30 +0000121
tkent@chromium.org99e49d82011-06-30 06:30:23 +0000122 HTMLElement* container = containerElement();
123 RenderBox* containerRenderer = container ? container->renderBox() : 0;
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000124
125 // Set the text block height
hyatt@apple.comfce3dc72013-03-11 20:00:37 +0000126 LayoutUnit desiredLogicalHeight = textBlockLogicalHeight();
127 LayoutUnit logicalHeightLimit = computeLogicalHeightLimit();
128 if (innerTextRenderer && innerTextRenderer->logicalHeight() > logicalHeightLimit) {
129 if (desiredLogicalHeight != innerTextRenderer->logicalHeight())
antti@apple.comca2a8ff2013-10-04 04:04:35 +0000130 setNeedsLayout(MarkOnlyThis);
jchaffraix@webkit.org67045252012-03-26 16:46:17 +0000131
hyatt@apple.comfce3dc72013-03-11 20:00:37 +0000132 m_desiredInnerTextLogicalHeight = desiredLogicalHeight;
133
akling@apple.com827be9c2013-10-29 02:58:43 +0000134 innerTextRenderer->style().setLogicalHeight(Length(desiredLogicalHeight, Fixed));
antti@apple.comca2a8ff2013-10-04 04:04:35 +0000135 innerTextRenderer->setNeedsLayout(MarkOnlyThis);
commit-queue@webkit.orga3934902013-03-16 02:27:56 +0000136 if (innerBlockRenderer) {
akling@apple.com827be9c2013-10-29 02:58:43 +0000137 innerBlockRenderer->style().setLogicalHeight(Length(desiredLogicalHeight, Fixed));
antti@apple.comca2a8ff2013-10-04 04:04:35 +0000138 innerBlockRenderer->setNeedsLayout(MarkOnlyThis);
commit-queue@webkit.orga3934902013-03-16 02:27:56 +0000139 }
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000140 }
tkent@chromium.org99e49d82011-06-30 06:30:23 +0000141 // The container might be taller because of decoration elements.
142 if (containerRenderer) {
143 containerRenderer->layoutIfNeeded();
hyatt@apple.comfce3dc72013-03-11 20:00:37 +0000144 LayoutUnit containerLogicalHeight = containerRenderer->logicalHeight();
145 if (containerLogicalHeight > logicalHeightLimit) {
akling@apple.com827be9c2013-10-29 02:58:43 +0000146 containerRenderer->style().setLogicalHeight(Length(logicalHeightLimit, Fixed));
antti@apple.comca2a8ff2013-10-04 04:04:35 +0000147 setNeedsLayout(MarkOnlyThis);
hyatt@apple.comfce3dc72013-03-11 20:00:37 +0000148 } else if (containerRenderer->logicalHeight() < contentLogicalHeight()) {
akling@apple.com827be9c2013-10-29 02:58:43 +0000149 containerRenderer->style().setLogicalHeight(Length(contentLogicalHeight(), Fixed));
antti@apple.comca2a8ff2013-10-04 04:04:35 +0000150 setNeedsLayout(MarkOnlyThis);
tkent@chromium.orge62e37a2012-03-02 05:43:01 +0000151 } else
akling@apple.com827be9c2013-10-29 02:58:43 +0000152 containerRenderer->style().setLogicalHeight(Length(containerLogicalHeight, Fixed));
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000153 }
154
jchaffraix@webkit.org67045252012-03-26 16:46:17 +0000155 // If we need another layout pass, we have changed one of children's height so we need to relayout them.
156 if (needsLayout())
hyatt@apple.comc9b1aef2013-09-09 20:23:21 +0000157 RenderBlockFlow::layoutBlock(true);
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000158
hyatt@apple.comfce3dc72013-03-11 20:00:37 +0000159 // Center the child block in the block progression direction (vertical centering for horizontal text fields).
zalan@apple.com70c7f312014-01-26 01:27:28 +0000160 if (!container && innerTextRenderer && innerTextRenderer->height() != contentLogicalHeight())
161 centerRenderer(*innerTextRenderer);
162 else
yosin@chromium.orgf5c62432012-06-18 04:57:05 +0000163 centerContainerIfNeeded(containerRenderer);
tkent@chromium.org5c8ac402010-04-30 07:45:09 +0000164
tkent@chromium.org06dfd042010-07-14 08:20:42 +0000165 // Ignores the paddings for the inner spin button.
tkent@chromium.org99e49d82011-06-30 06:30:23 +0000166 if (RenderBox* innerSpinBox = innerSpinButtonElement() ? innerSpinButtonElement()->renderBox() : 0) {
167 RenderBox* parentBox = innerSpinBox->parentBox();
akling@apple.com827be9c2013-10-29 02:58:43 +0000168 if (containerRenderer && !containerRenderer->style().isLeftToRightDirection())
hyatt@apple.comfce3dc72013-03-11 20:00:37 +0000169 innerSpinBox->setLogicalLocation(LayoutPoint(-paddingLogicalLeft(), -paddingBefore()));
tkent@chromium.orgc3761092011-07-20 07:52:39 +0000170 else
hyatt@apple.comfce3dc72013-03-11 20:00:37 +0000171 innerSpinBox->setLogicalLocation(LayoutPoint(parentBox->logicalWidth() - innerSpinBox->logicalWidth() + paddingLogicalRight(), -paddingBefore()));
172 innerSpinBox->setLogicalHeight(logicalHeight() - borderBefore() - borderAfter());
tkent@chromium.org06dfd042010-07-14 08:20:42 +0000173 }
tkent@chromium.org8e17b7c2011-07-14 02:16:54 +0000174
akling@apple.comca97cfb2013-09-13 05:32:54 +0000175 HTMLElement* placeholderElement = inputElement().placeholderElement();
tkent@chromium.org8e17b7c2011-07-14 02:16:54 +0000176 if (RenderBox* placeholderBox = placeholderElement ? placeholderElement->renderBox() : 0) {
dominicc@chromium.org1ded05f2013-03-18 08:01:57 +0000177 LayoutSize innerTextSize;
178 if (innerTextRenderer)
179 innerTextSize = innerTextRenderer->size();
bjonesbe@adobe.com562a50d2014-02-20 20:01:19 +0000180 placeholderBox->style().setWidth(Length(innerTextSize.width() - placeholderBox->horizontalBorderAndPaddingExtent(), Fixed));
181 placeholderBox->style().setHeight(Length(innerTextSize.height() - placeholderBox->verticalBorderAndPaddingExtent(), Fixed));
robert@webkit.org34541f52013-02-20 18:27:03 +0000182 bool neededLayout = placeholderBox->needsLayout();
jchaffraix@webkit.org1d6b4142012-03-26 16:52:01 +0000183 bool placeholderBoxHadLayout = placeholderBox->everHadLayout();
tkent@chromium.org8e17b7c2011-07-14 02:16:54 +0000184 placeholderBox->layoutIfNeeded();
dominicc@chromium.org1ded05f2013-03-18 08:01:57 +0000185 LayoutPoint textOffset;
186 if (innerTextRenderer)
187 textOffset = innerTextRenderer->location();
tkent@chromium.org8e17b7c2011-07-14 02:16:54 +0000188 if (innerBlockElement() && innerBlockElement()->renderBox())
189 textOffset += toLayoutSize(innerBlockElement()->renderBox()->location());
190 if (containerRenderer)
191 textOffset += toLayoutSize(containerRenderer->location());
192 placeholderBox->setLocation(textOffset);
jchaffraix@webkit.org1d6b4142012-03-26 16:52:01 +0000193
194 if (!placeholderBoxHadLayout && placeholderBox->checkForRepaintDuringLayout()) {
195 // This assumes a shadow tree without floats. If floats are added, the
196 // logic should be shared with RenderBlock::layoutBlockChild.
197 placeholderBox->repaint();
198 }
robert@webkit.org34541f52013-02-20 18:27:03 +0000199 // The placeholder gets layout last, after the parent text control and its other children,
200 // so in order to get the correct overflow from the placeholder we need to recompute it now.
robert@webkit.orgbc4e5562013-02-21 18:46:33 +0000201 if (neededLayout)
robert@webkit.org34541f52013-02-20 18:27:03 +0000202 computeOverflow(clientLogicalBottom());
tkent@chromium.org8e17b7c2011-07-14 02:16:54 +0000203 }
dbates@webkit.org395fca72013-12-06 19:59:38 +0000204
205#if PLATFORM(IOS)
206 // FIXME: We should not be adjusting styles during layout. <rdar://problem/7675493>
207 if (inputElement().isSearchField())
achristensen@apple.com9fb77fc2014-06-25 21:04:17 +0000208 RenderThemeIOS::adjustRoundBorderRadius(style(), *this);
dbates@webkit.org395fca72013-12-06 19:59:38 +0000209#endif
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000210}
211
allan.jensen@nokia.com9a9045b2012-08-28 09:41:54 +0000212bool RenderTextControlSingleLine::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000213{
allan.jensen@nokia.com9a9045b2012-08-28 09:41:54 +0000214 if (!RenderTextControl::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, hitTestAction))
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000215 return false;
216
tkent@chromium.org99e49d82011-06-30 06:30:23 +0000217 // Say that we hit the inner text element if
218 // - we hit a node inside the inner text element,
219 // - we hit the <input> element (e.g. we're over the border or padding), or
220 // - we hit regions not in any decoration buttons.
221 HTMLElement* container = containerElement();
akling@apple.comca97cfb2013-09-13 05:32:54 +0000222 if (result.innerNode()->isDescendantOf(innerTextElement()) || result.innerNode() == &inputElement() || (container && container == result.innerNode())) {
allan.jensen@nokia.com9a9045b2012-08-28 09:41:54 +0000223 LayoutPoint pointInParent = locationInContainer.point();
tkent@chromium.org99e49d82011-06-30 06:30:23 +0000224 if (container && innerBlockElement()) {
225 if (innerBlockElement()->renderBox())
eae@chromium.org9fef0e62011-07-08 22:01:17 +0000226 pointInParent -= toLayoutSize(innerBlockElement()->renderBox()->location());
tkent@chromium.org99e49d82011-06-30 06:30:23 +0000227 if (container->renderBox())
eae@chromium.org9fef0e62011-07-08 22:01:17 +0000228 pointInParent -= toLayoutSize(container->renderBox()->location());
tkent@chromium.org99e49d82011-06-30 06:30:23 +0000229 }
230 hitInnerTextElement(result, pointInParent, accumulatedOffset);
commit-queue@webkit.orgae578302011-06-22 19:55:23 +0000231 }
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000232 return true;
233}
234
weinig@apple.com1a57c822009-02-04 22:27:50 +0000235void RenderTextControlSingleLine::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000236{
hyatt@apple.comfce3dc72013-03-11 20:00:37 +0000237 m_desiredInnerTextLogicalHeight = -1;
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000238 RenderTextControl::styleDidChange(diff, oldStyle);
239
tkent@chromium.org99e49d82011-06-30 06:30:23 +0000240 // We may have set the width and the height in the old style in layout().
241 // Reset them now to avoid getting a spurious layout hint.
tkent@chromium.org72e4ae92011-05-23 10:10:38 +0000242 HTMLElement* innerBlock = innerBlockElement();
243 if (RenderObject* innerBlockRenderer = innerBlock ? innerBlock->renderer() : 0) {
akling@apple.com827be9c2013-10-29 02:58:43 +0000244 innerBlockRenderer->style().setHeight(Length());
245 innerBlockRenderer->style().setWidth(Length());
tkent@chromium.org99e49d82011-06-30 06:30:23 +0000246 }
247 HTMLElement* container = containerElement();
248 if (RenderObject* containerRenderer = container ? container->renderer() : 0) {
akling@apple.com827be9c2013-10-29 02:58:43 +0000249 containerRenderer->style().setHeight(Length());
250 containerRenderer->style().setWidth(Length());
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000251 }
weinig@apple.comeac56f72013-10-20 04:55:32 +0000252 RenderTextControlInnerBlock* innerTextRenderer = innerTextElement()->renderer();
tkent@chromium.org67f16922013-04-04 01:16:55 +0000253 if (innerTextRenderer && diff == StyleDifferenceLayout)
antti@apple.comca2a8ff2013-10-04 04:04:35 +0000254 innerTextRenderer->setNeedsLayout(MarkContainingBlockChain);
akling@apple.comca97cfb2013-09-13 05:32:54 +0000255 if (HTMLElement* placeholder = inputElement().placeholderElement())
antti@apple.com85635f02012-02-16 07:39:17 +0000256 placeholder->setInlineStyleProperty(CSSPropertyTextOverflow, textShouldBeTruncated() ? CSSValueEllipsis : CSSValueClip);
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000257 setHasOverflowClip(false);
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000258}
259
jorlow@chromium.org777bf4b2010-06-24 10:40:28 +0000260bool RenderTextControlSingleLine::hasControlClip() const
261{
tkent@chromium.org99e49d82011-06-30 06:30:23 +0000262 // Apply control clip for text fields with decorations.
263 return !!containerElement();
jorlow@chromium.org777bf4b2010-06-24 10:40:28 +0000264}
265
leviw@chromium.org49fdb332011-08-18 19:28:33 +0000266LayoutRect RenderTextControlSingleLine::controlClipRect(const LayoutPoint& additionalOffset) const
joepeck@webkit.org1fbeab32010-05-01 02:54:08 +0000267{
joepeck@webkit.org1fbeab32010-05-01 02:54:08 +0000268 ASSERT(hasControlClip());
dominicc@chromium.org1caaa512013-03-08 18:12:39 +0000269 LayoutRect clipRect = contentBoxRect();
270 if (containerElement()->renderBox())
271 clipRect = unionRect(clipRect, containerElement()->renderBox()->frameRect());
leviw@chromium.org35e01312011-06-03 02:41:09 +0000272 clipRect.moveBy(additionalOffset);
joepeck@webkit.org1fbeab32010-05-01 02:54:08 +0000273 return clipRect;
274}
275
mmaxfield@apple.comd35ea3d2014-03-16 00:17:56 +0000276float RenderTextControlSingleLine::getAverageCharWidth()
ojan@chromium.org68b773d2010-02-13 03:20:20 +0000277{
dbates@webkit.org395fca72013-12-06 19:59:38 +0000278#if !PLATFORM(IOS)
ojan@chromium.org68b773d2010-02-13 03:20:20 +0000279 // Since Lucida Grande is the default font, we want this to match the width
280 // of MS Shell Dlg, the default font for textareas in Firefox, Safari Win and
281 // IE for some encodings (in IE, the default font is encoding specific).
282 // 901 is the avgCharWidth value in the OS/2 table for MS Shell Dlg.
antti@apple.comc54cbc92015-01-15 14:19:56 +0000283 if (style().fontCascade().firstFamily() == "Lucida Grande")
ojan@chromium.org68b773d2010-02-13 03:20:20 +0000284 return scaleEmToUnits(901);
dbates@webkit.org395fca72013-12-06 19:59:38 +0000285#endif
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000286
mmaxfield@apple.comd35ea3d2014-03-16 00:17:56 +0000287 return RenderTextControl::getAverageCharWidth();
ojan@chromium.org68b773d2010-02-13 03:20:20 +0000288}
commit-queue@webkit.org1b4801a2011-08-08 09:16:54 +0000289
hyatt@apple.comfce3dc72013-03-11 20:00:37 +0000290LayoutUnit RenderTextControlSingleLine::preferredContentLogicalWidth(float charWidth) const
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000291{
commit-queue@webkit.org1b4801a2011-08-08 09:16:54 +0000292 int factor;
akling@apple.comca97cfb2013-09-13 05:32:54 +0000293 bool includesDecoration = inputElement().sizeShouldIncludeDecoration(factor);
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000294 if (factor <= 0)
295 factor = 20;
296
zalan@apple.com81badc12014-08-26 19:29:09 +0000297 LayoutUnit result = LayoutUnit::fromFloatCeil(charWidth * factor);
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000298
ojan@chromium.org68b773d2010-02-13 03:20:20 +0000299 float maxCharWidth = 0.f;
dbates@webkit.org395fca72013-12-06 19:59:38 +0000300
301#if !PLATFORM(IOS)
antti@apple.comc54cbc92015-01-15 14:19:56 +0000302 const AtomicString& family = style().fontCascade().firstFamily();
ojan@chromium.org68b773d2010-02-13 03:20:20 +0000303 // Since Lucida Grande is the default font, we want this to match the width
304 // of MS Shell Dlg, the default font for textareas in Firefox, Safari Win and
305 // IE for some encodings (in IE, the default font is encoding specific).
306 // 4027 is the (xMax - xMin) value in the "head" font table for MS Shell Dlg.
benjamin@webkit.orgdbf95292012-11-09 01:15:59 +0000307 if (family == "Lucida Grande")
ojan@chromium.org68b773d2010-02-13 03:20:20 +0000308 maxCharWidth = scaleEmToUnits(4027);
antti@apple.comc54cbc92015-01-15 14:19:56 +0000309 else if (style().fontCascade().hasValidAverageCharWidth())
antti@apple.com5a8f7942015-01-22 21:57:04 +0000310 maxCharWidth = roundf(style().fontCascade().primaryFont().maxCharWidth());
dbates@webkit.org395fca72013-12-06 19:59:38 +0000311#endif
ojan@chromium.org68b773d2010-02-13 03:20:20 +0000312
ojan@chromium.org149606a2009-04-29 20:31:53 +0000313 // For text inputs, IE adds some extra width.
ojan@chromium.org68b773d2010-02-13 03:20:20 +0000314 if (maxCharWidth > 0.f)
315 result += maxCharWidth - charWidth;
ojan@chromium.org149606a2009-04-29 20:31:53 +0000316
graouts@apple.com629cf132013-08-02 14:58:09 +0000317 if (includesDecoration)
akling@apple.comca97cfb2013-09-13 05:32:54 +0000318 result += inputElement().decorationWidth();
commit-queue@webkit.org1b4801a2011-08-08 09:16:54 +0000319
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000320 return result;
321}
322
hyatt@apple.comfce3dc72013-03-11 20:00:37 +0000323LayoutUnit RenderTextControlSingleLine::computeControlLogicalHeight(LayoutUnit lineHeight, LayoutUnit nonContentHeight) const
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000324{
tkent@chromium.orge69b1d12012-03-07 09:04:58 +0000325 return lineHeight + nonContentHeight;
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000326}
327
akling@apple.com689f7612014-12-14 08:21:05 +0000328Ref<RenderStyle> RenderTextControlSingleLine::createInnerTextStyle(const RenderStyle* startStyle) const
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000329{
akling@apple.come8eb70e2013-10-19 13:58:49 +0000330 auto textBlockStyle = RenderStyle::create();
331 textBlockStyle.get().inheritFrom(startStyle);
cdumez@apple.com78141732014-11-04 23:00:48 +0000332 adjustInnerTextStyle(startStyle, textBlockStyle.get());
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000333
akling@apple.come8eb70e2013-10-19 13:58:49 +0000334 textBlockStyle.get().setWhiteSpace(PRE);
335 textBlockStyle.get().setOverflowWrap(NormalOverflowWrap);
336 textBlockStyle.get().setOverflowX(OHIDDEN);
337 textBlockStyle.get().setOverflowY(OHIDDEN);
338 textBlockStyle.get().setTextOverflow(textShouldBeTruncated() ? TextOverflowEllipsis : TextOverflowClip);
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000339
hyatt@apple.comfce3dc72013-03-11 20:00:37 +0000340 if (m_desiredInnerTextLogicalHeight >= 0)
akling@apple.come8eb70e2013-10-19 13:58:49 +0000341 textBlockStyle.get().setLogicalHeight(Length(m_desiredInnerTextLogicalHeight, Fixed));
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000342 // Do not allow line-height to be smaller than our default.
akling@apple.come8eb70e2013-10-19 13:58:49 +0000343 if (textBlockStyle.get().fontMetrics().lineSpacing() > lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes))
344 textBlockStyle.get().setLineHeight(RenderStyle::initialLineHeight());
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000345
akling@apple.come8eb70e2013-10-19 13:58:49 +0000346 textBlockStyle.get().setDisplay(BLOCK);
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000347
akling@apple.come8eb70e2013-10-19 13:58:49 +0000348 return textBlockStyle;
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000349}
350
akling@apple.com689f7612014-12-14 08:21:05 +0000351Ref<RenderStyle> RenderTextControlSingleLine::createInnerBlockStyle(const RenderStyle* startStyle) const
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000352{
akling@apple.come8eb70e2013-10-19 13:58:49 +0000353 auto innerBlockStyle = RenderStyle::create();
354 innerBlockStyle.get().inheritFrom(startStyle);
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000355
akling@apple.come8eb70e2013-10-19 13:58:49 +0000356 innerBlockStyle.get().setFlexGrow(1);
commit-queue@webkit.orga3934902013-03-16 02:27:56 +0000357 // min-width: 0; is needed for correct shrinking.
358 // FIXME: Remove this line when https://bugs.webkit.org/show_bug.cgi?id=111790 is fixed.
akling@apple.come8eb70e2013-10-19 13:58:49 +0000359 innerBlockStyle.get().setMinWidth(Length(0, Fixed));
360 innerBlockStyle.get().setDisplay(BLOCK);
361 innerBlockStyle.get().setDirection(LTR);
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000362
363 // We don't want the shadow dom to be editable, so we set this block to read-only in case the input itself is editable.
akling@apple.come8eb70e2013-10-19 13:58:49 +0000364 innerBlockStyle.get().setUserModify(READ_ONLY);
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000365
akling@apple.come8eb70e2013-10-19 13:58:49 +0000366 return innerBlockStyle;
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000367}
368
jonlee@apple.com666eb272012-01-19 22:56:14 +0000369bool RenderTextControlSingleLine::textShouldBeTruncated() const
370{
akling@apple.com827be9c2013-10-29 02:58:43 +0000371 return document().focusedElement() != &inputElement() && style().textOverflow() == TextOverflowEllipsis;
jonlee@apple.com666eb272012-01-19 22:56:14 +0000372}
373
yosin@chromium.orgb0690b62013-01-21 01:29:07 +0000374void RenderTextControlSingleLine::autoscroll(const IntPoint& position)
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000375{
weinig@apple.comeac56f72013-10-20 04:55:32 +0000376 RenderTextControlInnerBlock* renderer = innerTextElement()->renderer();
dominicc@chromium.org1caaa512013-03-08 18:12:39 +0000377 if (!renderer)
378 return;
379 RenderLayer* layer = renderer->layer();
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000380 if (layer)
yosin@chromium.orgb0690b62013-01-21 01:29:07 +0000381 layer->autoscroll(position);
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000382}
383
eae@chromium.org05592852011-11-23 08:21:18 +0000384int RenderTextControlSingleLine::scrollWidth() const
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000385{
386 if (innerTextElement())
387 return innerTextElement()->scrollWidth();
weinig@apple.com19f6a182013-10-19 21:43:30 +0000388 return RenderBlockFlow::scrollWidth();
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000389}
390
eae@chromium.org05592852011-11-23 08:21:18 +0000391int RenderTextControlSingleLine::scrollHeight() const
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000392{
393 if (innerTextElement())
394 return innerTextElement()->scrollHeight();
weinig@apple.com19f6a182013-10-19 21:43:30 +0000395 return RenderBlockFlow::scrollHeight();
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000396}
397
eae@chromium.org05592852011-11-23 08:21:18 +0000398int RenderTextControlSingleLine::scrollLeft() const
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000399{
400 if (innerTextElement())
401 return innerTextElement()->scrollLeft();
weinig@apple.com19f6a182013-10-19 21:43:30 +0000402 return RenderBlockFlow::scrollLeft();
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000403}
404
eae@chromium.org05592852011-11-23 08:21:18 +0000405int RenderTextControlSingleLine::scrollTop() const
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000406{
407 if (innerTextElement())
408 return innerTextElement()->scrollTop();
weinig@apple.com19f6a182013-10-19 21:43:30 +0000409 return RenderBlockFlow::scrollTop();
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000410}
411
eae@chromium.org05592852011-11-23 08:21:18 +0000412void RenderTextControlSingleLine::setScrollLeft(int newLeft)
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000413{
414 if (innerTextElement())
415 innerTextElement()->setScrollLeft(newLeft);
416}
417
eae@chromium.org05592852011-11-23 08:21:18 +0000418void RenderTextControlSingleLine::setScrollTop(int newTop)
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000419{
420 if (innerTextElement())
421 innerTextElement()->setScrollTop(newTop);
422}
423
bfulgham@apple.com9c36fbd2014-02-03 23:10:31 +0000424bool RenderTextControlSingleLine::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier, Element** stopElement, RenderBox* startBox, const IntPoint& wheelEventAbsolutePoint)
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000425{
weinig@apple.comeac56f72013-10-20 04:55:32 +0000426 RenderTextControlInnerBlock* renderer = innerTextElement()->renderer();
dominicc@chromium.org1caaa512013-03-08 18:12:39 +0000427 if (!renderer)
428 return false;
429 RenderLayer* layer = renderer->layer();
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000430 if (layer && layer->scroll(direction, granularity, multiplier))
431 return true;
bfulgham@apple.com9c36fbd2014-02-03 23:10:31 +0000432 return RenderBlockFlow::scroll(direction, granularity, multiplier, stopElement, startBox, wheelEventAbsolutePoint);
eric@webkit.orgd2bb5a02009-03-17 23:44:11 +0000433}
434
akling@apple.comca895452013-09-25 15:40:58 +0000435bool RenderTextControlSingleLine::logicalScroll(ScrollLogicalDirection direction, ScrollGranularity granularity, float multiplier, Element** stopElement)
hyatt@apple.coma60d0ce2010-12-13 20:14:28 +0000436{
weinig@apple.comeac56f72013-10-20 04:55:32 +0000437 RenderLayer* layer = innerTextElement()->renderer()->layer();
akling@apple.com827be9c2013-10-29 02:58:43 +0000438 if (layer && layer->scroll(logicalToPhysical(direction, style().isHorizontalWritingMode(), style().isFlippedBlocksWritingMode()), granularity, multiplier))
hyatt@apple.coma60d0ce2010-12-13 20:14:28 +0000439 return true;
weinig@apple.com19f6a182013-10-19 21:43:30 +0000440 return RenderBlockFlow::logicalScroll(direction, granularity, multiplier, stopElement);
hyatt@apple.coma60d0ce2010-12-13 20:14:28 +0000441}
442
akling@apple.comca97cfb2013-09-13 05:32:54 +0000443HTMLInputElement& RenderTextControlSingleLine::inputElement() const
zimmermann@webkit.orgdceb5db2009-01-20 21:02:58 +0000444{
cdumez@apple.com72754ba2014-09-23 22:03:15 +0000445 return downcast<HTMLInputElement>(RenderTextControl::textFormControlElement());
zimmermann@webkit.orgdceb5db2009-01-20 21:02:58 +0000446}
447
zimmermann@webkit.org9402bba2008-12-28 13:54:17 +0000448}