Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[CTTE] Tighten RenderTextControl element typing.
<https://webkit.org/b/121275>

Reviewed by Anders Carlsson.

Codify these invariants:

- RenderTextControl always has a HTMLTextFormControl.
- RenderSearchField always has a HTMLInputElement.
- RenderTextControlSingleLine always has a HTMLInputElement.

None of these renderers are ever anonymous. Deleted element() and added
strongly typed reference getters instead.

Canonical link: https://commits.webkit.org/139228@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@155671 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Andreas Kling committed Sep 13, 2013
1 parent a0d20b4 commit 702535c
Show file tree
Hide file tree
Showing 13 changed files with 85 additions and 81 deletions.
16 changes: 16 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,19 @@
2013-09-12 Andreas Kling <akling@apple.com>

[CTTE] Tighten RenderTextControl element typing.
<https://webkit.org/b/121275>

Reviewed by Anders Carlsson.

Codify these invariants:

- RenderTextControl always has a HTMLTextFormControl.
- RenderSearchField always has a HTMLInputElement.
- RenderTextControlSingleLine always has a HTMLInputElement.

None of these renderers are ever anonymous. Deleted element() and added
strongly typed reference getters instead.

2013-09-12 Andreas Kling <akling@apple.com>

[CTTE] RenderListMarker is always anonymous and owned by RenderListItem.
Expand Down
16 changes: 8 additions & 8 deletions Source/WebCore/accessibility/AccessibilityRenderObject.cpp
Expand Up @@ -1386,8 +1386,8 @@ String AccessibilityRenderObject::selectedText() const
return String(); // need to return something distinct from empty string

if (isNativeTextControl()) {
HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement();
return textControl->selectedText();
HTMLTextFormControlElement& textControl = toRenderTextControl(m_renderer)->textFormControlElement();
return textControl.selectedText();
}

if (ariaRoleAttribute() == UnknownRole)
Expand Down Expand Up @@ -1420,8 +1420,8 @@ PlainTextRange AccessibilityRenderObject::selectedTextRange() const

AccessibilityRole ariaRole = ariaRoleAttribute();
if (isNativeTextControl() && ariaRole == UnknownRole) {
HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement();
return PlainTextRange(textControl->selectionStart(), textControl->selectionEnd() - textControl->selectionStart());
HTMLTextFormControlElement& textControl = toRenderTextControl(m_renderer)->textFormControlElement();
return PlainTextRange(textControl.selectionStart(), textControl.selectionEnd() - textControl.selectionStart());
}

