15f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2000 Dirk Mueller (mueller@kde.org)
4dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2004, 2006, 2009, 2010 Apple Inc. All rights reserved.
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderWidget.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "AXObjectCache.h"
27643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "AnimationController.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "GraphicsContext.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HitTestResult.h"
30ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "RenderCounter.h"
31545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#include "RenderLayer.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderView.h"
33231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "RenderWidgetProtector.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
35e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if USE(ACCELERATED_COMPOSITING)
36e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "RenderLayerBacking.h"
37e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif
38e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic HashMap<const Widget*, RenderWidget*>& widgetRendererMap()
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static HashMap<const Widget*, RenderWidget*>* staticWidgetRendererMap = new HashMap<const Widget*, RenderWidget*>;
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return *staticWidgetRendererMap;
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
49643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic size_t widgetHierarchyUpdateSuspendCount;
50643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
51643ca7872b450ea4efacab6188849e5aac2ba161Steve Blocktypedef HashMap<RefPtr<Widget>, FrameView*> WidgetToParentMap;
52643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
53643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic WidgetToParentMap& widgetNewParentMap()
54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
55643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    DEFINE_STATIC_LOCAL(WidgetToParentMap, map, ());
56643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return map;
57643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
58643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
59643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid RenderWidget::suspendWidgetHierarchyUpdates()
60643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
61643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    widgetHierarchyUpdateSuspendCount++;
62643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
63643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
64643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid RenderWidget::resumeWidgetHierarchyUpdates()
65643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
66643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ASSERT(widgetHierarchyUpdateSuspendCount);
67643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (widgetHierarchyUpdateSuspendCount == 1) {
68643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        WidgetToParentMap map = widgetNewParentMap();
69643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        widgetNewParentMap().clear();
70643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        WidgetToParentMap::iterator end = map.end();
71643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        for (WidgetToParentMap::iterator it = map.begin(); it != end; ++it) {
72643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            Widget* child = it->first.get();
73643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            ScrollView* currentParent = child->parent();
74643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            FrameView* newParent = it->second;
75643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (newParent != currentParent) {
76643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                if (currentParent)
77643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    currentParent->removeChild(child);
78643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                if (newParent)
79643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                    newParent->addChild(child);
80643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            }
81643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
82643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
83643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    widgetHierarchyUpdateSuspendCount--;
84643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
85643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
86643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic void moveWidgetToParentSoon(Widget* child, FrameView* parent)
87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!widgetHierarchyUpdateSuspendCount) {
89643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (parent)
90643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            parent->addChild(child);
91643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        else
92643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            child->removeFromParent();
93643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return;
94643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
95643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    widgetNewParentMap().set(child, parent);
96643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
97643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderWidget::RenderWidget(Node* node)
995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    : RenderReplaced(node)
1005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    , m_widget(0)
1015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    , m_frameView(node->document()->view())
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Reference counting is used to prevent the widget from being
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // destroyed while inside the Widget code, which might not be
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // able to handle that.
105643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    , m_refCount(1)
106643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
107643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    view()->addWidget(this);
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderWidget::destroy()
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We can't call the base class's destroy because we don't
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // want to unconditionally delete ourselves (we're ref-counted).
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // So the code below includes copied and pasted contents of
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // both RenderBox::destroy() and RenderObject::destroy().
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Fix originally made for <rdar://problem/4228818>.
117231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    animation()->cancelAnimations(this);
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (RenderView* v = view())
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        v->removeWidget(this);
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
123ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
124635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (AXObjectCache::accessibilityEnabled()) {
125635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        document()->axObjectCache()->childrenChanged(this->parent());
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        document()->axObjectCache()->remove(this);
127635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
128c9773ed4ca308bb2b8e70f49ba7fbaa35b1f46a2Steve Block
129c9773ed4ca308bb2b8e70f49ba7fbaa35b1f46a2Steve Block    if (!documentBeingDestroyed() && parent())
130c9773ed4ca308bb2b8e70f49ba7fbaa35b1f46a2Steve Block        parent()->dirtyLinesFromChangedChild(this);
131c9773ed4ca308bb2b8e70f49ba7fbaa35b1f46a2Steve Block
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    remove();
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (m_hasCounterNodeMap)
1352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        RenderCounter::destroyCounterNodes(this);
1362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
137643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    setWidget(0);
138643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // removes from override size map
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hasOverrideSize())
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setOverrideSize(-1);
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1432bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (style() && (style()->logicalHeight().isPercent() || style()->logicalMinHeight().isPercent() || style()->logicalMaxHeight().isPercent()))
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderBlock::removePercentHeightDescendant(this);
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (hasLayer()) {
1478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        layer()->clearClipRects();
1485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        setHasLayer(false);
1498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        destroyLayer();
1508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Grab the arena from node()->document()->renderArena() before clearing the node pointer.
1538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // Clear the node before deref-ing, as this may be deleted when deref is called.
1548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RenderArena* arena = renderArena();
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setNode(0);
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    deref(arena);
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderWidget::~RenderWidget()
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(m_refCount <= 0);
1625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    clearWidget();
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochbool RenderWidget::setWidgetGeometry(const IntRect& frame, const IntSize& boundsSize)
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
167dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!node())
168643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return false;
169643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
170dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    IntRect clipRect = enclosingLayer()->childrenClipRect();
171dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool clipChanged = m_clipRect != clipRect;
172dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool boundsChanged = m_widget->frameRect() != frame;
173dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
174dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!boundsChanged && !clipChanged)
175dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return false;
176dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
177dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_clipRect = clipRect;
178dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
179643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    RenderWidgetProtector protector(this);
180643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    RefPtr<Node> protectedNode(node());
181643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    m_widget->setFrameRect(frame);
18265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (m_widget) // setFrameRect can run arbitrary script, which might clear m_widget.
18365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        m_widget->setBoundsSize(boundsSize);
184e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
185e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if USE(ACCELERATED_COMPOSITING)
186e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (hasLayer() && layer()->isComposited())
187e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        layer()->backing()->updateAfterWidgetResize();
188e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#endif
189e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
190dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return boundsChanged;
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochvoid RenderWidget::setWidget(PassRefPtr<Widget> widget)
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
195643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (widget == m_widget)
196643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return;
197643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
198643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (m_widget) {
199643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        moveWidgetToParentSoon(m_widget.get(), 0);
200643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        widgetRendererMap().remove(m_widget.get());
201643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        clearWidget();
202643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
203643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    m_widget = widget;
204643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (m_widget) {
205643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        widgetRendererMap().add(m_widget.get(), this);
206643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // If we've already received a layout, apply the calculated space to the
207643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // widget immediately, but we have to have really been fully constructed (with a non-null
208643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // style pointer).
209643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (style()) {
210643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (!needsLayout())
21165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch                setWidgetGeometry(IntRect(localToAbsoluteQuad(FloatQuad(contentBoxRect())).boundingBox()), contentBoxRect().size());
212643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (style()->visibility() != VISIBLE)
213643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                m_widget->hide();
2142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            else {
215643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                m_widget->show();
2162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                repaint();
2172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            }
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
219643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        moveWidgetToParentSoon(m_widget.get(), m_frameView);
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderWidget::layout()
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(needsLayout());
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setNeedsLayout(false);
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianvoid RenderWidget::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderReplaced::styleDidChange(diff, oldStyle);
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_widget) {
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (style()->visibility() != VISIBLE)
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_widget->hide();
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_widget->show();
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
241231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid RenderWidget::showSubstituteImage(PassRefPtr<Image> prpImage)
242231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
243231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_substituteImage = prpImage;
244231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    repaint();
245231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
246231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
247f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid RenderWidget::notifyWidget(WidgetNotification notification)
248f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
249f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (m_widget)
250f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_widget->notifyWidget(notification);
251f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
252f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderWidget::paint(PaintInfo& paintInfo, int tx, int ty)
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!shouldPaint(paintInfo, tx, ty))
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
258635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    tx += x();
259635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ty += y();
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (hasBoxDecorations() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection))
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintBoxDecorations(paintInfo, tx, ty);
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintInfo.phase == PaintPhaseMask) {
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        paintMask(paintInfo, tx, ty);
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!m_frameView || paintInfo.phase != PaintPhaseForeground || style()->visibility() != VISIBLE)
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if PLATFORM(MAC)
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style()->highlight() != nullAtom && !paintInfo.context->paintingDisabled())
274635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        paintCustomHighlight(tx - x(), ty - y(), style()->highlight(), true);
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (style()->hasBorderRadius()) {
278231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        IntRect borderRect = IntRect(tx, ty, width(), height());
279231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
280231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (borderRect.isEmpty())
281231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return;
282231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
2838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // Push a clip if we have a border radius, since we want to round the foreground content that gets painted.
2848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        paintInfo.context->save();
285ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        paintInfo.context->addRoundedRectClip(style()->getRoundedBorderFor(borderRect));
2868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
2878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_widget) {
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Tell the widget to paint now.  This is the only time the widget is allowed
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // to paint itself.  That way it will composite properly with z-indexed layers.
291231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (m_substituteImage)
292643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            paintInfo.context->drawImage(m_substituteImage.get(), style()->colorSpace(), m_widget->frameRect());
293d0825bca7fe65beaee391d30da42e937db621564Steve Block        else {
294d0825bca7fe65beaee391d30da42e937db621564Steve Block            IntPoint widgetLocation = m_widget->frameRect().location();
295d0825bca7fe65beaee391d30da42e937db621564Steve Block            IntPoint paintLocation(tx + borderLeft() + paddingLeft(), ty + borderTop() + paddingTop());
296d0825bca7fe65beaee391d30da42e937db621564Steve Block            IntRect paintRect = paintInfo.rect;
297d0825bca7fe65beaee391d30da42e937db621564Steve Block
298d0825bca7fe65beaee391d30da42e937db621564Steve Block            IntSize paintOffset = paintLocation - widgetLocation;
299d0825bca7fe65beaee391d30da42e937db621564Steve Block            // When painting widgets into compositing layers, tx and ty are relative to the enclosing compositing layer,
300d0825bca7fe65beaee391d30da42e937db621564Steve Block            // not the root. In this case, shift the CTM and adjust the paintRect to be root-relative to fix plug-in drawing.
301d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (!paintOffset.isZero()) {
302d0825bca7fe65beaee391d30da42e937db621564Steve Block                paintInfo.context->translate(paintOffset);
303d0825bca7fe65beaee391d30da42e937db621564Steve Block                paintRect.move(-paintOffset);
304d0825bca7fe65beaee391d30da42e937db621564Steve Block            }
305d0825bca7fe65beaee391d30da42e937db621564Steve Block            m_widget->paint(paintInfo.context, paintRect);
3065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
307d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (!paintOffset.isZero())
308d0825bca7fe65beaee391d30da42e937db621564Steve Block                paintInfo.context->translate(-paintOffset);
309d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
3106c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
3116c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (m_widget->isFrameView()) {
3126c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            FrameView* frameView = static_cast<FrameView*>(m_widget.get());
31328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            bool runOverlapTests = !frameView->useSlowRepaintsIfNotOverlapped() || frameView->hasCompositedContentIncludingDescendants();
3146c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            if (paintInfo.overlapTestRequests && runOverlapTests) {
3156c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                ASSERT(!paintInfo.overlapTestRequests->contains(this));
3166c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                paintInfo.overlapTestRequests->set(this, m_widget->frameRect());
3176c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            }
3186c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen         }
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (style()->hasBorderRadius())
3228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        paintInfo.context->restore();
3238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Paint a partially transparent wash over selected widgets.
3258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (isSelected() && !document()->printing()) {
3268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // FIXME: selectionRect() is in absolute, not painting coordinates.
327643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        paintInfo.context->fillRect(selectionRect(), selectionBackgroundColor(), style()->colorSpace());
3288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RenderWidget::setOverlapTestResult(bool isOverlapped)
3325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
3335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(m_widget);
3345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ASSERT(m_widget->isFrameView());
3350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    static_cast<FrameView*>(m_widget.get())->setIsOverlapped(isOverlapped);
3365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
3375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderWidget::deref(RenderArena *arena)
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (--m_refCount <= 0)
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        arenaDelete(arena, this);
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderWidget::updateWidgetPosition()
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
346dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!m_widget || !node()) // Check the node in case destroy() has been called.
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
34965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    IntRect contentBox = contentBoxRect();
35065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    IntRect absoluteContentBox = IntRect(localToAbsoluteQuad(FloatQuad(contentBox)).boundingBox());
35165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    bool boundsChanged = setWidgetGeometry(absoluteContentBox, contentBox.size());
352643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
3538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // if the frame bounds got changed, or if view needs layout (possibly indicating
3548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // content size is wrong) we have to do a layout to set the right widget size
355545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (m_widget && m_widget->isFrameView()) {
3560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        FrameView* frameView = static_cast<FrameView*>(m_widget.get());
35728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        // Check the frame's page to make sure that the frame isn't in the process of being destroyed.
35828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        if ((boundsChanged || frameView->needsLayout()) && frameView->frame()->page())
3598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            frameView->layout();
3608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
363dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid RenderWidget::widgetPositionsUpdated()
364dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
365dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!m_widget)
366dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return;
367dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    m_widget->widgetPositionsUpdated();
368dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
369dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
370dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockIntRect RenderWidget::windowClipRect() const
371dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
372dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!m_frameView)
373dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return IntRect();
374dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
375dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return intersection(m_frameView->contentsToWindow(m_clipRect), m_frameView->windowClipRect());
376dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
377dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderWidget::setSelectionState(SelectionState state)
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (selectionState() != state) {
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RenderReplaced::setSelectionState(state);
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (m_widget)
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_widget->setIsSelected(isSelected());
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RenderWidget::clearWidget()
3885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
3895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    m_widget = 0;
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderWidget* RenderWidget::find(const Widget* widget)
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return widgetRendererMap().get(widget);
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction action)
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool hadResult = result.innerNode();
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool inside = RenderReplaced::nodeAtPoint(request, result, x, y, tx, ty, action);
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Check to see if we are really over the widget itself (and not just in the border/padding area).
403db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    if ((inside || result.isRectBasedTest()) && !hadResult && result.innerNode() == node())
404635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        result.setIsOverWidget(contentBoxRect().contains(result.localPoint()));
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return inside;
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
409