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 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All r
ights reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All r
ights reserved. |
7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) | 7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) |
8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. |
9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. |
(...skipping 1503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1514 | 1514 |
1515 PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToSho
w, PassRefPtr<NodeFilter> filter, ExceptionState& exceptionState) | 1515 PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToSho
w, PassRefPtr<NodeFilter> filter, ExceptionState& exceptionState) |
1516 { | 1516 { |
1517 if (!root) { | 1517 if (!root) { |
1518 exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "Node")); | 1518 exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::a
rgumentNullOrIncorrectType(1, "Node")); |
1519 return nullptr; | 1519 return nullptr; |
1520 } | 1520 } |
1521 return TreeWalker::create(root, whatToShow, filter); | 1521 return TreeWalker::create(root, whatToShow, filter); |
1522 } | 1522 } |
1523 | 1523 |
1524 bool Document::shouldCallRecalcStyleForDocument() | 1524 bool Document::needsRenderTreeUpdate() const |
1525 { | 1525 { |
1526 if (!isActive() || !view()) | 1526 if (!isActive() || !view()) |
1527 return false; | 1527 return false; |
1528 if (needsStyleRecalc() || childNeedsStyleRecalc()) | 1528 if (needsStyleRecalc() || childNeedsStyleRecalc()) |
1529 return true; | 1529 return true; |
1530 if (childNeedsDistributionRecalc()) | 1530 if (childNeedsDistributionRecalc()) |
1531 return true; | 1531 return true; |
1532 if (!m_useElementsNeedingUpdate.isEmpty()) | 1532 if (!m_useElementsNeedingUpdate.isEmpty()) |
1533 return true; | 1533 return true; |
1534 if (!m_layerUpdateElements.isEmpty()) | 1534 if (!m_layerUpdateElements.isEmpty()) |
1535 return true; | 1535 return true; |
1536 if (childNeedsStyleInvalidation()) | 1536 if (childNeedsStyleInvalidation()) |
1537 return true; | 1537 return true; |
1538 return false; | 1538 return false; |
1539 } | 1539 } |
1540 | 1540 |
1541 bool Document::shouldScheduleStyleRecalc() | 1541 bool Document::shouldScheduleRenderTreeUpdate() const |
1542 { | 1542 { |
1543 if (!isActive()) | 1543 if (!isActive()) |
1544 return false; | 1544 return false; |
1545 if (hasPendingStyleRecalc()) | 1545 if (hasPendingStyleRecalc()) |
1546 return false; | 1546 return false; |
1547 if (inStyleRecalc()) | 1547 if (inStyleRecalc()) |
1548 return false; | 1548 return false; |
1549 // InPreLayout will recalc style itself. There's no reason to schedule anoth
er recalc. | 1549 // InPreLayout will recalc style itself. There's no reason to schedule anoth
er recalc. |
1550 if (m_lifecycle.state() == DocumentLifecycle::InPreLayout) | 1550 if (m_lifecycle.state() == DocumentLifecycle::InPreLayout) |
1551 return false; | 1551 return false; |
1552 if (!shouldScheduleLayout()) | 1552 if (!shouldScheduleLayout()) |
1553 return false; | 1553 return false; |
1554 return true; | 1554 return true; |
1555 } | 1555 } |
1556 | 1556 |
1557 void Document::scheduleStyleRecalc() | 1557 void Document::scheduleRenderTreeUpdate() |
1558 { | 1558 { |
1559 if (!shouldScheduleStyleRecalc()) | 1559 if (!shouldScheduleRenderTreeUpdate()) |
1560 return; | 1560 return; |
1561 | 1561 |
1562 ASSERT(shouldCallRecalcStyleForDocument()); | 1562 ASSERT(needsRenderTreeUpdate()); |
1563 | 1563 |
1564 page()->animator().scheduleVisualUpdate(); | 1564 page()->animator().scheduleVisualUpdate(); |
1565 m_lifecycle.advanceTo(DocumentLifecycle::StyleRecalcPending); | 1565 m_lifecycle.advanceTo(DocumentLifecycle::StyleRecalcPending); |
1566 | 1566 |
1567 InspectorInstrumentation::didScheduleStyleRecalculation(this); | 1567 InspectorInstrumentation::didScheduleStyleRecalculation(this); |
1568 } | 1568 } |
1569 | 1569 |
1570 bool Document::hasPendingForcedStyleRecalc() const | 1570 bool Document::hasPendingForcedStyleRecalc() const |
1571 { | 1571 { |
1572 return hasPendingStyleRecalc() && !inStyleRecalc() && styleChangeType() >= S
ubtreeStyleChange; | 1572 return hasPendingStyleRecalc() && !inStyleRecalc() && styleChangeType() >= S
ubtreeStyleChange; |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1699 body->setNeedsStyleRecalc(SubtreeStyleChange); | 1699 body->setNeedsStyleRecalc(SubtreeStyleChange); |
1700 } | 1700 } |
1701 } | 1701 } |
1702 | 1702 |
1703 if (RenderStyle* style = documentElement()->renderStyle()) { | 1703 if (RenderStyle* style = documentElement()->renderStyle()) { |
1704 if (style->direction() != rootDirection || style->writingMode() != rootW
ritingMode) | 1704 if (style->direction() != rootDirection || style->writingMode() != rootW
ritingMode) |
1705 documentElement()->setNeedsStyleRecalc(SubtreeStyleChange); | 1705 documentElement()->setNeedsStyleRecalc(SubtreeStyleChange); |
1706 } | 1706 } |
1707 } | 1707 } |
1708 | 1708 |
1709 void Document::updateStyleIfNeeded() | 1709 void Document::updateRenderTree(StyleRecalcChange change) |
1710 { | |
1711 updateStyle(NoChange); | |
1712 } | |
1713 | |
1714 // FIXME: We need a better name than updateStyleIfNeeded. It's performing style
invalidation, | |
1715 // style recalc, distribution and <use> shadow tree creation. | |
1716 void Document::updateStyle(StyleRecalcChange change) | |
1717 { | 1710 { |
1718 ASSERT(isMainThread()); | 1711 ASSERT(isMainThread()); |
1719 | 1712 |
1720 if (change != Force && !shouldCallRecalcStyleForDocument()) | 1713 if (change != Force && !needsRenderTreeUpdate()) |
1721 return; | 1714 return; |
1722 | 1715 |
1723 if (inStyleRecalc()) | 1716 if (inStyleRecalc()) |
1724 return; | 1717 return; |
1725 | 1718 |
1726 // Entering here from inside layout or paint would be catastrophic since rec
alcStyle can | 1719 // Entering here from inside layout or paint would be catastrophic since rec
alcStyle can |
1727 // tear down the render tree or (unfortunately) run script. Kill the whole r
enderer if | 1720 // tear down the render tree or (unfortunately) run script. Kill the whole r
enderer if |
1728 // someone managed to get into here from inside layout or paint. | 1721 // someone managed to get into here from inside layout or paint. |
1729 RELEASE_ASSERT(!view()->isInPerformLayout()); | 1722 RELEASE_ASSERT(!view()->isInPerformLayout()); |
1730 RELEASE_ASSERT(!view()->isPainting()); | 1723 RELEASE_ASSERT(!view()->isPainting()); |
1731 | 1724 |
1732 // Script can run below in WidgetUpdates, so protect the LocalFrame. | 1725 // Script can run below in WidgetUpdates, so protect the LocalFrame. |
1733 RefPtr<LocalFrame> protect(m_frame); | 1726 RefPtr<LocalFrame> protect(m_frame); |
1734 | 1727 |
1735 TRACE_EVENT0("webkit", "Document::recalcStyle"); | 1728 TRACE_EVENT0("webkit", "Document::updateRenderTree"); |
1736 TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "RecalcStyle"); | 1729 TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "UpdateRenderTree"); |
1737 | 1730 |
1738 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRecalc
ulateStyle(this); | 1731 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRecalc
ulateStyle(this); |
1739 | 1732 |
1740 updateDistributionIfNeeded(); | 1733 updateDistributionIfNeeded(); |
1741 updateUseShadowTreesIfNeeded(); | 1734 updateUseShadowTreesIfNeeded(); |
1742 updateStyleInvalidationIfNeeded(); | 1735 updateStyleInvalidationIfNeeded(); |
1743 | 1736 |
1744 if (m_evaluateMediaQueriesOnStyleRecalc) { | 1737 // FIXME: This executes media query listeners which runs script, instead the
script |
1745 m_evaluateMediaQueriesOnStyleRecalc = false; | 1738 // should run at raf timing in ScriptedAnimationController just like resize
events. |
1746 evaluateMediaQueryList(); | 1739 evaluateMediaQueryListIfNeeded(); |
1747 } | |
1748 | 1740 |
1749 // FIXME: We should update style on our ancestor chain before proceeding | 1741 // FIXME: We should update style on our ancestor chain before proceeding |
1750 // however doing so currently causes several tests to crash, as LocalFrame::
setDocument calls Document::attach | 1742 // however doing so currently causes several tests to crash, as LocalFrame::
setDocument calls Document::attach |
1751 // before setting the DOMWindow on the LocalFrame, or the SecurityOrigin on
the document. The attach, in turn | 1743 // before setting the DOMWindow on the LocalFrame, or the SecurityOrigin on
the document. The attach, in turn |
1752 // resolves style (here) and then when we resolve style on the parent chain,
we may end up | 1744 // resolves style (here) and then when we resolve style on the parent chain,
we may end up |
1753 // re-attaching our containing iframe, which when asked HTMLFrameElementBase
::isURLAllowed | 1745 // re-attaching our containing iframe, which when asked HTMLFrameElementBase
::isURLAllowed |
1754 // hits a null-dereference due to security code always assuming the document
has a SecurityOrigin. | 1746 // hits a null-dereference due to security code always assuming the document
has a SecurityOrigin. |
1755 | 1747 |
1756 if (m_elemSheet && m_elemSheet->contents()->usesRemUnits()) | 1748 if (m_elemSheet && m_elemSheet->contents()->usesRemUnits()) |
1757 m_styleEngine->setUsesRemUnit(true); | 1749 m_styleEngine->setUsesRemUnit(true); |
1758 | 1750 |
1759 { | 1751 updateStyle(change); |
1760 RenderWidget::UpdateSuspendScope suspendWidgetHierarchyUpdates; | |
1761 m_lifecycle.advanceTo(DocumentLifecycle::InStyleRecalc); | |
1762 | |
1763 if (styleChangeType() >= SubtreeStyleChange) | |
1764 change = Force; | |
1765 | |
1766 // FIXME: Cannot access the ensureStyleResolver() before calling styleFo
rDocument below because | |
1767 // apparently the StyleResolver's constructor has side effects. We shoul
d fix it. | |
1768 // See printing/setPrinting.html, printing/width-overflow.html though th
ey only fail on | |
1769 // mac when accessing the resolver by what appears to be a viewport size
difference. | |
1770 | |
1771 if (change == Force) { | |
1772 m_hasNodesWithPlaceholderStyle = false; | |
1773 RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(
*this, m_styleEngine->fontSelector()); | |
1774 StyleRecalcChange localChange = RenderStyle::compare(documentStyle.g
et(), renderView()->style()); | |
1775 if (localChange != NoChange) | |
1776 renderView()->setStyle(documentStyle.release()); | |
1777 } | |
1778 | |
1779 clearNeedsStyleRecalc(); | |
1780 | |
1781 // Uncomment to enable printing of statistics about style sharing and th
e matched property cache. | |
1782 // Optionally pass StyleResolver::ReportSlowStats to print numbers that
require crawling the | |
1783 // entire DOM (where collecting them is very slow). | |
1784 // FIXME: Expose this as a runtime flag. | |
1785 // ensureStyleResolver().enableStats(/*StyleResolver::ReportSlowStats*/)
; | |
1786 | |
1787 if (StyleResolverStats* stats = ensureStyleResolver().stats()) | |
1788 stats->reset(); | |
1789 | |
1790 if (Element* documentElement = this->documentElement()) { | |
1791 inheritHtmlAndBodyElementStyles(change); | |
1792 dirtyElementsForLayerUpdate(); | |
1793 if (documentElement->shouldCallRecalcStyle(change)) | |
1794 documentElement->recalcStyle(change); | |
1795 while (dirtyElementsForLayerUpdate()) | |
1796 documentElement->recalcStyle(NoChange); | |
1797 } | |
1798 | |
1799 ensureStyleResolver().printStats(); | |
1800 | |
1801 view()->updateCompositingLayersAfterStyleChange(); | |
1802 | |
1803 clearChildNeedsStyleRecalc(); | |
1804 | |
1805 if (m_styleEngine->hasResolver()) { | |
1806 // Pseudo element removal and similar may only work with these flags
still set. Reset them after the style recalc. | |
1807 StyleResolver& resolver = m_styleEngine->ensureResolver(); | |
1808 m_styleEngine->resetCSSFeatureFlags(resolver.ensureUpdatedRuleFeatur
eSet()); | |
1809 resolver.clearStyleSharingList(); | |
1810 } | |
1811 | |
1812 ASSERT(!needsStyleRecalc()); | |
1813 ASSERT(!childNeedsStyleRecalc()); | |
1814 ASSERT(inStyleRecalc()); | |
1815 m_lifecycle.advanceTo(DocumentLifecycle::StyleClean); | |
1816 } | |
1817 | 1752 |
1818 // As a result of the style recalculation, the currently hovered element mig
ht have been | 1753 // As a result of the style recalculation, the currently hovered element mig
ht have been |
1819 // detached (for example, by setting display:none in the :hover style), sche
dule another mouseMove event | 1754 // detached (for example, by setting display:none in the :hover style), sche
dule another mouseMove event |
1820 // to check if any other elements ended up under the mouse pointer due to re
-layout. | 1755 // to check if any other elements ended up under the mouse pointer due to re
-layout. |
1821 if (hoverNode() && !hoverNode()->renderer() && frame()) | 1756 if (hoverNode() && !hoverNode()->renderer() && frame()) |
1822 frame()->eventHandler().dispatchFakeMouseMoveEventSoon(); | 1757 frame()->eventHandler().dispatchFakeMouseMoveEventSoon(); |
1823 | 1758 |
1824 if (m_focusedElement && !m_focusedElement->isFocusable()) | 1759 if (m_focusedElement && !m_focusedElement->isFocusable()) |
1825 clearFocusedElementSoon(); | 1760 clearFocusedElementSoon(); |
1826 | 1761 |
1827 #if ENABLE(SVG_FONTS) | 1762 #if ENABLE(SVG_FONTS) |
1828 if (svgExtensions()) | 1763 if (svgExtensions()) |
1829 accessSVGExtensions().removePendingSVGFontFaceElementsForRemoval(); | 1764 accessSVGExtensions().removePendingSVGFontFaceElementsForRemoval(); |
1830 #endif | 1765 #endif |
1831 InspectorInstrumentation::didRecalculateStyle(cookie); | 1766 InspectorInstrumentation::didRecalculateStyle(cookie); |
1832 } | 1767 } |
1833 | 1768 |
1834 void Document::updateStyleForNodeIfNeeded(Node* node) | 1769 void Document::updateStyle(StyleRecalcChange change) |
1835 { | 1770 { |
1836 if (!shouldCallRecalcStyleForDocument()) | 1771 TRACE_EVENT0("webkit", "Document::updateStyle"); |
| 1772 |
| 1773 RenderWidget::UpdateSuspendScope suspendWidgetHierarchyUpdates; |
| 1774 m_lifecycle.advanceTo(DocumentLifecycle::InStyleRecalc); |
| 1775 |
| 1776 if (styleChangeType() >= SubtreeStyleChange) |
| 1777 change = Force; |
| 1778 |
| 1779 // FIXME: Cannot access the ensureStyleResolver() before calling styleForDoc
ument below because |
| 1780 // apparently the StyleResolver's constructor has side effects. We should fi
x it. |
| 1781 // See printing/setPrinting.html, printing/width-overflow.html though they o
nly fail on |
| 1782 // mac when accessing the resolver by what appears to be a viewport size dif
ference. |
| 1783 |
| 1784 if (change == Force) { |
| 1785 m_hasNodesWithPlaceholderStyle = false; |
| 1786 RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(*thi
s, m_styleEngine->fontSelector()); |
| 1787 StyleRecalcChange localChange = RenderStyle::compare(documentStyle.get()
, renderView()->style()); |
| 1788 if (localChange != NoChange) |
| 1789 renderView()->setStyle(documentStyle.release()); |
| 1790 } |
| 1791 |
| 1792 clearNeedsStyleRecalc(); |
| 1793 |
| 1794 // Uncomment to enable printing of statistics about style sharing and the ma
tched property cache. |
| 1795 // Optionally pass StyleResolver::ReportSlowStats to print numbers that requ
ire crawling the |
| 1796 // entire DOM (where collecting them is very slow). |
| 1797 // FIXME: Expose this as a runtime flag. |
| 1798 // ensureStyleResolver().enableStats(/*StyleResolver::ReportSlowStats*/); |
| 1799 |
| 1800 if (StyleResolverStats* stats = ensureStyleResolver().stats()) |
| 1801 stats->reset(); |
| 1802 |
| 1803 if (Element* documentElement = this->documentElement()) { |
| 1804 inheritHtmlAndBodyElementStyles(change); |
| 1805 dirtyElementsForLayerUpdate(); |
| 1806 if (documentElement->shouldCallRecalcStyle(change)) |
| 1807 documentElement->recalcStyle(change); |
| 1808 while (dirtyElementsForLayerUpdate()) |
| 1809 documentElement->recalcStyle(NoChange); |
| 1810 } |
| 1811 |
| 1812 ensureStyleResolver().printStats(); |
| 1813 |
| 1814 view()->updateCompositingLayersAfterStyleChange(); |
| 1815 |
| 1816 clearChildNeedsStyleRecalc(); |
| 1817 |
| 1818 if (m_styleEngine->hasResolver()) { |
| 1819 // Pseudo element removal and similar may only work with these flags sti
ll set. Reset them after the style recalc. |
| 1820 StyleResolver& resolver = m_styleEngine->ensureResolver(); |
| 1821 m_styleEngine->resetCSSFeatureFlags(resolver.ensureUpdatedRuleFeatureSet
()); |
| 1822 resolver.clearStyleSharingList(); |
| 1823 } |
| 1824 |
| 1825 ASSERT(!needsStyleRecalc()); |
| 1826 ASSERT(!childNeedsStyleRecalc()); |
| 1827 ASSERT(inStyleRecalc()); |
| 1828 m_lifecycle.advanceTo(DocumentLifecycle::StyleClean); |
| 1829 } |
| 1830 |
| 1831 void Document::updateRenderTreeForNodeIfNeeded(Node* node) |
| 1832 { |
| 1833 if (!needsRenderTreeUpdate()) |
1837 return; | 1834 return; |
1838 | 1835 |
1839 // At this point, we know that we need to recalc some style on the document
in order to fully update styles. | 1836 // At this point, we know that we need to recalc some style on the document
in order to fully update styles. |
1840 // However, style on 'node' only needs to be recalculated if a global recomp
utation is needed, or a node on | 1837 // However, style on 'node' only needs to be recalculated if a global recomp
utation is needed, or a node on |
1841 // the path from 'node' to the root needs style recalc. | 1838 // the path from 'node' to the root needs style recalc. |
1842 | 1839 |
1843 // Global needed. | 1840 // Global needed. |
1844 bool needsRecalc = needsStyleRecalc() || childNeedsDistributionRecalc() || !
m_useElementsNeedingUpdate.isEmpty() || childNeedsStyleInvalidation(); | 1841 bool needsRecalc = needsStyleRecalc() || childNeedsDistributionRecalc() || !
m_useElementsNeedingUpdate.isEmpty() || childNeedsStyleInvalidation(); |
1845 | 1842 |
1846 // On the path. | 1843 // On the path. |
1847 for (Node* ancestor = node; ancestor && !needsRecalc; ancestor = ancestor->p
arentOrShadowHostNode()) | 1844 for (Node* ancestor = node; ancestor && !needsRecalc; ancestor = ancestor->p
arentOrShadowHostNode()) |
1848 needsRecalc = ancestor->needsStyleRecalc(); | 1845 needsRecalc = ancestor->needsStyleRecalc(); |
1849 if (needsRecalc) | 1846 if (needsRecalc) |
1850 updateStyleIfNeeded(); | 1847 updateRenderTreeIfNeeded(); |
1851 } | 1848 } |
1852 | 1849 |
1853 void Document::updateLayout() | 1850 void Document::updateLayout() |
1854 { | 1851 { |
1855 ASSERT(isMainThread()); | 1852 ASSERT(isMainThread()); |
1856 | 1853 |
1857 RefPtr<FrameView> frameView = view(); | 1854 RefPtr<FrameView> frameView = view(); |
1858 if (frameView && frameView->isInPerformLayout()) { | 1855 if (frameView && frameView->isInPerformLayout()) { |
1859 // View layout should not be re-entrant. | 1856 // View layout should not be re-entrant. |
1860 ASSERT_NOT_REACHED(); | 1857 ASSERT_NOT_REACHED(); |
1861 return; | 1858 return; |
1862 } | 1859 } |
1863 | 1860 |
1864 if (Element* oe = ownerElement()) | 1861 if (Element* oe = ownerElement()) |
1865 oe->document().updateLayout(); | 1862 oe->document().updateLayout(); |
1866 | 1863 |
1867 updateStyleIfNeeded(); | 1864 updateRenderTreeIfNeeded(); |
1868 | 1865 |
1869 // Only do a layout if changes have occurred that make it necessary. | 1866 // Only do a layout if changes have occurred that make it necessary. |
1870 if (isActive() && frameView && renderView() && (frameView->layoutPending() |
| renderView()->needsLayout())) | 1867 if (isActive() && frameView && renderView() && (frameView->layoutPending() |
| renderView()->needsLayout())) |
1871 frameView->layout(); | 1868 frameView->layout(); |
1872 } | 1869 } |
1873 | 1870 |
1874 void Document::setNeedsFocusedElementCheck() | 1871 void Document::setNeedsFocusedElementCheck() |
1875 { | 1872 { |
1876 setNeedsStyleRecalc(LocalStyleChange); | 1873 setNeedsStyleRecalc(LocalStyleChange); |
1877 } | 1874 } |
1878 | 1875 |
1879 void Document::clearFocusedElementSoon() | 1876 void Document::clearFocusedElementSoon() |
1880 { | 1877 { |
1881 if (!m_clearFocusedElementTimer.isActive()) | 1878 if (!m_clearFocusedElementTimer.isActive()) |
1882 m_clearFocusedElementTimer.startOneShot(0, FROM_HERE); | 1879 m_clearFocusedElementTimer.startOneShot(0, FROM_HERE); |
1883 } | 1880 } |
1884 | 1881 |
1885 void Document::clearFocusedElementTimerFired(Timer<Document>*) | 1882 void Document::clearFocusedElementTimerFired(Timer<Document>*) |
1886 { | 1883 { |
1887 updateStyleIfNeeded(); | 1884 updateRenderTreeIfNeeded(); |
1888 m_clearFocusedElementTimer.stop(); | 1885 m_clearFocusedElementTimer.stop(); |
1889 | 1886 |
1890 if (m_focusedElement && !m_focusedElement->isFocusable()) | 1887 if (m_focusedElement && !m_focusedElement->isFocusable()) |
1891 setFocusedElement(nullptr); | 1888 setFocusedElement(nullptr); |
1892 } | 1889 } |
1893 | 1890 |
1894 // FIXME: This is a bad idea and needs to be removed eventually. | 1891 // FIXME: This is a bad idea and needs to be removed eventually. |
1895 // Other browsers load stylesheets before they continue parsing the web page. | 1892 // Other browsers load stylesheets before they continue parsing the web page. |
1896 // Since we don't, we can run JavaScript code that needs answers before the | 1893 // Since we don't, we can run JavaScript code that needs answers before the |
1897 // stylesheets are loaded. Doing a layout ignoring the pending stylesheets | 1894 // stylesheets are loaded. Doing a layout ignoring the pending stylesheets |
(...skipping 12 matching lines...) Expand all Loading... |
1910 // is a hack, since what we really want to do is suspend JS instead of d
oing a layout with | 1907 // is a hack, since what we really want to do is suspend JS instead of d
oing a layout with |
1911 // inaccurate information. | 1908 // inaccurate information. |
1912 HTMLElement* bodyElement = body(); | 1909 HTMLElement* bodyElement = body(); |
1913 if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == N
oLayoutWithPendingSheets) { | 1910 if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == N
oLayoutWithPendingSheets) { |
1914 m_pendingSheetLayout = DidLayoutWithPendingSheets; | 1911 m_pendingSheetLayout = DidLayoutWithPendingSheets; |
1915 styleResolverChanged(RecalcStyleImmediately); | 1912 styleResolverChanged(RecalcStyleImmediately); |
1916 } else if (m_hasNodesWithPlaceholderStyle) { | 1913 } else if (m_hasNodesWithPlaceholderStyle) { |
1917 // If new nodes have been added or style recalc has been done with s
tyle sheets still | 1914 // If new nodes have been added or style recalc has been done with s
tyle sheets still |
1918 // pending, some nodes may not have had their real style calculated
yet. Normally this | 1915 // pending, some nodes may not have had their real style calculated
yet. Normally this |
1919 // gets cleaned when style sheets arrive but here we need up-to-date
style immediately. | 1916 // gets cleaned when style sheets arrive but here we need up-to-date
style immediately. |
1920 updateStyle(Force); | 1917 updateRenderTree(Force); |
1921 } | 1918 } |
1922 } | 1919 } |
1923 | 1920 |
1924 updateLayout(); | 1921 updateLayout(); |
1925 | 1922 |
1926 if (runPostLayoutTasks == RunPostLayoutTasksSynchronously && view()) | 1923 if (runPostLayoutTasks == RunPostLayoutTasksSynchronously && view()) |
1927 view()->flushAnyPendingPostLayoutTasks(); | 1924 view()->flushAnyPendingPostLayoutTasks(); |
1928 } | 1925 } |
1929 | 1926 |
1930 PassRefPtr<RenderStyle> Document::styleForElementIgnoringPendingStylesheets(Elem
ent* element) | 1927 PassRefPtr<RenderStyle> Document::styleForElementIgnoringPendingStylesheets(Elem
ent* element) |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2002 m_layerUpdateElements.clear(); | 1999 m_layerUpdateElements.clear(); |
2003 return true; | 2000 return true; |
2004 } | 2001 } |
2005 | 2002 |
2006 void Document::scheduleLayerUpdate(Element& element) | 2003 void Document::scheduleLayerUpdate(Element& element) |
2007 { | 2004 { |
2008 if (element.styleChangeType() == NeedsReattachStyleChange) | 2005 if (element.styleChangeType() == NeedsReattachStyleChange) |
2009 return; | 2006 return; |
2010 element.setNeedsLayerUpdate(); | 2007 element.setNeedsLayerUpdate(); |
2011 m_layerUpdateElements.add(&element); | 2008 m_layerUpdateElements.add(&element); |
2012 scheduleStyleRecalc(); | 2009 scheduleRenderTreeUpdate(); |
2013 } | 2010 } |
2014 | 2011 |
2015 void Document::unscheduleLayerUpdate(Element& element) | 2012 void Document::unscheduleLayerUpdate(Element& element) |
2016 { | 2013 { |
2017 element.clearNeedsLayerUpdate(); | 2014 element.clearNeedsLayerUpdate(); |
2018 m_layerUpdateElements.remove(&element); | 2015 m_layerUpdateElements.remove(&element); |
2019 } | 2016 } |
2020 | 2017 |
2021 void Document::scheduleUseShadowTreeUpdate(SVGUseElement& element) | 2018 void Document::scheduleUseShadowTreeUpdate(SVGUseElement& element) |
2022 { | 2019 { |
2023 m_useElementsNeedingUpdate.add(&element); | 2020 m_useElementsNeedingUpdate.add(&element); |
2024 scheduleStyleRecalc(); | 2021 scheduleRenderTreeUpdate(); |
2025 } | 2022 } |
2026 | 2023 |
2027 void Document::unscheduleUseShadowTreeUpdate(SVGUseElement& element) | 2024 void Document::unscheduleUseShadowTreeUpdate(SVGUseElement& element) |
2028 { | 2025 { |
2029 m_useElementsNeedingUpdate.remove(&element); | 2026 m_useElementsNeedingUpdate.remove(&element); |
2030 } | 2027 } |
2031 | 2028 |
2032 void Document::updateUseShadowTreesIfNeeded() | 2029 void Document::updateUseShadowTreesIfNeeded() |
2033 { | 2030 { |
2034 if (m_useElementsNeedingUpdate.isEmpty()) | 2031 if (m_useElementsNeedingUpdate.isEmpty()) |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2473 // Just bail out. Before or during the onload we were shifted to another
page. | 2470 // Just bail out. Before or during the onload we were shifted to another
page. |
2474 // The old i-Bench suite does this. When this happens don't bother paint
ing or laying out. | 2471 // The old i-Bench suite does this. When this happens don't bother paint
ing or laying out. |
2475 m_loadEventProgress = LoadEventCompleted; | 2472 m_loadEventProgress = LoadEventCompleted; |
2476 return; | 2473 return; |
2477 } | 2474 } |
2478 | 2475 |
2479 // We used to force a synchronous display and flush here. This really isn't | 2476 // We used to force a synchronous display and flush here. This really isn't |
2480 // necessary and can in fact be actively harmful if pages are loading at a r
ate of > 60fps | 2477 // necessary and can in fact be actively harmful if pages are loading at a r
ate of > 60fps |
2481 // (if your platform is syncing flushes and limiting them to 60fps). | 2478 // (if your platform is syncing flushes and limiting them to 60fps). |
2482 if (!ownerElement() || (ownerElement()->renderer() && !ownerElement()->rende
rer()->needsLayout())) { | 2479 if (!ownerElement() || (ownerElement()->renderer() && !ownerElement()->rende
rer()->needsLayout())) { |
2483 updateStyleIfNeeded(); | 2480 updateRenderTreeIfNeeded(); |
2484 | 2481 |
2485 // Always do a layout after loading if needed. | 2482 // Always do a layout after loading if needed. |
2486 if (view() && renderView() && (!renderView()->firstChild() || renderView
()->needsLayout())) | 2483 if (view() && renderView() && (!renderView()->firstChild() || renderView
()->needsLayout())) |
2487 view()->layout(); | 2484 view()->layout(); |
2488 } | 2485 } |
2489 | 2486 |
2490 m_loadEventProgress = LoadEventCompleted; | 2487 m_loadEventProgress = LoadEventCompleted; |
2491 | 2488 |
2492 if (frame() && renderView() && AXObjectCache::accessibilityEnabled()) { | 2489 if (frame() && renderView() && AXObjectCache::accessibilityEnabled()) { |
2493 // The AX cache may have been cleared at this point, but we need to make
sure it contains an | 2490 // The AX cache may have been cleared at this point, but we need to make
sure it contains an |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2600 } | 2597 } |
2601 | 2598 |
2602 void Document::setParsing(bool b) | 2599 void Document::setParsing(bool b) |
2603 { | 2600 { |
2604 m_isParsing = b; | 2601 m_isParsing = b; |
2605 | 2602 |
2606 if (m_isParsing && !m_elementDataCache) | 2603 if (m_isParsing && !m_elementDataCache) |
2607 m_elementDataCache = ElementDataCache::create(); | 2604 m_elementDataCache = ElementDataCache::create(); |
2608 } | 2605 } |
2609 | 2606 |
2610 bool Document::shouldScheduleLayout() | 2607 bool Document::shouldScheduleLayout() const |
2611 { | 2608 { |
2612 // This function will only be called when FrameView thinks a layout is neede
d. | 2609 // This function will only be called when FrameView thinks a layout is neede
d. |
2613 // This enforces a couple extra rules. | 2610 // This enforces a couple extra rules. |
2614 // | 2611 // |
2615 // (a) Only schedule a layout once the stylesheets are loaded. | 2612 // (a) Only schedule a layout once the stylesheets are loaded. |
2616 // (b) Only schedule layout once we have a body element. | 2613 // (b) Only schedule layout once we have a body element. |
2617 | 2614 |
2618 return (haveStylesheetsAndImportsLoaded() && body()) | 2615 return (haveStylesheetsAndImportsLoaded() && body()) |
2619 || (documentElement() && !isHTMLHtmlElement(*documentElement())); | 2616 || (documentElement() && !isHTMLHtmlElement(*documentElement())); |
2620 } | 2617 } |
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3281 { | 3278 { |
3282 return m_styleEngine->selectedStylesheetSetName(); | 3279 return m_styleEngine->selectedStylesheetSetName(); |
3283 } | 3280 } |
3284 | 3281 |
3285 void Document::setSelectedStylesheetSet(const String& aString) | 3282 void Document::setSelectedStylesheetSet(const String& aString) |
3286 { | 3283 { |
3287 m_styleEngine->setSelectedStylesheetSetName(aString); | 3284 m_styleEngine->setSelectedStylesheetSetName(aString); |
3288 styleResolverChanged(RecalcStyleDeferred); | 3285 styleResolverChanged(RecalcStyleDeferred); |
3289 } | 3286 } |
3290 | 3287 |
| 3288 void Document::evaluateMediaQueryListIfNeeded() |
| 3289 { |
| 3290 if (!m_evaluateMediaQueriesOnStyleRecalc) |
| 3291 return; |
| 3292 evaluateMediaQueryList(); |
| 3293 m_evaluateMediaQueriesOnStyleRecalc = false; |
| 3294 } |
| 3295 |
3291 void Document::evaluateMediaQueryList() | 3296 void Document::evaluateMediaQueryList() |
3292 { | 3297 { |
3293 if (m_mediaQueryMatcher) | 3298 if (m_mediaQueryMatcher) |
3294 m_mediaQueryMatcher->styleResolverChanged(); | 3299 m_mediaQueryMatcher->styleResolverChanged(); |
3295 } | 3300 } |
3296 | 3301 |
3297 void Document::notifyResizeForViewportUnits() | 3302 void Document::notifyResizeForViewportUnits() |
3298 { | 3303 { |
3299 if (!hasViewportUnits()) | 3304 if (!hasViewportUnits()) |
3300 return; | 3305 return; |
(...skipping 16 matching lines...) Expand all Loading... |
3317 renderView()->repaintViewAndCompositedLayers(); | 3322 renderView()->repaintViewAndCompositedLayers(); |
3318 } | 3323 } |
3319 | 3324 |
3320 if (!change.needsStyleRecalc()) | 3325 if (!change.needsStyleRecalc()) |
3321 return; | 3326 return; |
3322 | 3327 |
3323 m_evaluateMediaQueriesOnStyleRecalc = true; | 3328 m_evaluateMediaQueriesOnStyleRecalc = true; |
3324 setNeedsStyleRecalc(SubtreeStyleChange); | 3329 setNeedsStyleRecalc(SubtreeStyleChange); |
3325 | 3330 |
3326 if (updateTime == RecalcStyleImmediately) | 3331 if (updateTime == RecalcStyleImmediately) |
3327 updateStyleIfNeeded(); | 3332 updateRenderTreeIfNeeded(); |
3328 } | 3333 } |
3329 | 3334 |
3330 void Document::setHoverNode(PassRefPtr<Node> newHoverNode) | 3335 void Document::setHoverNode(PassRefPtr<Node> newHoverNode) |
3331 { | 3336 { |
3332 m_hoverNode = newHoverNode; | 3337 m_hoverNode = newHoverNode; |
3333 } | 3338 } |
3334 | 3339 |
3335 void Document::setActiveHoverElement(PassRefPtr<Element> newActiveElement) | 3340 void Document::setActiveHoverElement(PassRefPtr<Element> newActiveElement) |
3336 { | 3341 { |
3337 if (!newActiveElement) { | 3342 if (!newActiveElement) { |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3531 if (!focusChangeBlocked && m_focusedElement) { | 3536 if (!focusChangeBlocked && m_focusedElement) { |
3532 // Create the AXObject cache in a focus change because Chromium relies o
n it. | 3537 // Create the AXObject cache in a focus change because Chromium relies o
n it. |
3533 if (AXObjectCache* cache = axObjectCache()) | 3538 if (AXObjectCache* cache = axObjectCache()) |
3534 cache->handleFocusedUIElementChanged(oldFocusedElement.get(), newFoc
usedElement.get()); | 3539 cache->handleFocusedUIElementChanged(oldFocusedElement.get(), newFoc
usedElement.get()); |
3535 } | 3540 } |
3536 | 3541 |
3537 if (!focusChangeBlocked && frameHost()) | 3542 if (!focusChangeBlocked && frameHost()) |
3538 frameHost()->chrome().focusedNodeChanged(m_focusedElement.get()); | 3543 frameHost()->chrome().focusedNodeChanged(m_focusedElement.get()); |
3539 | 3544 |
3540 SetFocusedElementDone: | 3545 SetFocusedElementDone: |
3541 updateStyleIfNeeded(); | 3546 updateRenderTreeIfNeeded(); |
3542 if (LocalFrame* frame = this->frame()) | 3547 if (LocalFrame* frame = this->frame()) |
3543 frame->selection().didChangeFocus(); | 3548 frame->selection().didChangeFocus(); |
3544 return !focusChangeBlocked; | 3549 return !focusChangeBlocked; |
3545 } | 3550 } |
3546 | 3551 |
3547 void Document::setCSSTarget(Element* n) | 3552 void Document::setCSSTarget(Element* n) |
3548 { | 3553 { |
3549 if (m_cssTarget) | 3554 if (m_cssTarget) |
3550 m_cssTarget->didAffectSelector(AffectedSelectorTarget); | 3555 m_cssTarget->didAffectSelector(AffectedSelectorTarget); |
3551 m_cssTarget = n; | 3556 m_cssTarget = n; |
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4165 } | 4170 } |
4166 | 4171 |
4167 // Support for Javascript execCommand, and related methods | 4172 // Support for Javascript execCommand, and related methods |
4168 | 4173 |
4169 static Editor::Command command(Document* document, const String& commandName, bo
ol userInterface = false) | 4174 static Editor::Command command(Document* document, const String& commandName, bo
ol userInterface = false) |
4170 { | 4175 { |
4171 LocalFrame* frame = document->frame(); | 4176 LocalFrame* frame = document->frame(); |
4172 if (!frame || frame->document() != document) | 4177 if (!frame || frame->document() != document) |
4173 return Editor::Command(); | 4178 return Editor::Command(); |
4174 | 4179 |
4175 document->updateStyleIfNeeded(); | 4180 document->updateRenderTreeIfNeeded(); |
4176 return frame->editor().command(commandName, userInterface ? CommandFromDOMWi
thUserInterface : CommandFromDOM); | 4181 return frame->editor().command(commandName, userInterface ? CommandFromDOMWi
thUserInterface : CommandFromDOM); |
4177 } | 4182 } |
4178 | 4183 |
4179 bool Document::execCommand(const String& commandName, bool userInterface, const
String& value) | 4184 bool Document::execCommand(const String& commandName, bool userInterface, const
String& value) |
4180 { | 4185 { |
4181 // We don't allow recusrive |execCommand()| to protect against attack code. | 4186 // We don't allow recusrive |execCommand()| to protect against attack code. |
4182 // Recursive call of |execCommand()| could be happened by moving iframe | 4187 // Recursive call of |execCommand()| could be happened by moving iframe |
4183 // with script triggered by insertion, e.g. <iframe src="javascript:..."> | 4188 // with script triggered by insertion, e.g. <iframe src="javascript:..."> |
4184 // <iframe onload="...">. This usage is valid as of the specification | 4189 // <iframe onload="...">. This usage is valid as of the specification |
4185 // although, it isn't common use case, rather it is used as attack code. | 4190 // although, it isn't common use case, rather it is used as attack code. |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4448 RefPtr<Document> protect(this); | 4453 RefPtr<Document> protect(this); |
4449 | 4454 |
4450 if (RefPtr<LocalFrame> f = frame()) { | 4455 if (RefPtr<LocalFrame> f = frame()) { |
4451 // FrameLoader::finishedParsing() might end up calling Document::implici
tClose() if all | 4456 // FrameLoader::finishedParsing() might end up calling Document::implici
tClose() if all |
4452 // resource loads are complete. HTMLObjectElements can start loading the
ir resources from | 4457 // resource loads are complete. HTMLObjectElements can start loading the
ir resources from |
4453 // post attach callbacks triggered by recalcStyle(). This means if we p
arse out an <object> | 4458 // post attach callbacks triggered by recalcStyle(). This means if we p
arse out an <object> |
4454 // tag and then reach the end of the document without updating styles, w
e might not have yet | 4459 // tag and then reach the end of the document without updating styles, w
e might not have yet |
4455 // started the resource load and might fire the window load event too ea
rly. To avoid this | 4460 // started the resource load and might fire the window load event too ea
rly. To avoid this |
4456 // we force the styles to be up to date before calling FrameLoader::fini
shedParsing(). | 4461 // we force the styles to be up to date before calling FrameLoader::fini
shedParsing(). |
4457 // See https://bugs.webkit.org/show_bug.cgi?id=36864 starting around com
ment 35. | 4462 // See https://bugs.webkit.org/show_bug.cgi?id=36864 starting around com
ment 35. |
4458 updateStyleIfNeeded(); | 4463 updateRenderTreeIfNeeded(); |
4459 | 4464 |
4460 f->loader().finishedParsing(); | 4465 f->loader().finishedParsing(); |
4461 | 4466 |
4462 InspectorInstrumentation::domContentLoadedEventFired(f.get()); | 4467 InspectorInstrumentation::domContentLoadedEventFired(f.get()); |
4463 } | 4468 } |
4464 | 4469 |
4465 // Schedule dropping of the ElementDataCache. We keep it alive for a while a
fter parsing finishes | 4470 // Schedule dropping of the ElementDataCache. We keep it alive for a while a
fter parsing finishes |
4466 // so that dynamically inserted content can also benefit from sharing optimi
zations. | 4471 // so that dynamically inserted content can also benefit from sharing optimi
zations. |
4467 // Note that we don't refresh the timer on cache access since that could lea
d to huge caches being kept | 4472 // Note that we don't refresh the timer on cache access since that could lea
d to huge caches being kept |
4468 // alive indefinitely by something innocuous like JS setting .innerHTML repe
atedly on a timer. | 4473 // alive indefinitely by something innocuous like JS setting .innerHTML repe
atedly on a timer. |
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5303 sawCommonAncestor = true; | 5308 sawCommonAncestor = true; |
5304 if (allowActiveChanges) | 5309 if (allowActiveChanges) |
5305 nodesToAddToChain[i]->setActive(true); | 5310 nodesToAddToChain[i]->setActive(true); |
5306 if (!sawCommonAncestor) { | 5311 if (!sawCommonAncestor) { |
5307 nodesToAddToChain[i]->setHovered(true); | 5312 nodesToAddToChain[i]->setHovered(true); |
5308 if (event && (ancestorHasCapturingMouseenterListener || nodesToAddTo
Chain[i]->hasEventListeners(EventTypeNames::mouseenter))) | 5313 if (event && (ancestorHasCapturingMouseenterListener || nodesToAddTo
Chain[i]->hasEventListeners(EventTypeNames::mouseenter))) |
5309 nodesToAddToChain[i]->dispatchMouseEvent(*event, EventTypeNames:
:mouseenter, 0, oldHoverNode.get()); | 5314 nodesToAddToChain[i]->dispatchMouseEvent(*event, EventTypeNames:
:mouseenter, 0, oldHoverNode.get()); |
5310 } | 5315 } |
5311 } | 5316 } |
5312 | 5317 |
5313 updateStyleIfNeeded(); | 5318 updateRenderTreeIfNeeded(); |
5314 } | 5319 } |
5315 | 5320 |
5316 bool Document::haveStylesheetsLoaded() const | 5321 bool Document::haveStylesheetsLoaded() const |
5317 { | 5322 { |
5318 return m_styleEngine->haveStylesheetsLoaded(); | 5323 return m_styleEngine->haveStylesheetsLoaded(); |
5319 } | 5324 } |
5320 | 5325 |
5321 Locale& Document::getCachedLocale(const AtomicString& locale) | 5326 Locale& Document::getCachedLocale(const AtomicString& locale) |
5322 { | 5327 { |
5323 AtomicString localeKey = locale; | 5328 AtomicString localeKey = locale; |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5494 } | 5499 } |
5495 | 5500 |
5496 void Document::invalidateNodeListCaches(const QualifiedName* attrName) | 5501 void Document::invalidateNodeListCaches(const QualifiedName* attrName) |
5497 { | 5502 { |
5498 HashSet<LiveNodeListBase*>::iterator end = m_listsInvalidatedAtDocument.end(
); | 5503 HashSet<LiveNodeListBase*>::iterator end = m_listsInvalidatedAtDocument.end(
); |
5499 for (HashSet<LiveNodeListBase*>::iterator it = m_listsInvalidatedAtDocument.
begin(); it != end; ++it) | 5504 for (HashSet<LiveNodeListBase*>::iterator it = m_listsInvalidatedAtDocument.
begin(); it != end; ++it) |
5500 (*it)->invalidateCache(attrName); | 5505 (*it)->invalidateCache(attrName); |
5501 } | 5506 } |
5502 | 5507 |
5503 } // namespace WebCore | 5508 } // namespace WebCore |
OLD | NEW |