if (ariaRole == UnknownRole)
Expand All @@ -1433,8 +1433,8 @@ PlainTextRange AccessibilityRenderObject::selectedTextRange() const
void AccessibilityRenderObject::setSelectedTextRange(const PlainTextRange& range)
{
if (isNativeTextControl()) {
HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement();
textControl->setSelectionRange(range.start, range.start + range.length);
HTMLTextFormControlElement& textControl = toRenderTextControl(m_renderer)->textFormControlElement();
textControl.setSelectionRange(range.start, range.start + range.length);
return;
}

Expand Down Expand Up @@ -1818,7 +1818,7 @@ VisiblePosition AccessibilityRenderObject::visiblePositionForIndex(int index) co
return VisiblePosition();

if (isNativeTextControl())
return toRenderTextControl(m_renderer)->textFormControlElement()->visiblePositionForIndex(index);
return toRenderTextControl(m_renderer)->textFormControlElement().visiblePositionForIndex(index);

if (!allowsTextRanges() && !m_renderer->isText())
return VisiblePosition();
Expand All @@ -1833,7 +1833,7 @@ VisiblePosition AccessibilityRenderObject::visiblePositionForIndex(int index) co
int AccessibilityRenderObject::indexForVisiblePosition(const VisiblePosition& pos) const
{
if (isNativeTextControl())
return toRenderTextControl(m_renderer)->textFormControlElement()->indexForVisiblePosition(pos);
return toRenderTextControl(m_renderer)->textFormControlElement().indexForVisiblePosition(pos);

if (!isTextControl())
return 0;
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/editing/TextIterator.cpp
Expand Up @@ -681,7 +681,7 @@ bool TextIterator::handleReplacedElement()
}

if (m_entersTextControls && renderer->isTextControl()) {
if (HTMLElement* innerTextElement = toRenderTextControl(renderer)->textFormControlElement()->innerTextElement()) {
if (HTMLElement* innerTextElement = toRenderTextControl(renderer)->textFormControlElement().innerTextElement()) {
m_node = innerTextElement->containingShadowRoot();
pushFullyClippedState(m_fullyClippedStack, m_node);
m_offset = 0;
Expand Down
3 changes: 2 additions & 1 deletion Source/WebCore/html/SearchInputType.cpp
Expand Up @@ -71,7 +71,8 @@ void SearchInputType::addSearchResult()

RenderObject* SearchInputType::createRenderer(RenderArena* arena, RenderStyle*) const
{
return new (arena) RenderSearchField(element());
ASSERT(element()); // FIXME: element() should return a reference.
return new (arena) RenderSearchField(*element());
}

const AtomicString& SearchInputType::formControlType() const
Expand Down
3 changes: 2 additions & 1 deletion Source/WebCore/html/TextFieldInputType.cpp
Expand Up @@ -203,7 +203,8 @@ bool TextFieldInputType::shouldSubmitImplicitly(Event* event)

RenderObject* TextFieldInputType::createRenderer(RenderArena* arena, RenderStyle*) const
{
return new (arena) RenderTextControlSingleLine(element());
ASSERT(element()); // FIXME: element() should return a reference.
return new (arena) RenderTextControlSingleLine(*element());
}

bool TextFieldInputType::needsContainer() const
Expand Down
39 changes: 16 additions & 23 deletions Source/WebCore/rendering/RenderSearchField.cpp
Expand Up @@ -52,16 +52,12 @@ namespace WebCore {

using namespace HTMLNames;

// ----------------------------

RenderSearchField::RenderSearchField(Element* element)
RenderSearchField::RenderSearchField(HTMLInputElement& element)
: RenderTextControlSingleLine(element)
, m_searchPopupIsVisible(false)
, m_searchPopup(0)
{
ASSERT(element->isHTMLElement());
ASSERT(element->toInputElement());
ASSERT(element->toInputElement()->isSearchField());
ASSERT(element.isSearchField());
}

RenderSearchField::~RenderSearchField()
Expand All @@ -74,21 +70,20 @@ RenderSearchField::~RenderSearchField()

inline HTMLElement* RenderSearchField::resultsButtonElement() const
{
return inputElement()->resultsButtonElement();
return inputElement().resultsButtonElement();
}

inline HTMLElement* RenderSearchField::cancelButtonElement() const
{
return inputElement()->cancelButtonElement();
return inputElement().cancelButtonElement();
}

void RenderSearchField::addSearchResult()
{
HTMLInputElement* input = inputElement();
if (input->maxResults() <= 0)
if (inputElement().maxResults() <= 0)
return;

String value = input->value();
String value = inputElement().value();
if (value.isEmpty())
return;

Expand All @@ -102,7 +97,7 @@ void RenderSearchField::addSearchResult()
}

m_recentSearches.insert(0, value);
while (static_cast<int>(m_recentSearches.size()) > input->maxResults())
while (static_cast<int>(m_recentSearches.size()) > inputElement().maxResults())
m_recentSearches.removeLast();

const AtomicString& name = autosaveName();
Expand All @@ -129,11 +124,10 @@ void RenderSearchField::showPopup()
m_searchPopup->loadRecentSearches(name, m_recentSearches);

// Trim the recent searches list if the maximum size has changed since we last saved.
HTMLInputElement* input = inputElement();
if (static_cast<int>(m_recentSearches.size()) > input->maxResults()) {
if (static_cast<int>(m_recentSearches.size()) > inputElement().maxResults()) {
do {
m_recentSearches.removeLast();
} while (static_cast<int>(m_recentSearches.size()) > input->maxResults());
} while (static_cast<int>(m_recentSearches.size()) > inputElement().maxResults());

m_searchPopup->saveRecentSearches(name, m_recentSearches);
}
Expand Down Expand Up @@ -194,19 +188,18 @@ void RenderSearchField::updateCancelButtonVisibility() const

EVisibility RenderSearchField::visibilityForCancelButton() const
{
return (style()->visibility() == HIDDEN || inputElement()->value().isEmpty()) ? HIDDEN : VISIBLE;
return (style()->visibility() == HIDDEN || inputElement().value().isEmpty()) ? HIDDEN : VISIBLE;
}

const AtomicString& RenderSearchField::autosaveName() const
{
return element()->getAttribute(autosaveAttr);
return inputElement().getAttribute(autosaveAttr);
}

// PopupMenuClient methods
void RenderSearchField::valueChanged(unsigned listIndex, bool fireEvents)
{
ASSERT(static_cast<int>(listIndex) < listSize());
HTMLInputElement* input = inputElement();
if (static_cast<int>(listIndex) == (listSize() - 1)) {
if (fireEvents) {
m_recentSearches.clear();
Expand All @@ -218,10 +211,10 @@ void RenderSearchField::valueChanged(unsigned listIndex, bool fireEvents)
}
}
} else {
input->setValue(itemText(listIndex));
inputElement().setValue(itemText(listIndex));
if (fireEvents)
input->onSearch();
input->select();
inputElement().onSearch();
inputElement().select();
}
}

Expand Down Expand Up @@ -339,7 +332,7 @@ bool RenderSearchField::itemIsSelected(unsigned) const

void RenderSearchField::setTextFromItem(unsigned listIndex)
{
inputElement()->setValue(itemText(listIndex));
inputElement().setValue(itemText(listIndex));
}

FontSelector* RenderSearchField::fontSelector() const
Expand All @@ -357,7 +350,7 @@ PassRefPtr<Scrollbar> RenderSearchField::createScrollbar(ScrollableArea* scrolla
RefPtr<Scrollbar> widget;
bool hasCustomScrollbarStyle = style()->hasPseudoStyle(SCROLLBAR);
if (hasCustomScrollbarStyle)
widget = RenderScrollbar::createCustomScrollbar(scrollableArea, orientation, element());
widget = RenderScrollbar::createCustomScrollbar(scrollableArea, orientation, &inputElement());
else
widget = Scrollbar::createNativeScrollbar(scrollableArea, orientation, controlSize);
return widget.release();
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/RenderSearchField.h
Expand Up @@ -33,7 +33,7 @@ class SearchPopupMenu;

class RenderSearchField FINAL : public RenderTextControlSingleLine, private PopupMenuClient {
public:
RenderSearchField(Element*);
RenderSearchField(HTMLInputElement&);
virtual ~RenderSearchField();

void updateCancelButtonVisibility() const;
Expand Down
32 changes: 13 additions & 19 deletions Source/WebCore/rendering/RenderTextControl.cpp
Expand Up @@ -36,24 +36,24 @@ using namespace std;

namespace WebCore {

RenderTextControl::RenderTextControl(Element* element)
: RenderBlockFlow(element)
RenderTextControl::RenderTextControl(HTMLTextFormControlElement& element)
: RenderBlockFlow(&element)
{
ASSERT(isHTMLTextFormControlElement(element));
}

RenderTextControl::~RenderTextControl()
{
}

HTMLTextFormControlElement* RenderTextControl::textFormControlElement() const
HTMLTextFormControlElement& RenderTextControl::textFormControlElement() const
{
return toHTMLTextFormControlElement(element());
ASSERT(RenderObject::node());
return *toHTMLTextFormControlElement(RenderObject::node());
}

HTMLElement* RenderTextControl::innerTextElement() const
{
return textFormControlElement()->innerTextElement();
return textFormControlElement().innerTextElement();
}

void RenderTextControl::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
Expand All @@ -71,19 +71,13 @@ void RenderTextControl::styleDidChange(StyleDifference diff, const RenderStyle*
innerTextRenderer->setStyle(createInnerTextStyle(style()));
innerText->setNeedsStyleRecalc();
}
textFormControlElement()->updatePlaceholderVisibility(false);
textFormControlElement().updatePlaceholderVisibility(false);
}

static inline bool updateUserModifyProperty(Node* node, RenderStyle* style)
static inline bool updateUserModifyProperty(const HTMLTextFormControlElement& element, RenderStyle* style)
{
bool isDisabled = false;
bool isReadOnlyControl = false;

if (node->isElementNode()) {
Element* element = toElement(node);
isDisabled = element->isDisabledFormControl();
isReadOnlyControl = element->isTextFormControl() && toHTMLTextFormControlElement(element)->isReadOnly();
}
bool isDisabled = element.isDisabledFormControl();
bool isReadOnlyControl = element.isReadOnly();

style->setUserModify((isReadOnlyControl || isDisabled) ? READ_ONLY : READ_WRITE_PLAINTEXT_ONLY);
return isDisabled;
Expand All @@ -96,7 +90,7 @@ void RenderTextControl::adjustInnerTextStyle(const RenderStyle* startStyle, Rend
textBlockStyle->setDirection(style()->direction());
textBlockStyle->setUnicodeBidi(style()->unicodeBidi());

bool disabled = updateUserModifyProperty(element(), textBlockStyle);
bool disabled = updateUserModifyProperty(textFormControlElement(), textBlockStyle);
if (disabled)
textBlockStyle->setColor(theme()->disabledTextColor(textBlockStyle->visitedDependentColor(CSSPropertyColor), startStyle->visitedDependentColor(CSSPropertyBackgroundColor)));
}
Expand All @@ -122,7 +116,7 @@ void RenderTextControl::updateFromElement()
{
Element* innerText = innerTextElement();
if (innerText && innerText->renderer())
updateUserModifyProperty(element(), innerText->renderer()->style());
updateUserModifyProperty(textFormControlElement(), innerText->renderer()->style());
}

int RenderTextControl::scrollbarThickness() const
Expand Down Expand Up @@ -297,7 +291,7 @@ void RenderTextControl::addFocusRingRects(Vector<IntRect>& rects, const LayoutPo

RenderObject* RenderTextControl::layoutSpecialExcludedChild(bool relayoutChildren)
{
HTMLElement* placeholder = toHTMLTextFormControlElement(element())->placeholderElement();
HTMLElement* placeholder = textFormControlElement().placeholderElement();
RenderObject* placeholderRenderer = placeholder ? placeholder->renderer() : 0;
if (!placeholderRenderer)
return 0;
Expand Down
6 changes: 4 additions & 2 deletions Source/WebCore/rendering/RenderTextControl.h
Expand Up @@ -33,11 +33,11 @@ class RenderTextControl : public RenderBlockFlow {
public:
virtual ~RenderTextControl();

HTMLTextFormControlElement* textFormControlElement() const;
HTMLTextFormControlElement& textFormControlElement() const;
virtual PassRefPtr<RenderStyle> createInnerTextStyle(const RenderStyle* startStyle) const = 0;

protected:
RenderTextControl(Element*);
RenderTextControl(HTMLTextFormControlElement&);

// This convenience function should not be made public because innerTextElement may outlive the render tree.
HTMLElement* innerTextElement() const;
Expand Down Expand Up @@ -65,6 +65,8 @@ class RenderTextControl : public RenderBlockFlow {
virtual RenderObject* layoutSpecialExcludedChild(bool relayoutChildren);

private:
void element() const WTF_DELETED_FUNCTION;

virtual const char* renderName() const OVERRIDE { return "RenderTextControl"; }
virtual bool isTextControl() const OVERRIDE FINAL { return true; }
virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/RenderTextControlMultiLine.cpp
Expand Up @@ -33,7 +33,7 @@
namespace WebCore {

RenderTextControlMultiLine::RenderTextControlMultiLine(HTMLTextAreaElement& element)
: RenderTextControl(&element)
: RenderTextControl(element)
{
}

Expand Down

0 comments on commit 702535c

Please sign in to comment.