⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 238452 in webkit


Ignore:
Timestamp:
Nov 22, 2018, 3:47:33 PM (8 years ago)
Author:
rniwa@webkit.org
Message:

Modernize SVGURIReference::targetElementFromIRIString
https://bugs.webkit.org/show_bug.cgi?id=191898

Reviewed by Daniel Bates.

Made targetElementFromIRIString return an element and the fragment identifier,
and merged urlFromIRIStringWithFragmentIdentifier into it.

Also replaced the code computing the full URL using the base URL after removing
the fragment identifier and rejoining it later with a single call to completeURL.

No new tests since there should be no observable behavior change.

  • accessibility/AccessibilitySVGElement.cpp:

(WebCore::AccessibilitySVGElement::targetForUseElement const):

  • css/CSSCursorImageValue.cpp:

(WebCore::CSSCursorImageValue::updateCursorElement):

  • rendering/svg/RenderSVGTextPath.cpp:

(WebCore::RenderSVGTextPath::layoutPath const):

  • svg/SVGAltGlyphElement.cpp:

(WebCore::SVGAltGlyphElement::hasValidGlyphElements const):

  • svg/SVGFEImageElement.cpp:

(WebCore::SVGFEImageElement::buildPendingResource):

  • svg/SVGGlyphRefElement.cpp:

(WebCore::SVGGlyphRefElement::hasValidGlyphElement const):

  • svg/SVGLinearGradientElement.cpp:

(WebCore::SVGLinearGradientElement::collectGradientAttributes):

  • svg/SVGMPathElement.cpp:

(WebCore::SVGMPathElement::buildPendingResource):
(WebCore::SVGMPathElement::pathElement):

  • svg/SVGRadialGradientElement.cpp:

(WebCore::SVGRadialGradientElement::collectGradientAttributes):

  • svg/SVGTRefElement.cpp:

(WebCore::SVGTRefElement::detachTarget):
(WebCore::SVGTRefElement::buildPendingResource):

  • svg/SVGTextPathElement.cpp:

(WebCore::SVGTextPathElement::buildPendingResource):

  • svg/SVGURIReference.cpp:

(WebCore::SVGURIReference::targetElementFromIRIString):
(WebCore::urlFromIRIStringWithFragmentIdentifier): Deleted.

  • svg/SVGURIReference.h:
  • svg/SVGUseElement.cpp:

(WebCore::SVGUseElement::findTarget const):

  • svg/animation/SVGSMILElement.cpp:

(WebCore::SVGSMILElement::buildPendingResource):

  • svg/graphics/filters/SVGFEImage.cpp:

(WebCore::FEImage::referencedRenderer const):

