void RenderTextControl::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) { RenderBlockFlow::styleDidChange(diff, oldStyle); TextControlInnerTextElement* innerText = innerTextElement(); if (!innerText) return; RenderTextControlInnerBlock* innerTextRenderer = innerText->renderer(); if (innerTextRenderer) { // We may have set the width and the height in the old style in layout(). // Reset them now to avoid getting a spurious layout hint. innerTextRenderer->style().setHeight(Length()); innerTextRenderer->style().setWidth(Length()); innerTextRenderer->setStyle(createInnerTextStyle(&style())); } textFormControlElement().updatePlaceholderVisibility(); }
void RenderTextControlSingleLine::layout() { StackStats::LayoutCheckPoint layoutCheckPoint; // FIXME: We should remove the height-related hacks in layout() and // styleDidChange(). We need them because // - Center the inner elements vertically if the input height is taller than // the intrinsic height of the inner elements. // - Shrink the inner elment heights if the input height is samller than the // intrinsic heights of the inner elements. // We don't honor paddings and borders for textfields without decorations // and type=search if the text height is taller than the contentHeight() // because of compability. RenderTextControlInnerBlock* innerTextRenderer = innerTextElement()->renderer(); RenderBox* innerBlockRenderer = innerBlockElement() ? innerBlockElement()->renderBox() : 0; // To ensure consistency between layouts, we need to reset any conditionally overriden height. if (innerTextRenderer && !innerTextRenderer->style().logicalHeight().isAuto()) { innerTextRenderer->style().setLogicalHeight(Length(Auto)); setNeedsLayoutOnAncestors(innerTextRenderer, this); } if (innerBlockRenderer && !innerBlockRenderer->style().logicalHeight().isAuto()) { innerBlockRenderer->style().setLogicalHeight(Length(Auto)); setNeedsLayoutOnAncestors(innerBlockRenderer, this); } RenderBlockFlow::layoutBlock(false); HTMLElement* container = containerElement(); RenderBox* containerRenderer = container ? container->renderBox() : 0; // Set the text block height LayoutUnit desiredLogicalHeight = textBlockLogicalHeight(); LayoutUnit logicalHeightLimit = computeLogicalHeightLimit(); if (innerTextRenderer && innerTextRenderer->logicalHeight() > logicalHeightLimit) { if (desiredLogicalHeight != innerTextRenderer->logicalHeight()) setNeedsLayout(MarkOnlyThis); m_desiredInnerTextLogicalHeight = desiredLogicalHeight; innerTextRenderer->style().setLogicalHeight(Length(desiredLogicalHeight, Fixed)); innerTextRenderer->setNeedsLayout(MarkOnlyThis); if (innerBlockRenderer) { innerBlockRenderer->style().setLogicalHeight(Length(desiredLogicalHeight, Fixed)); innerBlockRenderer->setNeedsLayout(MarkOnlyThis); } } // The container might be taller because of decoration elements. if (containerRenderer) { containerRenderer->layoutIfNeeded(); LayoutUnit containerLogicalHeight = containerRenderer->logicalHeight(); if (containerLogicalHeight > logicalHeightLimit) { containerRenderer->style().setLogicalHeight(Length(logicalHeightLimit, Fixed)); setNeedsLayout(MarkOnlyThis); } else if (containerRenderer->logicalHeight() < contentLogicalHeight()) { containerRenderer->style().setLogicalHeight(Length(contentLogicalHeight(), Fixed)); setNeedsLayout(MarkOnlyThis); } else containerRenderer->style().setLogicalHeight(Length(containerLogicalHeight, Fixed)); } // If we need another layout pass, we have changed one of children's height so we need to relayout them. if (needsLayout()) RenderBlockFlow::layoutBlock(true); // Center the child block in the block progression direction (vertical centering for horizontal text fields). if (!container && innerTextRenderer && innerTextRenderer->height() != contentLogicalHeight()) centerRenderer(*innerTextRenderer); else centerContainerIfNeeded(containerRenderer); // Ignores the paddings for the inner spin button. if (RenderBox* innerSpinBox = innerSpinButtonElement() ? innerSpinButtonElement()->renderBox() : 0) { RenderBox* parentBox = innerSpinBox->parentBox(); if (containerRenderer && !containerRenderer->style().isLeftToRightDirection()) innerSpinBox->setLogicalLocation(LayoutPoint(-paddingLogicalLeft(), -paddingBefore())); else innerSpinBox->setLogicalLocation(LayoutPoint(parentBox->logicalWidth() - innerSpinBox->logicalWidth() + paddingLogicalRight(), -paddingBefore())); innerSpinBox->setLogicalHeight(logicalHeight() - borderBefore() - borderAfter()); } HTMLElement* placeholderElement = inputElement().placeholderElement(); if (RenderBox* placeholderBox = placeholderElement ? placeholderElement->renderBox() : 0) { LayoutSize innerTextSize; if (innerTextRenderer) innerTextSize = innerTextRenderer->size(); placeholderBox->style().setWidth(Length(innerTextSize.width() - placeholderBox->horizontalBorderAndPaddingExtent(), Fixed)); placeholderBox->style().setHeight(Length(innerTextSize.height() - placeholderBox->verticalBorderAndPaddingExtent(), Fixed)); bool neededLayout = placeholderBox->needsLayout(); bool placeholderBoxHadLayout = placeholderBox->everHadLayout(); placeholderBox->layoutIfNeeded(); LayoutPoint textOffset; if (innerTextRenderer) textOffset = innerTextRenderer->location(); if (innerBlockElement() && innerBlockElement()->renderBox()) textOffset += toLayoutSize(innerBlockElement()->renderBox()->location()); if (containerRenderer) textOffset += toLayoutSize(containerRenderer->location()); placeholderBox->setLocation(textOffset); if (!placeholderBoxHadLayout && placeholderBox->checkForRepaintDuringLayout()) { // This assumes a shadow tree without floats. If floats are added, the // logic should be shared with RenderBlock::layoutBlockChild. placeholderBox->repaint(); } // The placeholder gets layout last, after the parent text control and its other children, // so in order to get the correct overflow from the placeholder we need to recompute it now. if (neededLayout) computeOverflow(clientLogicalBottom()); } #if PLATFORM(IOS) // FIXME: We should not be adjusting styles during layout. <rdar://problem/7675493> if (inputElement().isSearchField()) RenderThemeIOS::adjustRoundBorderRadius(style(), *this); #endif }