OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Peter Kelly (pmk@post.com) | 4 * (C) 2001 Peter Kelly (pmk@post.com) |
5 * (C) 2001 Dirk Mueller (mueller@kde.org) | 5 * (C) 2001 Dirk Mueller (mueller@kde.org) |
6 * (C) 2007 David Smith (catfish.man@gmail.com) | 6 * (C) 2007 David Smith (catfish.man@gmail.com) |
7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc.
All rights reserved. | 7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. |
| 8 * All rights reserved. |
8 * (C) 2007 Eric Seidel (eric@webkit.org) | 9 * (C) 2007 Eric Seidel (eric@webkit.org) |
9 * | 10 * |
10 * This library is free software; you can redistribute it and/or | 11 * This library is free software; you can redistribute it and/or |
11 * modify it under the terms of the GNU Library General Public | 12 * modify it under the terms of the GNU Library General Public |
12 * License as published by the Free Software Foundation; either | 13 * License as published by the Free Software Foundation; either |
13 * version 2 of the License, or (at your option) any later version. | 14 * version 2 of the License, or (at your option) any later version. |
14 * | 15 * |
15 * This library is distributed in the hope that it will be useful, | 16 * This library is distributed in the hope that it will be useful, |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 | 223 |
223 void Element::setTabIndex(int value) { | 224 void Element::setTabIndex(int value) { |
224 setIntegralAttribute(tabindexAttr, value); | 225 setIntegralAttribute(tabindexAttr, value); |
225 } | 226 } |
226 | 227 |
227 short Element::tabIndex() const { | 228 short Element::tabIndex() const { |
228 return hasRareData() ? elementRareData()->tabIndex() : 0; | 229 return hasRareData() ? elementRareData()->tabIndex() : 0; |
229 } | 230 } |
230 | 231 |
231 bool Element::layoutObjectIsFocusable() const { | 232 bool Element::layoutObjectIsFocusable() const { |
232 // Elements in canvas fallback content are not rendered, but they are allowed
to be | 233 // Elements in canvas fallback content are not rendered, but they are allowed |
233 // focusable as long as their canvas is displayed and visible. | 234 // to be focusable as long as their canvas is displayed and visible. |
234 if (isInCanvasSubtree()) { | 235 if (isInCanvasSubtree()) { |
235 const HTMLCanvasElement* canvas = | 236 const HTMLCanvasElement* canvas = |
236 Traversal<HTMLCanvasElement>::firstAncestorOrSelf(*this); | 237 Traversal<HTMLCanvasElement>::firstAncestorOrSelf(*this); |
237 DCHECK(canvas); | 238 DCHECK(canvas); |
238 return canvas->layoutObject() && | 239 return canvas->layoutObject() && |
239 canvas->layoutObject()->style()->visibility() == | 240 canvas->layoutObject()->style()->visibility() == |
240 EVisibility::Visible; | 241 EVisibility::Visible; |
241 } | 242 } |
242 | 243 |
243 // FIXME: Even if we are not visible, we might have a child that is visible. | 244 // FIXME: Even if we are not visible, we might have a child that is visible. |
244 // Hyatt wants to fix that some day with a "has visible content" flag or the l
ike. | 245 // Hyatt wants to fix that some day with a "has visible content" flag or the |
| 246 // like. |
245 return layoutObject() && | 247 return layoutObject() && |
246 layoutObject()->style()->visibility() == EVisibility::Visible; | 248 layoutObject()->style()->visibility() == EVisibility::Visible; |
247 } | 249 } |
248 | 250 |
249 Node* Element::cloneNode(bool deep) { | 251 Node* Element::cloneNode(bool deep) { |
250 return deep ? cloneElementWithChildren() : cloneElementWithoutChildren(); | 252 return deep ? cloneElementWithChildren() : cloneElementWithoutChildren(); |
251 } | 253 } |
252 | 254 |
253 Element* Element::cloneElementWithChildren() { | 255 Element* Element::cloneElementWithChildren() { |
254 Element* clone = cloneElementWithoutChildren(); | 256 Element* clone = cloneElementWithoutChildren(); |
255 cloneChildNodes(clone); | 257 cloneChildNodes(clone); |
256 return clone; | 258 return clone; |
257 } | 259 } |
258 | 260 |
259 Element* Element::cloneElementWithoutChildren() { | 261 Element* Element::cloneElementWithoutChildren() { |
260 Element* clone = cloneElementWithoutAttributesAndChildren(); | 262 Element* clone = cloneElementWithoutAttributesAndChildren(); |
261 // This will catch HTML elements in the wrong namespace that are not correctly
copied. | 263 // This will catch HTML elements in the wrong namespace that are not correctly |
262 // This is a sanity check as HTML overloads some of the DOM methods. | 264 // copied. This is a sanity check as HTML overloads some of the DOM methods. |
263 DCHECK_EQ(isHTMLElement(), clone->isHTMLElement()); | 265 DCHECK_EQ(isHTMLElement(), clone->isHTMLElement()); |
264 | 266 |
265 clone->cloneDataFromElement(*this); | 267 clone->cloneDataFromElement(*this); |
266 return clone; | 268 return clone; |
267 } | 269 } |
268 | 270 |
269 Element* Element::cloneElementWithoutAttributesAndChildren() { | 271 Element* Element::cloneElementWithoutAttributesAndChildren() { |
270 return document().createElement(tagQName(), CreatedByCloneNode); | 272 return document().createElement(tagQName(), CreatedByCloneNode); |
271 } | 273 } |
272 | 274 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 } | 378 } |
377 if (UNLIKELY(elementData()->m_animatedSVGAttributesAreDirty)) { | 379 if (UNLIKELY(elementData()->m_animatedSVGAttributesAreDirty)) { |
378 DCHECK(isSVGElement()); | 380 DCHECK(isSVGElement()); |
379 // See comment in the AtomicString version of synchronizeAttribute() | 381 // See comment in the AtomicString version of synchronizeAttribute() |
380 // also. | 382 // also. |
381 toSVGElement(this)->synchronizeAnimatedSVGAttribute(name); | 383 toSVGElement(this)->synchronizeAnimatedSVGAttribute(name); |
382 } | 384 } |
383 } | 385 } |
384 | 386 |
385 void Element::synchronizeAttribute(const AtomicString& localName) const { | 387 void Element::synchronizeAttribute(const AtomicString& localName) const { |
386 // This version of synchronizeAttribute() is streamlined for the case where yo
u don't have a full QualifiedName, | 388 // This version of synchronizeAttribute() is streamlined for the case where |
387 // e.g when called from DOM API. | 389 // you don't have a full QualifiedName, e.g when called from DOM API. |
388 if (!elementData()) | 390 if (!elementData()) |
389 return; | 391 return; |
390 if (elementData()->m_styleAttributeIsDirty && | 392 if (elementData()->m_styleAttributeIsDirty && |
391 equalPossiblyIgnoringCase(localName, styleAttr.localName(), | 393 equalPossiblyIgnoringCase(localName, styleAttr.localName(), |
392 shouldIgnoreAttributeCase())) { | 394 shouldIgnoreAttributeCase())) { |
393 DCHECK(isStyledElement()); | 395 DCHECK(isStyledElement()); |
394 synchronizeStyleAttributeInternal(); | 396 synchronizeStyleAttributeInternal(); |
395 return; | 397 return; |
396 } | 398 } |
397 if (elementData()->m_animatedSVGAttributesAreDirty) { | 399 if (elementData()->m_animatedSVGAttributesAreDirty) { |
398 // We're not passing a namespace argument on purpose. SVGNames::*Attr are de
fined w/o namespaces as well. | 400 // We're not passing a namespace argument on purpose. SVGNames::*Attr are |
| 401 // defined w/o namespaces as well. |
399 | 402 |
400 // FIXME: this code is called regardless of whether name is an | 403 // FIXME: this code is called regardless of whether name is an |
401 // animated SVG Attribute. It would seem we should only call this method | 404 // animated SVG Attribute. It would seem we should only call this method |
402 // if SVGElement::isAnimatableAttribute is true, but the list of | 405 // if SVGElement::isAnimatableAttribute is true, but the list of |
403 // animatable attributes in isAnimatableAttribute does not suffice to | 406 // animatable attributes in isAnimatableAttribute does not suffice to |
404 // pass all layout tests. Also, m_animatedSVGAttributesAreDirty stays | 407 // pass all layout tests. Also, m_animatedSVGAttributesAreDirty stays |
405 // dirty unless synchronizeAnimatedSVGAttribute is called with | 408 // dirty unless synchronizeAnimatedSVGAttribute is called with |
406 // anyQName(). This means that even if Element::synchronizeAttribute() | 409 // anyQName(). This means that even if Element::synchronizeAttribute() |
407 // is called on all attributes, m_animatedSVGAttributesAreDirty remains | 410 // is called on all attributes, m_animatedSVGAttributesAreDirty remains |
408 // true. | 411 // true. |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 DCHECK(!layoutObject() || layoutObject()->isBox()); | 554 DCHECK(!layoutObject() || layoutObject()->isBox()); |
552 | 555 |
553 if (scrollState.fullyConsumed()) | 556 if (scrollState.fullyConsumed()) |
554 return; | 557 return; |
555 | 558 |
556 FloatSize delta(scrollState.deltaX(), scrollState.deltaY()); | 559 FloatSize delta(scrollState.deltaX(), scrollState.deltaY()); |
557 | 560 |
558 if (delta.isZero()) | 561 if (delta.isZero()) |
559 return; | 562 return; |
560 | 563 |
561 // TODO(esprehn): This should use updateStyleAndLayoutIgnorePendingStylesheets
ForNode. | 564 // TODO(esprehn): This should use |
| 565 // updateStyleAndLayoutIgnorePendingStylesheetsForNode. |
562 document().updateStyleAndLayoutIgnorePendingStylesheets(); | 566 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
563 | 567 |
564 LayoutBox* boxToScroll = nullptr; | 568 LayoutBox* boxToScroll = nullptr; |
565 | 569 |
566 // We should only ever scroll the effective root scroller this way when the | 570 // We should only ever scroll the effective root scroller this way when the |
567 // page removes the default applyScroll (ViewportScrollCallback). | 571 // page removes the default applyScroll (ViewportScrollCallback). |
568 if (document().rootScrollerController()->effectiveRootScroller() == this) | 572 if (document().rootScrollerController()->effectiveRootScroller() == this) |
569 boxToScroll = document().layoutView(); | 573 boxToScroll = document().layoutView(); |
570 else if (layoutObject()) | 574 else if (layoutObject()) |
571 boxToScroll = toLayoutBox(layoutObject()); | 575 boxToScroll = toLayoutBox(layoutObject()); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 document().updateStyleAndLayoutIgnorePendingStylesheetsForNode(this); | 697 document().updateStyleAndLayoutIgnorePendingStylesheetsForNode(this); |
694 | 698 |
695 if (LayoutBox* layoutObject = layoutBox()) | 699 if (LayoutBox* layoutObject = layoutBox()) |
696 return adjustLayoutUnitForAbsoluteZoom(layoutObject->clientTop(), | 700 return adjustLayoutUnitForAbsoluteZoom(layoutObject->clientTop(), |
697 layoutObject->styleRef()) | 701 layoutObject->styleRef()) |
698 .round(); | 702 .round(); |
699 return 0; | 703 return 0; |
700 } | 704 } |
701 | 705 |
702 int Element::clientWidth() { | 706 int Element::clientWidth() { |
703 // When in strict mode, clientWidth for the document element should return the
width of the containing frame. | 707 // When in strict mode, clientWidth for the document element should return the |
704 // When in quirks mode, clientWidth for the body element should return the wid
th of the containing frame. | 708 // width of the containing frame. |
| 709 // When in quirks mode, clientWidth for the body element should return the |
| 710 // width of the containing frame. |
705 bool inQuirksMode = document().inQuirksMode(); | 711 bool inQuirksMode = document().inQuirksMode(); |
706 if ((!inQuirksMode && document().documentElement() == this) || | 712 if ((!inQuirksMode && document().documentElement() == this) || |
707 (inQuirksMode && isHTMLElement() && document().body() == this)) { | 713 (inQuirksMode && isHTMLElement() && document().body() == this)) { |
708 LayoutViewItem layoutView = document().layoutViewItem(); | 714 LayoutViewItem layoutView = document().layoutViewItem(); |
709 if (!layoutView.isNull()) { | 715 if (!layoutView.isNull()) { |
710 if (!RuntimeEnabledFeatures::overlayScrollbarsEnabled() || | 716 if (!RuntimeEnabledFeatures::overlayScrollbarsEnabled() || |
711 !document().frame()->isLocalRoot()) | 717 !document().frame()->isLocalRoot()) |
712 document().updateStyleAndLayoutIgnorePendingStylesheetsForNode(this); | 718 document().updateStyleAndLayoutIgnorePendingStylesheetsForNode(this); |
713 if (document().page()->settings().forceZeroLayoutHeight()) | 719 if (document().page()->settings().forceZeroLayoutHeight()) |
714 return adjustLayoutUnitForAbsoluteZoom( | 720 return adjustLayoutUnitForAbsoluteZoom( |
(...skipping 11 matching lines...) Expand all Loading... |
726 | 732 |
727 if (LayoutBox* layoutObject = layoutBox()) | 733 if (LayoutBox* layoutObject = layoutBox()) |
728 return adjustLayoutUnitForAbsoluteZoom( | 734 return adjustLayoutUnitForAbsoluteZoom( |
729 LayoutUnit(layoutObject->pixelSnappedClientWidth()), | 735 LayoutUnit(layoutObject->pixelSnappedClientWidth()), |
730 layoutObject->styleRef()) | 736 layoutObject->styleRef()) |
731 .round(); | 737 .round(); |
732 return 0; | 738 return 0; |
733 } | 739 } |
734 | 740 |
735 int Element::clientHeight() { | 741 int Element::clientHeight() { |
736 // When in strict mode, clientHeight for the document element should return th
e height of the containing frame. | 742 // When in strict mode, clientHeight for the document element should return |
737 // When in quirks mode, clientHeight for the body element should return the he
ight of the containing frame. | 743 // the height of the containing frame. |
| 744 // When in quirks mode, clientHeight for the body element should return the |
| 745 // height of the containing frame. |
738 bool inQuirksMode = document().inQuirksMode(); | 746 bool inQuirksMode = document().inQuirksMode(); |
739 | 747 |
740 if ((!inQuirksMode && document().documentElement() == this) || | 748 if ((!inQuirksMode && document().documentElement() == this) || |
741 (inQuirksMode && isHTMLElement() && document().body() == this)) { | 749 (inQuirksMode && isHTMLElement() && document().body() == this)) { |
742 LayoutViewItem layoutView = document().layoutViewItem(); | 750 LayoutViewItem layoutView = document().layoutViewItem(); |
743 if (!layoutView.isNull()) { | 751 if (!layoutView.isNull()) { |
744 if (!RuntimeEnabledFeatures::overlayScrollbarsEnabled() || | 752 if (!RuntimeEnabledFeatures::overlayScrollbarsEnabled() || |
745 !document().frame()->isLocalRoot()) | 753 !document().frame()->isLocalRoot()) |
746 document().updateStyleAndLayoutIgnorePendingStylesheetsForNode(this); | 754 document().updateStyleAndLayoutIgnorePendingStylesheetsForNode(this); |
747 if (document().page()->settings().forceZeroLayoutHeight()) | 755 if (document().page()->settings().forceZeroLayoutHeight()) |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1287 styleAttributeChanged(newValue, reason); | 1295 styleAttributeChanged(newValue, reason); |
1288 } else if (isPresentationAttribute(name)) { | 1296 } else if (isPresentationAttribute(name)) { |
1289 elementData()->m_presentationAttributeStyleIsDirty = true; | 1297 elementData()->m_presentationAttributeStyleIsDirty = true; |
1290 setNeedsStyleRecalc(LocalStyleChange, | 1298 setNeedsStyleRecalc(LocalStyleChange, |
1291 StyleChangeReasonForTracing::fromAttribute(name)); | 1299 StyleChangeReasonForTracing::fromAttribute(name)); |
1292 } | 1300 } |
1293 } | 1301 } |
1294 | 1302 |
1295 invalidateNodeListCachesInAncestors(&name, this); | 1303 invalidateNodeListCachesInAncestors(&name, this); |
1296 | 1304 |
1297 // If there is currently no StyleResolver, we can't be sure that this attribut
e change won't affect style. | 1305 // If there is currently no StyleResolver, we can't be sure that this |
| 1306 // attribute change won't affect style. |
1298 if (!document().styleResolver()) | 1307 if (!document().styleResolver()) |
1299 setNeedsStyleRecalc(SubtreeStyleChange, | 1308 setNeedsStyleRecalc(SubtreeStyleChange, |
1300 StyleChangeReasonForTracing::fromAttribute(name)); | 1309 StyleChangeReasonForTracing::fromAttribute(name)); |
1301 | 1310 |
1302 if (isConnected()) { | 1311 if (isConnected()) { |
1303 if (AXObjectCache* cache = document().existingAXObjectCache()) | 1312 if (AXObjectCache* cache = document().existingAXObjectCache()) |
1304 cache->handleAttributeChanged(name, this); | 1313 cache->handleAttributeChanged(name, this); |
1305 } | 1314 } |
1306 } | 1315 } |
1307 | 1316 |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1470 document() | 1479 document() |
1471 .elementDataCache() | 1480 .elementDataCache() |
1472 ->cachedShareableElementDataWithAttributes(attributeVector); | 1481 ->cachedShareableElementDataWithAttributes(attributeVector); |
1473 else | 1482 else |
1474 m_elementData = | 1483 m_elementData = |
1475 ShareableElementData::createWithAttributes(attributeVector); | 1484 ShareableElementData::createWithAttributes(attributeVector); |
1476 } | 1485 } |
1477 | 1486 |
1478 parserDidSetAttributes(); | 1487 parserDidSetAttributes(); |
1479 | 1488 |
1480 // Use attributeVector instead of m_elementData because attributeChanged might
modify m_elementData. | 1489 // Use attributeVector instead of m_elementData because attributeChanged might |
| 1490 // modify m_elementData. |
1481 for (const auto& attribute : attributeVector) | 1491 for (const auto& attribute : attributeVector) |
1482 attributeChangedFromParserOrByCloning(attribute.name(), attribute.value(), | 1492 attributeChangedFromParserOrByCloning(attribute.name(), attribute.value(), |
1483 ModifiedDirectly); | 1493 ModifiedDirectly); |
1484 } | 1494 } |
1485 | 1495 |
1486 bool Element::hasEquivalentAttributes(const Element* other) const { | 1496 bool Element::hasEquivalentAttributes(const Element* other) const { |
1487 synchronizeAllAttributes(); | 1497 synchronizeAllAttributes(); |
1488 other->synchronizeAllAttributes(); | 1498 other->synchronizeAllAttributes(); |
1489 if (elementData() == other->elementData()) | 1499 if (elementData() == other->elementData()) |
1490 return true; | 1500 return true; |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1694 } | 1704 } |
1695 | 1705 |
1696 void Element::detachLayoutTree(const AttachContext& context) { | 1706 void Element::detachLayoutTree(const AttachContext& context) { |
1697 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; | 1707 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; |
1698 cancelFocusAppearanceUpdate(); | 1708 cancelFocusAppearanceUpdate(); |
1699 removeCallbackSelectors(); | 1709 removeCallbackSelectors(); |
1700 if (hasRareData()) { | 1710 if (hasRareData()) { |
1701 ElementRareData* data = elementRareData(); | 1711 ElementRareData* data = elementRareData(); |
1702 data->clearPseudoElements(); | 1712 data->clearPseudoElements(); |
1703 | 1713 |
1704 // attachLayoutTree() will clear the computed style for us when inside recal
cStyle. | 1714 // attachLayoutTree() will clear the computed style for us when inside |
| 1715 // recalcStyle. |
1705 if (!document().inStyleRecalc()) | 1716 if (!document().inStyleRecalc()) |
1706 data->clearComputedStyle(); | 1717 data->clearComputedStyle(); |
1707 | 1718 |
1708 if (ElementAnimations* elementAnimations = data->elementAnimations()) { | 1719 if (ElementAnimations* elementAnimations = data->elementAnimations()) { |
1709 if (context.performingReattach) { | 1720 if (context.performingReattach) { |
1710 // FIXME: We call detach from within style recalc, so compositingState i
s not up to date. | 1721 // FIXME: We call detach from within style recalc, so compositingState |
| 1722 // is not up to date. |
1711 // https://code.google.com/p/chromium/issues/detail?id=339847 | 1723 // https://code.google.com/p/chromium/issues/detail?id=339847 |
1712 DisableCompositingQueryAsserts disabler; | 1724 DisableCompositingQueryAsserts disabler; |
1713 | 1725 |
1714 // FIXME: restart compositor animations rather than pull back to the mai
n thread | 1726 // FIXME: restart compositor animations rather than pull back to the |
| 1727 // main thread |
1715 elementAnimations->restartAnimationOnCompositor(); | 1728 elementAnimations->restartAnimationOnCompositor(); |
1716 } else { | 1729 } else { |
1717 elementAnimations->cssAnimations().cancel(); | 1730 elementAnimations->cssAnimations().cancel(); |
1718 elementAnimations->setAnimationStyleChange(false); | 1731 elementAnimations->setAnimationStyleChange(false); |
1719 } | 1732 } |
1720 elementAnimations->clearBaseComputedStyle(); | 1733 elementAnimations->clearBaseComputedStyle(); |
1721 } | 1734 } |
1722 | 1735 |
1723 if (ElementShadow* shadow = data->shadow()) | 1736 if (ElementShadow* shadow = data->shadow()) |
1724 shadow->detach(context); | 1737 shadow->detach(context); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1783 } | 1796 } |
1784 } | 1797 } |
1785 return false; | 1798 return false; |
1786 } | 1799 } |
1787 | 1800 |
1788 PassRefPtr<ComputedStyle> Element::styleForLayoutObject() { | 1801 PassRefPtr<ComputedStyle> Element::styleForLayoutObject() { |
1789 DCHECK(document().inStyleRecalc()); | 1802 DCHECK(document().inStyleRecalc()); |
1790 | 1803 |
1791 RefPtr<ComputedStyle> style; | 1804 RefPtr<ComputedStyle> style; |
1792 | 1805 |
1793 // FIXME: Instead of clearing updates that may have been added from calls to s
tyleForElement | 1806 // FIXME: Instead of clearing updates that may have been added from calls to |
1794 // outside recalcStyle, we should just never set them if we're not inside reca
lcStyle. | 1807 // styleForElement outside recalcStyle, we should just never set them if we're |
| 1808 // not inside recalcStyle. |
1795 if (ElementAnimations* elementAnimations = this->elementAnimations()) | 1809 if (ElementAnimations* elementAnimations = this->elementAnimations()) |
1796 elementAnimations->cssAnimations().clearPendingUpdate(); | 1810 elementAnimations->cssAnimations().clearPendingUpdate(); |
1797 | 1811 |
1798 if (hasCustomStyleCallbacks()) | 1812 if (hasCustomStyleCallbacks()) |
1799 style = customStyleForLayoutObject(); | 1813 style = customStyleForLayoutObject(); |
1800 if (!style) | 1814 if (!style) |
1801 style = originalStyleForLayoutObject(); | 1815 style = originalStyleForLayoutObject(); |
1802 DCHECK(style); | 1816 DCHECK(style); |
1803 | 1817 |
1804 // styleForElement() might add active animations so we need to get it again. | 1818 // styleForElement() might add active animations so we need to get it again. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1842 if (change >= IndependentInherit) { | 1856 if (change >= IndependentInherit) { |
1843 if (ElementAnimations* elementAnimations = data->elementAnimations()) | 1857 if (ElementAnimations* elementAnimations = data->elementAnimations()) |
1844 elementAnimations->setAnimationStyleChange(false); | 1858 elementAnimations->setAnimationStyleChange(false); |
1845 } | 1859 } |
1846 } | 1860 } |
1847 if (parentComputedStyle()) | 1861 if (parentComputedStyle()) |
1848 change = recalcOwnStyle(change); | 1862 change = recalcOwnStyle(change); |
1849 clearNeedsStyleRecalc(); | 1863 clearNeedsStyleRecalc(); |
1850 } | 1864 } |
1851 | 1865 |
1852 // If we reattached we don't need to recalc the style of our descendants anymo
re. | 1866 // If we reattached we don't need to recalc the style of our descendants |
| 1867 // anymore. |
1853 if ((change >= UpdatePseudoElements && change < Reattach) || | 1868 if ((change >= UpdatePseudoElements && change < Reattach) || |
1854 childNeedsStyleRecalc()) { | 1869 childNeedsStyleRecalc()) { |
1855 SelectorFilterParentScope filterScope(*this); | 1870 SelectorFilterParentScope filterScope(*this); |
1856 StyleSharingDepthScope sharingScope(*this); | 1871 StyleSharingDepthScope sharingScope(*this); |
1857 | 1872 |
1858 updatePseudoElement(PseudoIdBefore, change); | 1873 updatePseudoElement(PseudoIdBefore, change); |
1859 | 1874 |
1860 if (change > UpdatePseudoElements || childNeedsStyleRecalc()) { | 1875 if (change > UpdatePseudoElements || childNeedsStyleRecalc()) { |
1861 for (ShadowRoot* root = youngestShadowRoot(); root; | 1876 for (ShadowRoot* root = youngestShadowRoot(); root; |
1862 root = root->olderShadowRoot()) { | 1877 root = root->olderShadowRoot()) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1924 | 1939 |
1925 StyleRecalcChange localChange = | 1940 StyleRecalcChange localChange = |
1926 ComputedStyle::stylePropagationDiff(oldStyle.get(), newStyle.get()); | 1941 ComputedStyle::stylePropagationDiff(oldStyle.get(), newStyle.get()); |
1927 if (localChange == NoChange) { | 1942 if (localChange == NoChange) { |
1928 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), stylesUnchanged, 1); | 1943 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), stylesUnchanged, 1); |
1929 } else { | 1944 } else { |
1930 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), stylesChanged, 1); | 1945 INCREMENT_STYLE_STATS_COUNTER(document().styleEngine(), stylesChanged, 1); |
1931 } | 1946 } |
1932 | 1947 |
1933 if (localChange == Reattach) { | 1948 if (localChange == Reattach) { |
1934 // TODO(nainar): Remove the style parameter being passed into buildLayoutTre
e(). | 1949 // TODO(nainar): Remove the style parameter being passed into |
1935 // ComputedStyle will now be stored on Node and accessed in buildLayoutTree(
) | 1950 // buildLayoutTree(). ComputedStyle will now be stored on Node and accessed |
1936 // using mutableComputedStyle(). | 1951 // in buildLayoutTree() using mutableComputedStyle(). |
1937 return buildLayoutTree(*newStyle); | 1952 return buildLayoutTree(*newStyle); |
1938 } | 1953 } |
1939 | 1954 |
1940 DCHECK(oldStyle); | 1955 DCHECK(oldStyle); |
1941 | 1956 |
1942 if (localChange != NoChange) | 1957 if (localChange != NoChange) |
1943 updateCallbackSelectors(oldStyle.get(), newStyle.get()); | 1958 updateCallbackSelectors(oldStyle.get(), newStyle.get()); |
1944 | 1959 |
1945 if (LayoutObject* layoutObject = this->layoutObject()) { | 1960 if (LayoutObject* layoutObject = this->layoutObject()) { |
1946 if (localChange != NoChange || | 1961 if (localChange != NoChange || |
1947 pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get()) || | 1962 pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get()) || |
1948 svgFilterNeedsLayerUpdate()) { | 1963 svgFilterNeedsLayerUpdate()) { |
1949 layoutObject->setStyle(newStyle.get()); | 1964 layoutObject->setStyle(newStyle.get()); |
1950 } else { | 1965 } else { |
1951 // Although no change occurred, we use the new style so that the cousin st
yle sharing code won't get | 1966 // Although no change occurred, we use the new style so that the cousin |
1952 // fooled into believing this style is the same. | 1967 // style sharing code won't get fooled into believing this style is the |
| 1968 // same. |
1953 // FIXME: We may be able to remove this hack, see discussion in | 1969 // FIXME: We may be able to remove this hack, see discussion in |
1954 // https://codereview.chromium.org/30453002/ | 1970 // https://codereview.chromium.org/30453002/ |
1955 layoutObject->setStyleInternal(newStyle.get()); | 1971 layoutObject->setStyleInternal(newStyle.get()); |
1956 } | 1972 } |
1957 } | 1973 } |
1958 | 1974 |
1959 if (getStyleChangeType() >= SubtreeStyleChange) | 1975 if (getStyleChangeType() >= SubtreeStyleChange) |
1960 return Force; | 1976 return Force; |
1961 | 1977 |
1962 if (change > Inherit || localChange > Inherit) | 1978 if (change > Inherit || localChange > Inherit) |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2316 if (hasRareData()) | 2332 if (hasRareData()) |
2317 elementRareData()->removeAttrNodeList(); | 2333 elementRareData()->removeAttrNodeList(); |
2318 } | 2334 } |
2319 | 2335 |
2320 Attr* Element::setAttributeNode(Attr* attrNode, | 2336 Attr* Element::setAttributeNode(Attr* attrNode, |
2321 ExceptionState& exceptionState) { | 2337 ExceptionState& exceptionState) { |
2322 Attr* oldAttrNode = attrIfExists(attrNode->getQualifiedName()); | 2338 Attr* oldAttrNode = attrIfExists(attrNode->getQualifiedName()); |
2323 if (oldAttrNode == attrNode) | 2339 if (oldAttrNode == attrNode) |
2324 return attrNode; // This Attr is already attached to the element. | 2340 return attrNode; // This Attr is already attached to the element. |
2325 | 2341 |
2326 // InUseAttributeError: Raised if node is an Attr that is already an attribute
of another Element object. | 2342 // InUseAttributeError: Raised if node is an Attr that is already an attribute |
2327 // The DOM user must explicitly clone Attr nodes to re-use them in other eleme
nts. | 2343 // of another Element object. The DOM user must explicitly clone Attr nodes |
| 2344 // to re-use them in other elements. |
2328 if (attrNode->ownerElement()) { | 2345 if (attrNode->ownerElement()) { |
2329 exceptionState.throwDOMException( | 2346 exceptionState.throwDOMException( |
2330 InUseAttributeError, | 2347 InUseAttributeError, |
2331 "The node provided is an attribute node that is already an attribute " | 2348 "The node provided is an attribute node that is already an attribute " |
2332 "of another Element; attribute nodes must be explicitly cloned."); | 2349 "of another Element; attribute nodes must be explicitly cloned."); |
2333 return nullptr; | 2350 return nullptr; |
2334 } | 2351 } |
2335 | 2352 |
2336 if (!isHTMLElement() && attrNode->document().isHTMLDocument() && | 2353 if (!isHTMLElement() && attrNode->document().isHTMLDocument() && |
2337 attrNode->name() != attrNode->name().lower()) | 2354 attrNode->name() != attrNode->name().lower()) |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2606 | 2623 |
2607 void Element::updateFocusAppearance( | 2624 void Element::updateFocusAppearance( |
2608 SelectionBehaviorOnFocus selectionBehavior) { | 2625 SelectionBehaviorOnFocus selectionBehavior) { |
2609 if (selectionBehavior == SelectionBehaviorOnFocus::None) | 2626 if (selectionBehavior == SelectionBehaviorOnFocus::None) |
2610 return; | 2627 return; |
2611 if (isRootEditableElement(*this)) { | 2628 if (isRootEditableElement(*this)) { |
2612 LocalFrame* frame = document().frame(); | 2629 LocalFrame* frame = document().frame(); |
2613 if (!frame) | 2630 if (!frame) |
2614 return; | 2631 return; |
2615 | 2632 |
2616 // When focusing an editable element in an iframe, don't reset the selection
if it already contains a selection. | 2633 // When focusing an editable element in an iframe, don't reset the selection |
| 2634 // if it already contains a selection. |
2617 if (this == frame->selection().rootEditableElement()) | 2635 if (this == frame->selection().rootEditableElement()) |
2618 return; | 2636 return; |
2619 | 2637 |
2620 // FIXME: We should restore the previous selection if there is one. | 2638 // FIXME: We should restore the previous selection if there is one. |
2621 VisibleSelection newSelection = createVisibleSelectionDeprecated( | 2639 VisibleSelection newSelection = createVisibleSelectionDeprecated( |
2622 firstPositionInOrBeforeNode(this), TextAffinity::Downstream); | 2640 firstPositionInOrBeforeNode(this), TextAffinity::Downstream); |
2623 // Passing DoNotSetFocus as this function is called after FocusController::s
etFocusedElement() | 2641 // Passing DoNotSetFocus as this function is called after |
2624 // and we don't want to change the focus to a new Element. | 2642 // FocusController::setFocusedElement() and we don't want to change the |
| 2643 // focus to a new Element. |
2625 frame->selection().setSelection(newSelection, | 2644 frame->selection().setSelection(newSelection, |
2626 FrameSelection::CloseTyping | | 2645 FrameSelection::CloseTyping | |
2627 FrameSelection::ClearTypingStyle | | 2646 FrameSelection::ClearTypingStyle | |
2628 FrameSelection::DoNotSetFocus); | 2647 FrameSelection::DoNotSetFocus); |
2629 | 2648 |
2630 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets | 2649 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets |
2631 // needs to be audited. See http://crbug.com/590369 for more details. | 2650 // needs to be audited. See http://crbug.com/590369 for more details. |
2632 document().updateStyleAndLayoutIgnorePendingStylesheets(); | 2651 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
2633 | 2652 |
2634 frame->selection().revealSelection(); | 2653 frame->selection().revealSelection(); |
2635 } else if (layoutObject() && !layoutObject()->isLayoutPart()) { | 2654 } else if (layoutObject() && !layoutObject()->isLayoutPart()) { |
2636 layoutObject()->scrollRectToVisible(boundingBox()); | 2655 layoutObject()->scrollRectToVisible(boundingBox()); |
2637 } | 2656 } |
2638 } | 2657 } |
2639 | 2658 |
2640 void Element::blur() { | 2659 void Element::blur() { |
2641 cancelFocusAppearanceUpdate(); | 2660 cancelFocusAppearanceUpdate(); |
2642 if (adjustedFocusedElementInTreeScope() == this) { | 2661 if (adjustedFocusedElementInTreeScope() == this) { |
2643 Document& doc = document(); | 2662 Document& doc = document(); |
2644 if (doc.page()) | 2663 if (doc.page()) |
2645 doc.page()->focusController().setFocusedElement(0, doc.frame()); | 2664 doc.page()->focusController().setFocusedElement(0, doc.frame()); |
2646 else | 2665 else |
2647 doc.clearFocusedElement(); | 2666 doc.clearFocusedElement(); |
2648 } | 2667 } |
2649 } | 2668 } |
2650 | 2669 |
2651 bool Element::supportsFocus() const { | 2670 bool Element::supportsFocus() const { |
2652 // FIXME: supportsFocus() can be called when layout is not up to date. | 2671 // FIXME: supportsFocus() can be called when layout is not up to date. |
2653 // Logic that deals with the layoutObject should be moved to layoutObjectIsFoc
usable(). | 2672 // Logic that deals with the layoutObject should be moved to |
| 2673 // layoutObjectIsFocusable(). |
2654 // But supportsFocus must return true when the element is editable, or else | 2674 // But supportsFocus must return true when the element is editable, or else |
2655 // it won't be focusable. Furthermore, supportsFocus cannot just return true | 2675 // it won't be focusable. Furthermore, supportsFocus cannot just return true |
2656 // always or else tabIndex() will change for all HTML elements. | 2676 // always or else tabIndex() will change for all HTML elements. |
2657 return hasElementFlag(TabIndexWasSetExplicitly) || | 2677 return hasElementFlag(TabIndexWasSetExplicitly) || |
2658 isRootEditableElement(*this) || | 2678 isRootEditableElement(*this) || |
2659 (isShadowHost(this) && authorShadowRoot() && | 2679 (isShadowHost(this) && authorShadowRoot() && |
2660 authorShadowRoot()->delegatesFocus()) || | 2680 authorShadowRoot()->delegatesFocus()) || |
2661 supportsSpatialNavigationFocus(); | 2681 supportsSpatialNavigationFocus(); |
2662 } | 2682 } |
2663 | 2683 |
2664 bool Element::supportsSpatialNavigationFocus() const { | 2684 bool Element::supportsSpatialNavigationFocus() const { |
2665 // This function checks whether the element satisfies the extended criteria | 2685 // This function checks whether the element satisfies the extended criteria |
2666 // for the element to be focusable, introduced by spatial navigation feature, | 2686 // for the element to be focusable, introduced by spatial navigation feature, |
2667 // i.e. checks if click or keyboard event handler is specified. | 2687 // i.e. checks if click or keyboard event handler is specified. |
2668 // This is the way to make it possible to navigate to (focus) elements | 2688 // This is the way to make it possible to navigate to (focus) elements |
2669 // which web designer meant for being active (made them respond to click event
s). | 2689 // which web designer meant for being active (made them respond to click |
| 2690 // events). |
2670 if (!isSpatialNavigationEnabled(document().frame()) || | 2691 if (!isSpatialNavigationEnabled(document().frame()) || |
2671 spatialNavigationIgnoresEventHandlers(document().frame())) | 2692 spatialNavigationIgnoresEventHandlers(document().frame())) |
2672 return false; | 2693 return false; |
2673 if (hasEventListeners(EventTypeNames::click) || | 2694 if (hasEventListeners(EventTypeNames::click) || |
2674 hasEventListeners(EventTypeNames::keydown) || | 2695 hasEventListeners(EventTypeNames::keydown) || |
2675 hasEventListeners(EventTypeNames::keypress) || | 2696 hasEventListeners(EventTypeNames::keypress) || |
2676 hasEventListeners(EventTypeNames::keyup)) | 2697 hasEventListeners(EventTypeNames::keyup)) |
2677 return true; | 2698 return true; |
2678 if (!isSVGElement()) | 2699 if (!isSVGElement()) |
2679 return false; | 2700 return false; |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2953 document().frame()->eventHandler().hasPointerCapture(pointerId, this); | 2974 document().frame()->eventHandler().hasPointerCapture(pointerId, this); |
2954 } | 2975 } |
2955 | 2976 |
2956 bool Element::hasProcessedPointerCapture(int pointerId) const { | 2977 bool Element::hasProcessedPointerCapture(int pointerId) const { |
2957 return document().frame() && | 2978 return document().frame() && |
2958 document().frame()->eventHandler().hasProcessedPointerCapture( | 2979 document().frame()->eventHandler().hasProcessedPointerCapture( |
2959 pointerId, this); | 2980 pointerId, this); |
2960 } | 2981 } |
2961 | 2982 |
2962 String Element::innerText() { | 2983 String Element::innerText() { |
2963 // We need to update layout, since plainText uses line boxes in the layout tre
e. | 2984 // We need to update layout, since plainText uses line boxes in the layout |
| 2985 // tree. |
2964 document().updateStyleAndLayoutIgnorePendingStylesheetsForNode(this); | 2986 document().updateStyleAndLayoutIgnorePendingStylesheetsForNode(this); |
2965 | 2987 |
2966 if (!layoutObject()) | 2988 if (!layoutObject()) |
2967 return textContent(true); | 2989 return textContent(true); |
2968 | 2990 |
2969 return plainText(EphemeralRange::rangeOfContents(*this), | 2991 return plainText(EphemeralRange::rangeOfContents(*this), |
2970 TextIteratorForInnerText); | 2992 TextIteratorForInnerText); |
2971 } | 2993 } |
2972 | 2994 |
2973 String Element::outerText() { | 2995 String Element::outerText() { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3057 return; | 3079 return; |
3058 ensureElementRareData().setMinimumSizeForResizing(size); | 3080 ensureElementRareData().setMinimumSizeForResizing(size); |
3059 } | 3081 } |
3060 | 3082 |
3061 const ComputedStyle* Element::ensureComputedStyle( | 3083 const ComputedStyle* Element::ensureComputedStyle( |
3062 PseudoId pseudoElementSpecifier) { | 3084 PseudoId pseudoElementSpecifier) { |
3063 if (PseudoElement* element = pseudoElement(pseudoElementSpecifier)) | 3085 if (PseudoElement* element = pseudoElement(pseudoElementSpecifier)) |
3064 return element->ensureComputedStyle(); | 3086 return element->ensureComputedStyle(); |
3065 | 3087 |
3066 if (!inActiveDocument()) { | 3088 if (!inActiveDocument()) { |
3067 // FIXME: Try to do better than this. Ensure that styleForElement() works fo
r elements that are not in the | 3089 // FIXME: Try to do better than this. Ensure that styleForElement() works |
3068 // document tree and figure out when to destroy the computed style for such
elements. | 3090 // for elements that are not in the document tree and figure out when to |
| 3091 // destroy the computed style for such elements. |
3069 return nullptr; | 3092 return nullptr; |
3070 } | 3093 } |
3071 | 3094 |
3072 // FIXME: Find and use the layoutObject from the pseudo element instead of the
actual element so that the 'length' | 3095 // FIXME: Find and use the layoutObject from the pseudo element instead of the |
3073 // properties, which are only known by the layoutObject because it did the lay
out, will be correct and so that the | 3096 // actual element so that the 'length' properties, which are only known by the |
| 3097 // layoutObject because it did the layout, will be correct and so that the |
3074 // values returned for the ":selection" pseudo-element will be correct. | 3098 // values returned for the ":selection" pseudo-element will be correct. |
3075 ComputedStyle* elementStyle = mutableComputedStyle(); | 3099 ComputedStyle* elementStyle = mutableComputedStyle(); |
3076 if (!elementStyle) { | 3100 if (!elementStyle) { |
3077 ElementRareData& rareData = ensureElementRareData(); | 3101 ElementRareData& rareData = ensureElementRareData(); |
3078 if (!rareData.computedStyle()) | 3102 if (!rareData.computedStyle()) |
3079 rareData.setComputedStyle( | 3103 rareData.setComputedStyle( |
3080 document().styleForElementIgnoringPendingStylesheets(this)); | 3104 document().styleForElementIgnoringPendingStylesheets(this)); |
3081 elementStyle = rareData.computedStyle(); | 3105 elementStyle = rareData.computedStyle(); |
3082 } | 3106 } |
3083 | 3107 |
3084 if (!pseudoElementSpecifier) | 3108 if (!pseudoElementSpecifier) |
3085 return elementStyle; | 3109 return elementStyle; |
3086 | 3110 |
3087 if (ComputedStyle* pseudoElementStyle = | 3111 if (ComputedStyle* pseudoElementStyle = |
3088 elementStyle->getCachedPseudoStyle(pseudoElementSpecifier)) | 3112 elementStyle->getCachedPseudoStyle(pseudoElementSpecifier)) |
3089 return pseudoElementStyle; | 3113 return pseudoElementStyle; |
3090 | 3114 |
3091 RefPtr<ComputedStyle> result = | 3115 RefPtr<ComputedStyle> result = |
3092 document().ensureStyleResolver().pseudoStyleForElement( | 3116 document().ensureStyleResolver().pseudoStyleForElement( |
3093 this, PseudoStyleRequest(pseudoElementSpecifier, | 3117 this, PseudoStyleRequest(pseudoElementSpecifier, |
3094 PseudoStyleRequest::ForComputedStyle), | 3118 PseudoStyleRequest::ForComputedStyle), |
3095 elementStyle); | 3119 elementStyle); |
3096 DCHECK(result); | 3120 DCHECK(result); |
3097 return elementStyle->addCachedPseudoStyle(result.release()); | 3121 return elementStyle->addCachedPseudoStyle(result.release()); |
3098 } | 3122 } |
3099 | 3123 |
3100 AtomicString Element::computeInheritedLanguage() const { | 3124 AtomicString Element::computeInheritedLanguage() const { |
3101 const Node* n = this; | 3125 const Node* n = this; |
3102 AtomicString value; | 3126 AtomicString value; |
3103 // The language property is inherited, so we iterate over the parents to find
the first language. | 3127 // The language property is inherited, so we iterate over the parents to find |
| 3128 // the first language. |
3104 do { | 3129 do { |
3105 if (n->isElementNode()) { | 3130 if (n->isElementNode()) { |
3106 if (const ElementData* elementData = toElement(n)->elementData()) { | 3131 if (const ElementData* elementData = toElement(n)->elementData()) { |
3107 AttributeCollection attributes = elementData->attributes(); | 3132 AttributeCollection attributes = elementData->attributes(); |
3108 // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7 | 3133 // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7 |
3109 if (const Attribute* attribute = attributes.find(XMLNames::langAttr)) | 3134 if (const Attribute* attribute = attributes.find(XMLNames::langAttr)) |
3110 value = attribute->value(); | 3135 value = attribute->value(); |
3111 else if (const Attribute* attribute = | 3136 else if (const Attribute* attribute = |
3112 attributes.find(HTMLNames::langAttr)) | 3137 attributes.find(HTMLNames::langAttr)) |
3113 value = attribute->value(); | 3138 value = attribute->value(); |
(...skipping 25 matching lines...) Expand all Loading... |
3139 if (element && (change == UpdatePseudoElements || | 3164 if (element && (change == UpdatePseudoElements || |
3140 element->shouldCallRecalcStyle(change))) { | 3165 element->shouldCallRecalcStyle(change))) { |
3141 if (pseudoId == PseudoIdFirstLetter && updateFirstLetter(element)) | 3166 if (pseudoId == PseudoIdFirstLetter && updateFirstLetter(element)) |
3142 return; | 3167 return; |
3143 | 3168 |
3144 // Need to clear the cached style if the PseudoElement wants a recalc so it | 3169 // Need to clear the cached style if the PseudoElement wants a recalc so it |
3145 // computes a new style. | 3170 // computes a new style. |
3146 if (element->needsStyleRecalc()) | 3171 if (element->needsStyleRecalc()) |
3147 layoutObject()->mutableStyle()->removeCachedPseudoStyle(pseudoId); | 3172 layoutObject()->mutableStyle()->removeCachedPseudoStyle(pseudoId); |
3148 | 3173 |
3149 // PseudoElement styles hang off their parent element's style so if we neede
d | 3174 // PseudoElement styles hang off their parent element's style so if we |
3150 // a style recalc we should Force one on the pseudo. | 3175 // needed a style recalc we should Force one on the pseudo. FIXME: We |
3151 // FIXME: We should figure out the right text sibling to pass. | 3176 // should figure out the right text sibling to pass. |
3152 element->recalcStyle(change == UpdatePseudoElements ? Force : change); | 3177 element->recalcStyle(change == UpdatePseudoElements ? Force : change); |
3153 | 3178 |
3154 // Wait until our parent is not displayed or pseudoElementLayoutObjectIsNeed
ed | 3179 // Wait until our parent is not displayed or |
3155 // is false, otherwise we could continuously create and destroy PseudoElemen
ts | 3180 // pseudoElementLayoutObjectIsNeeded is false, otherwise we could |
3156 // when LayoutObject::isChildAllowed on our parent returns false for the | 3181 // continuously create and destroy PseudoElements when |
| 3182 // LayoutObject::isChildAllowed on our parent returns false for the |
3157 // PseudoElement's layoutObject for each style recalc. | 3183 // PseudoElement's layoutObject for each style recalc. |
3158 if (!layoutObject() || | 3184 if (!layoutObject() || |
3159 !pseudoElementLayoutObjectIsNeeded( | 3185 !pseudoElementLayoutObjectIsNeeded( |
3160 layoutObject()->getCachedPseudoStyle(pseudoId))) | 3186 layoutObject()->getCachedPseudoStyle(pseudoId))) |
3161 elementRareData()->setPseudoElement(pseudoId, nullptr); | 3187 elementRareData()->setPseudoElement(pseudoId, nullptr); |
3162 } else if (pseudoId == PseudoIdFirstLetter && element && | 3188 } else if (pseudoId == PseudoIdFirstLetter && element && |
3163 change >= UpdatePseudoElements && | 3189 change >= UpdatePseudoElements && |
3164 !FirstLetterPseudoElement::firstLetterTextLayoutObject(*element)) { | 3190 !FirstLetterPseudoElement::firstLetterTextLayoutObject(*element)) { |
3165 // This can happen if we change to a float, for example. We need to cleanup
the | 3191 // This can happen if we change to a float, for example. We need to cleanup |
3166 // first-letter pseudoElement and then fix the text of the original remainin
g | 3192 // the first-letter pseudoElement and then fix the text of the original |
3167 // text layoutObject. | 3193 // remaining text layoutObject. This can be seen in Test 7 of |
3168 // This can be seen in Test 7 of fast/css/first-letter-removed-added.html | 3194 // fast/css/first-letter-removed-added.html |
3169 elementRareData()->setPseudoElement(pseudoId, nullptr); | 3195 elementRareData()->setPseudoElement(pseudoId, nullptr); |
3170 } else if (change >= UpdatePseudoElements) { | 3196 } else if (change >= UpdatePseudoElements) { |
3171 createPseudoElementIfNeeded(pseudoId); | 3197 createPseudoElementIfNeeded(pseudoId); |
3172 } | 3198 } |
3173 } | 3199 } |
3174 | 3200 |
3175 // If we're updating first letter, and the current first letter layoutObject | 3201 // If we're updating first letter, and the current first letter layoutObject |
3176 // is not the same as the one we're currently using we need to re-create | 3202 // is not the same as the one we're currently using we need to re-create |
3177 // the first letter layoutObject. | 3203 // the first letter layoutObject. |
3178 bool Element::updateFirstLetter(Element* element) { | 3204 bool Element::updateFirstLetter(Element* element) { |
(...skipping 12 matching lines...) Expand all Loading... |
3191 elementRareData()->setPseudoElement(PseudoIdFirstLetter, nullptr); | 3217 elementRareData()->setPseudoElement(PseudoIdFirstLetter, nullptr); |
3192 return true; | 3218 return true; |
3193 } | 3219 } |
3194 return false; | 3220 return false; |
3195 } | 3221 } |
3196 | 3222 |
3197 void Element::createPseudoElementIfNeeded(PseudoId pseudoId) { | 3223 void Element::createPseudoElementIfNeeded(PseudoId pseudoId) { |
3198 if (isPseudoElement()) | 3224 if (isPseudoElement()) |
3199 return; | 3225 return; |
3200 | 3226 |
3201 // Document::ensureStyleResolver is not inlined and shows up on profiles, avoi
d it here. | 3227 // Document::ensureStyleResolver is not inlined and shows up on profiles, |
| 3228 // avoid it here. |
3202 PseudoElement* element = | 3229 PseudoElement* element = |
3203 document().styleEngine().ensureResolver().createPseudoElementIfNeeded( | 3230 document().styleEngine().ensureResolver().createPseudoElementIfNeeded( |
3204 *this, pseudoId); | 3231 *this, pseudoId); |
3205 if (!element) | 3232 if (!element) |
3206 return; | 3233 return; |
3207 | 3234 |
3208 if (pseudoId == PseudoIdBackdrop) | 3235 if (pseudoId == PseudoIdBackdrop) |
3209 document().addToTopLayer(element, this); | 3236 document().addToTopLayer(element, this); |
3210 element->insertedInto(this); | 3237 element->insertedInto(this); |
3211 element->attachLayoutTree(); | 3238 element->attachLayoutTree(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3250 } | 3277 } |
3251 | 3278 |
3252 DOMStringMap& Element::dataset() { | 3279 DOMStringMap& Element::dataset() { |
3253 ElementRareData& rareData = ensureElementRareData(); | 3280 ElementRareData& rareData = ensureElementRareData(); |
3254 if (!rareData.dataset()) | 3281 if (!rareData.dataset()) |
3255 rareData.setDataset(DatasetDOMStringMap::create(this)); | 3282 rareData.setDataset(DatasetDOMStringMap::create(this)); |
3256 return *rareData.dataset(); | 3283 return *rareData.dataset(); |
3257 } | 3284 } |
3258 | 3285 |
3259 KURL Element::hrefURL() const { | 3286 KURL Element::hrefURL() const { |
3260 // FIXME: These all have href() or url(), but no common super class. Why doesn
't | 3287 // FIXME: These all have href() or url(), but no common super class. Why |
3261 // <link> implement URLUtils? | 3288 // doesn't <link> implement URLUtils? |
3262 if (isHTMLAnchorElement(*this) || isHTMLAreaElement(*this) || | 3289 if (isHTMLAnchorElement(*this) || isHTMLAreaElement(*this) || |
3263 isHTMLLinkElement(*this)) | 3290 isHTMLLinkElement(*this)) |
3264 return getURLAttribute(hrefAttr); | 3291 return getURLAttribute(hrefAttr); |
3265 if (isSVGAElement(*this)) | 3292 if (isSVGAElement(*this)) |
3266 return toSVGAElement(*this).legacyHrefURL(document()); | 3293 return toSVGAElement(*this).legacyHrefURL(document()); |
3267 return KURL(); | 3294 return KURL(); |
3268 } | 3295 } |
3269 | 3296 |
3270 KURL Element::getURLAttribute(const QualifiedName& name) const { | 3297 KURL Element::getURLAttribute(const QualifiedName& name) const { |
3271 #if DCHECK_IS_ON() | 3298 #if DCHECK_IS_ON() |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3352 for (Element* element = nextAncestorElement(this); element; | 3379 for (Element* element = nextAncestorElement(this); element; |
3353 element = nextAncestorElement(element)) | 3380 element = nextAncestorElement(element)) |
3354 element->setContainsFullScreenElement(flag); | 3381 element->setContainsFullScreenElement(flag); |
3355 } | 3382 } |
3356 | 3383 |
3357 void Element::setIsInTopLayer(bool inTopLayer) { | 3384 void Element::setIsInTopLayer(bool inTopLayer) { |
3358 if (isInTopLayer() == inTopLayer) | 3385 if (isInTopLayer() == inTopLayer) |
3359 return; | 3386 return; |
3360 setElementFlag(IsInTopLayer, inTopLayer); | 3387 setElementFlag(IsInTopLayer, inTopLayer); |
3361 | 3388 |
3362 // We must ensure a reattach occurs so the layoutObject is inserted in the cor
rect sibling order under LayoutView according to its | 3389 // We must ensure a reattach occurs so the layoutObject is inserted in the |
3363 // top layer position, or in its usual place if not in the top layer. | 3390 // correct sibling order under LayoutView according to its top layer position, |
| 3391 // or in its usual place if not in the top layer. |
3364 lazyReattachIfAttached(); | 3392 lazyReattachIfAttached(); |
3365 } | 3393 } |
3366 | 3394 |
3367 void Element::requestPointerLock() { | 3395 void Element::requestPointerLock() { |
3368 if (document().page()) | 3396 if (document().page()) |
3369 document().page()->pointerLockController().requestPointerLock(this); | 3397 document().page()->pointerLockController().requestPointerLock(this); |
3370 } | 3398 } |
3371 | 3399 |
3372 SpellcheckAttributeState Element::spellcheckAttributeState() const { | 3400 SpellcheckAttributeState Element::spellcheckAttributeState() const { |
3373 const AtomicString& value = fastGetAttribute(spellcheckAttr); | 3401 const AtomicString& value = fastGetAttribute(spellcheckAttr); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3515 const Document& oldDocument, | 3543 const Document& oldDocument, |
3516 const Document& newDocument) { | 3544 const Document& newDocument) { |
3517 if (oldDocument == newDocument) | 3545 if (oldDocument == newDocument) |
3518 return false; | 3546 return false; |
3519 if (oldDocument.baseURL() == newDocument.baseURL()) | 3547 if (oldDocument.baseURL() == newDocument.baseURL()) |
3520 return false; | 3548 return false; |
3521 const StylePropertySet* style = element.inlineStyle(); | 3549 const StylePropertySet* style = element.inlineStyle(); |
3522 if (!style) | 3550 if (!style) |
3523 return false; | 3551 return false; |
3524 for (unsigned i = 0; i < style->propertyCount(); ++i) { | 3552 for (unsigned i = 0; i < style->propertyCount(); ++i) { |
3525 // FIXME: Should handle all URL-based properties: CSSImageSetValue, CSSCurso
rImageValue, etc. | 3553 // FIXME: Should handle all URL-based properties: CSSImageSetValue, |
| 3554 // CSSCursorImageValue, etc. |
3526 if (style->propertyAt(i).value().isImageValue()) | 3555 if (style->propertyAt(i).value().isImageValue()) |
3527 return true; | 3556 return true; |
3528 } | 3557 } |
3529 return false; | 3558 return false; |
3530 } | 3559 } |
3531 | 3560 |
3532 static void reResolveURLsInInlineStyle(const Document& document, | 3561 static void reResolveURLsInInlineStyle(const Document& document, |
3533 MutableStylePropertySet& style) { | 3562 MutableStylePropertySet& style) { |
3534 for (unsigned i = 0; i < style.propertyCount(); ++i) { | 3563 for (unsigned i = 0; i < style.propertyCount(); ++i) { |
3535 StylePropertySet::PropertyReference property = style.propertyAt(i); | 3564 StylePropertySet::PropertyReference property = style.propertyAt(i); |
3536 // FIXME: Should handle all URL-based properties: CSSImageSetValue, CSSCurso
rImageValue, etc. | 3565 // FIXME: Should handle all URL-based properties: CSSImageSetValue, |
| 3566 // CSSCursorImageValue, etc. |
3537 if (property.value().isImageValue()) | 3567 if (property.value().isImageValue()) |
3538 toCSSImageValue(property.value()).reResolveURL(document); | 3568 toCSSImageValue(property.value()).reResolveURL(document); |
3539 } | 3569 } |
3540 } | 3570 } |
3541 | 3571 |
3542 void Element::didMoveToNewDocument(Document& oldDocument) { | 3572 void Element::didMoveToNewDocument(Document& oldDocument) { |
3543 Node::didMoveToNewDocument(oldDocument); | 3573 Node::didMoveToNewDocument(oldDocument); |
3544 | 3574 |
3545 // If the documents differ by quirks mode then they differ by case sensitivity | 3575 // If the documents differ by quirks mode then they differ by case sensitivity |
3546 // for class and id names so we need to go through the attribute change logic | 3576 // for class and id names so we need to go through the attribute change logic |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3672 | 3702 |
3673 if (!oldID.isNull() || !newID.isNull()) | 3703 if (!oldID.isNull() || !newID.isNull()) |
3674 updateId(oldID, newID); | 3704 updateId(oldID, newID); |
3675 | 3705 |
3676 const AtomicString& oldName = getNameAttribute(); | 3706 const AtomicString& oldName = getNameAttribute(); |
3677 const AtomicString& newName = other.getNameAttribute(); | 3707 const AtomicString& newName = other.getNameAttribute(); |
3678 | 3708 |
3679 if (!oldName.isNull() || !newName.isNull()) | 3709 if (!oldName.isNull() || !newName.isNull()) |
3680 updateName(oldName, newName); | 3710 updateName(oldName, newName); |
3681 | 3711 |
3682 // Quirks mode makes class and id not case sensitive. We can't share the Eleme
ntData | 3712 // Quirks mode makes class and id not case sensitive. We can't share the |
3683 // if the idForStyleResolution and the className need different casing. | 3713 // ElementData if the idForStyleResolution and the className need different |
| 3714 // casing. |
3684 bool ownerDocumentsHaveDifferentCaseSensitivity = false; | 3715 bool ownerDocumentsHaveDifferentCaseSensitivity = false; |
3685 if (other.hasClass() || other.hasID()) | 3716 if (other.hasClass() || other.hasID()) |
3686 ownerDocumentsHaveDifferentCaseSensitivity = | 3717 ownerDocumentsHaveDifferentCaseSensitivity = |
3687 other.document().inQuirksMode() != document().inQuirksMode(); | 3718 other.document().inQuirksMode() != document().inQuirksMode(); |
3688 | 3719 |
3689 // If 'other' has a mutable ElementData, convert it to an immutable one so we
can share it between both elements. | 3720 // If 'other' has a mutable ElementData, convert it to an immutable one so we |
3690 // We can only do this if there are no presentation attributes and sharing the
data won't result in different case sensitivity of class or id. | 3721 // can share it between both elements. |
| 3722 // We can only do this if there are no presentation attributes and sharing the |
| 3723 // data won't result in different case sensitivity of class or id. |
3691 if (other.m_elementData->isUnique() && | 3724 if (other.m_elementData->isUnique() && |
3692 !ownerDocumentsHaveDifferentCaseSensitivity && | 3725 !ownerDocumentsHaveDifferentCaseSensitivity && |
3693 !other.m_elementData->presentationAttributeStyle()) | 3726 !other.m_elementData->presentationAttributeStyle()) |
3694 const_cast<Element&>(other).m_elementData = | 3727 const_cast<Element&>(other).m_elementData = |
3695 toUniqueElementData(other.m_elementData)->makeShareableCopy(); | 3728 toUniqueElementData(other.m_elementData)->makeShareableCopy(); |
3696 | 3729 |
3697 if (!other.m_elementData->isUnique() && | 3730 if (!other.m_elementData->isUnique() && |
3698 !ownerDocumentsHaveDifferentCaseSensitivity && | 3731 !ownerDocumentsHaveDifferentCaseSensitivity && |
3699 !needsURLResolutionForInlineStyle(other, other.document(), document())) | 3732 !needsURLResolutionForInlineStyle(other, other.document(), document())) |
3700 m_elementData = other.m_elementData; | 3733 m_elementData = other.m_elementData; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3762 if (ensureMutableInlineStyle().isEmpty()) { | 3795 if (ensureMutableInlineStyle().isEmpty()) { |
3763 ensureUniqueElementData().m_inlineStyle.clear(); | 3796 ensureUniqueElementData().m_inlineStyle.clear(); |
3764 } | 3797 } |
3765 } | 3798 } |
3766 | 3799 |
3767 inline void Element::setInlineStyleFromString( | 3800 inline void Element::setInlineStyleFromString( |
3768 const AtomicString& newStyleString) { | 3801 const AtomicString& newStyleString) { |
3769 DCHECK(isStyledElement()); | 3802 DCHECK(isStyledElement()); |
3770 Member<StylePropertySet>& inlineStyle = elementData()->m_inlineStyle; | 3803 Member<StylePropertySet>& inlineStyle = elementData()->m_inlineStyle; |
3771 | 3804 |
3772 // Avoid redundant work if we're using shared attribute data with already pars
ed inline style. | 3805 // Avoid redundant work if we're using shared attribute data with already |
| 3806 // parsed inline style. |
3773 if (inlineStyle && !elementData()->isUnique()) | 3807 if (inlineStyle && !elementData()->isUnique()) |
3774 return; | 3808 return; |
3775 | 3809 |
3776 // We reconstruct the property set instead of mutating if there is no CSSOM wr
apper. | 3810 // We reconstruct the property set instead of mutating if there is no CSSOM |
3777 // This makes wrapperless property sets immutable and so cacheable. | 3811 // wrapper. This makes wrapperless property sets immutable and so cacheable. |
3778 if (inlineStyle && !inlineStyle->isMutable()) | 3812 if (inlineStyle && !inlineStyle->isMutable()) |
3779 inlineStyle.clear(); | 3813 inlineStyle.clear(); |
3780 | 3814 |
3781 if (!inlineStyle) { | 3815 if (!inlineStyle) { |
3782 inlineStyle = CSSParser::parseInlineStyleDeclaration(newStyleString, this); | 3816 inlineStyle = CSSParser::parseInlineStyleDeclaration(newStyleString, this); |
3783 } else { | 3817 } else { |
3784 DCHECK(inlineStyle->isMutable()); | 3818 DCHECK(inlineStyle->isMutable()); |
3785 static_cast<MutableStylePropertySet*>(inlineStyle.get()) | 3819 static_cast<MutableStylePropertySet*>(inlineStyle.get()) |
3786 ->parseDeclarationList(newStyleString, | 3820 ->parseDeclarationList(newStyleString, |
3787 document().elementSheet().contents()); | 3821 document().elementSheet().contents()); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3887 void Element::removeAllInlineStyleProperties() { | 3921 void Element::removeAllInlineStyleProperties() { |
3888 DCHECK(isStyledElement()); | 3922 DCHECK(isStyledElement()); |
3889 if (!inlineStyle()) | 3923 if (!inlineStyle()) |
3890 return; | 3924 return; |
3891 ensureMutableInlineStyle().clear(); | 3925 ensureMutableInlineStyle().clear(); |
3892 inlineStyleChanged(); | 3926 inlineStyleChanged(); |
3893 } | 3927 } |
3894 | 3928 |
3895 void Element::updatePresentationAttributeStyle() { | 3929 void Element::updatePresentationAttributeStyle() { |
3896 synchronizeAllAttributes(); | 3930 synchronizeAllAttributes(); |
3897 // ShareableElementData doesn't store presentation attribute style, so make su
re we have a UniqueElementData. | 3931 // ShareableElementData doesn't store presentation attribute style, so make |
| 3932 // sure we have a UniqueElementData. |
3898 UniqueElementData& elementData = ensureUniqueElementData(); | 3933 UniqueElementData& elementData = ensureUniqueElementData(); |
3899 elementData.m_presentationAttributeStyleIsDirty = false; | 3934 elementData.m_presentationAttributeStyleIsDirty = false; |
3900 elementData.m_presentationAttributeStyle = | 3935 elementData.m_presentationAttributeStyle = |
3901 computePresentationAttributeStyle(*this); | 3936 computePresentationAttributeStyle(*this); |
3902 } | 3937 } |
3903 | 3938 |
3904 void Element::addPropertyToPresentationAttributeStyle( | 3939 void Element::addPropertyToPresentationAttributeStyle( |
3905 MutableStylePropertySet* style, | 3940 MutableStylePropertySet* style, |
3906 CSSPropertyID propertyID, | 3941 CSSPropertyID propertyID, |
3907 CSSValueID identifier) { | 3942 CSSValueID identifier) { |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4046 } | 4081 } |
4047 | 4082 |
4048 DEFINE_TRACE_WRAPPERS(Element) { | 4083 DEFINE_TRACE_WRAPPERS(Element) { |
4049 if (hasRareData()) { | 4084 if (hasRareData()) { |
4050 visitor->traceWrappers(elementRareData()); | 4085 visitor->traceWrappers(elementRareData()); |
4051 } | 4086 } |
4052 ContainerNode::traceWrappers(visitor); | 4087 ContainerNode::traceWrappers(visitor); |
4053 } | 4088 } |
4054 | 4089 |
4055 } // namespace blink | 4090 } // namespace blink |
OLD | NEW |