Move setPseudoStyle() to RenderImage (from RenderElement.)
[WebKit-https.git] / Source / WebCore / rendering / RenderElement.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
5  *           (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com)
6  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
7  * Copyright (C) 2010, 2012 Google Inc. All rights reserved.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24
25 #include "config.h"
26 #include "RenderElement.h"
27
28 #include "AXObjectCache.h"
29 #include "AnimationController.h"
30 #include "ContentData.h"
31 #include "CursorList.h"
32 #include "EventHandler.h"
33 #include "Frame.h"
34 #include "HTMLElement.h"
35 #include "HTMLNames.h"
36 #include "RenderCounter.h"
37 #include "RenderDeprecatedFlexibleBox.h"
38 #include "RenderFlexibleBox.h"
39 #include "RenderGrid.h"
40 #include "RenderImage.h"
41 #include "RenderImageResourceStyleImage.h"
42 #include "RenderLayer.h"
43 #include "RenderLineBreak.h"
44 #include "RenderListItem.h"
45 #include "RenderMultiColumnBlock.h"
46 #include "RenderRegion.h"
47 #include "RenderRuby.h"
48 #include "RenderRubyText.h"
49 #include "RenderTableCaption.h"
50 #include "RenderTableCell.h"
51 #include "RenderTableCol.h"
52 #include "RenderTableRow.h"
53 #include "RenderText.h"
54 #include "RenderView.h"
55 #include "SVGRenderSupport.h"
56 #include "StyleResolver.h"
57 #include <wtf/StackStats.h>
58
59 #if USE(ACCELERATED_COMPOSITING)
60 #include "RenderLayerCompositor.h"
61 #endif
62
63 namespace WebCore {
64
65 bool RenderElement::s_affectsParentBlock = false;
66 bool RenderElement::s_noLongerAffectsParentBlock = false;
67
68 RenderElement::RenderElement(Element* element, unsigned baseTypeFlags)
69     : RenderObject(element)
70     , m_baseTypeFlags(baseTypeFlags)
71     , m_ancestorLineBoxDirty(false)
72     , m_firstChild(nullptr)
73     , m_lastChild(nullptr)
74     , m_style(0)
75 {
76 }
77
78 RenderElement::~RenderElement()
79 {
80     if (m_style) {
81         for (const FillLayer* bgLayer = m_style->backgroundLayers(); bgLayer; bgLayer = bgLayer->next()) {
82             if (StyleImage* backgroundImage = bgLayer->image())
83                 backgroundImage->removeClient(this);
84         }
85
86         for (const FillLayer* maskLayer = m_style->maskLayers(); maskLayer; maskLayer = maskLayer->next()) {
87             if (StyleImage* maskImage = maskLayer->image())
88                 maskImage->removeClient(this);
89         }
90
91         if (StyleImage* borderImage = m_style->borderImage().image())
92             borderImage->removeClient(this);
93
94         if (StyleImage* maskBoxImage = m_style->maskBoxImage().image())
95             maskBoxImage->removeClient(this);
96
97 #if ENABLE(CSS_SHAPES)
98         if (auto shapeValue = m_style->shapeInside()) {
99             if (auto shapeImage = shapeValue->image())
100                 shapeImage->removeClient(this);
101         }
102 #endif
103     }
104 }
105
106 RenderElement* RenderElement::createFor(Element& element, RenderStyle& style)
107 {
108     Document& document = element.document();
109     RenderArena& arena = *document.renderArena();
110
111     // Minimal support for content properties replacing an entire element.
112     // Works only if we have exactly one piece of content and it's a URL.
113     // Otherwise acts as if we didn't support this feature.
114     const ContentData* contentData = style.contentData();
115     if (contentData && !contentData->next() && contentData->isImage() && !element.isPseudoElement()) {
116         RenderImage* image = new (arena) RenderImage(&element);
117         // RenderImageResourceStyleImage requires a style being present on the image but we don't want to
118         // trigger a style change now as the node is not fully attached. Moving this code to style change
119         // doesn't make sense as it should be run once at renderer creation.
120         image->setStyleInternal(&style);
121         if (const StyleImage* styleImage = static_cast<const ImageContentData*>(contentData)->image()) {
122             image->setImageResource(RenderImageResourceStyleImage::create(const_cast<StyleImage*>(styleImage)));
123             image->setIsGeneratedContent();
124         } else
125             image->setImageResource(RenderImageResource::create());
126         image->setStyleInternal(0);
127         return image;
128     }
129
130     if (element.hasTagName(HTMLNames::rubyTag)) {
131         if (style.display() == INLINE)
132             return new (arena) RenderRubyAsInline(element);
133         if (style.display() == BLOCK)
134             return new (arena) RenderRubyAsBlock(element);
135     }
136     // treat <rt> as ruby text ONLY if it still has its default treatment of block
137     if (element.hasTagName(HTMLNames::rtTag) && style.display() == BLOCK)
138         return new (arena) RenderRubyText(element);
139     if (document.cssRegionsEnabled() && style.isDisplayRegionType() && !style.regionThread().isEmpty())
140         return new (arena) RenderRegion(&element, 0);
141     switch (style.display()) {
142     case NONE:
143         return 0;
144     case INLINE:
145         return new (arena) RenderInline(&element);
146     case BLOCK:
147     case INLINE_BLOCK:
148     case RUN_IN:
149     case COMPACT:
150         if ((!style.hasAutoColumnCount() || !style.hasAutoColumnWidth()) && document.regionBasedColumnsEnabled())
151             return new (arena) RenderMultiColumnBlock(element);
152         return new (arena) RenderBlockFlow(&element);
153     case LIST_ITEM:
154         return new (arena) RenderListItem(element);
155     case TABLE:
156     case INLINE_TABLE:
157         return new (arena) RenderTable(&element);
158     case TABLE_ROW_GROUP:
159     case TABLE_HEADER_GROUP:
160     case TABLE_FOOTER_GROUP:
161         return new (arena) RenderTableSection(&element);
162     case TABLE_ROW:
163         return new (arena) RenderTableRow(&element);
164     case TABLE_COLUMN_GROUP:
165     case TABLE_COLUMN:
166         return new (arena) RenderTableCol(element);
167     case TABLE_CELL:
168         return new (arena) RenderTableCell(&element);
169     case TABLE_CAPTION:
170         return new (arena) RenderTableCaption(element);
171     case BOX:
172     case INLINE_BOX:
173         return new (arena) RenderDeprecatedFlexibleBox(element);
174     case FLEX:
175     case INLINE_FLEX:
176         return new (arena) RenderFlexibleBox(&element);
177     case GRID:
178     case INLINE_GRID:
179         return new (arena) RenderGrid(element);
180     }
181     ASSERT_NOT_REACHED();
182     return nullptr;
183 }
184
185 enum StyleCacheState {
186     Cached,
187     Uncached
188 };
189
190 static PassRefPtr<RenderStyle> firstLineStyleForCachedUncachedType(StyleCacheState type, const RenderObject* renderer, RenderStyle* style)
191 {
192     const RenderObject* rendererForFirstLineStyle = renderer;
193     if (renderer->isBeforeOrAfterContent())
194         rendererForFirstLineStyle = renderer->parent();
195
196     if (rendererForFirstLineStyle->isRenderBlockFlow() || rendererForFirstLineStyle->isRenderButton()) {
197         if (RenderBlock* firstLineBlock = rendererForFirstLineStyle->firstLineBlock()) {
198             if (type == Cached)
199                 return firstLineBlock->getCachedPseudoStyle(FIRST_LINE, style);
200             return firstLineBlock->getUncachedPseudoStyle(PseudoStyleRequest(FIRST_LINE), style, firstLineBlock == renderer ? style : 0);
201         }
202     } else if (!rendererForFirstLineStyle->isAnonymous() && rendererForFirstLineStyle->isRenderInline()) {
203         RenderStyle* parentStyle = rendererForFirstLineStyle->parent()->firstLineStyle();
204         if (parentStyle != rendererForFirstLineStyle->parent()->style()) {
205             if (type == Cached) {
206                 // A first-line style is in effect. Cache a first-line style for ourselves.
207                 rendererForFirstLineStyle->style()->setHasPseudoStyle(FIRST_LINE_INHERITED);
208                 return rendererForFirstLineStyle->getCachedPseudoStyle(FIRST_LINE_INHERITED, parentStyle);
209             }
210             return rendererForFirstLineStyle->getUncachedPseudoStyle(PseudoStyleRequest(FIRST_LINE_INHERITED), parentStyle, style);
211         }
212     }
213     return 0;
214 }
215
216 PassRefPtr<RenderStyle> RenderElement::uncachedFirstLineStyle(RenderStyle* style) const
217 {
218     if (!document().styleSheetCollection().usesFirstLineRules())
219         return 0;
220
221     return firstLineStyleForCachedUncachedType(Uncached, this, style);
222 }
223
224 RenderStyle* RenderElement::cachedFirstLineStyle() const
225 {
226     ASSERT(document().styleSheetCollection().usesFirstLineRules());
227
228     RenderStyle* style = this->style();
229     if (RefPtr<RenderStyle> firstLineStyle = firstLineStyleForCachedUncachedType(Cached, this, style))
230         return firstLineStyle.get();
231
232     return style;
233 }
234
235 StyleDifference RenderElement::adjustStyleDifference(StyleDifference diff, unsigned contextSensitiveProperties) const
236 {
237 #if USE(ACCELERATED_COMPOSITING)
238     // If transform changed, and we are not composited, need to do a layout.
239     if (contextSensitiveProperties & ContextSensitivePropertyTransform) {
240         // Text nodes share style with their parents but transforms don't apply to them,
241         // hence the !isText() check.
242         // FIXME: when transforms are taken into account for overflow, we will need to do a layout.
243         if (!hasLayer() || !toRenderLayerModelObject(this)->layer()->isComposited()) {
244             // We need to set at least SimplifiedLayout, but if PositionedMovementOnly is already set
245             // then we actually need SimplifiedLayoutAndPositionedMovement.
246             if (!hasLayer())
247                 diff = StyleDifferenceLayout; // FIXME: Do this for now since SimplifiedLayout cannot handle updating floating objects lists.
248             else if (diff < StyleDifferenceLayoutPositionedMovementOnly)
249                 diff = StyleDifferenceSimplifiedLayout;
250             else if (diff < StyleDifferenceSimplifiedLayout)
251                 diff = StyleDifferenceSimplifiedLayoutAndPositionedMovement;
252         } else if (diff < StyleDifferenceRecompositeLayer)
253             diff = StyleDifferenceRecompositeLayer;
254     }
255
256     // If opacity changed, and we are not composited, need to repaint (also
257     // ignoring text nodes)
258     if (contextSensitiveProperties & ContextSensitivePropertyOpacity) {
259         if (!hasLayer() || !toRenderLayerModelObject(this)->layer()->isComposited())
260             diff = StyleDifferenceRepaintLayer;
261         else if (diff < StyleDifferenceRecompositeLayer)
262             diff = StyleDifferenceRecompositeLayer;
263     }
264     
265 #if ENABLE(CSS_FILTERS)
266     if ((contextSensitiveProperties & ContextSensitivePropertyFilter) && hasLayer()) {
267         RenderLayer* layer = toRenderLayerModelObject(this)->layer();
268         if (!layer->isComposited() || layer->paintsWithFilters())
269             diff = StyleDifferenceRepaintLayer;
270         else if (diff < StyleDifferenceRecompositeLayer)
271             diff = StyleDifferenceRecompositeLayer;
272     }
273 #endif
274     
275     // The answer to requiresLayer() for plugins, iframes, and canvas can change without the actual
276     // style changing, since it depends on whether we decide to composite these elements. When the
277     // layer status of one of these elements changes, we need to force a layout.
278     if (diff == StyleDifferenceEqual && style() && isRenderLayerModelObject()) {
279         if (hasLayer() != toRenderLayerModelObject(this)->requiresLayer())
280             diff = StyleDifferenceLayout;
281     }
282 #else
283     UNUSED_PARAM(contextSensitiveProperties);
284 #endif
285
286     // If we have no layer(), just treat a RepaintLayer hint as a normal Repaint.
287     if (diff == StyleDifferenceRepaintLayer && !hasLayer())
288         diff = StyleDifferenceRepaint;
289
290     return diff;
291 }
292
293 inline bool RenderElement::hasImmediateNonWhitespaceTextChildOrBorderOrOutline() const
294 {
295     for (const RenderObject* renderer = firstChild(); renderer; renderer = renderer->nextSibling()) {
296         if (renderer->isText() && !toRenderText(renderer)->isAllCollapsibleWhitespace())
297             return true;
298         if (renderer->style()->hasOutline() || renderer->style()->hasBorder())
299             return true;
300     }
301     return false;
302 }
303
304 inline bool RenderElement::shouldRepaintForStyleDifference(StyleDifference diff) const
305 {
306     return diff == StyleDifferenceRepaint || (diff == StyleDifferenceRepaintIfTextOrBorderOrOutline && hasImmediateNonWhitespaceTextChildOrBorderOrOutline());
307 }
308
309 void RenderElement::updateFillImages(const FillLayer* oldLayers, const FillLayer* newLayers)
310 {
311     // Optimize the common case
312     if (oldLayers && !oldLayers->next() && newLayers && !newLayers->next() && (oldLayers->image() == newLayers->image()))
313         return;
314     
315     // Go through the new layers and addClients first, to avoid removing all clients of an image.
316     for (const FillLayer* currNew = newLayers; currNew; currNew = currNew->next()) {
317         if (currNew->image())
318             currNew->image()->addClient(this);
319     }
320
321     for (const FillLayer* currOld = oldLayers; currOld; currOld = currOld->next()) {
322         if (currOld->image())
323             currOld->image()->removeClient(this);
324     }
325 }
326
327 void RenderElement::updateImage(StyleImage* oldImage, StyleImage* newImage)
328 {
329     if (oldImage == newImage)
330         return;
331     if (oldImage)
332         oldImage->removeClient(this);
333     if (newImage)
334         newImage->addClient(this);
335 }
336
337 #if ENABLE(CSS_SHAPES)
338 void RenderElement::updateShapeImage(const ShapeValue* oldShapeValue, const ShapeValue* newShapeValue)
339 {
340     if (oldShapeValue || newShapeValue)
341         updateImage(oldShapeValue ? oldShapeValue->image() : 0, newShapeValue ? newShapeValue->image() : 0);
342 }
343 #endif
344
345 void RenderElement::setStyle(PassRefPtr<RenderStyle> style)
346 {
347     if (m_style == style) {
348 #if USE(ACCELERATED_COMPOSITING)
349         // We need to run through adjustStyleDifference() for iframes, plugins, and canvas so
350         // style sharing is disabled for them. That should ensure that we never hit this code path.
351         ASSERT(!isRenderIFrame() && !isEmbeddedObject() && !isCanvas());
352 #endif
353         return;
354     }
355
356     StyleDifference diff = StyleDifferenceEqual;
357     unsigned contextSensitiveProperties = ContextSensitivePropertyNone;
358     if (m_style)
359         diff = m_style->diff(style.get(), contextSensitiveProperties);
360
361     diff = adjustStyleDifference(diff, contextSensitiveProperties);
362
363     styleWillChange(diff, style.get());
364     
365     RefPtr<RenderStyle> oldStyle = m_style.release();
366     setStyleInternal(style);
367
368     updateFillImages(oldStyle ? oldStyle->backgroundLayers() : 0, m_style ? m_style->backgroundLayers() : 0);
369     updateFillImages(oldStyle ? oldStyle->maskLayers() : 0, m_style ? m_style->maskLayers() : 0);
370
371     updateImage(oldStyle ? oldStyle->borderImage().image() : 0, m_style ? m_style->borderImage().image() : 0);
372     updateImage(oldStyle ? oldStyle->maskBoxImage().image() : 0, m_style ? m_style->maskBoxImage().image() : 0);
373
374 #if ENABLE(CSS_SHAPES)
375     updateShapeImage(oldStyle ? oldStyle->shapeInside() : 0, m_style ? m_style->shapeInside() : 0);
376 #endif
377
378     // We need to ensure that view->maximalOutlineSize() is valid for any repaints that happen
379     // during styleDidChange (it's used by clippedOverflowRectForRepaint()).
380     if (m_style->outlineWidth() > 0 && m_style->outlineSize() > maximalOutlineSize(PaintPhaseOutline))
381         view().setMaximalOutlineSize(m_style->outlineSize());
382
383     bool doesNotNeedLayout = !parent();
384
385     styleDidChange(diff, oldStyle.get());
386
387     // Text renderers use their parent style. Notify them about the change.
388     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
389         if (child->isText())
390             toRenderText(child)->styleDidChange(diff, oldStyle.get());
391     }
392
393     // FIXME: |this| might be destroyed here. This can currently happen for a RenderTextFragment when
394     // its first-letter block gets an update in RenderTextFragment::styleDidChange. For RenderTextFragment(s),
395     // we will safely bail out with the doesNotNeedLayout flag. We might want to broaden this condition
396     // in the future as we move renderer changes out of layout and into style changes.
397     if (doesNotNeedLayout)
398         return;
399
400     // Now that the layer (if any) has been updated, we need to adjust the diff again,
401     // check whether we should layout now, and decide if we need to repaint.
402     StyleDifference updatedDiff = adjustStyleDifference(diff, contextSensitiveProperties);
403     
404     if (diff <= StyleDifferenceLayoutPositionedMovementOnly) {
405         if (updatedDiff == StyleDifferenceLayout)
406             setNeedsLayoutAndPrefWidthsRecalc();
407         else if (updatedDiff == StyleDifferenceLayoutPositionedMovementOnly)
408             setNeedsPositionedMovementLayout(oldStyle.get());
409         else if (updatedDiff == StyleDifferenceSimplifiedLayoutAndPositionedMovement) {
410             setNeedsPositionedMovementLayout(oldStyle.get());
411             setNeedsSimplifiedNormalFlowLayout();
412         } else if (updatedDiff == StyleDifferenceSimplifiedLayout)
413             setNeedsSimplifiedNormalFlowLayout();
414     }
415
416     if (updatedDiff == StyleDifferenceRepaintLayer || shouldRepaintForStyleDifference(updatedDiff)) {
417         // Do a repaint with the new style now, e.g., for example if we go from
418         // not having an outline to having an outline.
419         repaint();
420     }
421 }
422
423 void RenderElement::setAnimatableStyle(PassRefPtr<RenderStyle> style)
424 {
425     setStyle(animation().updateAnimations(this, style.get()));
426 }
427
428 void RenderElement::addChild(RenderObject* newChild, RenderObject* beforeChild)
429 {
430     bool needsTable = false;
431
432     if (newChild->isRenderTableCol()) {
433         RenderTableCol* newTableColumn = toRenderTableCol(newChild);
434         bool isColumnInColumnGroup = newTableColumn->isTableColumn() && isRenderTableCol();
435         needsTable = !isTable() && !isColumnInColumnGroup;
436     } else if (newChild->isTableCaption())
437         needsTable = !isTable();
438     else if (newChild->isTableSection())
439         needsTable = !isTable();
440     else if (newChild->isTableRow())
441         needsTable = !isTableSection();
442     else if (newChild->isTableCell())
443         needsTable = !isTableRow();
444
445     if (needsTable) {
446         RenderTable* table;
447         RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : m_lastChild;
448         if (afterChild && afterChild->isAnonymous() && afterChild->isTable() && !afterChild->isBeforeContent())
449             table = toRenderTable(afterChild);
450         else {
451             table = RenderTable::createAnonymousWithParentRenderer(this);
452             addChild(table, beforeChild);
453         }
454         table->addChild(newChild);
455     } else
456         insertChildInternal(newChild, beforeChild, NotifyChildren);
457
458     if (newChild->isText())
459         toRenderText(newChild)->styleDidChange(StyleDifferenceEqual, nullptr);
460
461     // SVG creates renderers for <g display="none">, as SVG requires children of hidden
462     // <g>s to have renderers - at least that's how our implementation works. Consider:
463     // <g display="none"><foreignObject><body style="position: relative">FOO...
464     // - requiresLayer() would return true for the <body>, creating a new RenderLayer
465     // - when the document is painted, both layers are painted. The <body> layer doesn't
466     //   know that it's inside a "hidden SVG subtree", and thus paints, even if it shouldn't.
467     // To avoid the problem alltogether, detect early if we're inside a hidden SVG subtree
468     // and stop creating layers at all for these cases - they're not used anyways.
469     if (newChild->hasLayer() && !layerCreationAllowedForSubtree())
470         toRenderLayerModelObject(newChild)->layer()->removeOnlyThisLayer();
471
472 #if ENABLE(SVG)
473     SVGRenderSupport::childAdded(this, newChild);
474 #endif
475 }
476
477 void RenderElement::removeChild(RenderObject* oldChild)
478 {
479     removeChildInternal(oldChild, NotifyChildren);
480 }
481
482 void RenderElement::destroyLeftoverChildren()
483 {
484     while (m_firstChild) {
485         if (m_firstChild->isListMarker() || (m_firstChild->style()->styleType() == FIRST_LETTER && !m_firstChild->isText()))
486             m_firstChild->removeFromParent(); // List markers are owned by their enclosing list and so don't get destroyed by this container. Similarly, first letters are destroyed by their remaining text fragment.
487         else if (m_firstChild->isRunIn() && m_firstChild->node()) {
488             m_firstChild->node()->setRenderer(0);
489             m_firstChild->node()->setNeedsStyleRecalc();
490             m_firstChild->destroy();
491         } else {
492             // Destroy any anonymous children remaining in the render tree, as well as implicit (shadow) DOM elements like those used in the engine-based text fields.
493             if (m_firstChild->node())
494                 m_firstChild->node()->setRenderer(0);
495             m_firstChild->destroy();
496         }
497     }
498 }
499
500 void RenderElement::insertChildInternal(RenderObject* newChild, RenderObject* beforeChild, NotifyChildrenType notifyChildren)
501 {
502     ASSERT(canHaveChildren() || canHaveGeneratedChildren());
503     ASSERT(!newChild->parent());
504     ASSERT(!isRenderBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell()));
505
506     while (beforeChild && beforeChild->parent() && beforeChild->parent() != this)
507         beforeChild = beforeChild->parent();
508
509     // This should never happen, but if it does prevent render tree corruption
510     // where child->parent() ends up being owner but child->nextSibling()->parent()
511     // is not owner.
512     if (beforeChild && beforeChild->parent() != this) {
513         ASSERT_NOT_REACHED();
514         return;
515     }
516
517     newChild->setParent(this);
518
519     if (m_firstChild == beforeChild)
520         m_firstChild = newChild;
521
522     if (beforeChild) {
523         RenderObject* previousSibling = beforeChild->previousSibling();
524         if (previousSibling)
525             previousSibling->setNextSibling(newChild);
526         newChild->setPreviousSibling(previousSibling);
527         newChild->setNextSibling(beforeChild);
528         beforeChild->setPreviousSibling(newChild);
529     } else {
530         if (lastChild())
531             lastChild()->setNextSibling(newChild);
532         newChild->setPreviousSibling(lastChild());
533         m_lastChild = newChild;
534     }
535
536     if (!documentBeingDestroyed()) {
537         if (notifyChildren == NotifyChildren)
538             newChild->insertedIntoTree();
539         RenderCounter::rendererSubtreeAttached(newChild);
540     }
541
542     newChild->setNeedsLayoutAndPrefWidthsRecalc();
543     setPreferredLogicalWidthsDirty(true);
544     if (!normalChildNeedsLayout())
545         setChildNeedsLayout(); // We may supply the static position for an absolute positioned child.
546
547     if (AXObjectCache* cache = document().axObjectCache())
548         cache->childrenChanged(this);
549 }
550
551 void RenderElement::removeChildInternal(RenderObject* oldChild, NotifyChildrenType notifyChildren)
552 {
553     ASSERT(canHaveChildren() || canHaveGeneratedChildren());
554     ASSERT(oldChild->parent() == this);
555
556     if (oldChild->isFloatingOrOutOfFlowPositioned())
557         toRenderBox(oldChild)->removeFloatingOrPositionedChildFromBlockLists();
558
559     // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or
560     // that a positioned child got yanked). We also repaint, so that the area exposed when the child
561     // disappears gets repainted properly.
562     if (!documentBeingDestroyed() && notifyChildren == NotifyChildren && oldChild->everHadLayout()) {
563         oldChild->setNeedsLayoutAndPrefWidthsRecalc();
564         // We only repaint |oldChild| if we have a RenderLayer as its visual overflow may not be tracked by its parent.
565         if (oldChild->isBody())
566             view().repaintRootContents();
567         else
568             oldChild->repaint();
569     }
570
571     // If we have a line box wrapper, delete it.
572     if (oldChild->isBox())
573         toRenderBox(oldChild)->deleteLineBoxWrapper();
574     else if (oldChild->isLineBreak())
575         toRenderLineBreak(oldChild)->deleteInlineBoxWrapper();
576
577     // If oldChild is the start or end of the selection, then clear the selection to
578     // avoid problems of invalid pointers.
579     // FIXME: The FrameSelection should be responsible for this when it
580     // is notified of DOM mutations.
581     if (!documentBeingDestroyed() && oldChild->isSelectionBorder())
582         view().clearSelection();
583
584     if (!documentBeingDestroyed() && notifyChildren == NotifyChildren)
585         oldChild->willBeRemovedFromTree();
586
587     // WARNING: There should be no code running between willBeRemovedFromTree and the actual removal below.
588     // This is needed to avoid race conditions where willBeRemovedFromTree would dirty the tree's structure
589     // and the code running here would force an untimely rebuilding, leaving |oldChild| dangling.
590
591     if (oldChild->previousSibling())
592         oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
593     if (oldChild->nextSibling())
594         oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
595
596     if (m_firstChild == oldChild)
597         m_firstChild = oldChild->nextSibling();
598     if (m_lastChild == oldChild)
599         m_lastChild = oldChild->previousSibling();
600
601     oldChild->setPreviousSibling(0);
602     oldChild->setNextSibling(0);
603     oldChild->setParent(0);
604
605     // rendererRemovedFromTree walks the whole subtree. We can improve performance
606     // by skipping this step when destroying the entire tree.
607     if (!documentBeingDestroyed())
608         RenderCounter::rendererRemovedFromTree(oldChild);
609
610     if (AXObjectCache* cache = document().existingAXObjectCache())
611         cache->childrenChanged(this);
612 }
613
614 static void addLayers(RenderElement* obj, RenderLayer* parentLayer, RenderElement*& newObject, RenderLayer*& beforeChild)
615 {
616     if (obj->hasLayer()) {
617         if (!beforeChild && newObject) {
618             // We need to figure out the layer that follows newObject. We only do
619             // this the first time we find a child layer, and then we update the
620             // pointer values for newObject and beforeChild used by everyone else.
621             beforeChild = newObject->parent()->findNextLayer(parentLayer, newObject);
622             newObject = nullptr;
623         }
624         parentLayer->addChild(toRenderLayerModelObject(obj)->layer(), beforeChild);
625         return;
626     }
627
628     for (RenderObject* current = obj->firstChild(); current; current = current->nextSibling()) {
629         if (current->isRenderElement())
630             addLayers(toRenderElement(current), parentLayer, newObject, beforeChild);
631     }
632 }
633
634 void RenderElement::addLayers(RenderLayer* parentLayer)
635 {
636     if (!parentLayer)
637         return;
638
639     RenderElement* renderer = this;
640     RenderLayer* beforeChild = nullptr;
641     WebCore::addLayers(this, parentLayer, renderer, beforeChild);
642 }
643
644 void RenderElement::removeLayers(RenderLayer* parentLayer)
645 {
646     if (!parentLayer)
647         return;
648
649     if (hasLayer()) {
650         parentLayer->removeChild(toRenderLayerModelObject(this)->layer());
651         return;
652     }
653
654     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
655         if (child->isRenderElement())
656             toRenderElement(child)->removeLayers(parentLayer);
657     }
658 }
659
660 void RenderElement::moveLayers(RenderLayer* oldParent, RenderLayer* newParent)
661 {
662     if (!newParent)
663         return;
664
665     if (hasLayer()) {
666         RenderLayer* layer = toRenderLayerModelObject(this)->layer();
667         ASSERT(oldParent == layer->parent());
668         if (oldParent)
669             oldParent->removeChild(layer);
670         newParent->addChild(layer);
671         return;
672     }
673
674     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
675         if (child->isRenderElement())
676             toRenderElement(child)->moveLayers(oldParent, newParent);
677     }
678 }
679
680 RenderLayer* RenderElement::findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint, bool checkParent)
681 {
682     // Error check the parent layer passed in. If it's null, we can't find anything.
683     if (!parentLayer)
684         return 0;
685
686     // Step 1: If our layer is a child of the desired parent, then return our layer.
687     RenderLayer* ourLayer = hasLayer() ? toRenderLayerModelObject(this)->layer() : nullptr;
688     if (ourLayer && ourLayer->parent() == parentLayer)
689         return ourLayer;
690
691     // Step 2: If we don't have a layer, or our layer is the desired parent, then descend
692     // into our siblings trying to find the next layer whose parent is the desired parent.
693     if (!ourLayer || ourLayer == parentLayer) {
694         for (RenderObject* child = startPoint ? startPoint->nextSibling() : firstChild(); child; child = child->nextSibling()) {
695             if (!child->isRenderElement())
696                 continue;
697             RenderLayer* nextLayer = toRenderElement(child)->findNextLayer(parentLayer, nullptr, false);
698             if (nextLayer)
699                 return nextLayer;
700         }
701     }
702
703     // Step 3: If our layer is the desired parent layer, then we're finished. We didn't
704     // find anything.
705     if (parentLayer == ourLayer)
706         return nullptr;
707
708     // Step 4: If |checkParent| is set, climb up to our parent and check its siblings that
709     // follow us to see if we can locate a layer.
710     if (checkParent && parent())
711         return parent()->findNextLayer(parentLayer, this, true);
712
713     return nullptr;
714 }
715
716 bool RenderElement::layerCreationAllowedForSubtree() const
717 {
718 #if ENABLE(SVG)
719     RenderElement* parentRenderer = parent();
720     while (parentRenderer) {
721         if (parentRenderer->isSVGHiddenContainer())
722             return false;
723         parentRenderer = parentRenderer->parent();
724     }
725 #endif
726     
727     return true;
728 }
729
730 void RenderElement::propagateStyleToAnonymousChildren(StylePropagationType propagationType)
731 {
732     // FIXME: We could save this call when the change only affected non-inherited properties.
733     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
734         if (child->isText())
735             continue;
736         if (!child->isAnonymous() || child->style()->styleType() != NOPSEUDO)
737             continue;
738
739         if (propagationType == PropagateToBlockChildrenOnly && !child->isRenderBlock())
740             continue;
741
742 #if ENABLE(FULLSCREEN_API)
743         if (child->isRenderFullScreen() || child->isRenderFullScreenPlaceholder())
744             continue;
745 #endif
746
747         RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), child->style()->display());
748         if (style()->specifiesColumns()) {
749             if (child->style()->specifiesColumns())
750                 newStyle->inheritColumnPropertiesFrom(style());
751             if (child->style()->columnSpan())
752                 newStyle->setColumnSpan(ColumnSpanAll);
753         }
754
755         // Preserve the position style of anonymous block continuations as they can have relative or sticky position when
756         // they contain block descendants of relative or sticky positioned inlines.
757         if (child->isInFlowPositioned() && toRenderBlock(child)->isAnonymousBlockContinuation())
758             newStyle->setPosition(child->style()->position());
759
760         toRenderElement(child)->setStyle(newStyle.release());
761     }
762 }
763
764 // On low-powered/mobile devices, preventing blitting on a scroll can cause noticeable delays
765 // when scrolling a page with a fixed background image. As an optimization, assuming there are
766 // no fixed positoned elements on the page, we can acclerate scrolling (via blitting) if we
767 // ignore the CSS property "background-attachment: fixed".
768 static bool shouldRepaintFixedBackgroundsOnScroll()
769 {
770 #if ENABLE(FAST_MOBILE_SCROLLING)
771     return false;
772 #else
773     return true;
774 #endif
775 }
776
777 static inline bool rendererHasBackground(const RenderObject* renderer)
778 {
779     return renderer && renderer->hasBackground();
780 }
781
782 void RenderElement::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
783 {
784     if (m_style) {
785         // If our z-index changes value or our visibility changes,
786         // we need to dirty our stacking context's z-order list.
787         if (newStyle) {
788             bool visibilityChanged = m_style->visibility() != newStyle->visibility() 
789                 || m_style->zIndex() != newStyle->zIndex() 
790                 || m_style->hasAutoZIndex() != newStyle->hasAutoZIndex();
791 #if ENABLE(DASHBOARD_SUPPORT) || ENABLE(DRAGGABLE_REGION)
792             if (visibilityChanged)
793                 document().setAnnotatedRegionsDirty(true);
794 #endif
795             if (visibilityChanged) {
796                 if (AXObjectCache* cache = document().existingAXObjectCache())
797                     cache->childrenChanged(parent());
798             }
799
800             // Keep layer hierarchy visibility bits up to date if visibility changes.
801             if (m_style->visibility() != newStyle->visibility()) {
802                 if (RenderLayer* layer = enclosingLayer()) {
803                     if (newStyle->visibility() == VISIBLE)
804                         layer->setHasVisibleContent();
805                     else if (layer->hasVisibleContent() && (this == &layer->renderer() || layer->renderer().style()->visibility() != VISIBLE)) {
806                         layer->dirtyVisibleContentStatus();
807                         if (diff > StyleDifferenceRepaintLayer)
808                             repaint();
809                     }
810                 }
811             }
812         }
813
814         if (m_parent && (newStyle->outlineSize() < m_style->outlineSize() || shouldRepaintForStyleDifference(diff)))
815             repaint();
816         if (isFloating() && (m_style->floating() != newStyle->floating()))
817             // For changes in float styles, we need to conceivably remove ourselves
818             // from the floating objects list.
819             toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
820         else if (isOutOfFlowPositioned() && (m_style->position() != newStyle->position()))
821             // For changes in positioning styles, we need to conceivably remove ourselves
822             // from the positioned objects list.
823             toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
824
825         s_affectsParentBlock = isFloatingOrOutOfFlowPositioned()
826             && (!newStyle->isFloating() && !newStyle->hasOutOfFlowPosition())
827             && parent() && (parent()->isRenderBlockFlow() || parent()->isRenderInline());
828
829         s_noLongerAffectsParentBlock = ((!isFloating() && newStyle->isFloating()) || (!isOutOfFlowPositioned() && newStyle->hasOutOfFlowPosition()))
830             && parent() && parent()->isRenderBlock();
831
832         // reset style flags
833         if (diff == StyleDifferenceLayout || diff == StyleDifferenceLayoutPositionedMovementOnly) {
834             setFloating(false);
835             clearPositionedState();
836         }
837         setHorizontalWritingMode(true);
838         setHasBoxDecorations(false);
839         setHasOverflowClip(false);
840         setHasTransform(false);
841         setHasReflection(false);
842     } else {
843         s_affectsParentBlock = false;
844         s_noLongerAffectsParentBlock = false;
845     }
846
847     bool repaintFixedBackgroundsOnScroll = shouldRepaintFixedBackgroundsOnScroll();
848
849     bool newStyleSlowScroll = newStyle && repaintFixedBackgroundsOnScroll && newStyle->hasFixedBackgroundImage();
850     bool oldStyleSlowScroll = m_style && repaintFixedBackgroundsOnScroll && m_style->hasFixedBackgroundImage();
851
852 #if USE(ACCELERATED_COMPOSITING)
853     bool drawsRootBackground = isRoot() || (isBody() && !rendererHasBackground(document().documentElement()->renderer()));
854     if (drawsRootBackground && repaintFixedBackgroundsOnScroll) {
855         if (view().compositor().supportsFixedRootBackgroundCompositing()) {
856             if (newStyleSlowScroll && newStyle->hasEntirelyFixedBackground())
857                 newStyleSlowScroll = false;
858
859             if (oldStyleSlowScroll && m_style->hasEntirelyFixedBackground())
860                 oldStyleSlowScroll = false;
861         }
862     }
863 #endif
864     if (oldStyleSlowScroll != newStyleSlowScroll) {
865         if (oldStyleSlowScroll)
866             view().frameView().removeSlowRepaintObject(this);
867
868         if (newStyleSlowScroll)
869             view().frameView().addSlowRepaintObject(this);
870     }
871 }
872
873 static bool areNonIdenticalCursorListsEqual(const RenderStyle* a, const RenderStyle* b)
874 {
875     ASSERT(a->cursors() != b->cursors());
876     return a->cursors() && b->cursors() && *a->cursors() == *b->cursors();
877 }
878
879 static inline bool areCursorsEqual(const RenderStyle* a, const RenderStyle* b)
880 {
881     return a->cursor() == b->cursor() && (a->cursors() == b->cursors() || areNonIdenticalCursorListsEqual(a, b));
882 }
883
884 void RenderElement::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
885 {
886     if (s_affectsParentBlock)
887         handleDynamicFloatPositionChange();
888
889     if (s_noLongerAffectsParentBlock)
890         removeAnonymousWrappersForInlinesIfNecessary();
891 #if ENABLE(SVG)
892     SVGRenderSupport::styleChanged(this);
893 #endif
894
895     if (!m_parent)
896         return;
897     
898     if (diff == StyleDifferenceLayout || diff == StyleDifferenceSimplifiedLayout) {
899         RenderCounter::rendererStyleChanged(this, oldStyle, m_style.get());
900
901         // If the object already needs layout, then setNeedsLayout won't do
902         // any work. But if the containing block has changed, then we may need
903         // to mark the new containing blocks for layout. The change that can
904         // directly affect the containing block of this object is a change to
905         // the position style.
906         if (needsLayout() && oldStyle->position() != m_style->position())
907             markContainingBlocksForLayout();
908
909         if (diff == StyleDifferenceLayout)
910             setNeedsLayoutAndPrefWidthsRecalc();
911         else
912             setNeedsSimplifiedNormalFlowLayout();
913     } else if (diff == StyleDifferenceSimplifiedLayoutAndPositionedMovement) {
914         setNeedsPositionedMovementLayout(oldStyle);
915         setNeedsSimplifiedNormalFlowLayout();
916     } else if (diff == StyleDifferenceLayoutPositionedMovementOnly)
917         setNeedsPositionedMovementLayout(oldStyle);
918
919     // Don't check for repaint here; we need to wait until the layer has been
920     // updated by subclasses before we know if we have to repaint (in setStyle()).
921
922     if (oldStyle && !areCursorsEqual(oldStyle, style()))
923         frame().eventHandler().scheduleCursorUpdate();
924 }
925
926 void RenderElement::insertedIntoTree()
927 {
928     RenderObject::insertedIntoTree();
929
930     // Keep our layer hierarchy updated. Optimize for the common case where we don't have any children
931     // and don't have a layer attached to ourselves.
932     RenderLayer* layer = nullptr;
933     if (firstChild() || hasLayer()) {
934         layer = parent()->enclosingLayer();
935         addLayers(layer);
936     }
937
938     // If |this| is visible but this object was not, tell the layer it has some visible content
939     // that needs to be drawn and layer visibility optimization can't be used
940     if (parent()->style()->visibility() != VISIBLE && style()->visibility() == VISIBLE && !hasLayer()) {
941         if (!layer)
942             layer = parent()->enclosingLayer();
943         if (layer)
944             layer->setHasVisibleContent();
945     }
946 }
947
948 void RenderElement::willBeRemovedFromTree()
949 {
950     // If we remove a visible child from an invisible parent, we don't know the layer visibility any more.
951     RenderLayer* layer = nullptr;
952     if (parent()->style()->visibility() != VISIBLE && style()->visibility() == VISIBLE && !hasLayer()) {
953         if ((layer = parent()->enclosingLayer()))
954             layer->dirtyVisibleContentStatus();
955     }
956     // Keep our layer hierarchy updated.
957     if (firstChild() || hasLayer()) {
958         if (!layer)
959             layer = parent()->enclosingLayer();
960         removeLayers(layer);
961     }
962
963     bool repaintFixedBackgroundsOnScroll = shouldRepaintFixedBackgroundsOnScroll();
964     if (repaintFixedBackgroundsOnScroll && m_style && m_style->hasFixedBackgroundImage())
965         view().frameView().removeSlowRepaintObject(this);
966
967     if (isOutOfFlowPositioned() && parent()->childrenInline())
968         parent()->dirtyLinesFromChangedChild(this);
969
970     RenderObject::willBeRemovedFromTree();
971 }
972
973 void RenderElement::willBeDestroyed()
974 {
975     animation().cancelAnimations(this);
976
977     destroyLeftoverChildren();
978
979     RenderObject::willBeDestroyed();
980 }
981
982 void RenderElement::setNeedsPositionedMovementLayout(const RenderStyle* oldStyle)
983 {
984     ASSERT(!isSetNeedsLayoutForbidden());
985     if (needsPositionedMovementLayout())
986         return;
987     setNeedsPositionedMovementLayoutBit(true);
988     markContainingBlocksForLayout();
989     if (hasLayer()) {
990         if (oldStyle && style()->diffRequiresRepaint(oldStyle))
991             setLayerNeedsFullRepaint();
992         else
993             setLayerNeedsFullRepaintForPositionedMovementLayout();
994     }
995 }
996
997 void RenderElement::clearChildNeedsLayout()
998 {
999     setNormalChildNeedsLayoutBit(false);
1000     setPosChildNeedsLayoutBit(false);
1001     setNeedsSimplifiedNormalFlowLayoutBit(false);
1002     setNormalChildNeedsLayoutBit(false);
1003     setNeedsPositionedMovementLayoutBit(false);
1004 }
1005
1006 void RenderElement::setNeedsSimplifiedNormalFlowLayout()
1007 {
1008     ASSERT(!isSetNeedsLayoutForbidden());
1009     if (needsSimplifiedNormalFlowLayout())
1010         return;
1011     setNeedsSimplifiedNormalFlowLayoutBit(true);
1012     markContainingBlocksForLayout();
1013     if (hasLayer())
1014         setLayerNeedsFullRepaint();
1015 }
1016
1017 RenderElement* RenderElement::rendererForRootBackground()
1018 {
1019     ASSERT(isRoot());
1020     if (!hasBackground() && element() && element()->hasTagName(HTMLNames::htmlTag)) {
1021         // Locate the <body> element using the DOM. This is easier than trying
1022         // to crawl around a render tree with potential :before/:after content and
1023         // anonymous blocks created by inline <body> tags etc. We can locate the <body>
1024         // render object very easily via the DOM.
1025         if (auto body = document().body()) {
1026             if (body->hasLocalName(HTMLNames::bodyTag)) {
1027                 if (auto renderer = body->renderer())
1028                     return renderer;
1029             }
1030         }
1031     }
1032     return this;
1033 }
1034
1035 RenderElement* RenderElement::hoverAncestor() const
1036 {
1037     // When searching for the hover ancestor and encountering a named flow thread,
1038     // the search will continue with the DOM ancestor of the top-most element
1039     // in the named flow thread.
1040     // See https://bugs.webkit.org/show_bug.cgi?id=111749
1041     RenderElement* hoverAncestor = parent();
1042
1043     // Skip anonymous blocks directly flowed into flow threads as it would
1044     // prevent us from continuing the search on the DOM tree when reaching the named flow thread.
1045     if (hoverAncestor && hoverAncestor->isAnonymousBlock() && hoverAncestor->parent() && hoverAncestor->parent()->isRenderNamedFlowThread())
1046         hoverAncestor = hoverAncestor->parent();
1047
1048     if (hoverAncestor && hoverAncestor->isRenderNamedFlowThread()) {
1049         hoverAncestor = nullptr;
1050         if (Element* element = this->element()) {
1051             if (auto parent = element->parentNode())
1052                 hoverAncestor = parent->renderer();
1053         }
1054     }
1055
1056     return hoverAncestor;
1057 }
1058
1059 void RenderElement::layout()
1060 {
1061     StackStats::LayoutCheckPoint layoutCheckPoint;
1062     ASSERT(needsLayout());
1063     RenderObject* child = firstChild();
1064     while (child) {
1065         if (child->needsLayout())
1066             toRenderElement(child)->layout();
1067         ASSERT(!child->needsLayout());
1068         child = child->nextSibling();
1069     }
1070     clearNeedsLayout();
1071 }
1072
1073 }