1 /** 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 3 * (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 * 20 */ 21 22 #include "config.h" 23 #include "RenderTextControlMultiLine.h" 24 25 #include "Event.h" 26 #include "EventNames.h" 27 #include "Frame.h" 28 #include "HTMLNames.h" 29 #include "HTMLTextAreaElement.h" 30 #include "HitTestResult.h" 31 #ifdef ANDROID_LAYOUT 32 #include "Settings.h" 33 #endif 34 35 namespace WebCore { 36 37 RenderTextControlMultiLine::RenderTextControlMultiLine(Node* node, bool placeholderVisible) 38 : RenderTextControl(node, placeholderVisible) 39 { 40 } 41 42 RenderTextControlMultiLine::~RenderTextControlMultiLine() 43 { 44 if (node()) 45 static_cast<HTMLTextAreaElement*>(node())->rendererWillBeDestroyed(); 46 } 47 48 void RenderTextControlMultiLine::subtreeHasChanged() 49 { 50 RenderTextControl::subtreeHasChanged(); 51 HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(node()); 52 textArea->setFormControlValueMatchesRenderer(false); 53 textArea->setNeedsValidityCheck(); 54 55 if (!node()->focused()) 56 return; 57 58 node()->dispatchEvent(Event::create(eventNames().inputEvent, true, false)); 59 60 if (Frame* frame = document()->frame()) 61 frame->textDidChangeInTextArea(textArea); 62 } 63 64 bool RenderTextControlMultiLine::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction) 65 { 66 if (!RenderTextControl::nodeAtPoint(request, result, x, y, tx, ty, hitTestAction)) 67 return false; 68 69 bool resultIsTextValueOrPlaceholder 70 = (!m_placeholderVisible && result.innerNode() == innerTextElement()) 71 || (m_placeholderVisible && result.innerNode()->isDescendantOf(innerTextElement())); 72 if (result.innerNode() == node() || resultIsTextValueOrPlaceholder) 73 hitInnerTextElement(result, x, y, tx, ty); 74 75 return true; 76 } 77 78 void RenderTextControlMultiLine::forwardEvent(Event* event) 79 { 80 RenderTextControl::forwardEvent(event); 81 } 82 83 int RenderTextControlMultiLine::preferredContentWidth(float charWidth) const 84 { 85 int factor = static_cast<HTMLTextAreaElement*>(node())->cols(); 86 return static_cast<int>(ceilf(charWidth * factor)) + scrollbarThickness(); 87 } 88 89 void RenderTextControlMultiLine::adjustControlHeightBasedOnLineHeight(int lineHeight) 90 { 91 setHeight(height() + lineHeight * static_cast<HTMLTextAreaElement*>(node())->rows()); 92 } 93 94 int RenderTextControlMultiLine::baselinePosition(bool, bool) const 95 { 96 return height() + marginTop() + marginBottom(); 97 } 98 99 void RenderTextControlMultiLine::updateFromElement() 100 { 101 createSubtreeIfNeeded(0); 102 RenderTextControl::updateFromElement(); 103 104 HTMLTextAreaElement* textArea = static_cast<HTMLTextAreaElement*>(node()); 105 if (m_placeholderVisible) 106 setInnerTextValue(textArea->getAttribute(HTMLNames::placeholderAttr)); 107 else 108 setInnerTextValue(textArea->value()); 109 } 110 111 void RenderTextControlMultiLine::cacheSelection(int start, int end) 112 { 113 static_cast<HTMLTextAreaElement*>(node())->cacheSelection(start, end); 114 } 115 116 PassRefPtr<RenderStyle> RenderTextControlMultiLine::createInnerTextStyle(const RenderStyle* startStyle) const 117 { 118 RefPtr<RenderStyle> textBlockStyle; 119 if (m_placeholderVisible) { 120 if (RenderStyle* pseudoStyle = getCachedPseudoStyle(INPUT_PLACEHOLDER)) 121 textBlockStyle = RenderStyle::clone(pseudoStyle); 122 } 123 if (!textBlockStyle) { 124 textBlockStyle = RenderStyle::create(); 125 textBlockStyle->inheritFrom(startStyle); 126 } 127 128 adjustInnerTextStyle(startStyle, textBlockStyle.get()); 129 textBlockStyle->setDisplay(BLOCK); 130 131 return textBlockStyle.release(); 132 } 133 134 RenderStyle* RenderTextControlMultiLine::textBaseStyle() const 135 { 136 return style(); 137 } 138 139 } 140