OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "core/fetch/ImageResource.h" | 33 #include "core/fetch/ImageResource.h" |
34 #include "core/html/HTMLIFrameElement.h" | 34 #include "core/html/HTMLIFrameElement.h" |
35 #include "core/html/HTMLMediaElement.h" | 35 #include "core/html/HTMLMediaElement.h" |
36 #include "core/html/canvas/CanvasRenderingContext.h" | 36 #include "core/html/canvas/CanvasRenderingContext.h" |
37 #include "core/inspector/InspectorInstrumentation.h" | 37 #include "core/inspector/InspectorInstrumentation.h" |
38 #include "core/page/Chrome.h" | 38 #include "core/page/Chrome.h" |
39 #include "core/page/FrameView.h" | 39 #include "core/page/FrameView.h" |
40 #include "core/page/Settings.h" | 40 #include "core/page/Settings.h" |
41 #include "core/page/animation/AnimationController.h" | 41 #include "core/page/animation/AnimationController.h" |
42 #include "core/page/scrolling/ScrollingCoordinator.h" | 42 #include "core/page/scrolling/ScrollingCoordinator.h" |
43 #include "core/platform/animation/KeyframeValueList.h" | |
44 #include "core/platform/graphics/FontCache.h" | 43 #include "core/platform/graphics/FontCache.h" |
45 #include "core/platform/graphics/GraphicsContext.h" | 44 #include "core/platform/graphics/GraphicsContext.h" |
46 #include "core/platform/graphics/GraphicsLayer.h" | 45 #include "core/platform/graphics/GraphicsLayer.h" |
47 #include "core/plugins/PluginView.h" | 46 #include "core/plugins/PluginView.h" |
48 #include "core/rendering/RenderApplet.h" | 47 #include "core/rendering/RenderApplet.h" |
49 #include "core/rendering/RenderEmbeddedObject.h" | 48 #include "core/rendering/RenderEmbeddedObject.h" |
50 #include "core/rendering/RenderIFrame.h" | 49 #include "core/rendering/RenderIFrame.h" |
51 #include "core/rendering/RenderImage.h" | 50 #include "core/rendering/RenderImage.h" |
52 #include "core/rendering/RenderLayer.h" | 51 #include "core/rendering/RenderLayer.h" |
53 #include "core/rendering/RenderLayerCompositor.h" | 52 #include "core/rendering/RenderLayerCompositor.h" |
54 #include "core/rendering/RenderVideo.h" | 53 #include "core/rendering/RenderVideo.h" |
55 #include "core/rendering/RenderView.h" | 54 #include "core/rendering/RenderView.h" |
| 55 #include "core/rendering/animation/WebAnimationProvider.h" |
56 #include "core/rendering/style/KeyframeList.h" | 56 #include "core/rendering/style/KeyframeList.h" |
57 #include "wtf/CurrentTime.h" | 57 #include "wtf/CurrentTime.h" |
58 #include "wtf/text/StringBuilder.h" | 58 #include "wtf/text/StringBuilder.h" |
59 | 59 |
60 #include "core/platform/graphics/filters/custom/CustomFilterOperation.h" | 60 #include "core/platform/graphics/filters/custom/CustomFilterOperation.h" |
61 #include "core/rendering/FilterEffectRenderer.h" | 61 #include "core/rendering/FilterEffectRenderer.h" |
62 | 62 |
63 #include "core/platform/graphics/GraphicsContext3D.h" | 63 #include "core/platform/graphics/GraphicsContext3D.h" |
64 | 64 |
65 using namespace std; | 65 using namespace std; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 { | 145 { |
146 Page* page = layer->renderer()->frame()->page(); | 146 Page* page = layer->renderer()->frame()->page(); |
147 if (!page) | 147 if (!page) |
148 return 0; | 148 return 0; |
149 | 149 |
150 return page->scrollingCoordinator(); | 150 return page->scrollingCoordinator(); |
151 } | 151 } |
152 | 152 |
153 RenderLayerBacking::RenderLayerBacking(RenderLayer* layer) | 153 RenderLayerBacking::RenderLayerBacking(RenderLayer* layer) |
154 : m_owningLayer(layer) | 154 : m_owningLayer(layer) |
| 155 , m_animationProvider(adoptPtr(new WebAnimationProvider)) |
155 , m_artificiallyInflatedBounds(false) | 156 , m_artificiallyInflatedBounds(false) |
156 , m_boundsConstrainedByClipping(false) | 157 , m_boundsConstrainedByClipping(false) |
157 , m_isMainFrameRenderViewLayer(false) | 158 , m_isMainFrameRenderViewLayer(false) |
158 , m_requiresOwnBackingStore(true) | 159 , m_requiresOwnBackingStore(true) |
159 , m_canCompositeFilters(false) | 160 , m_canCompositeFilters(false) |
160 , m_backgroundLayerPaintsFixedRootBackground(false) | 161 , m_backgroundLayerPaintsFixedRootBackground(false) |
161 { | 162 { |
162 if (layer->isRootLayer()) { | 163 if (layer->isRootLayer()) { |
163 Frame& frame = toRenderView(renderer())->frameView()->frame(); | 164 Frame& frame = toRenderView(renderer())->frameView()->frame(); |
164 Page* page = frame.page(); | 165 Page* page = frame.page(); |
(...skipping 1538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1703 | 1704 |
1704 #ifndef NDEBUG | 1705 #ifndef NDEBUG |
1705 void RenderLayerBacking::verifyNotPainting() | 1706 void RenderLayerBacking::verifyNotPainting() |
1706 { | 1707 { |
1707 ASSERT(!renderer()->frame()->page() || !renderer()->frame()->page()->isPaint
ing()); | 1708 ASSERT(!renderer()->frame()->page() || !renderer()->frame()->page()->isPaint
ing()); |
1708 } | 1709 } |
1709 #endif | 1710 #endif |
1710 | 1711 |
1711 bool RenderLayerBacking::startAnimation(double timeOffset, const CSSAnimationDat
a* anim, const KeyframeList& keyframes) | 1712 bool RenderLayerBacking::startAnimation(double timeOffset, const CSSAnimationDat
a* anim, const KeyframeList& keyframes) |
1712 { | 1713 { |
1713 bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity); | |
1714 bool hasTransform = renderer()->isBox() && keyframes.containsProperty(CSSPro
pertyWebkitTransform); | 1714 bool hasTransform = renderer()->isBox() && keyframes.containsProperty(CSSPro
pertyWebkitTransform); |
1715 bool hasFilter = keyframes.containsProperty(CSSPropertyWebkitFilter); | 1715 IntSize boxSize; |
1716 | 1716 if (hasTransform) |
1717 if (!hasOpacity && !hasTransform && !hasFilter) | 1717 boxSize = toRenderBox(renderer())->pixelSnappedBorderBoxRect().size(); |
| 1718 WebAnimations animations(m_animationProvider->startAnimation(timeOffset, ani
m, keyframes, hasTransform, boxSize)); |
| 1719 if (animations.isEmpty()) |
1718 return false; | 1720 return false; |
1719 | 1721 |
1720 KeyframeValueList transformVector(AnimatedPropertyWebkitTransform); | |
1721 KeyframeValueList opacityVector(AnimatedPropertyOpacity); | |
1722 KeyframeValueList filterVector(AnimatedPropertyWebkitFilter); | |
1723 | |
1724 size_t numKeyframes = keyframes.size(); | |
1725 for (size_t i = 0; i < numKeyframes; ++i) { | |
1726 const KeyframeValue& currentKeyframe = keyframes[i]; | |
1727 const RenderStyle* keyframeStyle = currentKeyframe.style(); | |
1728 double key = currentKeyframe.key(); | |
1729 | |
1730 if (!keyframeStyle) | |
1731 continue; | |
1732 | |
1733 // Get timing function. | |
1734 RefPtr<TimingFunction> tf = KeyframeValue::timingFunction(currentKeyfram
e.style(), keyframes.animationName()); | |
1735 | |
1736 bool isFirstOrLastKeyframe = key == 0 || key == 1; | |
1737 if ((hasTransform && isFirstOrLastKeyframe) || currentKeyframe.containsP
roperty(CSSPropertyWebkitTransform)) | |
1738 transformVector.insert(adoptPtr(new TransformAnimationValue(key, &(k
eyframeStyle->transform()), tf))); | |
1739 | |
1740 if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsPro
perty(CSSPropertyOpacity)) | |
1741 opacityVector.insert(adoptPtr(new FloatAnimationValue(key, keyframeS
tyle->opacity(), tf))); | |
1742 | |
1743 if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProp
erty(CSSPropertyWebkitFilter)) | |
1744 filterVector.insert(adoptPtr(new FilterAnimationValue(key, &(keyfram
eStyle->filter()), tf))); | |
1745 } | |
1746 | |
1747 bool didAnimate = false; | 1722 bool didAnimate = false; |
1748 | 1723 if (animations.m_transformAnimation && m_graphicsLayer->addAnimation(animati
ons.m_transformAnimation.get())) |
1749 if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderB
ox(renderer())->pixelSnappedBorderBoxRect().size(), anim, keyframes.animationNam
e(), timeOffset)) | |
1750 didAnimate = true; | 1724 didAnimate = true; |
1751 | 1725 if (animations.m_opacityAnimation && m_graphicsLayer->addAnimation(animation
s.m_opacityAnimation.get())) |
1752 if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), an
im, keyframes.animationName(), timeOffset)) | |
1753 didAnimate = true; | 1726 didAnimate = true; |
1754 | 1727 if (animations.m_filterAnimation && m_graphicsLayer->addAnimation(animations
.m_filterAnimation.get())) |
1755 if (hasFilter && m_graphicsLayer->addAnimation(filterVector, IntSize(), anim
, keyframes.animationName(), timeOffset)) | |
1756 didAnimate = true; | 1728 didAnimate = true; |
1757 | 1729 |
1758 return didAnimate; | 1730 return didAnimate; |
1759 } | 1731 } |
1760 | 1732 |
1761 void RenderLayerBacking::animationPaused(double timeOffset, const String& animat
ionName) | 1733 void RenderLayerBacking::animationPaused(double timeOffset, const String& animat
ionName) |
1762 { | 1734 { |
1763 m_graphicsLayer->pauseAnimation(animationName, timeOffset); | 1735 int animationId = m_animationProvider->getWebAnimationId(animationName); |
| 1736 if (animationId) |
| 1737 m_graphicsLayer->pauseAnimation(animationId, timeOffset); |
1764 } | 1738 } |
1765 | 1739 |
1766 void RenderLayerBacking::animationFinished(const String& animationName) | 1740 void RenderLayerBacking::animationFinished(const String& animationName) |
1767 { | 1741 { |
1768 m_graphicsLayer->removeAnimation(animationName); | 1742 int animationId = m_animationProvider->getWebAnimationId(animationName); |
| 1743 if (animationId) |
| 1744 m_graphicsLayer->removeAnimation(animationId); |
1769 } | 1745 } |
1770 | 1746 |
1771 bool RenderLayerBacking::startTransition(double timeOffset, CSSPropertyID proper
ty, const RenderStyle* fromStyle, const RenderStyle* toStyle) | 1747 bool RenderLayerBacking::startTransition(double timeOffset, CSSPropertyID proper
ty, const RenderStyle* fromStyle, const RenderStyle* toStyle) |
1772 { | 1748 { |
| 1749 ASSERT(property != CSSPropertyInvalid); |
| 1750 IntSize boxSize; |
| 1751 if (property == CSSPropertyWebkitTransform && m_owningLayer->hasTransform())
{ |
| 1752 ASSERT(renderer()->isBox()); |
| 1753 boxSize = toRenderBox(renderer())->pixelSnappedBorderBoxRect().size(); |
| 1754 } |
| 1755 float fromOpacity = 0; |
| 1756 float toOpacity = 0; |
| 1757 if (property == CSSPropertyOpacity) { |
| 1758 fromOpacity = compositingOpacity(fromStyle->opacity()); |
| 1759 toOpacity = compositingOpacity(toStyle->opacity()); |
| 1760 } |
| 1761 WebAnimations animations(m_animationProvider->startTransition(timeOffset, pr
operty, fromStyle, |
| 1762 toStyle, m_owningLayer->hasTransform(), m_owningLayer->hasFilter(), boxS
ize, fromOpacity, toOpacity)); |
1773 bool didAnimate = false; | 1763 bool didAnimate = false; |
1774 | 1764 if (animations.m_transformAnimation && m_graphicsLayer->addAnimation(animati
ons.m_transformAnimation.get())) { |
1775 ASSERT(property != CSSPropertyInvalid); | 1765 // To ensure that the correct transform is visible when the animation en
ds, also set the final transform. |
1776 | 1766 updateTransform(toStyle); |
1777 if (property == CSSPropertyOpacity) { | 1767 didAnimate = true; |
1778 const CSSAnimationData* opacityAnim = toStyle->transitionForProperty(CSS
PropertyOpacity); | |
1779 if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) { | |
1780 KeyframeValueList opacityVector(AnimatedPropertyOpacity); | |
1781 opacityVector.insert(adoptPtr(new FloatAnimationValue(0, compositing
Opacity(fromStyle->opacity())))); | |
1782 opacityVector.insert(adoptPtr(new FloatAnimationValue(1, compositing
Opacity(toStyle->opacity())))); | |
1783 // The boxSize param is only used for transform animations (which ca
n only run on RenderBoxes), so we pass an empty size here. | |
1784 if (m_graphicsLayer->addAnimation(opacityVector, IntSize(), opacityA
nim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOff
set)) { | |
1785 // To ensure that the correct opacity is visible when the animat
ion ends, also set the final opacity. | |
1786 updateOpacity(toStyle); | |
1787 didAnimate = true; | |
1788 } | |
1789 } | |
1790 } | 1768 } |
1791 | 1769 if (animations.m_opacityAnimation && m_graphicsLayer->addAnimation(animation
s.m_opacityAnimation.get())) { |
1792 if (property == CSSPropertyWebkitTransform && m_owningLayer->hasTransform())
{ | 1770 // To ensure that the correct opacity is visible when the animation ends
, also set the final opacity. |
1793 const CSSAnimationData* transformAnim = toStyle->transitionForProperty(C
SSPropertyWebkitTransform); | 1771 updateOpacity(toStyle); |
1794 if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) { | 1772 didAnimate = true; |
1795 KeyframeValueList transformVector(AnimatedPropertyWebkitTransform); | |
1796 transformVector.insert(adoptPtr(new TransformAnimationValue(0, &from
Style->transform()))); | |
1797 transformVector.insert(adoptPtr(new TransformAnimationValue(1, &toSt
yle->transform()))); | |
1798 if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(rende
rer())->pixelSnappedBorderBoxRect().size(), transformAnim, GraphicsLayer::animat
ionNameForTransition(AnimatedPropertyWebkitTransform), timeOffset)) { | |
1799 // To ensure that the correct transform is visible when the anim
ation ends, also set the final transform. | |
1800 updateTransform(toStyle); | |
1801 didAnimate = true; | |
1802 } | |
1803 } | |
1804 } | 1773 } |
1805 | 1774 if (animations.m_filterAnimation && m_graphicsLayer->addAnimation(animations
.m_filterAnimation.get())) { |
1806 if (property == CSSPropertyWebkitFilter && m_owningLayer->hasFilter()) { | 1775 // To ensure that the correct filter is visible when the animation ends,
also set the final filter. |
1807 const CSSAnimationData* filterAnim = toStyle->transitionForProperty(CSSP
ropertyWebkitFilter); | 1776 updateFilters(toStyle); |
1808 if (filterAnim && !filterAnim->isEmptyOrZeroDuration()) { | 1777 didAnimate = true; |
1809 KeyframeValueList filterVector(AnimatedPropertyWebkitFilter); | |
1810 filterVector.insert(adoptPtr(new FilterAnimationValue(0, &fromStyle-
>filter()))); | |
1811 filterVector.insert(adoptPtr(new FilterAnimationValue(1, &toStyle->f
ilter()))); | |
1812 if (m_graphicsLayer->addAnimation(filterVector, IntSize(), filterAni
m, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitFilter), time
Offset)) { | |
1813 // To ensure that the correct filter is visible when the animati
on ends, also set the final filter. | |
1814 updateFilters(toStyle); | |
1815 didAnimate = true; | |
1816 } | |
1817 } | |
1818 } | 1778 } |
1819 | 1779 |
1820 return didAnimate; | 1780 return didAnimate; |
1821 } | 1781 } |
1822 | 1782 |
1823 void RenderLayerBacking::transitionPaused(double timeOffset, CSSPropertyID prope
rty) | 1783 void RenderLayerBacking::transitionPaused(double timeOffset, CSSPropertyID prope
rty) |
1824 { | 1784 { |
1825 AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property); | 1785 int animationId = m_animationProvider->getWebAnimationId(property); |
1826 if (animatedProperty != AnimatedPropertyInvalid) | 1786 if (animationId) |
1827 m_graphicsLayer->pauseAnimation(GraphicsLayer::animationNameForTransitio
n(animatedProperty), timeOffset); | 1787 m_graphicsLayer->pauseAnimation(animationId, timeOffset); |
1828 } | 1788 } |
1829 | 1789 |
1830 void RenderLayerBacking::transitionFinished(CSSPropertyID property) | 1790 void RenderLayerBacking::transitionFinished(CSSPropertyID property) |
1831 { | 1791 { |
1832 AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property); | 1792 int animationId = m_animationProvider->getWebAnimationId(property); |
1833 if (animatedProperty != AnimatedPropertyInvalid) | 1793 if (animationId) |
1834 m_graphicsLayer->removeAnimation(GraphicsLayer::animationNameForTransiti
on(animatedProperty)); | 1794 m_graphicsLayer->removeAnimation(animationId); |
1835 } | 1795 } |
1836 | 1796 |
1837 void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, double tim
e) | 1797 void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, double tim
e) |
1838 { | 1798 { |
1839 renderer()->animation()->notifyAnimationStarted(renderer(), time); | 1799 renderer()->animation()->notifyAnimationStarted(renderer(), time); |
1840 } | 1800 } |
1841 | 1801 |
1842 // This is used for the 'freeze' API, for testing only. | 1802 // This is used for the 'freeze' API, for testing only. |
1843 void RenderLayerBacking::suspendAnimations(double time) | 1803 void RenderLayerBacking::suspendAnimations(double time) |
1844 { | 1804 { |
1845 m_graphicsLayer->suspendAnimations(time); | 1805 m_graphicsLayer->suspendAnimations(time); |
1846 } | 1806 } |
1847 | 1807 |
1848 void RenderLayerBacking::resumeAnimations() | 1808 void RenderLayerBacking::resumeAnimations() |
1849 { | 1809 { |
1850 m_graphicsLayer->resumeAnimations(); | 1810 m_graphicsLayer->resumeAnimations(); |
1851 } | 1811 } |
1852 | 1812 |
1853 IntRect RenderLayerBacking::compositedBounds() const | 1813 IntRect RenderLayerBacking::compositedBounds() const |
1854 { | 1814 { |
1855 return m_compositedBounds; | 1815 return m_compositedBounds; |
1856 } | 1816 } |
1857 | 1817 |
1858 void RenderLayerBacking::setCompositedBounds(const IntRect& bounds) | 1818 void RenderLayerBacking::setCompositedBounds(const IntRect& bounds) |
1859 { | 1819 { |
1860 m_compositedBounds = bounds; | 1820 m_compositedBounds = bounds; |
1861 } | 1821 } |
1862 | 1822 |
1863 CSSPropertyID RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID
property) | |
1864 { | |
1865 CSSPropertyID cssProperty = CSSPropertyInvalid; | |
1866 switch (property) { | |
1867 case AnimatedPropertyWebkitTransform: | |
1868 cssProperty = CSSPropertyWebkitTransform; | |
1869 break; | |
1870 case AnimatedPropertyOpacity: | |
1871 cssProperty = CSSPropertyOpacity; | |
1872 break; | |
1873 case AnimatedPropertyBackgroundColor: | |
1874 cssProperty = CSSPropertyBackgroundColor; | |
1875 break; | |
1876 case AnimatedPropertyWebkitFilter: | |
1877 cssProperty = CSSPropertyWebkitFilter; | |
1878 break; | |
1879 case AnimatedPropertyInvalid: | |
1880 ASSERT_NOT_REACHED(); | |
1881 } | |
1882 return cssProperty; | |
1883 } | |
1884 | |
1885 AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(CSSPropertyID
cssProperty) | |
1886 { | |
1887 switch (cssProperty) { | |
1888 case CSSPropertyWebkitTransform: | |
1889 return AnimatedPropertyWebkitTransform; | |
1890 case CSSPropertyOpacity: | |
1891 return AnimatedPropertyOpacity; | |
1892 case CSSPropertyBackgroundColor: | |
1893 return AnimatedPropertyBackgroundColor; | |
1894 case CSSPropertyWebkitFilter: | |
1895 return AnimatedPropertyWebkitFilter; | |
1896 default: | |
1897 // It's fine if we see other css properties here; they are just not
accelerated. | |
1898 break; | |
1899 } | |
1900 return AnimatedPropertyInvalid; | |
1901 } | |
1902 | |
1903 CompositingLayerType RenderLayerBacking::compositingLayerType() const | 1823 CompositingLayerType RenderLayerBacking::compositingLayerType() const |
1904 { | 1824 { |
1905 if (m_graphicsLayer->hasContentsLayer()) | 1825 if (m_graphicsLayer->hasContentsLayer()) |
1906 return MediaCompositingLayer; | 1826 return MediaCompositingLayer; |
1907 | 1827 |
1908 if (m_graphicsLayer->drawsContent()) | 1828 if (m_graphicsLayer->drawsContent()) |
1909 return NormalCompositingLayer; | 1829 return NormalCompositingLayer; |
1910 | 1830 |
1911 return ContainerCompositingLayer; | 1831 return ContainerCompositingLayer; |
1912 } | 1832 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1965 } else if (graphicsLayer == m_scrollingContentsLayer.get()) { | 1885 } else if (graphicsLayer == m_scrollingContentsLayer.get()) { |
1966 name = "Scrolling Contents Layer"; | 1886 name = "Scrolling Contents Layer"; |
1967 } else { | 1887 } else { |
1968 ASSERT_NOT_REACHED(); | 1888 ASSERT_NOT_REACHED(); |
1969 } | 1889 } |
1970 | 1890 |
1971 return name; | 1891 return name; |
1972 } | 1892 } |
1973 | 1893 |
1974 } // namespace WebCore | 1894 } // namespace WebCore |
OLD | NEW |