18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/**
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *           (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderTextControl.h"
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "AXObjectCache.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Editor.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Event.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "EventNames.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLBRElement.h"
31f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include "HTMLFormControlElement.h"
326b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "HTMLInputElement.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HitTestResult.h"
3565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "Position.h"
368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "RenderLayer.h"
37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "RenderText.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ScrollbarTheme.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SelectionController.h"
40635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Text.h"
418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "TextControlInnerElements.h"
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "TextIterator.h"
43ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "TextRun.h"
442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <wtf/unicode/CharacterNames.h>
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames;
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Value chosen by observation.  This can be tweaked.
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const int minColorContrastValue = 1300;
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic Color disabledTextColor(const Color& textColor, const Color& backgroundColor)
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The explicit check for black is an optimization for the 99% case (black on white).
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This also means that black on black will turn into grey on black when disabled.
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Color disabledColor;
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (textColor.rgb() == Color::black || differenceSquared(textColor, Color::white) > differenceSquared(backgroundColor, Color::white))
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        disabledColor = textColor.light();
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        disabledColor = textColor.dark();
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If there's not very much contrast between the disabled color and the background color,
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // just leave the text color alone.  We don't want to change a good contrast color scheme so that it has really bad contrast.
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the the contrast was already poor, then it doesn't do any good to change it to a different poor contrast color scheme.
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (differenceSquared(disabledColor, backgroundColor) < minColorContrastValue)
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return textColor;
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return disabledColor;
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
74231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockRenderTextControl::RenderTextControl(Node* node, bool placeholderVisible)
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    : RenderBlock(node)
76231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    , m_placeholderVisible(placeholderVisible)
77643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    , m_lastChangeWasUserEdit(false)
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderTextControl::~RenderTextControl()
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The children renderers have already been destroyed by destroyLeftoverChildren
84635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (m_innerText)
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_innerText->detach();
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderTextControl::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderBlock::styleDidChange(diff, oldStyle);
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_innerText) {
938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        RenderBlock* textBlockRenderer = toRenderBlock(m_innerText->renderer());
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RefPtr<RenderStyle> textBlockStyle = createInnerTextStyle(style());
95635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // We may have set the width and the height in the old style in layout().
96635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // Reset them now to avoid getting a spurious layout hint.
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        textBlockRenderer->style()->setHeight(Length());
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        textBlockRenderer->style()->setWidth(Length());
99231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        setInnerTextStyle(textBlockStyle);
100231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
101231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
102231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderTextControl::setInnerTextStyle(PassRefPtr<RenderStyle> style)
104231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (m_innerText) {
106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        RefPtr<RenderStyle> textStyle = style;
107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_innerText->renderer()->setStyle(textStyle);
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (Node* n = m_innerText->firstChild(); n; n = n->traverseNextNode(m_innerText.get())) {
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (n->renderer())
110231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                n->renderer()->setStyle(textStyle);
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianstatic inline bool updateUserModifyProperty(Node* node, RenderStyle* style)
1168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
1178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool isEnabled = true;
1188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool isReadOnlyControl = false;
1198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (node->isElementNode()) {
1215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        Element* element = static_cast<Element*>(node);
1225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        isEnabled = element->isEnabledFormControl();
1235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        isReadOnlyControl = element->isReadOnlyFormControl();
1248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    style->setUserModify((isReadOnlyControl || !isEnabled) ? READ_ONLY : READ_WRITE_PLAINTEXT_ONLY);
1278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return !isEnabled;
1288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
130635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderTextControl::adjustInnerTextStyle(const RenderStyle* startStyle, RenderStyle* textBlockStyle) const
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // The inner block, if present, always has its direction set to LTR,
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // so we need to inherit the direction from the element.
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    textBlockStyle->setDirection(style()->direction());
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    bool disabled = updateUserModifyProperty(node(), textBlockStyle);
1378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (disabled)
138e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        textBlockStyle->setColor(disabledTextColor(textBlockStyle->visitedDependentColor(CSSPropertyColor), startStyle->visitedDependentColor(CSSPropertyBackgroundColor)));
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
141635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderTextControl::createSubtreeIfNeeded(TextControlInnerElement* innerBlock)
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
143635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (!m_innerText) {
144635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // Create the text block element
145635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // For non-search fields, there is no intermediate innerBlock as the shadow node.
146635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // m_innerText will be the shadow node in that case.
147635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        RenderStyle* parentStyle = innerBlock ? innerBlock->renderer()->style() : style();
1482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        m_innerText = TextControlInnerTextElement::create(document(), innerBlock ? 0 : toHTMLElement(node()));
149635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        m_innerText->attachInnerElement(innerBlock ? innerBlock : node(), createInnerTextStyle(parentStyle), renderArena());
150635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
153635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderTextControl::textBlockHeight() const
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15521939df44de1705786c545cd1bf519d47250322dBen Murdoch    return height() - borderAndPaddingHeight();
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
158635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderTextControl::textBlockWidth() const
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16021939df44de1705786c545cd1bf519d47250322dBen Murdoch    return width() - borderAndPaddingWidth() - m_innerText->renderBox()->paddingLeft() - m_innerText->renderBox()->paddingRight();
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderTextControl::updateFromElement()
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    updateUserModifyProperty(node(), m_innerText->renderer()->style());
166635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
168635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderTextControl::setInnerTextValue(const String& innerTextValue)
169635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
170dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    String value = innerTextValue;
171635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (value != text() || !m_innerText->hasChildNodes()) {
172635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (value != text()) {
173545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            if (Frame* frame = this->frame()) {
174635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                frame->editor()->clearUndoRedoOperations();
1755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                if (AXObjectCache::accessibilityEnabled())
177231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    document()->axObjectCache()->postNotification(this, AXObjectCache::AXValueChanged, false);
1785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
179635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
181635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ExceptionCode ec = 0;
182635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        m_innerText->setInnerText(value, ec);
183635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        ASSERT(!ec);
184635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
185635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (value.endsWith("\n") || value.endsWith("\r")) {
1865af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            m_innerText->appendChild(HTMLBRElement::create(document()), ec);
187635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            ASSERT(!ec);
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
189635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
190d0825bca7fe65beaee391d30da42e937db621564Steve Block        // We set m_lastChangeWasUserEdit to false since this change was not explicitly made by the user (say, via typing on the keyboard), see <rdar://problem/5359921>.
191643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        m_lastChangeWasUserEdit = false;
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    static_cast<Element*>(node())->setFormControlValueMatchesRenderer(true);
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
197643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid RenderTextControl::setLastChangeWasUserEdit(bool lastChangeWasUserEdit)
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
199643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    m_lastChangeWasUserEdit = lastChangeWasUserEdit;
200643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    document()->setIgnoreAutofocus(lastChangeWasUserEdit);
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
20328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuint RenderTextControl::selectionStart() const
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
205545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    Frame* frame = this->frame();
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!frame)
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
208d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch
209d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    HTMLElement* innerText = innerTextElement();
210d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // Do not call innerTextElement() in the function arguments as creating a VisiblePosition
211d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // from frame->selection->start() can blow us from underneath. Also, function ordering is
212d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // usually dependent on the compiler.
213d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    return RenderTextControl::indexForVisiblePosition(innerText, frame->selection()->start());
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
21628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuint RenderTextControl::selectionEnd() const
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
218545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    Frame* frame = this->frame();
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!frame)
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
221d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch
222d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    HTMLElement* innerText = innerTextElement();
223d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // Do not call innerTextElement() in the function arguments as creating a VisiblePosition
224d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // from frame->selection->end() can blow us from underneath. Also, function ordering is
225d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    // usually dependent on the compiler.
226d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    return RenderTextControl::indexForVisiblePosition(innerText, frame->selection()->end());
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
229e14391e94c850b8bd03680c23b38978db68687a8John Reckbool RenderTextControl::hasVisibleTextArea() const
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
231e14391e94c850b8bd03680c23b38978db68687a8John Reck    return style()->visibility() == HIDDEN || !m_innerText || !m_innerText->renderer() || !m_innerText->renderBox()->height();
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
234e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid setSelectionRange(Node* node, int start, int end)
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
236e14391e94c850b8bd03680c23b38978db68687a8John Reck    ASSERT(node);
237e14391e94c850b8bd03680c23b38978db68687a8John Reck    node->document()->updateLayoutIgnorePendingStylesheets();
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
239e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (!node->renderer() || !node->renderer()->isTextControl())
240e14391e94c850b8bd03680c23b38978db68687a8John Reck        return;
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    end = max(end, 0);
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    start = min(max(start, 0), end);
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
245e14391e94c850b8bd03680c23b38978db68687a8John Reck    RenderTextControl* control = toRenderTextControl(node->renderer());
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
247e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (control->hasVisibleTextArea()) {
248e14391e94c850b8bd03680c23b38978db68687a8John Reck        control->cacheSelection(start, end);
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
251e14391e94c850b8bd03680c23b38978db68687a8John Reck    VisiblePosition startPosition = control->visiblePositionForIndex(start);
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    VisiblePosition endPosition;
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (start == end)
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        endPosition = startPosition;
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
256e14391e94c850b8bd03680c23b38978db68687a8John Reck        endPosition = control->visiblePositionForIndex(end);
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // startPosition and endPosition can be null position for example when
2590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // "-webkit-user-select: none" style attribute is specified.
2600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (startPosition.isNotNull() && endPosition.isNotNull()) {
26181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ASSERT(startPosition.deepEquivalent().deprecatedNode()->shadowAncestorNode() == node && endPosition.deepEquivalent().deprecatedNode()->shadowAncestorNode() == node);
2620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
2638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    VisibleSelection newSelection = VisibleSelection(startPosition, endPosition);
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
265e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (Frame* frame = node->document()->frame())
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        frame->selection()->setSelection(newSelection);
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
269d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdochbool RenderTextControl::isSelectableElement(HTMLElement* innerText, Node* node)
2706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{
271d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    if (!node || !innerText)
2726b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return false;
273d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch
274d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    if (node->rootEditableElement() == innerText)
2756b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return true;
2766b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
277d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    if (!innerText->contains(node))
2786b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return false;
2796b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
2806b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    Node* shadowAncestor = node->shadowAncestorNode();
2816b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    return shadowAncestor && (shadowAncestor->hasTagName(textareaTag)
2826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        || (shadowAncestor->hasTagName(inputTag) && static_cast<HTMLInputElement*>(shadowAncestor)->isTextField()));
2836b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner}
2846b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
28565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic inline void setContainerAndOffsetForRange(Node* node, int offset, Node*& containerNode, int& offsetInContainer)
28665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
28765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (node->isTextNode()) {
28865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        containerNode = node;
28965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        offsetInContainer = offset;
29065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    } else {
29165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        containerNode = node->parentNode();
29265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        offsetInContainer = node->nodeIndex() + offset;
29365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
29465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
29565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
296a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochPassRefPtr<Range> RenderTextControl::selection(int start, int end) const
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
29865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    ASSERT(start <= end);
299a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!m_innerText)
300a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return 0;
301a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
30265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!m_innerText->firstChild())
30365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return Range::create(document(), m_innerText, 0, m_innerText, 0);
30465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
30565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    int offset = 0;
30665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Node* startNode = 0;
30765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Node* endNode = 0;
30865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (Node* node = m_innerText->firstChild(); node; node = node->traverseNextNode(m_innerText.get())) {
30965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        ASSERT(!node->firstChild());
31065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        ASSERT(node->isTextNode() || node->hasTagName(brTag));
31165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        int length = node->isTextNode() ? lastOffsetInNode(node) : 1;
31265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
31365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (offset <= start && start <= offset + length)
31465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            setContainerAndOffsetForRange(node, start - offset, startNode, start);
31565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
31665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (offset <= end && end <= offset + length) {
31765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            setContainerAndOffsetForRange(node, end - offset, endNode, end);
31865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            break;
31965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
32065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
32165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        offset += length;
32265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
32365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
32465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!startNode || !endNode)
32565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return 0;
32665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
32765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return Range::create(document(), startNode, start, endNode, end);
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
33028040489d744e0c5d475a88663056c9040ed5320Teng-Hui ZhuVisiblePosition RenderTextControl::visiblePositionForIndex(int index) const
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (index <= 0)
33381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return VisiblePosition(Position(m_innerText.get(), 0, Position::PositionIsOffsetInAnchor), DOWNSTREAM);
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ExceptionCode ec = 0;
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<Range> range = Range::create(document());
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    range->selectNodeContents(m_innerText.get(), ec);
337635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(!ec);
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CharacterIterator it(range.get());
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    it.advance(index - 1);
340635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    Node* endContainer = it.range()->endContainer(ec);
341635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(!ec);
342635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    int endOffset = it.range()->endOffset(ec);
343635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(!ec);
34481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return VisiblePosition(Position(endContainer, endOffset, Position::PositionIsOffsetInAnchor), UPSTREAM);
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
347d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdochint RenderTextControl::indexForVisiblePosition(HTMLElement* innerTextElement, const VisiblePosition& pos)
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Position indexPosition = pos.deepEquivalent();
350d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    if (!RenderTextControl::isSelectableElement(innerTextElement, indexPosition.deprecatedNode()))
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ExceptionCode ec = 0;
353d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    RefPtr<Range> range = Range::create(indexPosition.document());
354d0147a863b872ecaa451ab0dce2a348760e99e2cBen Murdoch    range->setStart(innerTextElement, 0, ec);
355635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(!ec);
35681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    range->setEnd(indexPosition.deprecatedNode(), indexPosition.deprecatedEditingOffset(), ec);
357635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(!ec);
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return TextIterator::rangeLength(range.get());
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderTextControl::subtreeHasChanged()
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
363643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    m_lastChangeWasUserEdit = true;
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString RenderTextControl::finishText(Vector<UChar>& result) const
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Remove one trailing newline; there's always one that's collapsed out by rendering.
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t size = result.size();
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (size && result[size - 1] == '\n')
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result.shrink(--size);
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return String::adopt(result);
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString RenderTextControl::text()
3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_innerText)
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "";
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<UChar> result;
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (Node* n = m_innerText.get(); n; n = n->traverseNextNode(m_innerText.get())) {
384635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (n->hasTagName(brTag))
385635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            result.append(&newlineCharacter, 1);
386635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        else if (n->isTextNode()) {
3870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            String data = static_cast<Text*>(n)->data();
3880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            result.append(data.characters(), data.length());
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return finishText(result);
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void getNextSoftBreak(RootInlineBox*& line, Node*& breakNode, unsigned& breakOffset)
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RootInlineBox* next;
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (; line; line = next) {
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        next = line->nextRootBox();
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (next && !line->endsWithBreak()) {
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            ASSERT(line->lineBreakObj());
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            breakNode = line->lineBreakObj()->node();
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            breakOffset = line->lineBreakPos();
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            line = next;
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    breakNode = 0;
4095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    breakOffset = 0;
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString RenderTextControl::textWithHardLineBreaks()
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_innerText)
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "";
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4175ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    RenderBlock* renderer = toRenderBlock(m_innerText->renderer());
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!renderer)
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return "";
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node* breakNode;
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned breakOffset;
4235ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    RootInlineBox* line = renderer->firstRootBox();
4245ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (!line)
4255ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return "";
4265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    getNextSoftBreak(line, breakNode, breakOffset);
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<UChar> result;
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4315ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    for (Node* n = m_innerText->firstChild(); n; n = n->traverseNextNode(m_innerText.get())) {
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (n->hasTagName(brTag))
4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result.append(&newlineCharacter, 1);
4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else if (n->isTextNode()) {
4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Text* text = static_cast<Text*>(n);
4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            String data = text->data();
4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            unsigned length = data.length();
4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            unsigned position = 0;
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (breakNode == n && breakOffset <= length) {
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (breakOffset > position) {
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result.append(data.characters() + position, breakOffset - position);
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    position = breakOffset;
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result.append(&newlineCharacter, 1);
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                getNextSoftBreak(line, breakNode, breakOffset);
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result.append(data.characters() + position, length - position);
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        while (breakNode == n)
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            getNextSoftBreak(line, breakNode, breakOffset);
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return finishText(result);
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
456635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectint RenderTextControl::scrollbarThickness() const
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
458635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // FIXME: We should get the size of the scrollbar from the RenderTheme instead.
459635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return ScrollbarTheme::nativeTheme()->scrollbarThickness();
460635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
462bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderTextControl::computeLogicalHeight()
463635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
464635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    setHeight(m_innerText->renderBox()->borderTop() + m_innerText->renderBox()->borderBottom() +
465635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project              m_innerText->renderBox()->paddingTop() + m_innerText->renderBox()->paddingBottom() +
466635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project              m_innerText->renderBox()->marginTop() + m_innerText->renderBox()->marginBottom());
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
468a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    adjustControlHeightBasedOnLineHeight(m_innerText->renderBox()->lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes));
46921939df44de1705786c545cd1bf519d47250322dBen Murdoch    setHeight(height() + borderAndPaddingHeight());
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We are able to have a horizontal scrollbar if the overflow style is scroll, or if its auto and there's no word wrap.
4728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (style()->overflowX() == OSCROLL ||  (style()->overflowX() == OAUTO && m_innerText->renderer()->style()->wordWrap() == NormalWordWrap))
473635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        setHeight(height() + scrollbarThickness());
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
475bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    RenderBlock::computeLogicalHeight();
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderTextControl::hitInnerTextElement(HitTestResult& result, int xPos, int yPos, int tx, int ty)
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
480635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    result.setInnerNode(m_innerText.get());
4818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    result.setInnerNonSharedNode(m_innerText.get());
482635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    result.setLocalPoint(IntPoint(xPos - tx - x() - m_innerText->renderBox()->x(),
483635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                                  yPos - ty - y() - m_innerText->renderBox()->y()));
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
486635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderTextControl::forwardEvent(Event* event)
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
488635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (event->type() == eventNames().blurEvent || event->type() == eventNames().focusEvent)
489635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
490635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    m_innerText->defaultEventHandler(event);
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
493692e5dbf12901edacf14812a6fae25462920af42Steve Blockstatic const char* fontFamiliesWithInvalidCharWidth[] = {
494692e5dbf12901edacf14812a6fae25462920af42Steve Block    "American Typewriter",
495692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Arial Hebrew",
496692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Chalkboard",
497692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Cochin",
498692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Corsiva Hebrew",
499692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Courier",
500692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Euphemia UCAS",
501692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Geneva",
502692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Gill Sans",
503692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Hei",
504692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Helvetica",
505692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Hoefler Text",
506692e5dbf12901edacf14812a6fae25462920af42Steve Block    "InaiMathi",
507692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Kai",
508692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Lucida Grande",
509692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Marker Felt",
510692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Monaco",
511692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Mshtakan",
512692e5dbf12901edacf14812a6fae25462920af42Steve Block    "New Peninim MT",
513692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Osaka",
514692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Raanana",
515692e5dbf12901edacf14812a6fae25462920af42Steve Block    "STHeiti",
516692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Symbol",
517692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Times",
518692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Apple Braille",
519692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Apple LiGothic",
520692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Apple LiSung",
521692e5dbf12901edacf14812a6fae25462920af42Steve Block    "Apple Symbols",
522692e5dbf12901edacf14812a6fae25462920af42Steve Block    "AppleGothic",
523692e5dbf12901edacf14812a6fae25462920af42Steve Block    "AppleMyungjo",
524692e5dbf12901edacf14812a6fae25462920af42Steve Block    "#GungSeo",
525692e5dbf12901edacf14812a6fae25462920af42Steve Block    "#HeadLineA",
526692e5dbf12901edacf14812a6fae25462920af42Steve Block    "#PCMyungjo",
527692e5dbf12901edacf14812a6fae25462920af42Steve Block    "#PilGi",
528692e5dbf12901edacf14812a6fae25462920af42Steve Block};
529692e5dbf12901edacf14812a6fae25462920af42Steve Block
530692e5dbf12901edacf14812a6fae25462920af42Steve Block// For font families where any of the fonts don't have a valid entry in the OS/2 table
531692e5dbf12901edacf14812a6fae25462920af42Steve Block// for avgCharWidth, fallback to the legacy webkit behavior of getting the avgCharWidth
532692e5dbf12901edacf14812a6fae25462920af42Steve Block// from the width of a '0'. This only seems to apply to a fixed number of Mac fonts,
533692e5dbf12901edacf14812a6fae25462920af42Steve Block// but, in order to get similar rendering across platforms, we do this check for
534692e5dbf12901edacf14812a6fae25462920af42Steve Block// all platforms.
535692e5dbf12901edacf14812a6fae25462920af42Steve Blockbool RenderTextControl::hasValidAvgCharWidth(AtomicString family)
536692e5dbf12901edacf14812a6fae25462920af42Steve Block{
537692e5dbf12901edacf14812a6fae25462920af42Steve Block    static HashSet<AtomicString>* fontFamiliesWithInvalidCharWidthMap = 0;
5384576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
539692e5dbf12901edacf14812a6fae25462920af42Steve Block    if (!fontFamiliesWithInvalidCharWidthMap) {
540692e5dbf12901edacf14812a6fae25462920af42Steve Block        fontFamiliesWithInvalidCharWidthMap = new HashSet<AtomicString>;
5414576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
5424576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        for (size_t i = 0; i < WTF_ARRAY_LENGTH(fontFamiliesWithInvalidCharWidth); ++i)
543692e5dbf12901edacf14812a6fae25462920af42Steve Block            fontFamiliesWithInvalidCharWidthMap->add(AtomicString(fontFamiliesWithInvalidCharWidth[i]));
544692e5dbf12901edacf14812a6fae25462920af42Steve Block    }
545692e5dbf12901edacf14812a6fae25462920af42Steve Block
546692e5dbf12901edacf14812a6fae25462920af42Steve Block    return !fontFamiliesWithInvalidCharWidthMap->contains(family);
547692e5dbf12901edacf14812a6fae25462920af42Steve Block}
548692e5dbf12901edacf14812a6fae25462920af42Steve Block
549692e5dbf12901edacf14812a6fae25462920af42Steve Blockfloat RenderTextControl::getAvgCharWidth(AtomicString family)
550692e5dbf12901edacf14812a6fae25462920af42Steve Block{
551692e5dbf12901edacf14812a6fae25462920af42Steve Block    if (hasValidAvgCharWidth(family))
552692e5dbf12901edacf14812a6fae25462920af42Steve Block        return roundf(style()->font().primaryFont()->avgCharWidth());
553692e5dbf12901edacf14812a6fae25462920af42Steve Block
554692e5dbf12901edacf14812a6fae25462920af42Steve Block    const UChar ch = '0';
55581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return style()->font().width(TextRun(&ch, 1, false, 0, 0, TextRun::AllowTrailingExpansion, false));
556692e5dbf12901edacf14812a6fae25462920af42Steve Block}
557692e5dbf12901edacf14812a6fae25462920af42Steve Block
558692e5dbf12901edacf14812a6fae25462920af42Steve Blockfloat RenderTextControl::scaleEmToUnits(int x) const
559692e5dbf12901edacf14812a6fae25462920af42Steve Block{
560692e5dbf12901edacf14812a6fae25462920af42Steve Block    // This matches the unitsPerEm value for MS Shell Dlg and Courier New from the "head" font table.
561692e5dbf12901edacf14812a6fae25462920af42Steve Block    float unitsPerEm = 2048.0f;
562692e5dbf12901edacf14812a6fae25462920af42Steve Block    return roundf(style()->font().size() * x / unitsPerEm);
563692e5dbf12901edacf14812a6fae25462920af42Steve Block}
564692e5dbf12901edacf14812a6fae25462920af42Steve Block
565bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid RenderTextControl::computePreferredLogicalWidths()
5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
567bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    ASSERT(preferredLogicalWidthsDirty());
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
569bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_minPreferredLogicalWidth = 0;
570bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_maxPreferredLogicalWidth = 0;
5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->width().isFixed() && style()->width().value() > 0)
573bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(style()->width().value());
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else {
5755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // Use average character width. Matches IE.
576692e5dbf12901edacf14812a6fae25462920af42Steve Block        AtomicString family = style()->font().family().family();
577bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_maxPreferredLogicalWidth = preferredContentWidth(getAvgCharWidth(family)) + m_innerText->renderBox()->paddingLeft() + m_innerText->renderBox()->paddingRight();
5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
581bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value()));
582bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->minWidth().value()));
5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (style()->width().isPercent() || (style()->width().isAuto() && style()->height().isPercent()))
584bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = 0;
5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
586bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth;
5878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->maxWidth().isFixed() && style()->maxWidth().value() != undefinedLength) {
589bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->maxWidth().value()));
590bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(style()->maxWidth().value()));
5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
59321939df44de1705786c545cd1bf519d47250322dBen Murdoch    int toAdd = borderAndPaddingWidth();
5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
595bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_minPreferredLogicalWidth += toAdd;
596bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    m_maxPreferredLogicalWidth += toAdd;
5978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
598bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    setPreferredLogicalWidthsDirty(false);
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
601635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid RenderTextControl::selectionChanged(bool userTriggered)
6028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
603635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    cacheSelection(selectionStart(), selectionEnd());
604635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
605545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (Frame* frame = this->frame()) {
606635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (frame->selection()->isRange() && userTriggered)
607231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            node()->dispatchEvent(Event::create(eventNames().selectEvent, true, false));
6088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
611d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid RenderTextControl::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
613d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (width() && height())
614d0825bca7fe65beaee391d30da42e937db621564Steve Block        rects.append(IntRect(tx, ty, width(), height()));
6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
617635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectHTMLElement* RenderTextControl::innerTextElement() const
6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
619635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return m_innerText.get();
6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
622231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderTextControl::updatePlaceholderVisibility(bool placeholderShouldBeVisible, bool placeholderValueChanged)
623231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
624231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool oldPlaceholderVisible = m_placeholderVisible;
625231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_placeholderVisible = placeholderShouldBeVisible;
6266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (oldPlaceholderVisible != m_placeholderVisible || placeholderValueChanged)
6276b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        repaint();
6286b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner}
629231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
6306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid RenderTextControl::paintPlaceholder(PaintInfo& paintInfo, int tx, int ty)
6316b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{
6326b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (style()->visibility() != VISIBLE)
6336b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return;
6346b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
6356b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    IntRect clipRect(tx + borderLeft(), ty + borderTop(), width() - borderLeft() - borderRight(), height() - borderBottom() - borderTop());
6366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (clipRect.isEmpty())
6376b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return;
6386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
6396b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    paintInfo.context->save();
6406b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
6416b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    paintInfo.context->clip(clipRect);
6426b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
6436b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    RefPtr<RenderStyle> placeholderStyle = getCachedPseudoStyle(INPUT_PLACEHOLDER);
6446b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (!placeholderStyle)
6456b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        placeholderStyle = style();
6466b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
6476b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    paintInfo.context->setFillColor(placeholderStyle->visitedDependentColor(CSSPropertyColor), placeholderStyle->colorSpace());
6486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
6496b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    String placeholderText = static_cast<HTMLTextFormControlElement*>(node())->strippedPlaceholder();
65081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    TextRun textRun(placeholderText.characters(), placeholderText.length(), false, 0, 0, TextRun::AllowTrailingExpansion, !placeholderStyle->isLeftToRightDirection(), placeholderStyle->unicodeBidi() == Override);
6516b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
6526b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    RenderBox* textRenderer = innerTextElement() ? innerTextElement()->renderBox() : 0;
6536b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (textRenderer) {
6546b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        IntPoint textPoint;
6552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        textPoint.setY(ty + textBlockInsetTop() + placeholderStyle->fontMetrics().ascent());
6566b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        if (placeholderStyle->isLeftToRightDirection())
6576b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            textPoint.setX(tx + textBlockInsetLeft());
6586b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        else
6596b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner            textPoint.setX(tx + width() - textBlockInsetRight() - style()->font().width(textRun));
6606b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
6616b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        paintInfo.context->drawBidiText(placeholderStyle->font(), textRun, textPoint);
662231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
6636b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    paintInfo.context->restore();
6646b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner}
6656b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
6666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brennervoid RenderTextControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
6676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner{
6686b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (m_placeholderVisible && paintInfo.phase == PaintPhaseForeground)
6696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        paintPlaceholder(paintInfo, tx, ty);
6706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
6716b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    RenderBlock::paintObject(paintInfo, tx, ty);
672231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
673231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
6748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
675