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
23#include "core/svg/SVGURIReference.h"
24
25#include "XLinkNames.h"
26#include "platform/weborigin/KURL.h"
27
28namespace WebCore {
29
30bool SVGURIReference::parseAttribute(const QualifiedName& name, const AtomicString& value)
31{
32    if (name.matches(XLinkNames::hrefAttr)) {
33        setHrefBaseValue(value);
34        return true;
35    }
36
37    return false;
38}
39
40bool SVGURIReference::isKnownAttribute(const QualifiedName& attrName)
41{
42    return attrName.matches(XLinkNames::hrefAttr);
43}
44
45String SVGURIReference::fragmentIdentifierFromIRIString(const String& url, const Document& document)
46{
47    size_t start = url.find('#');
48    if (start == kNotFound)
49        return emptyString();
50
51    KURL base = start ? KURL(document.baseURI(), url.substring(0, start)) : document.baseURI();
52    if (equalIgnoringFragmentIdentifier(base, document.url()))
53        return url.substring(start + 1);
54
55    return emptyString();
56}
57
58static inline KURL urlFromIRIStringWithFragmentIdentifier(const String& url, const Document& document, String& fragmentIdentifier)
59{
60    size_t startOfFragmentIdentifier = url.find('#');
61    if (startOfFragmentIdentifier == kNotFound)
62        return KURL();
63
64    // Exclude the '#' character when determining the fragmentIdentifier.
65    fragmentIdentifier = url.substring(startOfFragmentIdentifier + 1);
66    if (startOfFragmentIdentifier) {
67        KURL base(document.baseURI(), url.substring(0, startOfFragmentIdentifier));
68        return KURL(base, url.substring(startOfFragmentIdentifier));
69    }
70
71    return KURL(document.baseURI(), url.substring(startOfFragmentIdentifier));
72}
73
74Element* SVGURIReference::targetElementFromIRIString(const String& iri, const Document& document, String* fragmentIdentifier, Document* externalDocument)
75{
76    // If there's no fragment identifier contained within the IRI string, we can't lookup an element.
77    String id;
78    KURL url = urlFromIRIStringWithFragmentIdentifier(iri, document, id);
79    if (url == KURL())
80        return 0;
81
82    if (fragmentIdentifier)
83        *fragmentIdentifier = id;
84
85    if (id.isEmpty())
86        return 0;
87
88    if (externalDocument) {
89        // Enforce that the referenced url matches the url of the document that we've loaded for it!
90        ASSERT(equalIgnoringFragmentIdentifier(url, externalDocument->url()));
91        return externalDocument->getElementById(id);
92    }
93
94    // Exit early if the referenced url is external, and we have no externalDocument given.
95    if (isExternalURIReference(iri, document))
96        return 0;
97
98    return document.getElementById(id);
99}
100
101void SVGURIReference::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes)
102{
103    supportedAttributes.add(XLinkNames::hrefAttr);
104}
105
106}
107