1417 lines
58 KiB
Diff
1417 lines
58 KiB
Diff
|
diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp
|
||
|
--- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp 1970-01-01 01:00:00.000000000 +0100
|
||
|
+++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.cpp 2010-06-11 15:29:14.567278020 +0200
|
||
|
@@ -0,0 +1,101 @@
|
||
|
+/*
|
||
|
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
|
||
|
+
|
||
|
+ This library is free software; you can redistribute it and/or
|
||
|
+ modify it under the terms of the GNU Library General Public
|
||
|
+ License as published by the Free Software Foundation; either
|
||
|
+ version 2 of the License, or (at your option) any later version.
|
||
|
+
|
||
|
+ This library is distributed in the hope that it will be useful,
|
||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
+ Library General Public License for more details.
|
||
|
+
|
||
|
+ You should have received a copy of the GNU Library General Public License
|
||
|
+ aint with this library; see the file COPYING.LIB. If not, write to
|
||
|
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
+ Boston, MA 02110-1301, USA.
|
||
|
+*/
|
||
|
+
|
||
|
+#include "config.h"
|
||
|
+
|
||
|
+#if ENABLE(SVG)
|
||
|
+#include "RenderSVGShadowTreeRootContainer.h"
|
||
|
+
|
||
|
+#include "MouseEvent.h"
|
||
|
+#include "SVGShadowTreeElements.h"
|
||
|
+#include "SVGUseElement.h"
|
||
|
+
|
||
|
+namespace WebCore {
|
||
|
+
|
||
|
+RenderSVGShadowTreeRootContainer::RenderSVGShadowTreeRootContainer(SVGUseElement* node)
|
||
|
+ : RenderSVGTransformableContainer(node)
|
||
|
+ , m_recreateTree(false)
|
||
|
+{
|
||
|
+}
|
||
|
+
|
||
|
+RenderSVGShadowTreeRootContainer::~RenderSVGShadowTreeRootContainer()
|
||
|
+{
|
||
|
+ if (m_shadowRoot && m_shadowRoot->attached())
|
||
|
+ m_shadowRoot->detach();
|
||
|
+}
|
||
|
+
|
||
|
+void RenderSVGShadowTreeRootContainer::updateStyle(Node::StyleChange change)
|
||
|
+{
|
||
|
+ if (m_shadowRoot && m_shadowRoot->attached())
|
||
|
+ m_shadowRoot->recalcStyle(change);
|
||
|
+}
|
||
|
+
|
||
|
+void RenderSVGShadowTreeRootContainer::updateFromElement()
|
||
|
+{
|
||
|
+ bool hadExistingTree = m_shadowRoot;
|
||
|
+
|
||
|
+ SVGUseElement* useElement = static_cast<SVGUseElement*>(node());
|
||
|
+ if (!m_shadowRoot) {
|
||
|
+ ASSERT(!m_recreateTree);
|
||
|
+ m_shadowRoot = new SVGShadowTreeRootElement(document(), useElement);
|
||
|
+ useElement->buildPendingResource();
|
||
|
+ }
|
||
|
+
|
||
|
+ ASSERT(m_shadowRoot->shadowParentNode() == useElement);
|
||
|
+
|
||
|
+ bool shouldRecreateTree = m_recreateTree;
|
||
|
+ if (m_recreateTree) {
|
||
|
+ ASSERT(hadExistingTree);
|
||
|
+
|
||
|
+ if (m_shadowRoot->attached())
|
||
|
+ m_shadowRoot->detach();
|
||
|
+
|
||
|
+ m_shadowRoot->removeAllChildren();
|
||
|
+ m_recreateTree = false;
|
||
|
+ }
|
||
|
+
|
||
|
+ // Only rebuild the shadow tree, if we a) never had a tree or b) we were specifically asked to do so
|
||
|
+ // If the use element is a pending resource, and a) or b) is true, do nothing, and wait for the use
|
||
|
+ // element to be asked to buildPendingResource(), this will call us again, with m_recreateTrue=true.
|
||
|
+ if ((shouldRecreateTree || !hadExistingTree) && !useElement->isPendingResource()) {
|
||
|
+ useElement->buildShadowAndInstanceTree(m_shadowRoot.get());
|
||
|
+
|
||
|
+ // Attach shadow root element
|
||
|
+ m_shadowRoot->attachElement(style(), renderArena());
|
||
|
+
|
||
|
+ // Attach subtree, as if it was a regular non-shadow tree
|
||
|
+ for (Node* child = m_shadowRoot->firstChild(); child; child = child->nextSibling())
|
||
|
+ child->attach();
|
||
|
+ }
|
||
|
+
|
||
|
+ ASSERT(!m_recreateTree);
|
||
|
+ RenderSVGTransformableContainer::updateFromElement();
|
||
|
+}
|
||
|
+
|
||
|
+void RenderSVGShadowTreeRootContainer::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
|
||
|
+{
|
||
|
+ RenderSVGTransformableContainer::styleDidChange(diff, oldStyle);
|
||
|
+
|
||
|
+ if (RenderObject* shadowRootRenderer = m_shadowRoot ? m_shadowRoot->renderer() : 0)
|
||
|
+ shadowRootRenderer->setStyle(style());
|
||
|
+}
|
||
|
+
|
||
|
+}
|
||
|
+
|
||
|
+#endif
|
||
|
diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.h qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.h
|
||
|
--- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.h 1970-01-01 01:00:00.000000000 +0100
|
||
|
+++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/RenderSVGShadowTreeRootContainer.h 2010-06-11 15:29:14.568278907 +0200
|
||
|
@@ -0,0 +1,50 @@
|
||
|
+/*
|
||
|
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
|
||
|
+
|
||
|
+ This library is free software; you can redistribute it and/or
|
||
|
+ modify it under the terms of the GNU Library General Public
|
||
|
+ License as published by the Free Software Foundation; either
|
||
|
+ version 2 of the License, or (at your option) any later version.
|
||
|
+
|
||
|
+ This library is distributed in the hope that it will be useful,
|
||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
+ Library General Public License for more details.
|
||
|
+
|
||
|
+ You should have received a copy of the GNU Library General Public License
|
||
|
+ aint with this library; see the file COPYING.LIB. If not, write to
|
||
|
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
+ Boston, MA 02110-1301, USA.
|
||
|
+*/
|
||
|
+
|
||
|
+#ifndef RenderSVGShadowTreeRootContainer_h
|
||
|
+#define RenderSVGShadowTreeRootContainer_h
|
||
|
+
|
||
|
+#if ENABLE(SVG)
|
||
|
+#include "RenderSVGTransformableContainer.h"
|
||
|
+
|
||
|
+namespace WebCore {
|
||
|
+
|
||
|
+class SVGUseElement;
|
||
|
+class SVGShadowTreeRootElement;
|
||
|
+
|
||
|
+class RenderSVGShadowTreeRootContainer : public RenderSVGTransformableContainer {
|
||
|
+public:
|
||
|
+ RenderSVGShadowTreeRootContainer(SVGUseElement*);
|
||
|
+ virtual ~RenderSVGShadowTreeRootContainer();
|
||
|
+
|
||
|
+ void markShadowTreeForRecreation() { m_recreateTree = true; }
|
||
|
+ void updateStyle(Node::StyleChange);
|
||
|
+ virtual void updateFromElement();
|
||
|
+
|
||
|
+private:
|
||
|
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
|
||
|
+
|
||
|
+ bool m_recreateTree;
|
||
|
+ RefPtr<SVGShadowTreeRootElement> m_shadowRoot;
|
||
|
+};
|
||
|
+
|
||
|
+}
|
||
|
+
|
||
|
+#endif
|
||
|
+#endif
|
||
|
diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.cpp qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.cpp
|
||
|
--- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.cpp 2010-06-02 04:03:11.000000000 +0200
|
||
|
+++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/RenderSVGTransformableContainer.cpp 2010-06-11 15:29:14.568278907 +0200
|
||
|
@@ -1,5 +1,5 @@
|
||
|
/*
|
||
|
- Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
|
||
|
+ Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
|
||
|
2004, 2005, 2006 Rob Buis <buis@kde.org>
|
||
|
2009 Google, Inc.
|
||
|
|
||
|
@@ -20,12 +20,12 @@
|
||
|
*/
|
||
|
|
||
|
#include "config.h"
|
||
|
-#if ENABLE(SVG)
|
||
|
|
||
|
+#if ENABLE(SVG)
|
||
|
#include "RenderSVGTransformableContainer.h"
|
||
|
|
||
|
+#include "SVGShadowTreeElements.h"
|
||
|
#include "SVGStyledTransformableElement.h"
|
||
|
-#include "SVGTransformList.h"
|
||
|
|
||
|
namespace WebCore {
|
||
|
|
||
|
@@ -47,6 +47,14 @@
|
||
|
void RenderSVGTransformableContainer::calculateLocalTransform()
|
||
|
{
|
||
|
m_localTransform = static_cast<SVGStyledTransformableElement*>(node())->animatedLocalTransform();
|
||
|
+ if (!node()->hasTagName(SVGNames::gTag) || !static_cast<SVGGElement*>(node())->isShadowTreeContainerElement())
|
||
|
+ return;
|
||
|
+
|
||
|
+ FloatSize translation = static_cast<SVGShadowTreeContainerElement*>(node())->containerTranslation();
|
||
|
+ if (translation.width() == 0 && translation.height() == 0)
|
||
|
+ return;
|
||
|
+
|
||
|
+ m_localTransform.translateRight(translation.width(), translation.height());
|
||
|
}
|
||
|
|
||
|
}
|
||
|
diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.cpp qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.cpp
|
||
|
--- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.cpp 1970-01-01 01:00:00.000000000 +0100
|
||
|
+++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.cpp 2010-06-11 15:29:14.567278020 +0200
|
||
|
@@ -0,0 +1,80 @@
|
||
|
+/*
|
||
|
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
|
||
|
+
|
||
|
+ This library is free software; you can redistribute it and/or
|
||
|
+ modify it under the terms of the GNU Library General Public
|
||
|
+ License as published by the Free Software Foundation; either
|
||
|
+ version 2 of the License, or (at your option) any later version.
|
||
|
+
|
||
|
+ This library is distributed in the hope that it will be useful,
|
||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
+ Library General Public License for more details.
|
||
|
+
|
||
|
+ You should have received a copy of the GNU Library General Public License
|
||
|
+ aint with this library; see the file COPYING.LIB. If not, write to
|
||
|
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
+ Boston, MA 02110-1301, USA.
|
||
|
+*/
|
||
|
+
|
||
|
+#include "config.h"
|
||
|
+
|
||
|
+#if ENABLE(SVG)
|
||
|
+#include "SVGShadowTreeElements.h"
|
||
|
+
|
||
|
+#include "Document.h"
|
||
|
+#include "FloatSize.h"
|
||
|
+#include "RenderObject.h"
|
||
|
+#include "SVGNames.h"
|
||
|
+
|
||
|
+namespace WebCore {
|
||
|
+
|
||
|
+// SVGShadowTreeContainerElement
|
||
|
+SVGShadowTreeContainerElement::SVGShadowTreeContainerElement(Document* document)
|
||
|
+ : SVGGElement(SVGNames::gTag, document)
|
||
|
+{
|
||
|
+}
|
||
|
+
|
||
|
+SVGShadowTreeContainerElement::~SVGShadowTreeContainerElement()
|
||
|
+{
|
||
|
+}
|
||
|
+
|
||
|
+FloatSize SVGShadowTreeContainerElement::containerTranslation() const
|
||
|
+{
|
||
|
+ return FloatSize(m_xOffset.value(this), m_yOffset.value(this));
|
||
|
+}
|
||
|
+
|
||
|
+// SVGShadowTreeRootElement
|
||
|
+SVGShadowTreeRootElement::SVGShadowTreeRootElement(Document* document, Node* shadowParent)
|
||
|
+ : SVGShadowTreeContainerElement(document)
|
||
|
+ , m_shadowParent(shadowParent)
|
||
|
+{
|
||
|
+ setInDocument(true);
|
||
|
+}
|
||
|
+
|
||
|
+SVGShadowTreeRootElement::~SVGShadowTreeRootElement()
|
||
|
+{
|
||
|
+}
|
||
|
+
|
||
|
+void SVGShadowTreeRootElement::attachElement(PassRefPtr<RenderStyle> style, RenderArena* arena)
|
||
|
+{
|
||
|
+ ASSERT(m_shadowParent);
|
||
|
+
|
||
|
+ // Create the renderer with the specified style
|
||
|
+ RenderObject* renderer = createRenderer(arena, style.get());
|
||
|
+ if (renderer) {
|
||
|
+ setRenderer(renderer);
|
||
|
+ renderer->setStyle(style);
|
||
|
+ }
|
||
|
+
|
||
|
+ // Set these explicitly since this normally happens during an attach()
|
||
|
+ setAttached();
|
||
|
+
|
||
|
+ // Add the renderer to the render tree
|
||
|
+ if (renderer)
|
||
|
+ m_shadowParent->renderer()->addChild(renderer);
|
||
|
+}
|
||
|
+
|
||
|
+}
|
||
|
+
|
||
|
+#endif
|
||
|
diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.h qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.h
|
||
|
--- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.h 1970-01-01 01:00:00.000000000 +0100
|
||
|
+++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/rendering/SVGShadowTreeElements.h 2010-06-11 15:29:14.568278907 +0200
|
||
|
@@ -0,0 +1,67 @@
|
||
|
+/*
|
||
|
+ Copyright (C) Research In Motion Limited 2010. All rights reserved.
|
||
|
+
|
||
|
+ This library is free software; you can redistribute it and/or
|
||
|
+ modify it under the terms of the GNU Library General Public
|
||
|
+ License as published by the Free Software Foundation; either
|
||
|
+ version 2 of the License, or (at your option) any later version.
|
||
|
+
|
||
|
+ This library is distributed in the hope that it will be useful,
|
||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
+ Library General Public License for more details.
|
||
|
+
|
||
|
+ You should have received a copy of the GNU Library General Public License
|
||
|
+ aint with this library; see the file COPYING.LIB. If not, write to
|
||
|
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
+ Boston, MA 02110-1301, USA.
|
||
|
+*/
|
||
|
+
|
||
|
+#ifndef SVGShadowTreeElements_h
|
||
|
+#define SVGShadowTreeElements_h
|
||
|
+
|
||
|
+#if ENABLE(SVG)
|
||
|
+#include "SVGGElement.h"
|
||
|
+#include "SVGLength.h"
|
||
|
+
|
||
|
+namespace WebCore {
|
||
|
+
|
||
|
+class FloatSize;
|
||
|
+
|
||
|
+class SVGShadowTreeContainerElement : public SVGGElement {
|
||
|
+public:
|
||
|
+ SVGShadowTreeContainerElement(Document*);
|
||
|
+ virtual ~SVGShadowTreeContainerElement();
|
||
|
+
|
||
|
+ virtual bool isShadowTreeContainerElement() const { return true; }
|
||
|
+
|
||
|
+ FloatSize containerTranslation() const;
|
||
|
+ void setContainerOffset(const SVGLength& x, const SVGLength& y)
|
||
|
+ {
|
||
|
+ m_xOffset = x;
|
||
|
+ m_yOffset = y;
|
||
|
+ }
|
||
|
+
|
||
|
+private:
|
||
|
+ SVGLength m_xOffset;
|
||
|
+ SVGLength m_yOffset;
|
||
|
+};
|
||
|
+
|
||
|
+class SVGShadowTreeRootElement : public SVGShadowTreeContainerElement {
|
||
|
+public:
|
||
|
+ SVGShadowTreeRootElement(Document*, Node* shadowParent);
|
||
|
+ virtual ~SVGShadowTreeRootElement();
|
||
|
+
|
||
|
+ virtual bool isShadowNode() const { return m_shadowParent; }
|
||
|
+ virtual Node* shadowParentNode() { return m_shadowParent; }
|
||
|
+
|
||
|
+ void attachElement(PassRefPtr<RenderStyle>, RenderArena*);
|
||
|
+
|
||
|
+private:
|
||
|
+ Node* m_shadowParent;
|
||
|
+};
|
||
|
+
|
||
|
+}
|
||
|
+
|
||
|
+#endif
|
||
|
+#endif
|
||
|
diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp
|
||
|
--- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp 2010-06-02 04:03:10.000000000 +0200
|
||
|
+++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp 2010-06-11 15:29:14.559280466 +0200
|
||
|
@@ -54,7 +54,6 @@
|
||
|
|
||
|
SVGElement::SVGElement(const QualifiedName& tagName, Document* document)
|
||
|
: StyledElement(tagName, document, CreateElementZeroRefCount)
|
||
|
- , m_shadowParent(0)
|
||
|
, m_cursorElement(0)
|
||
|
, m_cursorImageValue(0)
|
||
|
{
|
||
|
@@ -285,7 +284,11 @@
|
||
|
|
||
|
ContainerNode* SVGElement::eventParentNode()
|
||
|
{
|
||
|
- return m_shadowParent ? m_shadowParent : StyledElement::eventParentNode();
|
||
|
+ if (Node* shadowParent = shadowParentNode()) {
|
||
|
+ ASSERT(shadowParent->isContainerNode());
|
||
|
+ return static_cast<ContainerNode*>(shadowParent);
|
||
|
+ }
|
||
|
+ return StyledElement::eventParentNode();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElement.h qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElement.h
|
||
|
--- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElement.h 2010-06-02 04:03:11.000000000 +0200
|
||
|
+++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElement.h 2010-06-11 15:29:14.564280678 +0200
|
||
|
@@ -60,8 +60,6 @@
|
||
|
virtual bool isGradientStop() const { return false; }
|
||
|
virtual bool isTextContent() const { return false; }
|
||
|
|
||
|
- void setShadowParentNode(ContainerNode* node) { m_shadowParent = node; }
|
||
|
-
|
||
|
// For SVGTests
|
||
|
virtual bool isValid() const { return true; }
|
||
|
|
||
|
@@ -95,13 +93,9 @@
|
||
|
friend class SVGElementInstance;
|
||
|
|
||
|
virtual bool isSVGElement() const { return true; }
|
||
|
-
|
||
|
virtual bool isSupported(StringImpl* feature, StringImpl* version) const;
|
||
|
-
|
||
|
- virtual bool isShadowNode() const { return m_shadowParent; }
|
||
|
- virtual Node* shadowParentNode() { return m_shadowParent; }
|
||
|
- virtual ContainerNode* eventParentNode();
|
||
|
|
||
|
+ virtual ContainerNode* eventParentNode();
|
||
|
virtual void buildPendingResource() { }
|
||
|
|
||
|
void mapInstanceToElement(SVGElementInstance*);
|
||
|
@@ -109,7 +103,6 @@
|
||
|
|
||
|
virtual bool haveLoadedRequiredResources();
|
||
|
|
||
|
- ContainerNode* m_shadowParent;
|
||
|
mutable SynchronizablePropertyController m_propertyController;
|
||
|
|
||
|
SVGCursorElement* m_cursorElement;
|
||
|
diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.cpp qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.cpp
|
||
|
--- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.cpp 2010-06-02 04:03:10.000000000 +0200
|
||
|
+++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.cpp 2010-06-11 15:29:14.560280508 +0200
|
||
|
@@ -33,10 +33,6 @@
|
||
|
|
||
|
#include <wtf/RefCountedLeakCounter.h>
|
||
|
|
||
|
-#if USE(JSC)
|
||
|
-#include "GCController.h"
|
||
|
-#endif
|
||
|
-
|
||
|
namespace WebCore {
|
||
|
|
||
|
#ifndef NDEBUG
|
||
|
@@ -51,8 +47,7 @@
|
||
|
}
|
||
|
|
||
|
SVGElementInstance::SVGElementInstance(SVGUseElement* useElement, PassRefPtr<SVGElement> originalElement)
|
||
|
- : m_needsUpdate(false)
|
||
|
- , m_useElement(useElement)
|
||
|
+ : m_useElement(useElement)
|
||
|
, m_element(originalElement)
|
||
|
, m_previousSibling(0)
|
||
|
, m_nextSibling(0)
|
||
|
@@ -93,20 +88,6 @@
|
||
|
m_shadowTreeElement = element;
|
||
|
}
|
||
|
|
||
|
-void SVGElementInstance::forgetWrapper()
|
||
|
-{
|
||
|
-#if USE(JSC)
|
||
|
- // FIXME: This is fragile, as discussed with Sam. Need to find a better solution.
|
||
|
- // Think about the case where JS explicitely holds "var root = useElement.instanceRoot;".
|
||
|
- // We still have to recreate this wrapper somehow. The gc collection below, won't catch it.
|
||
|
-
|
||
|
- // If the use shadow tree has been rebuilt, just the JSSVGElementInstance objects
|
||
|
- // are still holding RefPtrs of SVGElementInstance objects, which prevent us to
|
||
|
- // be deleted (and the shadow tree is not destructed as well). Force JS GC.
|
||
|
- gcController().garbageCollectNow();
|
||
|
-#endif
|
||
|
-}
|
||
|
-
|
||
|
void SVGElementInstance::appendChild(PassRefPtr<SVGElementInstance> child)
|
||
|
{
|
||
|
appendChildToContainer<SVGElementInstance, SVGElementInstance>(child.get(), this);
|
||
|
@@ -114,27 +95,24 @@
|
||
|
|
||
|
void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element)
|
||
|
{
|
||
|
- if (!element)
|
||
|
+ if (!element || !element->isStyled())
|
||
|
+ return;
|
||
|
+
|
||
|
+ if (static_cast<SVGStyledElement*>(element)->instanceUpdatesBlocked())
|
||
|
return;
|
||
|
|
||
|
HashSet<SVGElementInstance*> set = element->instancesForElement();
|
||
|
if (set.isEmpty())
|
||
|
return;
|
||
|
|
||
|
- // Find all use elements referencing the instances - ask them _once_ to rebuild.
|
||
|
+ // Mark all use elements referencing 'element' for rebuilding
|
||
|
HashSet<SVGElementInstance*>::const_iterator it = set.begin();
|
||
|
const HashSet<SVGElementInstance*>::const_iterator end = set.end();
|
||
|
|
||
|
- for (; it != end; ++it)
|
||
|
- (*it)->setNeedsUpdate(true);
|
||
|
-}
|
||
|
-
|
||
|
-void SVGElementInstance::setNeedsUpdate(bool value)
|
||
|
-{
|
||
|
- m_needsUpdate = value;
|
||
|
-
|
||
|
- if (m_needsUpdate)
|
||
|
- correspondingUseElement()->setNeedsStyleRecalc();
|
||
|
+ for (; it != end; ++it) {
|
||
|
+ ASSERT((*it)->correspondingElement() == element);
|
||
|
+ (*it)->correspondingUseElement()->invalidateShadowTree();
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
ScriptExecutionContext* SVGElementInstance::scriptExecutionContext() const
|
||
|
diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.h qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.h
|
||
|
--- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.h 2010-06-02 04:03:11.000000000 +0200
|
||
|
+++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGElementInstance.h 2010-06-11 15:29:14.556183347 +0200
|
||
|
@@ -46,9 +46,6 @@
|
||
|
|
||
|
virtual ~SVGElementInstance();
|
||
|
|
||
|
- bool needsUpdate() const { return m_needsUpdate; }
|
||
|
- void setNeedsUpdate(bool);
|
||
|
-
|
||
|
virtual ScriptExecutionContext* scriptExecutionContext() const;
|
||
|
|
||
|
virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
|
||
|
@@ -129,7 +126,6 @@
|
||
|
|
||
|
void appendChild(PassRefPtr<SVGElementInstance> child);
|
||
|
void setShadowTreeElement(SVGElement*);
|
||
|
- void forgetWrapper();
|
||
|
|
||
|
template<class GenericNode, class GenericNodeContainer>
|
||
|
friend void appendChildToContainer(GenericNode* child, GenericNodeContainer* container);
|
||
|
@@ -153,8 +149,6 @@
|
||
|
virtual EventTargetData* eventTargetData();
|
||
|
virtual EventTargetData* ensureEventTargetData();
|
||
|
|
||
|
- bool m_needsUpdate : 1;
|
||
|
-
|
||
|
SVGUseElement* m_useElement;
|
||
|
RefPtr<SVGElement> m_element;
|
||
|
RefPtr<SVGElement> m_shadowTreeElement;
|
||
|
diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGGElement.h qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGGElement.h
|
||
|
--- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGGElement.h 2010-06-02 04:03:10.000000000 +0200
|
||
|
+++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGGElement.h 2010-06-11 15:29:14.564280678 +0200
|
||
|
@@ -37,6 +37,7 @@
|
||
|
SVGGElement(const QualifiedName&, Document*);
|
||
|
virtual ~SVGGElement();
|
||
|
|
||
|
+ virtual bool isShadowTreeContainerElement() const { return false; }
|
||
|
virtual bool isValid() const { return SVGTests::isValid(); }
|
||
|
|
||
|
virtual void parseMappedAttribute(MappedAttribute*);
|
||
|
diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.cpp qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.cpp
|
||
|
--- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.cpp 2010-06-02 04:03:11.000000000 +0200
|
||
|
+++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.cpp 2010-06-11 15:29:14.562280735 +0200
|
||
|
@@ -45,11 +45,11 @@
|
||
|
using namespace SVGNames;
|
||
|
|
||
|
char SVGStyledElementIdentifier[] = "SVGStyledElement";
|
||
|
-static HashSet<const SVGStyledElement*>* gElementsWithInstanceUpdatesBlocked = 0;
|
||
|
|
||
|
SVGStyledElement::SVGStyledElement(const QualifiedName& tagName, Document* doc)
|
||
|
: SVGElement(tagName, doc)
|
||
|
, m_className(this, HTMLNames::classAttr)
|
||
|
+ , m_instanceUpdatesBlocked(false)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
@@ -270,19 +270,6 @@
|
||
|
SVGResource::removeClient(this);
|
||
|
SVGElement::detach();
|
||
|
}
|
||
|
-
|
||
|
-void SVGStyledElement::setInstanceUpdatesBlocked(bool blockUpdates)
|
||
|
-{
|
||
|
- if (blockUpdates) {
|
||
|
- if (!gElementsWithInstanceUpdatesBlocked)
|
||
|
- gElementsWithInstanceUpdatesBlocked = new HashSet<const SVGStyledElement*>;
|
||
|
- gElementsWithInstanceUpdatesBlocked->add(this);
|
||
|
- } else {
|
||
|
- ASSERT(gElementsWithInstanceUpdatesBlocked);
|
||
|
- ASSERT(gElementsWithInstanceUpdatesBlocked->contains(this));
|
||
|
- gElementsWithInstanceUpdatesBlocked->remove(this);
|
||
|
- }
|
||
|
-}
|
||
|
|
||
|
}
|
||
|
|
||
|
diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.h qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.h
|
||
|
--- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.h 2010-06-02 04:03:10.000000000 +0200
|
||
|
+++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGStyledElement.h 2010-06-11 15:29:14.554166596 +0200
|
||
|
@@ -49,10 +49,9 @@
|
||
|
|
||
|
virtual bool rendererIsNeeded(RenderStyle*);
|
||
|
virtual SVGResource* canvasResource() { return 0; }
|
||
|
-
|
||
|
+
|
||
|
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
|
||
|
virtual void parseMappedAttribute(MappedAttribute*);
|
||
|
-
|
||
|
virtual void svgAttributeChanged(const QualifiedName&);
|
||
|
|
||
|
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
|
||
|
@@ -62,8 +61,9 @@
|
||
|
|
||
|
void invalidateResourcesInAncestorChain() const;
|
||
|
virtual void detach();
|
||
|
-
|
||
|
- void setInstanceUpdatesBlocked(bool);
|
||
|
+
|
||
|
+ bool instanceUpdatesBlocked() const { return m_instanceUpdatesBlocked; }
|
||
|
+ void setInstanceUpdatesBlocked(bool value) { m_instanceUpdatesBlocked = value; }
|
||
|
|
||
|
protected:
|
||
|
virtual bool hasRelativeValues() const { return true; }
|
||
|
@@ -72,6 +72,7 @@
|
||
|
|
||
|
private:
|
||
|
ANIMATED_PROPERTY_DECLARATIONS(SVGStyledElement, SVGStyledElementIdentifier, HTMLNames::classAttrString, String, ClassName, className)
|
||
|
+ bool m_instanceUpdatesBlocked;
|
||
|
};
|
||
|
|
||
|
} // namespace WebCore
|
||
|
diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp
|
||
|
--- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp 2010-06-02 04:03:10.000000000 +0200
|
||
|
+++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp 2010-06-11 15:43:17.347280236 +0200
|
||
|
@@ -1,7 +1,7 @@
|
||
|
/*
|
||
|
Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
|
||
|
2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
|
||
|
- Copyright (C) Research In Motion Limited 2009. All rights reserved.
|
||
|
+ Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
|
||
|
|
||
|
This file is part of the KDE project
|
||
|
|
||
|
@@ -35,12 +35,13 @@
|
||
|
#include "MappedAttribute.h"
|
||
|
#include "NodeRenderStyle.h"
|
||
|
#include "RegisteredEventListener.h"
|
||
|
-#include "RenderSVGTransformableContainer.h"
|
||
|
+#include "RenderSVGShadowTreeRootContainer.h"
|
||
|
#include "SVGElementInstance.h"
|
||
|
#include "SVGElementInstanceList.h"
|
||
|
#include "SVGGElement.h"
|
||
|
#include "SVGLength.h"
|
||
|
#include "SVGPreserveAspectRatio.h"
|
||
|
+#include "SVGShadowTreeElements.h"
|
||
|
#include "SVGSMILElement.h"
|
||
|
#include "SVGSVGElement.h"
|
||
|
#include "SVGSymbolElement.h"
|
||
|
@@ -67,6 +68,8 @@
|
||
|
, m_height(this, SVGNames::heightAttr, LengthModeHeight)
|
||
|
, m_href(this, XLinkNames::hrefAttr)
|
||
|
, m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false)
|
||
|
+ , m_isPendingResource(false)
|
||
|
+ , m_needsShadowTreeRecreation(false)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
@@ -76,6 +79,16 @@
|
||
|
|
||
|
SVGElementInstance* SVGUseElement::instanceRoot() const
|
||
|
{
|
||
|
+ // If there is no element instance tree, force immediate SVGElementInstance tree
|
||
|
+ // creation, as we can't wait for the lazy creation to happen if ie. JS wants to
|
||
|
+ // access the instanceRoot object right after creating the element on-the-fly
|
||
|
+ if (!m_targetElementInstance) {
|
||
|
+ if (RenderSVGShadowTreeRootContainer* shadowRoot = static_cast<RenderSVGShadowTreeRootContainer*>(renderer())) {
|
||
|
+ shadowRoot->markShadowTreeForRecreation();
|
||
|
+ shadowRoot->updateFromElement();
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
return m_targetElementInstance.get();
|
||
|
}
|
||
|
|
||
|
@@ -114,14 +127,15 @@
|
||
|
|
||
|
void SVGUseElement::insertedIntoDocument()
|
||
|
{
|
||
|
+ // This functions exists to assure assumptions made in the code regarding SVGElementInstance creation/destruction are satisfied.
|
||
|
SVGElement::insertedIntoDocument();
|
||
|
- buildPendingResource();
|
||
|
+ ASSERT(!m_targetElementInstance);
|
||
|
+ ASSERT(!m_isPendingResource);
|
||
|
}
|
||
|
|
||
|
void SVGUseElement::removedFromDocument()
|
||
|
{
|
||
|
m_targetElementInstance = 0;
|
||
|
- m_shadowTreeRootElement = 0;
|
||
|
SVGElement::removedFromDocument();
|
||
|
}
|
||
|
|
||
|
@@ -129,87 +143,120 @@
|
||
|
{
|
||
|
SVGStyledTransformableElement::svgAttributeChanged(attrName);
|
||
|
|
||
|
- if (!attached())
|
||
|
+ if (!renderer())
|
||
|
return;
|
||
|
|
||
|
- if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr ||
|
||
|
- attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr ||
|
||
|
- SVGTests::isKnownAttribute(attrName) ||
|
||
|
- SVGLangSpace::isKnownAttribute(attrName) ||
|
||
|
- SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
|
||
|
- SVGURIReference::isKnownAttribute(attrName) ||
|
||
|
- SVGStyledTransformableElement::isKnownAttribute(attrName)) {
|
||
|
- buildPendingResource();
|
||
|
+ if (SVGURIReference::isKnownAttribute(attrName)) {
|
||
|
+ if (m_isPendingResource) {
|
||
|
+ document()->accessSVGExtensions()->removePendingResource(m_resourceId);
|
||
|
+ m_resourceId = String();
|
||
|
+ m_isPendingResource = false;
|
||
|
+ }
|
||
|
|
||
|
- if (m_shadowTreeRootElement)
|
||
|
- m_shadowTreeRootElement->setNeedsStyleRecalc();
|
||
|
+ invalidateShadowTree();
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr) {
|
||
|
+ updateContainerOffsets();
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ // Be very careful here, if svgAttributeChanged() has been called because a SVG CSS property changed, we do NOT want to reclone the tree!
|
||
|
+ if (SVGStyledElement::isKnownAttribute(attrName)) {
|
||
|
+ setNeedsStyleRecalc();
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ // TODO: We should be able to remove the need for width/height to require a reclone, similar to the x/y logic.
|
||
|
+ if (attrName == SVGNames::widthAttr
|
||
|
+ || attrName == SVGNames::heightAttr
|
||
|
+ || SVGTests::isKnownAttribute(attrName)
|
||
|
+ || SVGLangSpace::isKnownAttribute(attrName)
|
||
|
+ || SVGExternalResourcesRequired::isKnownAttribute(attrName)
|
||
|
+ || SVGStyledTransformableElement::isKnownAttribute(attrName)) {
|
||
|
+ invalidateShadowTree();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
-void SVGUseElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
|
||
|
+static void updateContainerOffset(SVGElementInstance* targetInstance)
|
||
|
{
|
||
|
- SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
|
||
|
+ // Depth-first used to write the method in early exit style, no particular other reason.
|
||
|
+ for (SVGElementInstance* instance = targetInstance->firstChild(); instance; instance = instance->nextSibling())
|
||
|
+ updateContainerOffset(instance);
|
||
|
|
||
|
- if (!attached())
|
||
|
+ SVGElement* correspondingElement = targetInstance->correspondingElement();
|
||
|
+ ASSERT(correspondingElement);
|
||
|
+
|
||
|
+ if (!correspondingElement->hasTagName(SVGNames::useTag))
|
||
|
return;
|
||
|
|
||
|
- buildPendingResource();
|
||
|
+ SVGElement* shadowTreeElement = targetInstance->shadowTreeElement();
|
||
|
+ ASSERT(shadowTreeElement);
|
||
|
+ ASSERT(shadowTreeElement->hasTagName(SVGNames::gTag));
|
||
|
+
|
||
|
+ if (!static_cast<SVGGElement*>(shadowTreeElement)->isShadowTreeContainerElement())
|
||
|
+ return;
|
||
|
|
||
|
- if (m_shadowTreeRootElement)
|
||
|
- m_shadowTreeRootElement->setNeedsStyleRecalc();
|
||
|
+ // Spec: An additional transformation translate(x,y) is appended to the end
|
||
|
+ // (i.e., right-side) of the transform attribute on the generated 'g', where x
|
||
|
+ // and y represent the values of the x and y attributes on the 'use' element.
|
||
|
+ SVGUseElement* useElement = static_cast<SVGUseElement*>(correspondingElement);
|
||
|
+ SVGShadowTreeContainerElement* containerElement = static_cast<SVGShadowTreeContainerElement*>(shadowTreeElement);
|
||
|
+ containerElement->setContainerOffset(useElement->x(), useElement->y());
|
||
|
}
|
||
|
-
|
||
|
-static bool shadowTreeContainsChangedNodes(SVGElementInstance* target)
|
||
|
+
|
||
|
+void SVGUseElement::updateContainerOffsets()
|
||
|
{
|
||
|
- if (!target) // when use is referencing an non-existing element, there will be no Instance tree built
|
||
|
- return false;
|
||
|
+ if (!m_targetElementInstance)
|
||
|
+ return;
|
||
|
|
||
|
- if (target->needsUpdate())
|
||
|
- return true;
|
||
|
+ // Update root container offset (not reachable through instance tree)
|
||
|
+ SVGElement* shadowRoot = m_targetElementInstance->shadowTreeElement();
|
||
|
+ ASSERT(shadowRoot);
|
||
|
|
||
|
- for (SVGElementInstance* instance = target->firstChild(); instance; instance = instance->nextSibling())
|
||
|
- if (shadowTreeContainsChangedNodes(instance))
|
||
|
- return true;
|
||
|
+ Node* parentNode = shadowRoot->parentNode();
|
||
|
+ ASSERT(parentNode);
|
||
|
+ ASSERT(parentNode->isSVGElement());
|
||
|
+ ASSERT(parentNode->hasTagName(SVGNames::gTag));
|
||
|
+ ASSERT(static_cast<SVGGElement*>(parentNode)->isShadowTreeContainerElement());
|
||
|
|
||
|
- return false;
|
||
|
+ SVGShadowTreeContainerElement* containerElement = static_cast<SVGShadowTreeContainerElement*>(parentNode);
|
||
|
+ containerElement->setContainerOffset(x(), y());
|
||
|
+
|
||
|
+ // Update whole subtree, scanning for shadow container elements, marking a cloned use subtree
|
||
|
+ updateContainerOffset(m_targetElementInstance.get());
|
||
|
+
|
||
|
+ if (renderer())
|
||
|
+ renderer()->setNeedsLayout(true);
|
||
|
}
|
||
|
|
||
|
void SVGUseElement::recalcStyle(StyleChange change)
|
||
|
{
|
||
|
- if (attached() && needsStyleRecalc() && shadowTreeContainsChangedNodes(m_targetElementInstance.get())) {
|
||
|
- buildPendingResource();
|
||
|
-
|
||
|
- if (m_shadowTreeRootElement)
|
||
|
- m_shadowTreeRootElement->setNeedsStyleRecalc();
|
||
|
+ // Eventually mark shadow root element needing style recalc
|
||
|
+ if (needsStyleRecalc() && m_targetElementInstance) {
|
||
|
+ if (SVGElement* shadowRoot = m_targetElementInstance->shadowTreeElement())
|
||
|
+ shadowRoot->setNeedsStyleRecalc();
|
||
|
}
|
||
|
|
||
|
- SVGStyledElement::recalcStyle(change);
|
||
|
+ SVGStyledTransformableElement::recalcStyle(change);
|
||
|
|
||
|
- // The shadow tree root element is NOT a direct child element of us.
|
||
|
- // So we have to take care it receives style updates, manually.
|
||
|
- if (!m_shadowTreeRootElement || !m_shadowTreeRootElement->attached())
|
||
|
- return;
|
||
|
-
|
||
|
- // Mimic Element::recalcStyle(). The main difference is that we don't call attach() on the
|
||
|
- // shadow tree root element, but call attachShadowTree() here. Calling attach() will crash
|
||
|
- // as the shadow tree root element has no (direct) parent node. Yes, shadow trees are tricky.
|
||
|
- if (change >= Inherit || m_shadowTreeRootElement->needsStyleRecalc()) {
|
||
|
- RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(m_shadowTreeRootElement.get());
|
||
|
- StyleChange ch = Node::diff(m_shadowTreeRootElement->renderStyle(), newStyle.get());
|
||
|
- if (ch == Detach) {
|
||
|
- ASSERT(m_shadowTreeRootElement->attached());
|
||
|
- m_shadowTreeRootElement->detach();
|
||
|
- attachShadowTree();
|
||
|
-
|
||
|
- // attach recalulates the style for all children. No need to do it twice.
|
||
|
- m_shadowTreeRootElement->setNeedsStyleRecalc(NoStyleChange);
|
||
|
- m_shadowTreeRootElement->setChildNeedsStyleRecalc(false);
|
||
|
- return;
|
||
|
- }
|
||
|
+ bool needsStyleUpdate = !m_needsShadowTreeRecreation;
|
||
|
+ if (m_needsShadowTreeRecreation) {
|
||
|
+ static_cast<RenderSVGShadowTreeRootContainer*>(renderer())->markShadowTreeForRecreation();
|
||
|
+ m_needsShadowTreeRecreation = false;
|
||
|
}
|
||
|
|
||
|
- // Only change==Detach needs special treatment, for anything else recalcStyle() works.
|
||
|
- m_shadowTreeRootElement->recalcStyle(change);
|
||
|
+ RenderSVGShadowTreeRootContainer* shadowRoot = static_cast<RenderSVGShadowTreeRootContainer*>(renderer());
|
||
|
+ if (!shadowRoot)
|
||
|
+ return;
|
||
|
+
|
||
|
+ shadowRoot->updateFromElement();
|
||
|
+
|
||
|
+ if (!needsStyleUpdate)
|
||
|
+ return;
|
||
|
+
|
||
|
+ shadowRoot->updateStyle(change);
|
||
|
}
|
||
|
|
||
|
#ifdef DUMP_INSTANCE_TREE
|
||
|
@@ -218,17 +265,21 @@
|
||
|
SVGElement* element = targetInstance->correspondingElement();
|
||
|
ASSERT(element);
|
||
|
|
||
|
+ SVGElement* shadowTreeElement = targetInstance->shadowTreeElement();
|
||
|
+ ASSERT(shadowTreeElement);
|
||
|
+
|
||
|
String elementId = element->getIDAttribute();
|
||
|
String elementNodeName = element->nodeName();
|
||
|
+ String shadowTreeElementNodeName = shadowTreeElement->nodeName();
|
||
|
String parentNodeName = element->parentNode() ? element->parentNode()->nodeName() : "null";
|
||
|
String firstChildNodeName = element->firstChild() ? element->firstChild()->nodeName() : "null";
|
||
|
|
||
|
for (unsigned int i = 0; i < depth; ++i)
|
||
|
text += " ";
|
||
|
|
||
|
- text += String::format("SVGElementInstance this=%p, (parentNode=%s, firstChild=%s, correspondingElement=%s (%p), shadowTreeElement=%p, id=%s)\n",
|
||
|
- targetInstance, parentNodeName.latin1().data(), firstChildNodeName.latin1().data(), elementNodeName.latin1().data(),
|
||
|
- element, targetInstance->shadowTreeElement(), elementId.latin1().data());
|
||
|
+ text += String::format("SVGElementInstance this=%p, (parentNode=%s (%p), firstChild=%s (%p), correspondingElement=%s (%p), shadowTreeElement=%s (%p), id=%s)\n",
|
||
|
+ targetInstance, parentNodeName.latin1().data(), element->parentNode(), firstChildNodeName.latin1().data(), element->firstChild(),
|
||
|
+ elementNodeName.latin1().data(), element, shadowTreeElementNodeName.latin1().data(), shadowTreeElement, elementId.latin1().data());
|
||
|
|
||
|
for (unsigned int i = 0; i < depth; ++i)
|
||
|
text += " ";
|
||
|
@@ -284,16 +335,36 @@
|
||
|
|
||
|
void SVGUseElement::buildPendingResource()
|
||
|
{
|
||
|
+ // If we're called the first time (during shadow tree root creation from RenderSVGShadowTreeRootContainer)
|
||
|
+ // we either determine that our target is available or not - then we add ourselves to the pending resource list
|
||
|
+ // Once the pending resource appears, it will call buildPendingResource(), so we're called a second time.
|
||
|
String id = SVGURIReference::getTarget(href());
|
||
|
Element* targetElement = document()->getElementById(id);
|
||
|
+ ASSERT(!m_targetElementInstance);
|
||
|
|
||
|
if (!targetElement) {
|
||
|
- // TODO: We want to deregister as pending resource, if our href() changed!
|
||
|
- // TODO: Move to svgAttributeChanged, once we're fixing use & the new dynamic update concept.
|
||
|
+ if (m_isPendingResource)
|
||
|
+ return;
|
||
|
+
|
||
|
+ m_isPendingResource = true;
|
||
|
+ m_resourceId = id;
|
||
|
document()->accessSVGExtensions()->addPendingResource(id, this);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
+ if (m_isPendingResource) {
|
||
|
+ ASSERT(!m_targetElementInstance);
|
||
|
+ m_isPendingResource = false;
|
||
|
+ invalidateShadowTree();
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+void SVGUseElement::buildShadowAndInstanceTree(SVGShadowTreeRootElement* shadowRoot)
|
||
|
+{
|
||
|
+ String id = SVGURIReference::getTarget(href());
|
||
|
+ Element* targetElement = document()->getElementById(id);
|
||
|
+ ASSERT(targetElement);
|
||
|
+
|
||
|
// Do not build the shadow/instance tree for <use> elements living in a shadow tree.
|
||
|
// The will be expanded soon anyway - see expandUseElementsInShadowTree().
|
||
|
Node* parent = parentNode();
|
||
|
@@ -308,17 +379,13 @@
|
||
|
if (targetElement && targetElement->isSVGElement())
|
||
|
target = static_cast<SVGElement*>(targetElement);
|
||
|
|
||
|
- if (m_targetElementInstance) {
|
||
|
- m_targetElementInstance->forgetWrapper();
|
||
|
+ if (m_targetElementInstance)
|
||
|
m_targetElementInstance = 0;
|
||
|
- }
|
||
|
|
||
|
// Do not allow self-referencing.
|
||
|
// 'target' may be null, if it's a non SVG namespaced element.
|
||
|
- if (!target || target == this) {
|
||
|
- m_shadowTreeRootElement = 0;
|
||
|
+ if (!target || target == this)
|
||
|
return;
|
||
|
- }
|
||
|
|
||
|
// Why a seperated instance/shadow tree? SVG demands it:
|
||
|
// The instance tree is accesable from JavaScript, and has to
|
||
|
@@ -340,45 +407,45 @@
|
||
|
// Non-appearing <use> content is easier to debug, then half-appearing content.
|
||
|
if (foundProblem) {
|
||
|
m_targetElementInstance = 0;
|
||
|
- m_shadowTreeRootElement = 0;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Assure instance tree building was successfull
|
||
|
ASSERT(m_targetElementInstance);
|
||
|
+ ASSERT(!m_targetElementInstance->shadowTreeElement());
|
||
|
ASSERT(m_targetElementInstance->correspondingUseElement() == this);
|
||
|
|
||
|
- // Setup shadow tree root node
|
||
|
- m_shadowTreeRootElement = new SVGGElement(SVGNames::gTag, document());
|
||
|
- m_shadowTreeRootElement->setInDocument();
|
||
|
- m_shadowTreeRootElement->setShadowParentNode(this);
|
||
|
-
|
||
|
- // Spec: An additional transformation translate(x,y) is appended to the end
|
||
|
- // (i.e., right-side) of the transform attribute on the generated 'g', where x
|
||
|
- // and y represent the values of the x and y attributes on the 'use' element.
|
||
|
- if (x().value(this) != 0.0 || y().value(this) != 0.0) {
|
||
|
- String transformString = String::format("translate(%f, %f)", x().value(this), y().value(this));
|
||
|
- m_shadowTreeRootElement->setAttribute(SVGNames::transformAttr, transformString);
|
||
|
- }
|
||
|
+ ASSERT(m_targetElementInstance->correspondingElement() == target);
|
||
|
|
||
|
// Build shadow tree from instance tree
|
||
|
// This also handles the special cases: <use> on <symbol>, <use> on <svg>.
|
||
|
- buildShadowTree(target, m_targetElementInstance.get());
|
||
|
+ buildShadowTree(shadowRoot, target, m_targetElementInstance.get());
|
||
|
|
||
|
#if ENABLE(SVG) && ENABLE(SVG_USE)
|
||
|
// Expand all <use> elements in the shadow tree.
|
||
|
// Expand means: replace the actual <use> element by what it references.
|
||
|
- expandUseElementsInShadowTree(m_shadowTreeRootElement.get());
|
||
|
+ expandUseElementsInShadowTree(shadowRoot, shadowRoot);
|
||
|
|
||
|
// Expand all <symbol> elements in the shadow tree.
|
||
|
// Expand means: replace the actual <symbol> element by the <svg> element.
|
||
|
- expandSymbolElementsInShadowTree(m_shadowTreeRootElement.get());
|
||
|
-
|
||
|
+ expandSymbolElementsInShadowTree(shadowRoot, shadowRoot);
|
||
|
#endif
|
||
|
|
||
|
// Now that the shadow tree is completly expanded, we can associate
|
||
|
// shadow tree elements <-> instances in the instance tree.
|
||
|
- associateInstancesWithShadowTreeElements(m_shadowTreeRootElement->firstChild(), m_targetElementInstance.get());
|
||
|
+ associateInstancesWithShadowTreeElements(shadowRoot->firstChild(), m_targetElementInstance.get());
|
||
|
+
|
||
|
+ // If no shadow tree element is present, this means that the reference root
|
||
|
+ // element was removed, as it is disallowed (ie. <use> on <foreignObject>)
|
||
|
+ // Do NOT leave an inconsistent instance tree around, instead destruct it.
|
||
|
+ if (!m_targetElementInstance->shadowTreeElement()) {
|
||
|
+ shadowRoot->removeAllChildren();
|
||
|
+ m_targetElementInstance = 0;
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ // Consistency checks - this is assumed in updateContainerOffset().
|
||
|
+ ASSERT(m_targetElementInstance->shadowTreeElement()->parentNode() == shadowRoot);
|
||
|
|
||
|
// Eventually dump instance tree
|
||
|
#ifdef DUMP_INSTANCE_TREE
|
||
|
@@ -395,8 +462,8 @@
|
||
|
|
||
|
PassRefPtr<XMLSerializer> serializer = XMLSerializer::create();
|
||
|
|
||
|
- String markup = serializer->serializeToString(m_shadowTreeRootElement.get(), ec);
|
||
|
- ASSERT(ec == 0);
|
||
|
+ String markup = serializer->serializeToString(shadowRoot, ec);
|
||
|
+ ASSERT(!ec);
|
||
|
|
||
|
fprintf(stderr, "Dumping <use> shadow tree markup:\n%s\n", markup.latin1().data());
|
||
|
#endif
|
||
|
@@ -404,30 +471,33 @@
|
||
|
// Transfer event listeners assigned to the referenced element to our shadow tree elements.
|
||
|
transferEventListenersToShadowTree(m_targetElementInstance.get());
|
||
|
|
||
|
- // The DOM side is setup properly. Now we have to attach the root shadow
|
||
|
- // tree element manually - using attach() won't work for "shadow nodes".
|
||
|
- attachShadowTree();
|
||
|
+ // Update container translation offsets
|
||
|
+ updateContainerOffsets();
|
||
|
}
|
||
|
|
||
|
RenderObject* SVGUseElement::createRenderer(RenderArena* arena, RenderStyle*)
|
||
|
{
|
||
|
- return new (arena) RenderSVGTransformableContainer(this);
|
||
|
+ return new (arena) RenderSVGShadowTreeRootContainer(this);
|
||
|
+}
|
||
|
+
|
||
|
+static void updateFromElementCallback(Node* node)
|
||
|
+{
|
||
|
+ if (RenderObject* renderer = node->renderer())
|
||
|
+ renderer->updateFromElement();
|
||
|
}
|
||
|
|
||
|
void SVGUseElement::attach()
|
||
|
{
|
||
|
SVGStyledTransformableElement::attach();
|
||
|
|
||
|
- // If we're a pending resource, this doesn't have any effect.
|
||
|
- attachShadowTree();
|
||
|
+ if (renderer())
|
||
|
+ queuePostAttachCallback(updateFromElementCallback, this);
|
||
|
}
|
||
|
|
||
|
void SVGUseElement::detach()
|
||
|
{
|
||
|
SVGStyledTransformableElement::detach();
|
||
|
-
|
||
|
- if (m_shadowTreeRootElement)
|
||
|
- m_shadowTreeRootElement->detach();
|
||
|
+ m_targetElementInstance = 0;
|
||
|
}
|
||
|
|
||
|
static bool isDirectReference(Node* n)
|
||
|
@@ -443,10 +513,10 @@
|
||
|
|
||
|
Path SVGUseElement::toClipPath() const
|
||
|
{
|
||
|
- if (!m_shadowTreeRootElement)
|
||
|
- const_cast<SVGUseElement*>(this)->buildPendingResource();
|
||
|
+ Node* n = m_targetElementInstance ? m_targetElementInstance->shadowTreeElement() : 0;
|
||
|
+ if (!n)
|
||
|
+ return Path();
|
||
|
|
||
|
- Node* n = m_shadowTreeRootElement->firstChild();
|
||
|
if (n->isSVGElement() && static_cast<SVGElement*>(n)->isStyledTransformable()) {
|
||
|
if (!isDirectReference(n))
|
||
|
// Spec: Indirect references are an error (14.3.5)
|
||
|
@@ -480,11 +550,12 @@
|
||
|
continue;
|
||
|
|
||
|
// Create SVGElementInstance object, for both container/non-container nodes.
|
||
|
- RefPtr<SVGElementInstance> instancePtr = SVGElementInstance::create(this, element);
|
||
|
- targetInstance->appendChild(instancePtr.get());
|
||
|
+ RefPtr<SVGElementInstance> instance = SVGElementInstance::create(this, element);
|
||
|
+ SVGElementInstance* instancePtr = instance.get();
|
||
|
+ targetInstance->appendChild(instance.release());
|
||
|
|
||
|
// Enter recursion, appending new instance tree nodes to the "instance" object.
|
||
|
- buildInstanceTree(element, instancePtr.get(), foundProblem);
|
||
|
+ buildInstanceTree(element, instancePtr, foundProblem);
|
||
|
}
|
||
|
|
||
|
// Spec: If the referenced object is itself a 'use', or if there are 'use' subelements within the referenced
|
||
|
@@ -525,10 +596,11 @@
|
||
|
|
||
|
// Create an instance object, even if we're dealing with a cycle
|
||
|
RefPtr<SVGElementInstance> newInstance = SVGElementInstance::create(this, target);
|
||
|
- targetInstance->appendChild(newInstance);
|
||
|
+ SVGElementInstance* newInstancePtr = newInstance.get();
|
||
|
+ targetInstance->appendChild(newInstance.release());
|
||
|
|
||
|
// Eventually enter recursion to build SVGElementInstance objects for the sub-tree children
|
||
|
- buildInstanceTree(target, newInstance.get(), foundProblem);
|
||
|
+ buildInstanceTree(target, newInstancePtr, foundProblem);
|
||
|
}
|
||
|
|
||
|
void SVGUseElement::alterShadowTreeForSVGTag(SVGElement* target)
|
||
|
@@ -559,7 +631,7 @@
|
||
|
}
|
||
|
}
|
||
|
|
||
|
-void SVGUseElement::buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance)
|
||
|
+void SVGUseElement::buildShadowTree(SVGShadowTreeRootElement* shadowRoot, SVGElement* target, SVGElementInstance* targetInstance)
|
||
|
{
|
||
|
// For instance <use> on <foreignObject> (direct case).
|
||
|
if (isDisallowedElement(target))
|
||
|
@@ -581,8 +653,8 @@
|
||
|
ASSERT(newChildPtr);
|
||
|
|
||
|
ExceptionCode ec = 0;
|
||
|
- m_shadowTreeRootElement->appendChild(newChild.release(), ec);
|
||
|
- ASSERT(ec == 0);
|
||
|
+ shadowRoot->appendChild(newChild.release(), ec);
|
||
|
+ ASSERT(!ec);
|
||
|
|
||
|
// Handle use referencing <svg> special case
|
||
|
if (target->hasTagName(SVGNames::svgTag))
|
||
|
@@ -590,7 +662,7 @@
|
||
|
}
|
||
|
|
||
|
#if ENABLE(SVG) && ENABLE(SVG_USE)
|
||
|
-void SVGUseElement::expandUseElementsInShadowTree(Node* element)
|
||
|
+void SVGUseElement::expandUseElementsInShadowTree(SVGShadowTreeRootElement* shadowRoot, Node* element)
|
||
|
{
|
||
|
// Why expand the <use> elements in the shadow tree here, and not just
|
||
|
// do this directly in buildShadowTree, if we encounter a <use> element?
|
||
|
@@ -611,28 +683,14 @@
|
||
|
// Don't ASSERT(target) here, it may be "pending", too.
|
||
|
if (target) {
|
||
|
// Setup sub-shadow tree root node
|
||
|
- RefPtr<SVGElement> cloneParent = new SVGGElement(SVGNames::gTag, document());
|
||
|
+ RefPtr<SVGShadowTreeContainerElement> cloneParent = new SVGShadowTreeContainerElement(document());
|
||
|
|
||
|
// Spec: In the generated content, the 'use' will be replaced by 'g', where all attributes from the
|
||
|
// 'use' element except for x, y, width, height and xlink:href are transferred to the generated 'g' element.
|
||
|
transferUseAttributesToReplacedElement(use, cloneParent.get());
|
||
|
|
||
|
- // Spec: An additional transformation translate(x,y) is appended to the end
|
||
|
- // (i.e., right-side) of the transform attribute on the generated 'g', where x
|
||
|
- // and y represent the values of the x and y attributes on the 'use' element.
|
||
|
- if (use->x().value(this) != 0.0 || use->y().value(this) != 0.0) {
|
||
|
- if (!cloneParent->hasAttribute(SVGNames::transformAttr)) {
|
||
|
- String transformString = String::format("translate(%f, %f)", use->x().value(this), use->y().value(this));
|
||
|
- cloneParent->setAttribute(SVGNames::transformAttr, transformString);
|
||
|
- } else {
|
||
|
- String transformString = String::format(" translate(%f, %f)", use->x().value(this), use->y().value(this));
|
||
|
- const AtomicString& transformAttribute = cloneParent->getAttribute(SVGNames::transformAttr);
|
||
|
- cloneParent->setAttribute(SVGNames::transformAttr, transformAttribute + transformString);
|
||
|
- }
|
||
|
- }
|
||
|
-
|
||
|
ExceptionCode ec = 0;
|
||
|
-
|
||
|
+
|
||
|
// For instance <use> on <foreignObject> (direct case).
|
||
|
if (isDisallowedElement(target)) {
|
||
|
// We still have to setup the <use> replacment (<g>). Otherwhise
|
||
|
@@ -640,7 +698,7 @@
|
||
|
// Replace <use> with referenced content.
|
||
|
ASSERT(use->parentNode());
|
||
|
use->parentNode()->replaceChild(cloneParent.release(), use, ec);
|
||
|
- ASSERT(ec == 0);
|
||
|
+ ASSERT(!ec);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
@@ -660,28 +718,28 @@
|
||
|
ASSERT(newChildPtr);
|
||
|
|
||
|
cloneParent->appendChild(newChild.release(), ec);
|
||
|
- ASSERT(ec == 0);
|
||
|
+ ASSERT(!ec);
|
||
|
|
||
|
// Replace <use> with referenced content.
|
||
|
ASSERT(use->parentNode());
|
||
|
use->parentNode()->replaceChild(cloneParent.release(), use, ec);
|
||
|
- ASSERT(ec == 0);
|
||
|
+ ASSERT(!ec);
|
||
|
|
||
|
// Handle use referencing <svg> special case
|
||
|
if (target->hasTagName(SVGNames::svgTag))
|
||
|
alterShadowTreeForSVGTag(newChildPtr);
|
||
|
|
||
|
// Immediately stop here, and restart expanding.
|
||
|
- expandUseElementsInShadowTree(m_shadowTreeRootElement.get());
|
||
|
+ expandUseElementsInShadowTree(shadowRoot, shadowRoot);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (RefPtr<Node> child = element->firstChild(); child; child = child->nextSibling())
|
||
|
- expandUseElementsInShadowTree(child.get());
|
||
|
+ expandUseElementsInShadowTree(shadowRoot, child.get());
|
||
|
}
|
||
|
|
||
|
-void SVGUseElement::expandSymbolElementsInShadowTree(Node* element)
|
||
|
+void SVGUseElement::expandSymbolElementsInShadowTree(SVGShadowTreeRootElement* shadowRoot, Node* element)
|
||
|
{
|
||
|
if (element->hasTagName(SVGNames::symbolTag)) {
|
||
|
// Spec: The referenced 'symbol' and its contents are deep-cloned into the generated tree,
|
||
|
@@ -708,7 +766,7 @@
|
||
|
for (Node* child = element->firstChild(); child; child = child->nextSibling()) {
|
||
|
RefPtr<Node> newChild = child->cloneNode(true);
|
||
|
svgElement->appendChild(newChild.release(), ec);
|
||
|
- ASSERT(ec == 0);
|
||
|
+ ASSERT(!ec);
|
||
|
}
|
||
|
|
||
|
// We don't walk the target tree element-by-element, and clone each element,
|
||
|
@@ -722,43 +780,19 @@
|
||
|
// Replace <symbol> with <svg>.
|
||
|
ASSERT(element->parentNode());
|
||
|
element->parentNode()->replaceChild(svgElement.release(), element, ec);
|
||
|
- ASSERT(ec == 0);
|
||
|
+ ASSERT(!ec);
|
||
|
|
||
|
// Immediately stop here, and restart expanding.
|
||
|
- expandSymbolElementsInShadowTree(m_shadowTreeRootElement.get());
|
||
|
+ expandSymbolElementsInShadowTree(shadowRoot, shadowRoot);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (RefPtr<Node> child = element->firstChild(); child; child = child->nextSibling())
|
||
|
- expandSymbolElementsInShadowTree(child.get());
|
||
|
+ expandSymbolElementsInShadowTree(shadowRoot, child.get());
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
-
|
||
|
-void SVGUseElement::attachShadowTree()
|
||
|
-{
|
||
|
- if (!m_shadowTreeRootElement || m_shadowTreeRootElement->attached() || !document()->shouldCreateRenderers() || !attached() || !renderer())
|
||
|
- return;
|
||
|
|
||
|
- // Inspired by RenderTextControl::createSubtreeIfNeeded().
|
||
|
- if (renderer()->canHaveChildren() && childShouldCreateRenderer(m_shadowTreeRootElement.get())) {
|
||
|
- RefPtr<RenderStyle> style = m_shadowTreeRootElement->styleForRenderer();
|
||
|
-
|
||
|
- if (m_shadowTreeRootElement->rendererIsNeeded(style.get())) {
|
||
|
- m_shadowTreeRootElement->setRenderer(m_shadowTreeRootElement->createRenderer(document()->renderArena(), style.get()));
|
||
|
- if (RenderObject* shadowRenderer = m_shadowTreeRootElement->renderer()) {
|
||
|
- shadowRenderer->setStyle(style.release());
|
||
|
- renderer()->addChild(shadowRenderer, m_shadowTreeRootElement->nextRenderer());
|
||
|
- m_shadowTreeRootElement->setAttached();
|
||
|
- }
|
||
|
- }
|
||
|
-
|
||
|
- // This will take care of attaching all shadow tree child nodes.
|
||
|
- for (Node* child = m_shadowTreeRootElement->firstChild(); child; child = child->nextSibling())
|
||
|
- child->attach();
|
||
|
- }
|
||
|
-}
|
||
|
-
|
||
|
void SVGUseElement::transferEventListenersToShadowTree(SVGElementInstance* target)
|
||
|
{
|
||
|
if (!target)
|
||
|
@@ -846,14 +880,19 @@
|
||
|
return instance;
|
||
|
|
||
|
for (SVGElementInstance* current = instance->firstChild(); current; current = current->nextSibling()) {
|
||
|
- SVGElementInstance* search = instanceForShadowTreeElement(element, current);
|
||
|
- if (search)
|
||
|
+ if (SVGElementInstance* search = instanceForShadowTreeElement(element, current))
|
||
|
return search;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+void SVGUseElement::invalidateShadowTree()
|
||
|
+{
|
||
|
+ m_needsShadowTreeRecreation = true;
|
||
|
+ setNeedsStyleRecalc();
|
||
|
+}
|
||
|
+
|
||
|
void SVGUseElement::transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const
|
||
|
{
|
||
|
ASSERT(from);
|
||
|
@@ -864,19 +903,19 @@
|
||
|
ExceptionCode ec = 0;
|
||
|
|
||
|
to->removeAttribute(SVGNames::xAttr, ec);
|
||
|
- ASSERT(ec == 0);
|
||
|
+ ASSERT(!ec);
|
||
|
|
||
|
to->removeAttribute(SVGNames::yAttr, ec);
|
||
|
- ASSERT(ec == 0);
|
||
|
+ ASSERT(!ec);
|
||
|
|
||
|
to->removeAttribute(SVGNames::widthAttr, ec);
|
||
|
- ASSERT(ec == 0);
|
||
|
+ ASSERT(!ec);
|
||
|
|
||
|
to->removeAttribute(SVGNames::heightAttr, ec);
|
||
|
- ASSERT(ec == 0);
|
||
|
+ ASSERT(!ec);
|
||
|
|
||
|
to->removeAttribute(XLinkNames::hrefAttr, ec);
|
||
|
- ASSERT(ec == 0);
|
||
|
+ ASSERT(!ec);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGUseElement.h qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGUseElement.h
|
||
|
--- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/svg/SVGUseElement.h 2010-06-02 04:03:10.000000000 +0200
|
||
|
+++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/svg/SVGUseElement.h 2010-06-11 15:29:14.557181915 +0200
|
||
|
@@ -32,6 +32,7 @@
|
||
|
|
||
|
class SVGElementInstance;
|
||
|
class SVGLength;
|
||
|
+ class SVGShadowTreeRootElement;
|
||
|
|
||
|
class SVGUseElement : public SVGStyledTransformableElement,
|
||
|
public SVGTests,
|
||
|
@@ -52,11 +53,9 @@
|
||
|
virtual void buildPendingResource();
|
||
|
|
||
|
virtual void parseMappedAttribute(MappedAttribute*);
|
||
|
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
|
||
|
-
|
||
|
virtual void svgAttributeChanged(const QualifiedName&);
|
||
|
- virtual void recalcStyle(StyleChange = NoChange);
|
||
|
|
||
|
+ virtual void recalcStyle(StyleChange = NoChange);
|
||
|
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
|
||
|
virtual void attach();
|
||
|
virtual void detach();
|
||
|
@@ -65,6 +64,12 @@
|
||
|
|
||
|
static void removeDisallowedElementsFromSubtree(Node* element);
|
||
|
SVGElementInstance* instanceForShadowTreeElement(Node* element) const;
|
||
|
+ void invalidateShadowTree();
|
||
|
+
|
||
|
+ private:
|
||
|
+ friend class RenderSVGShadowTreeRootContainer;
|
||
|
+ bool isPendingResource() const { return m_isPendingResource; }
|
||
|
+ void buildShadowAndInstanceTree(SVGShadowTreeRootElement*);
|
||
|
|
||
|
private:
|
||
|
ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGNames::useTagString, SVGNames::xAttrString, SVGLength, X, x)
|
||
|
@@ -86,26 +91,25 @@
|
||
|
void handleDeepUseReferencing(SVGUseElement* use, SVGElementInstance* targetInstance, bool& foundCycle);
|
||
|
|
||
|
// Shadow tree handling
|
||
|
- PassRefPtr<SVGSVGElement> buildShadowTreeForSymbolTag(SVGElement* target, SVGElementInstance* targetInstance);
|
||
|
- void alterShadowTreeForSVGTag(SVGElement* target);
|
||
|
-
|
||
|
- void buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance);
|
||
|
+ void alterShadowTreeForSVGTag(SVGElement*);
|
||
|
+ void buildShadowTree(SVGShadowTreeRootElement*, SVGElement* target, SVGElementInstance* targetInstance);
|
||
|
|
||
|
#if ENABLE(SVG) && ENABLE(SVG_USE)
|
||
|
- void expandUseElementsInShadowTree(Node* element);
|
||
|
- void expandSymbolElementsInShadowTree(Node* element);
|
||
|
+ void expandUseElementsInShadowTree(SVGShadowTreeRootElement*, Node* element);
|
||
|
+ void expandSymbolElementsInShadowTree(SVGShadowTreeRootElement*, Node* element);
|
||
|
#endif
|
||
|
|
||
|
- void attachShadowTree();
|
||
|
-
|
||
|
// "Tree connector"
|
||
|
void associateInstancesWithShadowTreeElements(Node* target, SVGElementInstance* targetInstance);
|
||
|
SVGElementInstance* instanceForShadowTreeElement(Node* element, SVGElementInstance* instance) const;
|
||
|
|
||
|
void transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const;
|
||
|
void transferEventListenersToShadowTree(SVGElementInstance* target);
|
||
|
+ void updateContainerOffsets();
|
||
|
|
||
|
- RefPtr<SVGElement> m_shadowTreeRootElement;
|
||
|
+ bool m_isPendingResource;
|
||
|
+ bool m_needsShadowTreeRecreation;
|
||
|
+ String m_resourceId;
|
||
|
RefPtr<SVGElementInstance> m_targetElementInstance;
|
||
|
};
|
||
|
|
||
|
diff -urN qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/WebCore.pro qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/WebCore.pro
|
||
|
--- qt-everywhere-opensource-src-4.6.3/src/3rdparty/webkit/WebCore/WebCore.pro 2010-06-02 04:03:11.000000000 +0200
|
||
|
+++ qt-everywhere-opensource-src-4.6.3-CVE-1303-1304/src/3rdparty/webkit/WebCore/WebCore.pro 2010-06-11 15:29:11.343280486 +0200
|
||
|
@@ -2066,6 +2066,7 @@
|
||
|
rendering/RenderSVGInlineText.h \
|
||
|
rendering/RenderSVGModelObject.h \
|
||
|
rendering/RenderSVGRoot.h \
|
||
|
+ rendering/RenderSVGShadowTreeRootContainer.h \
|
||
|
rendering/RenderSVGText.h \
|
||
|
rendering/RenderSVGTextPath.h \
|
||
|
rendering/RenderSVGTransformableContainer.h \
|
||
|
@@ -2121,6 +2122,7 @@
|
||
|
rendering/SVGRenderSupport.h \
|
||
|
rendering/SVGRenderTreeAsText.h \
|
||
|
rendering/SVGRootInlineBox.h \
|
||
|
+ rendering/SVGShadowTreeElements.h \
|
||
|
rendering/TextControlInnerElements.h \
|
||
|
rendering/TransformState.h \
|
||
|
svg/animation/SMILTimeContainer.h \
|
||
|
@@ -3093,6 +3095,7 @@
|
||
|
rendering/RenderSVGInlineText.cpp \
|
||
|
rendering/RenderSVGModelObject.cpp \
|
||
|
rendering/RenderSVGRoot.cpp \
|
||
|
+ rendering/RenderSVGShadowTreeRootContainer.cpp \
|
||
|
rendering/RenderSVGText.cpp \
|
||
|
rendering/RenderSVGTextPath.cpp \
|
||
|
rendering/RenderSVGTransformableContainer.cpp \
|
||
|
@@ -3102,7 +3105,8 @@
|
||
|
rendering/SVGInlineFlowBox.cpp \
|
||
|
rendering/SVGInlineTextBox.cpp \
|
||
|
rendering/SVGRenderSupport.cpp \
|
||
|
- rendering/SVGRootInlineBox.cpp
|
||
|
+ rendering/SVGRootInlineBox.cpp \
|
||
|
+ rendering/SVGShadowTreeElements.cpp
|
||
|
|
||
|
|
||
|
# GENERATOR 5-C:
|