Changeset 207840 in webkit


Ignore:
Timestamp:
Oct 25, 2016 1:17:36 PM (7 years ago)
Author:
aestes@apple.com
Message:

Implement rel=noopener
https://bugs.webkit.org/show_bug.cgi?id=155166
<rdar://problem/25193787>

Reviewed by Brent Fulgham.

Source/WebCore:

Added support for rel=noopener to a and area elements.

Tests: fast/dom/Window/a-rel-noopener.html

fast/dom/Window/area-rel-noopener.html

  • html/HTMLAnchorElement.cpp:

(WebCore::HTMLAnchorElement::HTMLAnchorElement): Stopped initializing m_linkRelations to 0.
(WebCore::HTMLAnchorElement::parseAttribute): Declared static AtomicStrings for "noreferrer"
and "noopener", and created a SpaceSplitString from the rel attribute value to test for these
two values.
(WebCore::HTMLAnchorElement::hasRel): Updated to use OptionSet::contains().
(WebCore::HTMLAnchorElement::relList): Added a check for "noopener".
(WebCore::HTMLAnchorElement::handleClick): Passed NewFrameOpenerPolicy::Suppress to
FrameLoader::urlSelected() if rel=noopener was specified.

  • html/HTMLAnchorElement.h: Changed the Relation enum to an enum class, removed unused enum

values, and changed m_linkRelations from a 30-bit unsigned integer to an OptionSet<Relation>
(HTMLAnchorElement is still 128 bytes on 64-bit).

  • loader/FrameLoader.cpp:

(WebCore::FrameLoader::urlSelected): Changed to only compute a NewFrameOpenerPolicy from the
referrer policy if an explicit NewFrameOpenerPolicy isn't specified. Removed the version of
urlSelected() that did not take a downloadAttribute parameter.

  • loader/FrameLoader.h: Added an Optional<NewFrameOpenerPolicy> parameter to urlSelected(),

and set a default argument for downloadAttribute instead of having a second version of
urlSelected().

LayoutTests:

  • fast/dom/DOMTokenList-supports-expected.txt:
  • fast/dom/DOMTokenList-supports.html:
  • fast/dom/Window/a-rel-noopener-expected.txt: Added.
  • fast/dom/Window/a-rel-noopener.html: Added.
  • fast/dom/Window/area-rel-noopener-expected.txt: Added.
  • fast/dom/Window/area-rel-noopener.html: Added.
  • fast/dom/Window/resources/rel-noopener.js: Added.