Location:
trunk/Source/WebCore
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r238451 r238452  
     12018-11-21  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Modernize SVGURIReference::targetElementFromIRIString
     4        https://bugs.webkit.org/show_bug.cgi?id=191898
     5
     6        Reviewed by Daniel Bates.
     7
     8        Made targetElementFromIRIString return an element and the fragment identifier,
     9        and merged urlFromIRIStringWithFragmentIdentifier into it.
     10
     11        Also replaced the code computing the full URL using the base URL after removing
     12        the fragment identifier and rejoining it later with a single call to completeURL.
     13
     14        No new tests since there should be no observable behavior change.
     15
     16        * accessibility/AccessibilitySVGElement.cpp:
     17        (WebCore::AccessibilitySVGElement::targetForUseElement const):
     18        * css/CSSCursorImageValue.cpp:
     19        (WebCore::CSSCursorImageValue::updateCursorElement):
     20        * rendering/svg/RenderSVGTextPath.cpp:
     21        (WebCore::RenderSVGTextPath::layoutPath const):
     22        * svg/SVGAltGlyphElement.cpp:
     23        (WebCore::SVGAltGlyphElement::hasValidGlyphElements const):
     24        * svg/SVGFEImageElement.cpp:
     25        (WebCore::SVGFEImageElement::buildPendingResource):
     26        * svg/SVGGlyphRefElement.cpp:
     27        (WebCore::SVGGlyphRefElement::hasValidGlyphElement const):
     28        * svg/SVGLinearGradientElement.cpp:
     29        (WebCore::SVGLinearGradientElement::collectGradientAttributes):
     30        * svg/SVGMPathElement.cpp:
     31        (WebCore::SVGMPathElement::buildPendingResource):
     32        (WebCore::SVGMPathElement::pathElement):
     33        * svg/SVGRadialGradientElement.cpp:
     34        (WebCore::SVGRadialGradientElement::collectGradientAttributes):
     35        * svg/SVGTRefElement.cpp:
     36        (WebCore::SVGTRefElement::detachTarget):
     37        (WebCore::SVGTRefElement::buildPendingResource):
     38        * svg/SVGTextPathElement.cpp:
     39        (WebCore::SVGTextPathElement::buildPendingResource):
     40        * svg/SVGURIReference.cpp:
     41        (WebCore::SVGURIReference::targetElementFromIRIString):
     42        (WebCore::urlFromIRIStringWithFragmentIdentifier): Deleted.
     43        * svg/SVGURIReference.h:
     44        * svg/SVGUseElement.cpp:
     45        (WebCore::SVGUseElement::findTarget const):
     46        * svg/animation/SVGSMILElement.cpp:
     47        (WebCore::SVGSMILElement::buildPendingResource):
     48        * svg/graphics/filters/SVGFEImage.cpp:
     49        (WebCore::FEImage::referencedRenderer const):
     50
    1512018-11-22  Dean Jackson  <dino@apple.com>
    252
  • trunk/Source/WebCore/accessibility/AccessibilitySVGElement.cpp

    r224074 r238452  
    6666        href = getAttribute(HTMLNames::hrefAttr);
    6767
    68     Element* target = SVGURIReference::targetElementFromIRIString(href, use.document());
    69     if (target)
    70         return axObjectCache()->getOrCreate(target);
    71 
    72     return nullptr;
     68    auto target = SVGURIReference::targetElementFromIRIString(href, use.document());
     69    if (!target.element)
     70        return nullptr;
     71    return axObjectCache()->getOrCreate(target.element.get());
    7372}
    7473
  • trunk/Source/WebCore/css/CSSCursorImageValue.cpp

    r218890 r238452  
    7070        return nullptr;
    7171
    72     auto* element = SVGURIReference::targetElementFromIRIString(m_originalURL, document);
     72    auto element = SVGURIReference::targetElementFromIRIString(m_originalURL, document).element;
    7373    if (!is<SVGCursorElement>(element))
    7474        return nullptr;
  • trunk/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp

    r224537 r238452  
    4747Path RenderSVGTextPath::layoutPath() const
    4848{
    49     Element* targetElement = SVGURIReference::targetElementFromIRIString(textPathElement().href(), document());
    50     if (!targetElement || !targetElement->hasTagName(SVGNames::pathTag))
     49    auto target = SVGURIReference::targetElementFromIRIString(textPathElement().href(), document());
     50    if (!is<SVGPathElement>(target.element))
    5151        return Path();
    52    
    53     SVGPathElement& pathElement = downcast<SVGPathElement>(*targetElement);
    54    
     52
     53    SVGPathElement& pathElement = downcast<SVGPathElement>(*target.element);
     54
    5555    Path path = pathFromGraphicsElement(&pathElement);
    5656
  • trunk/Source/WebCore/svg/SVGAltGlyphElement.cpp

    r234683 r238452  
    8282bool SVGAltGlyphElement::hasValidGlyphElements(Vector<String>& glyphNames) const
    8383{
    84     String target;
    85     auto element = makeRefPtr(targetElementFromIRIString(getAttribute(SVGNames::hrefAttr, XLinkNames::hrefAttr), document(), &target));
     84    auto target = targetElementFromIRIString(getAttribute(SVGNames::hrefAttr, XLinkNames::hrefAttr), document());
    8685
    87     if (is<SVGGlyphElement>(element)) {
    88         glyphNames.append(target);
     86    if (is<SVGGlyphElement>(target.element)) {
     87        glyphNames.append(target.identifier);
    8988        return true;
    9089    }
     90   
     91    if (!is<SVGAltGlyphDefElement>(target.element))
     92        return false;
    9193
    92     if (is<SVGAltGlyphDefElement>(element) && downcast<SVGAltGlyphDefElement>(*element).hasValidGlyphElements(glyphNames))
    93         return true;
    94 
    95     return false;
     94    return downcast<SVGAltGlyphDefElement>(*target.element).hasValidGlyphElements(glyphNames);
    9695}
    9796
  • trunk/Source/WebCore/svg/SVGFEImageElement.cpp

    r234683 r238452  
    9595        return;
    9696
    97     String id;
    98     auto target = makeRefPtr(SVGURIReference::targetElementFromIRIString(href(), document(), &id));
    99     if (!target) {
    100         if (id.isEmpty())
     97    auto target = SVGURIReference::targetElementFromIRIString(href(), document());
     98    if (!target.element) {
     99        if (target.identifier.isEmpty())
    101100            requestImageResource();
    102101        else {
    103             document().accessSVGExtensions().addPendingResource(id, this);
     102            document().accessSVGExtensions().addPendingResource(target.identifier, this);
    104103            ASSERT(hasPendingResources());
    105104        }
    106     } else if (target->isSVGElement()) {
     105    } else if (target.element->isSVGElement()) {
    107106        // Register us with the target in the dependencies map. Any change of hrefElement
    108107        // that leads to relayout/repainting now informs us, so we can react to it.
    109         document().accessSVGExtensions().addElementReferencingTarget(this, downcast<SVGElement>(target.get()));
     108        document().accessSVGExtensions().addElementReferencingTarget(this, downcast<SVGElement>(target.element.get()));
    110109    }
    111110
  • trunk/Source/WebCore/svg/SVGGlyphRefElement.cpp

    r234683 r238452  
    5151    // FIXME: We only support xlink:href so far.
    5252    // https://bugs.webkit.org/show_bug.cgi?id=64787
    53     return is<SVGGlyphElement>(targetElementFromIRIString(getAttribute(SVGNames::hrefAttr, XLinkNames::hrefAttr), document(), &glyphName));
     53    auto target = targetElementFromIRIString(getAttribute(SVGNames::hrefAttr, XLinkNames::hrefAttr), document());
     54    glyphName = target.identifier;
     55    return is<SVGGlyphElement>(target.element);
    5456}
    5557
  • trunk/Source/WebCore/svg/SVGLinearGradientElement.cpp

    r234620 r238452  
    142142        return false;
    143143
    144     HashSet<SVGGradientElement*> processedGradients;
    145     SVGGradientElement* current = this;
     144    HashSet<Ref<SVGGradientElement>> processedGradients;
     145    Ref<SVGGradientElement> current { *this };
    146146
    147     setGradientAttributes(*current, attributes);
    148     processedGradients.add(current);
     147    setGradientAttributes(current.get(), attributes);
     148    processedGradients.add(current.copyRef());
    149149
    150150    while (true) {
    151151        // Respect xlink:href, take attributes from referenced element
    152         auto refNode = makeRefPtr(SVGURIReference::targetElementFromIRIString(current->href(), document()));
    153         if (is<SVGGradientElement>(refNode)) {
    154             current = downcast<SVGGradientElement>(refNode.get());
     152        auto target = SVGURIReference::targetElementFromIRIString(current->href(), document());
     153        if (is<SVGGradientElement>(target.element)) {
     154            current = downcast<SVGGradientElement>(*target.element);
    155155
    156156            // Cycle detection
     
    161161                return false;
    162162
    163             setGradientAttributes(*current, attributes, current->hasTagName(SVGNames::linearGradientTag));
    164             processedGradients.add(current);
     163            setGradientAttributes(current.get(), attributes, current->hasTagName(SVGNames::linearGradientTag));
     164            processedGradients.add(current.copyRef());
    165165        } else
    166166            return true;
  • trunk/Source/WebCore/svg/SVGMPathElement.cpp

    r234683 r238452  
    5656        return;
    5757
    58     String id;
    59     auto target = makeRefPtr(SVGURIReference::targetElementFromIRIString(href(), document(), &id));
    60     if (!target) {
     58    auto target = SVGURIReference::targetElementFromIRIString(href(), document());
     59    if (!target.element) {
    6160        // Do not register as pending if we are already pending this resource.
    62         if (document().accessSVGExtensions().isPendingResource(this, id))
     61        if (document().accessSVGExtensions().isPendingResource(this, target.identifier))
    6362            return;
    6463
    65         if (!id.isEmpty()) {
    66             document().accessSVGExtensions().addPendingResource(id, this);
     64        if (!target.identifier.isEmpty()) {
     65            document().accessSVGExtensions().addPendingResource(target.identifier, this);
    6766            ASSERT(hasPendingResources());
    6867        }
    69     } else if (target->isSVGElement()) {
     68    } else if (target.element->isSVGElement()) {
    7069        // Register us with the target in the dependencies map. Any change of hrefElement
    7170        // that leads to relayout/repainting now informs us, so we can react to it.
    72         document().accessSVGExtensions().addElementReferencingTarget(this, downcast<SVGElement>(target.get()));
     71        document().accessSVGExtensions().addElementReferencingTarget(this, downcast<SVGElement>(target.element.get()));
    7372    }
    7473
     
    123122RefPtr<SVGPathElement> SVGMPathElement::pathElement()
    124123{
    125     Element* target = targetElementFromIRIString(href(), document());
    126     if (is<SVGPathElement>(target))
    127         return downcast<SVGPathElement>(target);
     124    auto target = targetElementFromIRIString(href(), document());
     125    if (is<SVGPathElement>(target.element))
     126        return downcast<SVGPathElement>(target.element.get());
    128127    return nullptr;
    129128}
  • trunk/Source/WebCore/svg/SVGRadialGradientElement.cpp

    r234620 r238452  
    162162    while (true) {
    163163        // Respect xlink:href, take attributes from referenced element
    164         auto refNode = makeRefPtr(SVGURIReference::targetElementFromIRIString(current->href(), document()));
    165         if (is<SVGGradientElement>(refNode)) {
    166             current = downcast<SVGGradientElement>(refNode.get());
     164        auto target = SVGURIReference::targetElementFromIRIString(current->href(), document());
     165        if (is<SVGGradientElement>(target.element)) {
     166            current = downcast<SVGGradientElement>(target.element.get());
    167167
    168168            // Cycle detection
  • trunk/Source/WebCore/svg/SVGTRefElement.cpp

    r234683 r238452  
    168168
    169169    // Mark the referenced ID as pending.
    170     String id;
    171     SVGURIReference::targetElementFromIRIString(href(), document(), &id);
    172     if (!id.isEmpty())
    173         document().accessSVGExtensions().addPendingResource(id, this);
     170    auto target = SVGURIReference::targetElementFromIRIString(href(), document());
     171    if (!target.identifier.isEmpty())
     172        document().accessSVGExtensions().addPendingResource(target.identifier, this);
    174173}
    175174
     
    232231        return;
    233232
    234     String id;
    235     RefPtr<Element> target = SVGURIReference::targetElementFromIRIString(href(), document(), &id);
    236     if (!target.get()) {
    237         if (id.isEmpty())
     233    auto target = SVGURIReference::targetElementFromIRIString(href(), document());
     234    if (!target.element) {
     235        if (target.identifier.isEmpty())
    238236            return;
    239237
    240         document().accessSVGExtensions().addPendingResource(id, this);
     238        document().accessSVGExtensions().addPendingResource(target.identifier, this);
    241239        ASSERT(hasPendingResources());
    242240        return;
     
    248246    // case when we land here from SVGUseElement::buildShadowTree().
    249247    if (!isInShadowTree())
    250         m_targetListener->attach(target.copyRef());
    251 
    252     updateReferencedText(target.get());
     248        m_targetListener->attach(target.element.copyRef());
     249
     250    updateReferencedText(target.element.get());
    253251}
    254252
  • trunk/Source/WebCore/svg/SVGTextPathElement.cpp

    r234683 r238452  
    142142        return;
    143143
    144     String id;
    145     auto target = makeRefPtr(SVGURIReference::targetElementFromIRIString(href(), document(), &id));
    146     if (!target) {
     144    auto target = SVGURIReference::targetElementFromIRIString(href(), document());
     145    if (!target.element) {
    147146        // Do not register as pending if we are already pending this resource.
    148         if (document().accessSVGExtensions().isPendingResource(this, id))
     147        if (document().accessSVGExtensions().isPendingResource(this, target.identifier))
    149148            return;
    150149
    151         if (!id.isEmpty()) {
    152             document().accessSVGExtensions().addPendingResource(id, this);
     150        if (!target.identifier.isEmpty()) {
     151            document().accessSVGExtensions().addPendingResource(target.identifier, this);
    153152            ASSERT(hasPendingResources());
    154153        }
    155     } else if (target->hasTagName(SVGNames::pathTag)) {
     154    } else if (target.element->hasTagName(SVGNames::pathTag)) {
    156155        // Register us with the target in the dependencies map. Any change of hrefElement
    157156        // that leads to relayout/repainting now informs us, so we can react to it.
    158         document().accessSVGExtensions().addElementReferencingTarget(this, downcast<SVGElement>(target.get()));
     157        document().accessSVGExtensions().addElementReferencingTarget(this, downcast<SVGElement>(target.element.get()));
    159158    }
    160159}
  • trunk/Source/WebCore/svg/SVGURIReference.cpp

    r234683 r238452  
    8888}
    8989
    90 static inline URL urlFromIRIStringWithFragmentIdentifier(const String& url, const Document& document, String& fragmentIdentifier)
     90auto SVGURIReference::targetElementFromIRIString(const String& iri, const Document& document, RefPtr<Document> externalDocument) -> TargetElementResult
    9191{
    92     size_t startOfFragmentIdentifier = url.find('#');
     92    // If there's no fragment identifier contained within the IRI string, we can't lookup an element.
     93    size_t startOfFragmentIdentifier = iri.find('#');
    9394    if (startOfFragmentIdentifier == notFound)
    94         return URL();
     95        return { };
    9596
    9697    // Exclude the '#' character when determining the fragmentIdentifier.
    97     fragmentIdentifier = url.substring(startOfFragmentIdentifier + 1);
    98     if (startOfFragmentIdentifier) {
    99         URL base(document.baseURL(), url.substring(0, startOfFragmentIdentifier));
    100         return URL(base, url.substring(startOfFragmentIdentifier));
    101     }
     98    auto id = iri.substring(startOfFragmentIdentifier + 1);
     99    if (id.isEmpty())
     100        return { };
    102101
    103     return URL(document.baseURL(), url.substring(startOfFragmentIdentifier));
    104 }
    105 
    106 Element* SVGURIReference::targetElementFromIRIString(const String& iri, const Document& document, String* fragmentIdentifier, const Document* externalDocument)
    107 {
    108     // If there's no fragment identifier contained within the IRI string, we can't lookup an element.
    109     String id;
    110     URL url = urlFromIRIStringWithFragmentIdentifier(iri, document, id);
    111     if (url == URL())
    112         return 0;
    113 
    114     if (fragmentIdentifier)
    115         *fragmentIdentifier = id;
    116 
    117     if (id.isEmpty())
    118         return 0;
    119 
     102    auto url = document.completeURL(iri);
    120103    if (externalDocument) {
    121104        // Enforce that the referenced url matches the url of the document that we've loaded for it!
    122105        ASSERT(equalIgnoringFragmentIdentifier(url, externalDocument->url()));
    123         return externalDocument->getElementById(id);
     106        return { externalDocument->getElementById(id), WTFMove(id) };
    124107    }
    125108
    126109    // Exit early if the referenced url is external, and we have no externalDocument given.
    127110    if (isExternalURIReference(iri, document))
    128         return 0;
     111        return { nullptr, WTFMove(id) };
    129112
    130     return document.getElementById(id);
     113    return { document.getElementById(id), WTFMove(id) };
    131114}
    132115
  • trunk/Source/WebCore/svg/SVGURIReference.h

    r234620 r238452  
    4242
    4343    static String fragmentIdentifierFromIRIString(const String&, const Document&);
    44     static Element* targetElementFromIRIString(const String&, const Document&, String* fragmentIdentifier = nullptr, const Document* externalDocument = nullptr);
     44
     45    struct TargetElementResult {
     46        RefPtr<Element> element;
     47        String identifier;
     48    };
     49    static TargetElementResult targetElementFromIRIString(const String&, const Document&, RefPtr<Document> externalDocument = nullptr);
    4550
    4651    static bool isExternalURIReference(const String& uri, const Document& document)
  • trunk/Source/WebCore/svg/SVGUseElement.cpp

    r234995 r238452  
    411411    auto& original = correspondingElement ? downcast<SVGUseElement>(*correspondingElement) : *this;
    412412
    413     auto targetCandidate = makeRefPtr(targetElementFromIRIString(original.href(), original.document(), targetID, original.externalDocument()));
    414     if (targetID && !targetID->isNull()) {
     413    auto targetResult = targetElementFromIRIString(original.href(), original.document(), original.externalDocument());
     414    if (targetID) {
     415        *targetID = WTFMove(targetResult.identifier);
    415416        // If the reference is external, don't return the target ID to the caller.
    416417        // The caller would use the target ID to wait for a pending resource on the wrong document.
    417418        // If we ever want the change that and let the caller to wait on the external document,
    418419        // we should change this function so it returns the appropriate document to go with the ID.
    419         if (isExternalURIReference(original.href(), original.document()))
    420             *targetID = String();
    421     }
    422     if (!is<SVGElement>(targetCandidate))
     420        if (!targetID->isNull() && isExternalURIReference(original.href(), original.document()))
     421            *targetID = String { };
     422    }
     423    if (!is<SVGElement>(targetResult.element))
    423424        return nullptr;
    424     auto& target = downcast<SVGElement>(*targetCandidate);
     425    auto& target = downcast<SVGElement>(*targetResult.element);
    425426
    426427    if (!target.isConnected() || isDisallowedElement(target))
  • trunk/Source/WebCore/svg/animation/SVGSMILElement.cpp

    r234995 r238452  
    184184    if (href.isEmpty())
    185185        target = parentElement();
    186     else
    187         target = SVGURIReference::targetElementFromIRIString(href.string(), document(), &id);
     186    else {
     187        auto result = SVGURIReference::targetElementFromIRIString(href.string(), document());
     188        target = WTFMove(result.element);
     189        id = WTFMove(result.identifier);
     190    }
    188191    SVGElement* svgTarget = is<SVGElement>(target) ? downcast<SVGElement>(target.get()) : nullptr;
    189192
  • trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp

    r225366 r238452  
    8282{
    8383    if (!m_document)
    84         return 0;
    85     Element* hrefElement = SVGURIReference::targetElementFromIRIString(m_href, *m_document);
    86     if (!hrefElement || !hrefElement->isSVGElement())
    87         return 0;
    88     return hrefElement->renderer();
     84        return nullptr;
     85    auto target = SVGURIReference::targetElementFromIRIString(m_href, *m_document);
     86    if (!is<SVGElement>(target.element))
     87        return nullptr;
     88    return target.element->renderer();
    8989}
    9090
Note: See TracChangeset for help on using the changeset viewer.