| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde
.org> | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde
.org> |
| 3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> |
| 4 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. | 4 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. |
| 5 * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved. | 5 * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved. |
| 6 * Copyright (C) 2012 University of Szeged | 6 * Copyright (C) 2012 University of Szeged |
| 7 * Copyright (C) 2012 Renata Hodovan <reni@webkit.org> | 7 * Copyright (C) 2012 Renata Hodovan <reni@webkit.org> |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 return sharedLoadEventSender; | 52 return sharedLoadEventSender; |
| 53 } | 53 } |
| 54 | 54 |
| 55 inline SVGUseElement::SVGUseElement(Document& document) | 55 inline SVGUseElement::SVGUseElement(Document& document) |
| 56 : SVGGraphicsElement(SVGNames::useTag, document) | 56 : SVGGraphicsElement(SVGNames::useTag, document) |
| 57 , SVGURIReference(this) | 57 , SVGURIReference(this) |
| 58 , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(SVG
LengthMode::Width))) | 58 , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(SVG
LengthMode::Width))) |
| 59 , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(SVG
LengthMode::Height))) | 59 , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(SVG
LengthMode::Height))) |
| 60 , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::cr
eate(SVGLengthMode::Width))) | 60 , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::cr
eate(SVGLengthMode::Width))) |
| 61 , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::
create(SVGLengthMode::Height))) | 61 , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::
create(SVGLengthMode::Height))) |
| 62 , m_elementIdentifierIsLocal(true) |
| 62 , m_haveFiredLoadEvent(false) | 63 , m_haveFiredLoadEvent(false) |
| 63 , m_needsShadowTreeRecreation(false) | 64 , m_needsShadowTreeRecreation(false) |
| 64 { | 65 { |
| 65 ASSERT(hasCustomStyleCallbacks()); | 66 ASSERT(hasCustomStyleCallbacks()); |
| 66 ThreadState::current()->registerPreFinalizer(this); | 67 ThreadState::current()->registerPreFinalizer(this); |
| 67 | 68 |
| 68 addToPropertyMap(m_x); | 69 addToPropertyMap(m_x); |
| 69 addToPropertyMap(m_y); | 70 addToPropertyMap(m_y); |
| 70 addToPropertyMap(m_width); | 71 addToPropertyMap(m_width); |
| 71 addToPropertyMap(m_height); | 72 addToPropertyMap(m_height); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 | 125 |
| 125 void SVGUseElement::removedFrom(ContainerNode* rootParent) | 126 void SVGUseElement::removedFrom(ContainerNode* rootParent) |
| 126 { | 127 { |
| 127 SVGGraphicsElement::removedFrom(rootParent); | 128 SVGGraphicsElement::removedFrom(rootParent); |
| 128 if (rootParent->isConnected()) { | 129 if (rootParent->isConnected()) { |
| 129 clearShadowTree(); | 130 clearShadowTree(); |
| 130 cancelShadowTreeRecreation(); | 131 cancelShadowTreeRecreation(); |
| 131 } | 132 } |
| 132 } | 133 } |
| 133 | 134 |
| 134 Document* SVGUseElement::externalDocument() const | |
| 135 { | |
| 136 // Gracefully handle error condition. | |
| 137 if (!resourceIsValid()) | |
| 138 return nullptr; | |
| 139 ASSERT(m_resource->document()); | |
| 140 return m_resource->document(); | |
| 141 } | |
| 142 | |
| 143 static void transferUseWidthAndHeightIfNeeded(const SVGUseElement& use, SVGEleme
nt& shadowElement, const SVGElement& originalElement) | 135 static void transferUseWidthAndHeightIfNeeded(const SVGUseElement& use, SVGEleme
nt& shadowElement, const SVGElement& originalElement) |
| 144 { | 136 { |
| 145 DEFINE_STATIC_LOCAL(const AtomicString, hundredPercentString, ("100%")); | 137 DEFINE_STATIC_LOCAL(const AtomicString, hundredPercentString, ("100%")); |
| 146 // Use |originalElement| for checking the element type, because we will | 138 // Use |originalElement| for checking the element type, because we will |
| 147 // have replaced a <symbol> with an <svg> in the instance tree. | 139 // have replaced a <symbol> with an <svg> in the instance tree. |
| 148 if (isSVGSymbolElement(originalElement)) { | 140 if (isSVGSymbolElement(originalElement)) { |
| 149 // Spec (<use> on <symbol>): This generated 'svg' will always have | 141 // Spec (<use> on <symbol>): This generated 'svg' will always have |
| 150 // explicit values for attributes width and height. If attributes | 142 // explicit values for attributes width and height. If attributes |
| 151 // width and/or height are provided on the 'use' element, then these | 143 // width and/or height are provided on the 'use' element, then these |
| 152 // attributes will be transferred to the generated 'svg'. If attributes | 144 // attributes will be transferred to the generated 'svg'. If attributes |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 { | 177 { |
| 186 SVGAnimatedPropertyBase* property = propertyFromAttribute(name); | 178 SVGAnimatedPropertyBase* property = propertyFromAttribute(name); |
| 187 if (property == m_x) | 179 if (property == m_x) |
| 188 addPropertyToPresentationAttributeStyle(style, CSSPropertyX, m_x->curren
tValue()->asCSSPrimitiveValue()); | 180 addPropertyToPresentationAttributeStyle(style, CSSPropertyX, m_x->curren
tValue()->asCSSPrimitiveValue()); |
| 189 else if (property == m_y) | 181 else if (property == m_y) |
| 190 addPropertyToPresentationAttributeStyle(style, CSSPropertyY, m_y->curren
tValue()->asCSSPrimitiveValue()); | 182 addPropertyToPresentationAttributeStyle(style, CSSPropertyY, m_y->curren
tValue()->asCSSPrimitiveValue()); |
| 191 else | 183 else |
| 192 SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, st
yle); | 184 SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, st
yle); |
| 193 } | 185 } |
| 194 | 186 |
| 187 void SVGUseElement::updateTargetReference() |
| 188 { |
| 189 KURL resolvedUrl = document().completeURL(hrefString()); |
| 190 m_elementIdentifier = AtomicString(resolvedUrl.fragmentIdentifier()); |
| 191 m_elementIdentifierIsLocal = resolvedUrl.isNull() |
| 192 || equalIgnoringFragmentIdentifier(resolvedUrl, document().url()); |
| 193 if (m_elementIdentifierIsLocal) { |
| 194 setDocumentResource(nullptr); |
| 195 return; |
| 196 } |
| 197 if (m_elementIdentifier.isEmpty() |
| 198 || (m_resource && equalIgnoringFragmentIdentifier(resolvedUrl, m_resourc
e->url()))) |
| 199 return; |
| 200 FetchRequest request(ResourceRequest(resolvedUrl), localName()); |
| 201 setDocumentResource(DocumentResource::fetchSVGDocument(request, document().f
etcher())); |
| 202 } |
| 203 |
| 195 void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) | 204 void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) |
| 196 { | 205 { |
| 197 if (attrName == SVGNames::xAttr | 206 if (attrName == SVGNames::xAttr |
| 198 || attrName == SVGNames::yAttr | 207 || attrName == SVGNames::yAttr |
| 199 || attrName == SVGNames::widthAttr | 208 || attrName == SVGNames::widthAttr |
| 200 || attrName == SVGNames::heightAttr) { | 209 || attrName == SVGNames::heightAttr) { |
| 201 SVGElement::InvalidationGuard invalidationGuard(this); | 210 SVGElement::InvalidationGuard invalidationGuard(this); |
| 202 | 211 |
| 203 if (attrName == SVGNames::xAttr | 212 if (attrName == SVGNames::xAttr |
| 204 || attrName == SVGNames::yAttr) { | 213 || attrName == SVGNames::yAttr) { |
| 205 invalidateSVGPresentationAttributeStyle(); | 214 invalidateSVGPresentationAttributeStyle(); |
| 206 setNeedsStyleRecalc(LocalStyleChange, | 215 setNeedsStyleRecalc(LocalStyleChange, |
| 207 StyleChangeReasonForTracing::fromAttribute(attrName)); | 216 StyleChangeReasonForTracing::fromAttribute(attrName)); |
| 208 } | 217 } |
| 209 | 218 |
| 210 updateRelativeLengthsInformation(); | 219 updateRelativeLengthsInformation(); |
| 211 if (m_targetElementInstance) { | 220 if (m_targetElementInstance) { |
| 212 ASSERT(m_targetElementInstance->correspondingElement()); | 221 ASSERT(m_targetElementInstance->correspondingElement()); |
| 213 transferUseWidthAndHeightIfNeeded(*this, *m_targetElementInstance, *
m_targetElementInstance->correspondingElement()); | 222 transferUseWidthAndHeightIfNeeded(*this, *m_targetElementInstance, *
m_targetElementInstance->correspondingElement()); |
| 214 } | 223 } |
| 215 | 224 |
| 216 LayoutObject* object = this->layoutObject(); | 225 LayoutObject* object = this->layoutObject(); |
| 217 if (object) | 226 if (object) |
| 218 markForLayoutAndParentResourceInvalidation(object); | 227 markForLayoutAndParentResourceInvalidation(object); |
| 219 return; | 228 return; |
| 220 } | 229 } |
| 221 | 230 |
| 222 if (SVGURIReference::isKnownAttribute(attrName)) { | 231 if (SVGURIReference::isKnownAttribute(attrName)) { |
| 223 SVGElement::InvalidationGuard invalidationGuard(this); | 232 SVGElement::InvalidationGuard invalidationGuard(this); |
| 224 if (isStructurallyExternal()) { | 233 updateTargetReference(); |
| 225 KURL url = document().completeURL(hrefString()); | |
| 226 const KURL& existingURL = m_resource ? m_resource->url() : KURL(); | |
| 227 if (url.hasFragmentIdentifier() && !equalIgnoringFragmentIdentifier(
url, existingURL)) { | |
| 228 FetchRequest request(ResourceRequest(url), localName()); | |
| 229 setDocumentResource(DocumentResource::fetchSVGDocument(request,
document().fetcher())); | |
| 230 } | |
| 231 } else { | |
| 232 setDocumentResource(nullptr); | |
| 233 } | |
| 234 | |
| 235 invalidateShadowTree(); | 234 invalidateShadowTree(); |
| 236 | |
| 237 return; | 235 return; |
| 238 } | 236 } |
| 239 | 237 |
| 240 SVGGraphicsElement::svgAttributeChanged(attrName); | 238 SVGGraphicsElement::svgAttributeChanged(attrName); |
| 241 } | 239 } |
| 242 | 240 |
| 243 static bool isDisallowedElement(const Element& element) | 241 static bool isDisallowedElement(const Element& element) |
| 244 { | 242 { |
| 245 // Spec: "Any 'svg', 'symbol', 'g', graphics element or other 'use' is poten
tially a template object that can be re-used | 243 // Spec: "Any 'svg', 'symbol', 'g', graphics element or other 'use' is poten
tially a template object that can be re-used |
| 246 // (i.e., "instanced") in the SVG document via a 'use' element." | 244 // (i.e., "instanced") in the SVG document via a 'use' element." |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 { | 296 { |
| 299 clearInstanceRoot(); | 297 clearInstanceRoot(); |
| 300 | 298 |
| 301 // FIXME: We should try to optimize this, to at least allow partial reclones
. | 299 // FIXME: We should try to optimize this, to at least allow partial reclones
. |
| 302 if (ShadowRoot* shadowTreeRootElement = userAgentShadowRoot()) | 300 if (ShadowRoot* shadowTreeRootElement = userAgentShadowRoot()) |
| 303 shadowTreeRootElement->removeChildren(OmitSubtreeModifiedEvent); | 301 shadowTreeRootElement->removeChildren(OmitSubtreeModifiedEvent); |
| 304 | 302 |
| 305 removeAllOutgoingReferences(); | 303 removeAllOutgoingReferences(); |
| 306 } | 304 } |
| 307 | 305 |
| 306 Element* SVGUseElement::resolveTargetElement() |
| 307 { |
| 308 if (m_elementIdentifier.isEmpty()) |
| 309 return nullptr; |
| 310 const TreeScope* lookupScope = nullptr; |
| 311 if (m_elementIdentifierIsLocal) |
| 312 lookupScope = &treeScope(); |
| 313 else if (resourceIsValid()) |
| 314 lookupScope = m_resource->document(); |
| 315 else |
| 316 return nullptr; |
| 317 Element* target = lookupScope->getElementById(m_elementIdentifier); |
| 318 // TODO(fs): Why would the Element not be "connected" at this point? |
| 319 if (target && target->isConnected()) |
| 320 return target; |
| 321 // Don't record any pending references for external resources. |
| 322 if (!m_resource) { |
| 323 document().accessSVGExtensions().addPendingResource(m_elementIdentifier,
this); |
| 324 DCHECK(hasPendingResources()); |
| 325 } |
| 326 return nullptr; |
| 327 } |
| 328 |
| 308 void SVGUseElement::buildPendingResource() | 329 void SVGUseElement::buildPendingResource() |
| 309 { | 330 { |
| 310 if (inUseShadowTree()) | 331 if (inUseShadowTree()) |
| 311 return; | 332 return; |
| 312 clearShadowTree(); | 333 clearShadowTree(); |
| 313 cancelShadowTreeRecreation(); | 334 cancelShadowTreeRecreation(); |
| 314 if (!isConnected()) | 335 if (!isConnected()) |
| 315 return; | 336 return; |
| 316 Document* externalDocument = this->externalDocument(); | 337 Element* target = resolveTargetElement(); |
| 317 if (isStructurallyExternal() && !externalDocument) | 338 if (target && target->isSVGElement()) { |
| 318 return; | |
| 319 | |
| 320 AtomicString id; | |
| 321 Element* target = targetElementFromIRIString(hrefString(), treeScope(), &id,
externalDocument); | |
| 322 if (!target || !target->isConnected()) { | |
| 323 // If we can't find the target of an external element, just give up. | |
| 324 // We can't observe if the target somewhen enters the external document,
nor should we do it. | |
| 325 if (externalDocument) | |
| 326 return; | |
| 327 if (id.isEmpty()) | |
| 328 return; | |
| 329 | |
| 330 document().accessSVGExtensions().addPendingResource(id, this); | |
| 331 ASSERT(hasPendingResources()); | |
| 332 return; | |
| 333 } | |
| 334 | |
| 335 if (target->isSVGElement()) { | |
| 336 buildShadowAndInstanceTree(toSVGElement(*target)); | 339 buildShadowAndInstanceTree(toSVGElement(*target)); |
| 337 invalidateDependentShadowTrees(); | 340 invalidateDependentShadowTrees(); |
| 338 } | 341 } |
| 339 | 342 |
| 340 ASSERT(!m_needsShadowTreeRecreation); | 343 ASSERT(!m_needsShadowTreeRecreation); |
| 341 } | 344 } |
| 342 | 345 |
| 343 static void associateCorrespondingElements(SVGElement& targetRoot, SVGElement& i
nstanceRoot) | 346 static void associateCorrespondingElements(SVGElement& targetRoot, SVGElement& i
nstanceRoot) |
| 344 { | 347 { |
| 345 auto targetRange = Traversal<SVGElement>::inclusiveDescendantsOf(targetRoot)
; | 348 auto targetRange = Traversal<SVGElement>::inclusiveDescendantsOf(targetRoot)
; |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 | 751 |
| 749 if (m_resource) | 752 if (m_resource) |
| 750 m_resource->removeClient(this); | 753 m_resource->removeClient(this); |
| 751 | 754 |
| 752 m_resource = resource; | 755 m_resource = resource; |
| 753 if (m_resource) | 756 if (m_resource) |
| 754 m_resource->addClient(this); | 757 m_resource->addClient(this); |
| 755 } | 758 } |
| 756 | 759 |
| 757 } // namespace blink | 760 } // namespace blink |
| OLD | NEW |