1/* 2 * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> 3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 */ 20 21#include "config.h" 22#include "SVGURIReference.h" 23 24#include "Attribute.h" 25#include "Document.h" 26#include "Element.h" 27#include "URL.h" 28#include "XLinkNames.h" 29 30namespace WebCore { 31 32bool SVGURIReference::parseAttribute(const QualifiedName& name, const AtomicString& value) 33{ 34 if (name.matches(XLinkNames::hrefAttr)) { 35 setHrefBaseValue(value); 36 return true; 37 } 38 39 return false; 40} 41 42bool SVGURIReference::isKnownAttribute(const QualifiedName& attrName) 43{ 44 return attrName.matches(XLinkNames::hrefAttr); 45} 46 47String SVGURIReference::fragmentIdentifierFromIRIString(const String& url, Document& document) 48{ 49 size_t start = url.find('#'); 50 if (start == notFound) 51 return emptyString(); 52 53 URL base = start ? URL(document.baseURI(), url.substring(0, start)) : document.baseURI(); 54 String fragmentIdentifier = url.substring(start); 55 URL kurl(base, fragmentIdentifier); 56 if (equalIgnoringFragmentIdentifier(kurl, document.url())) 57 return fragmentIdentifier.substring(1); 58 59 // The url doesn't have any fragment identifier. 60 return emptyString(); 61} 62 63static inline URL urlFromIRIStringWithFragmentIdentifier(const String& url, Document& document, String& fragmentIdentifier) 64{ 65 size_t startOfFragmentIdentifier = url.find('#'); 66 if (startOfFragmentIdentifier == notFound) 67 return URL(); 68 69 // Exclude the '#' character when determining the fragmentIdentifier. 70 fragmentIdentifier = url.substring(startOfFragmentIdentifier + 1); 71 if (startOfFragmentIdentifier) { 72 URL base(document.baseURI(), url.substring(0, startOfFragmentIdentifier)); 73 return URL(base, url.substring(startOfFragmentIdentifier)); 74 } 75 76 return URL(document.baseURI(), url.substring(startOfFragmentIdentifier)); 77} 78 79Element* SVGURIReference::targetElementFromIRIString(const String& iri, Document& document, String* fragmentIdentifier, Document* externalDocument) 80{ 81 // If there's no fragment identifier contained within the IRI string, we can't lookup an element. 82 String id; 83 URL url = urlFromIRIStringWithFragmentIdentifier(iri, document, id); 84 if (url == URL()) 85 return 0; 86 87 if (fragmentIdentifier) 88 *fragmentIdentifier = id; 89 90 if (id.isEmpty()) 91 return 0; 92 93 if (externalDocument) { 94 // Enforce that the referenced url matches the url of the document that we've loaded for it! 95 ASSERT(equalIgnoringFragmentIdentifier(url, externalDocument->url())); 96 return externalDocument->getElementById(id); 97 } 98 99 // Exit early if the referenced url is external, and we have no externalDocument given. 100 if (isExternalURIReference(iri, document)) 101 return 0; 102 103 return document.getElementById(id); 104} 105 106void SVGURIReference::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes) 107{ 108 supportedAttributes.add(XLinkNames::hrefAttr); 109} 110 111} 112