Location:
trunk
Files:
5 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r207839 r207840  
     12016-10-25  Andy Estes  <aestes@apple.com>
     2
     3        Implement rel=noopener
     4        https://bugs.webkit.org/show_bug.cgi?id=155166
     5        <rdar://problem/25193787>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        * fast/dom/DOMTokenList-supports-expected.txt:
     10        * fast/dom/DOMTokenList-supports.html:
     11        * fast/dom/Window/a-rel-noopener-expected.txt: Added.
     12        * fast/dom/Window/a-rel-noopener.html: Added.
     13        * fast/dom/Window/area-rel-noopener-expected.txt: Added.
     14        * fast/dom/Window/area-rel-noopener.html: Added.
     15        * fast/dom/Window/resources/rel-noopener.js: Added.
     16
    1172016-10-25  Eric Carlson  <eric.carlson@apple.com>
    218
  • trunk/LayoutTests/fast/dom/DOMTokenList-supports-expected.txt

    r206561 r207840  
    2222PASS anchor.relList.supports(anchorRelSupportedValues[i]) is true
    2323PASS anchor.relList.supports(anchorRelSupportedValues[i].toUpperCase()) is true
     24PASS anchor.relList.supports(anchorRelSupportedValues[i]) is true
     25PASS anchor.relList.supports(anchorRelSupportedValues[i].toUpperCase()) is true
    2426PASS anchor.relList.supports('unsupported') is false
    2527
    2628* HTMLAreaElement.relList
    2729PASS area.relList.__proto__ is DOMTokenList.prototype
     30PASS area.relList.supports(areaRelSupportedValues[i]) is true
     31PASS area.relList.supports(areaRelSupportedValues[i].toUpperCase()) is true
    2832PASS area.relList.supports(areaRelSupportedValues[i]) is true
    2933PASS area.relList.supports(areaRelSupportedValues[i].toUpperCase()) is true
  • trunk/LayoutTests/fast/dom/DOMTokenList-supports.html

    r206561 r207840  
    2323var anchor = document.createElement("a");
    2424shouldBe("anchor.relList.__proto__", "DOMTokenList.prototype");
    25 var anchorRelSupportedValues = ["noreferrer"];
     25var anchorRelSupportedValues = ["noreferrer", "noopener"];
    2626for (var i = 0; i < anchorRelSupportedValues.length; i++) {
    2727    shouldBeTrue("anchor.relList.supports(anchorRelSupportedValues[i])");
     
    3434var area = document.createElement("area");
    3535shouldBe("area.relList.__proto__", "DOMTokenList.prototype");
    36 var areaRelSupportedValues = ["noreferrer"];
     36var areaRelSupportedValues = ["noreferrer", "noopener"];
    3737for (var i = 0; i < areaRelSupportedValues.length; i++) {
    3838    shouldBeTrue("area.relList.supports(areaRelSupportedValues[i])");
  • trunk/Source/WebCore/ChangeLog

    r207839 r207840  
     12016-10-25  Andy Estes  <aestes@apple.com>
     2
     3        Implement rel=noopener
     4        https://bugs.webkit.org/show_bug.cgi?id=155166
     5        <rdar://problem/25193787>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Added support for rel=noopener to a and area elements.
     10
     11        Tests: fast/dom/Window/a-rel-noopener.html
     12               fast/dom/Window/area-rel-noopener.html
     13
     14        * html/HTMLAnchorElement.cpp:
     15        (WebCore::HTMLAnchorElement::HTMLAnchorElement): Stopped initializing m_linkRelations to 0.
     16        (WebCore::HTMLAnchorElement::parseAttribute): Declared static AtomicStrings for "noreferrer"
     17        and "noopener", and created a SpaceSplitString from the rel attribute value to test for these
     18        two values.
     19        (WebCore::HTMLAnchorElement::hasRel): Updated to use OptionSet::contains().
     20        (WebCore::HTMLAnchorElement::relList): Added a check for "noopener".
     21        (WebCore::HTMLAnchorElement::handleClick): Passed NewFrameOpenerPolicy::Suppress to
     22        FrameLoader::urlSelected() if rel=noopener was specified.
     23        * html/HTMLAnchorElement.h: Changed the Relation enum to an enum class, removed unused enum
     24        values, and changed m_linkRelations from a 30-bit unsigned integer to an OptionSet<Relation>
     25        (HTMLAnchorElement is still 128 bytes on 64-bit).
     26        * loader/FrameLoader.cpp:
     27        (WebCore::FrameLoader::urlSelected): Changed to only compute a NewFrameOpenerPolicy from the
     28        referrer policy if an explicit NewFrameOpenerPolicy isn't specified. Removed the version of
     29        urlSelected() that did not take a downloadAttribute parameter.
     30        * loader/FrameLoader.h: Added an Optional<NewFrameOpenerPolicy> parameter to urlSelected(),
     31        and set a default argument for downloadAttribute instead of having a second version of
     32        urlSelected().
     33
    1342016-10-25  Eric Carlson  <eric.carlson@apple.com>
    235
  • trunk/Source/WebCore/html/HTMLAnchorElement.cpp

    r207458 r207840  
    6060    , m_hasRootEditableElementForSelectionOnMouseDown(false)
    6161    , m_wasShiftKeyDownOnMouseDown(false)
    62     , m_linkRelations(0)
    6362    , m_cachedVisitedLinkHash(0)
    6463{
     
    251250    } else if (name == relAttr) {
    252251        // Update HTMLAnchorElement::relList() if more rel attributes values are supported.
    253         if (SpaceSplitString::spaceSplitStringContainsValue(value, "noreferrer", true))
    254             m_linkRelations |= RelationNoReferrer;
     252        static NeverDestroyed<AtomicString> noReferrer("noreferrer", AtomicString::ConstructFromLiteral);
     253        static NeverDestroyed<AtomicString> noOpener("noopener", AtomicString::ConstructFromLiteral);
     254        const bool shouldFoldCase = true;
     255        SpaceSplitString relValue(value, shouldFoldCase);
     256        if (relValue.contains(noReferrer))
     257            m_linkRelations |= Relation::NoReferrer;
     258        if (relValue.contains(noOpener))
     259            m_linkRelations |= Relation::NoOpener;
    255260        if (m_relList)
    256261            m_relList->associatedAttributeValueChanged(value);
     
    297302}
    298303
    299 bool HTMLAnchorElement::hasRel(uint32_t relation) const
    300 {
    301     return m_linkRelations & relation;
     304bool HTMLAnchorElement::hasRel(Relation relation) const
     305{
     306    return m_linkRelations.contains(relation);
    302307}
    303308
     
    306311    if (!m_relList)
    307312        m_relList = std::make_unique<DOMTokenList>(*this, HTMLNames::relAttr, [](StringView token) {
    308             return equalIgnoringASCIICase(token, "noreferrer");
     313            return equalIgnoringASCIICase(token, "noreferrer") || equalIgnoringASCIICase(token, "noopener");
    309314        });
    310315    return *m_relList;
     
    390395#endif
    391396
    392     frame->loader().urlSelected(completedURL, target(), &event, LockHistory::No, LockBackForwardList::No, hasRel(RelationNoReferrer) ? NeverSendReferrer : MaybeSendReferrer, document().shouldOpenExternalURLsPolicyToPropagate(), downloadAttribute);
     397    ShouldSendReferrer shouldSendReferrer = hasRel(Relation::NoReferrer) ? NeverSendReferrer : MaybeSendReferrer;
     398    auto newFrameOpenerPolicy = hasRel(Relation::NoOpener) ? makeOptional(NewFrameOpenerPolicy::Suppress) : Nullopt;
     399    frame->loader().urlSelected(completedURL, target(), &event, LockHistory::No, LockBackForwardList::No, shouldSendReferrer, document().shouldOpenExternalURLsPolicyToPropagate(), newFrameOpenerPolicy, downloadAttribute);
    393400
    394401    sendPings(completedURL);
  • trunk/Source/WebCore/html/HTMLAnchorElement.h

    r205249 r207840  
    33 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
    44 *           (C) 2000 Simon Hausmann <hausmann@kde.org>
    5  * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
     5 * Copyright (C) 2007-2016 Apple Inc. All rights reserved.
    66 *
    77 * This library is free software; you can redistribute it and/or
     
    2828#include "LinkHash.h"
    2929#include "URLUtils.h"
     30#include <wtf/OptionSet.h>
    3031
    3132namespace WebCore {
     
    3435
    3536// Link relation bitmask values.
    36 // FIXME: Uncomment as the various link relations are implemented.
    37 enum {
    38 //     RelationAlternate   = 0x00000001,
    39 //     RelationArchives    = 0x00000002,
    40 //     RelationAuthor      = 0x00000004,
    41 //     RelationBoomark     = 0x00000008,
    42 //     RelationExternal    = 0x00000010,
    43 //     RelationFirst       = 0x00000020,
    44 //     RelationHelp        = 0x00000040,
    45 //     RelationIndex       = 0x00000080,
    46 //     RelationLast        = 0x00000100,
    47 //     RelationLicense     = 0x00000200,
    48 //     RelationNext        = 0x00000400,
    49 //     RelationNoFolow    = 0x00000800,
    50     RelationNoReferrer     = 0x00001000,
    51 //     RelationPrev        = 0x00002000,
    52 //     RelationSearch      = 0x00004000,
    53 //     RelationSidebar     = 0x00008000,
    54 //     RelationTag         = 0x00010000,
    55 //     RelationUp          = 0x00020000,
     37enum class Relation {
     38    NoReferrer = 1 << 0,
     39    NoOpener = 1 << 1,
    5640};
    5741
     
    7761    bool willRespondToMouseClickEvents() final;
    7862
    79     bool hasRel(uint32_t relation) const;
     63    bool hasRel(Relation) const;
    8064   
    8165    LinkHash visitedLinkHash() const;
     
    118102    void clearRootEditableElementForSelectionOnMouseDown();
    119103
    120     bool m_hasRootEditableElementForSelectionOnMouseDown : 1;
    121     bool m_wasShiftKeyDownOnMouseDown : 1;
    122     uint32_t m_linkRelations : 30;
     104    bool m_hasRootEditableElementForSelectionOnMouseDown;
     105    bool m_wasShiftKeyDownOnMouseDown;
     106    OptionSet<Relation> m_linkRelations;
    123107    mutable LinkHash m_cachedVisitedLinkHash;
    124108
  • trunk/Source/WebCore/loader/FrameLoader.cpp

    r207086 r207840  
    346346}
    347347
    348 void FrameLoader::urlSelected(const URL& url, const String& passedTarget, Event* triggeringEvent, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, const AtomicString& downloadAttribute)
    349 {
    350     NewFrameOpenerPolicy newFrameOpenerPolicy = shouldSendReferrer == NeverSendReferrer ? NewFrameOpenerPolicy::Suppress : NewFrameOpenerPolicy::Allow;
    351 
     348void FrameLoader::urlSelected(const URL& url, const String& passedTarget, Event* triggeringEvent, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, Optional<NewFrameOpenerPolicy> openerPolicy, const AtomicString& downloadAttribute)
     349{
     350    NewFrameOpenerPolicy newFrameOpenerPolicy = openerPolicy.valueOr(shouldSendReferrer == NeverSendReferrer ? NewFrameOpenerPolicy::Suppress : NewFrameOpenerPolicy::Allow);
    352351    urlSelected(FrameLoadRequest(m_frame.document()->securityOrigin(), ResourceRequest(url), passedTarget, lockHistory, lockBackForwardList, shouldSendReferrer, AllowNavigationToInvalidURL::Yes, newFrameOpenerPolicy, DoNotReplaceDocumentIfJavaScriptURL, shouldOpenExternalURLsPolicy, downloadAttribute), triggeringEvent);
    353 }
    354 
    355 void FrameLoader::urlSelected(const URL& url, const String& passedTarget, Event* triggeringEvent, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldSendReferrer shouldSendReferrer, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
    356 {
    357     NewFrameOpenerPolicy newFrameOpenerPolicy = shouldSendReferrer == NeverSendReferrer ? NewFrameOpenerPolicy::Suppress : NewFrameOpenerPolicy::Allow;
    358 
    359     urlSelected(FrameLoadRequest(m_frame.document()->securityOrigin(), ResourceRequest(url), passedTarget, lockHistory, lockBackForwardList, shouldSendReferrer, AllowNavigationToInvalidURL::Yes, newFrameOpenerPolicy, DoNotReplaceDocumentIfJavaScriptURL, shouldOpenExternalURLsPolicy, nullAtom), triggeringEvent);
    360352}
    361353
  • trunk/Source/WebCore/loader/FrameLoader.h

    r207086 r207840  
    120120
    121121    void changeLocation(const FrameLoadRequest&);
    122     WEBCORE_EXPORT void urlSelected(const URL&, const String& target, Event*, LockHistory, LockBackForwardList, ShouldSendReferrer, ShouldOpenExternalURLsPolicy, const AtomicString& downloadAttribute);
    123     WEBCORE_EXPORT void urlSelected(const URL&, const String& target, Event*, LockHistory, LockBackForwardList, ShouldSendReferrer, ShouldOpenExternalURLsPolicy);
     122    WEBCORE_EXPORT void urlSelected(const URL&, const String& target, Event*, LockHistory, LockBackForwardList, ShouldSendReferrer, ShouldOpenExternalURLsPolicy, Optional<NewFrameOpenerPolicy> = Nullopt, const AtomicString& downloadAttribute = nullAtom);
    124123    void submitForm(PassRefPtr<FormSubmission>);
    125124
Note: See TracChangeset for help on using the changeset viewer.