Home | History | Annotate | Download | only in rendering
      1 /**
      2  * Copyright (C) 2005 Apple Computer, Inc.
      3  *
      4  * This library is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU Library General Public
      6  * License as published by the Free Software Foundation; either
      7  * version 2 of the License, or (at your option) any later version.
      8  *
      9  * This library is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  * Library General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Library General Public License
     15  * along with this library; see the file COPYING.LIB.  If not, write to
     16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  * Boston, MA 02110-1301, USA.
     18  *
     19  */
     20 
     21 #include "config.h"
     22 #include "core/rendering/RenderButton.h"
     23 
     24 namespace blink {
     25 
     26 using namespace HTMLNames;
     27 
     28 RenderButton::RenderButton(Element* element)
     29     : RenderFlexibleBox(element)
     30     , m_inner(0)
     31 {
     32 }
     33 
     34 RenderButton::~RenderButton()
     35 {
     36 }
     37 
     38 void RenderButton::addChild(RenderObject* newChild, RenderObject* beforeChild)
     39 {
     40     if (!m_inner) {
     41         // Create an anonymous block.
     42         ASSERT(!firstChild());
     43         m_inner = createAnonymousBlock(style()->display());
     44         RenderFlexibleBox::addChild(m_inner);
     45     }
     46 
     47     m_inner->addChild(newChild, beforeChild);
     48 }
     49 
     50 void RenderButton::removeChild(RenderObject* oldChild)
     51 {
     52     // m_inner should be the only child, but checking for direct children who
     53     // are not m_inner prevents security problems when that assumption is
     54     // violated.
     55     if (oldChild == m_inner || !m_inner || oldChild->parent() == this) {
     56         ASSERT(oldChild == m_inner || !m_inner);
     57         RenderFlexibleBox::removeChild(oldChild);
     58         m_inner = 0;
     59     } else
     60         m_inner->removeChild(oldChild);
     61 }
     62 
     63 void RenderButton::updateAnonymousChildStyle(const RenderObject* child, RenderStyle* childStyle) const
     64 {
     65     ASSERT(!m_inner || child == m_inner);
     66 
     67     childStyle->setFlexGrow(1.0f);
     68     // Use margin:auto instead of align-items:center to get safe centering, i.e.
     69     // when the content overflows, treat it the same as align-items: flex-start.
     70     childStyle->setMarginTop(Length());
     71     childStyle->setMarginBottom(Length());
     72     childStyle->setFlexDirection(style()->flexDirection());
     73     childStyle->setJustifyContent(style()->justifyContent());
     74     childStyle->setFlexWrap(style()->flexWrap());
     75     childStyle->setAlignItems(style()->alignItems());
     76     childStyle->setAlignContent(style()->alignContent());
     77 }
     78 
     79 bool RenderButton::canHaveGeneratedChildren() const
     80 {
     81     // Input elements can't have generated children, but button elements can. We'll
     82     // write the code assuming any other button types that might emerge in the future
     83     // can also have children.
     84     return !isHTMLInputElement(*node());
     85 }
     86 
     87 LayoutRect RenderButton::controlClipRect(const LayoutPoint& additionalOffset) const
     88 {
     89     // Clip to the padding box to at least give content the extra padding space.
     90     return LayoutRect(additionalOffset.x() + borderLeft(), additionalOffset.y() + borderTop(), width() - borderLeft() - borderRight(), height() - borderTop() - borderBottom());
     91 }
     92 
     93 int RenderButton::baselinePosition(FontBaseline baseline, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
     94 {
     95     ASSERT(linePositionMode == PositionOnContainingLine);
     96     // We want to call the RenderBlock version of firstLineBoxBaseline to
     97     // avoid RenderFlexibleBox synthesizing a baseline that we don't want.
     98     // We use this check as a proxy for "are there any line boxes in this button"
     99     if (!hasLineIfEmpty() && RenderBlock::firstLineBoxBaseline() == -1) {
    100         // To ensure that we have a consistent baseline when we have no children,
    101         // even when we have the anonymous RenderBlock child, we calculate the
    102         // baseline for the empty case manually here.
    103         if (direction == HorizontalLine)
    104             return marginTop() + borderTop() + paddingTop() + contentHeight();
    105 
    106         return marginRight() + borderRight() + paddingRight() + contentWidth();
    107     }
    108     return RenderFlexibleBox::baselinePosition(baseline, firstLine, direction, linePositionMode);
    109 }
    110 
    111 } // namespace blink
    112