Chromium Code Reviews| Index: third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp |
| diff --git a/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp b/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp |
| index e74548006ea6219402dacb1a555a086e67eb9440..8ced595746198909fe6f53676e91fd6f3c575bbd 100644 |
| --- a/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp |
| +++ b/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp |
| @@ -35,13 +35,84 @@ |
| #include "core/loader/FrameLoaderClient.h" |
| #include "core/loader/PingLoader.h" |
| #include "core/page/ChromeClient.h" |
| +#include "platform/RuntimeEnabledFeatures.h" |
| #include "platform/network/NetworkHints.h" |
| #include "platform/weborigin/SecurityPolicy.h" |
| +#include "public/platform/WebNavigationHintType.h" |
| namespace blink { |
| using namespace HTMLNames; |
| +class HTMLAnchorElement::NavigationHintSender : public GarbageCollected<HTMLAnchorElement::NavigationHintSender> { |
| +public: |
| + static NavigationHintSender* create(HTMLAnchorElement* anchorElement) |
| + { |
| + return new NavigationHintSender(anchorElement); |
| + } |
| + void handleEvent(Event*); |
| + |
| + DECLARE_VIRTUAL_TRACE(); |
| + |
| +private: |
| + explicit NavigationHintSender(HTMLAnchorElement*); |
| + bool shouldSendNavigationHint() const; |
| + void maybeSendNavigationHint(WebNavigationHintType); |
| + |
| + Member<HTMLAnchorElement> m_anchorElement; |
| +}; |
| + |
| +void HTMLAnchorElement::NavigationHintSender::handleEvent(Event* event) |
| +{ |
| + if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) |
| + maybeSendNavigationHint(WebNavigationHintType::LinkMouseDown); |
| + else if (event->type() == EventTypeNames::gesturetapunconfirmed) |
| + maybeSendNavigationHint(WebNavigationHintType::LinkTapUnconfirmed); |
| + else if (event->type() == EventTypeNames::gestureshowpress) |
| + maybeSendNavigationHint(WebNavigationHintType::LinkTapDown); |
| +} |
| + |
| +DEFINE_TRACE(HTMLAnchorElement::NavigationHintSender) |
| +{ |
| + visitor->trace(m_anchorElement); |
| +} |
| + |
| +HTMLAnchorElement::NavigationHintSender::NavigationHintSender(HTMLAnchorElement* anchorElement) |
| + : m_anchorElement(anchorElement) |
| +{ |
| +} |
| + |
| +bool HTMLAnchorElement::NavigationHintSender::shouldSendNavigationHint() const |
| +{ |
| + const KURL& url = m_anchorElement->href(); |
| + if (!url.protocolIsInHTTPFamily()) |
|
falken
2016/06/09 13:24:16
Why is it restricted to HTTP? Is this because the
horo
2016/06/14 11:03:14
Done.
|
| + return false; |
| + Document& document = m_anchorElement->document(); |
| + if (!document.frame()) |
| + return false; |
| + if (!document.getSecurityOrigin()->canDisplay(url)) |
| + return false; |
| + if (url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(document.url(), url)) |
|
falken
2016/06/09 13:24:16
Is this avoiding the hint if the link is to curren
horo
2016/06/14 11:03:14
When the user clicks a link which is to the curren
|
| + return false; |
| + |
| + // If the opener is to be suppressed and the target frame name is set, |
| + // WebContentsImpl::CreateNewWindow() will create a new process when the |
| + // user click the anchor element. In such case we shouldn't start the |
| + // Service Worker not to keep the current process running. |
|
falken
2016/06/09 13:24:16
Ah yes this code is pretty SW-specific but the nam
|
| + const bool openerSuppressed = m_anchorElement->hasRel(RelationNoReferrer) || m_anchorElement->hasRel(RelationNoOpener); |
| + if (openerSuppressed && !m_anchorElement->getAttribute(targetAttr).isEmpty()) |
| + return false; |
| + return true; |
| +} |
| + |
| +void HTMLAnchorElement::NavigationHintSender::maybeSendNavigationHint(WebNavigationHintType type) |
| +{ |
| + if (!shouldSendNavigationHint()) |
| + return; |
| + |
| + // TODO(horo): Send the navigation hint message to the browser process. |
| +} |
| + |
| HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document& document) |
| : HTMLElement(tagName, document) |
| , m_linkRelations(0) |
| @@ -59,6 +130,12 @@ HTMLAnchorElement::~HTMLAnchorElement() |
| { |
| } |
| +DEFINE_TRACE(HTMLAnchorElement) |
| +{ |
| + visitor->trace(m_navigationHintsender); |
| + HTMLElement::trace(visitor); |
| +} |
| + |
| bool HTMLAnchorElement::supportsFocus() const |
| { |
| if (hasEditableStyle()) |
| @@ -162,6 +239,10 @@ void HTMLAnchorElement::defaultEventHandler(Event* event) |
| return; |
| } |
| + // TODO(horo): Call NavigationHintSender::handleEvent() when |
| + // SpeculativeLaunchServiceWorker feature is enabled. |
| + // ensureNavigationHintSender()->handleEvent(event); |
| + |
| if (isLinkClick(event) && isLiveLink()) { |
| handleClick(event); |
| return; |
| @@ -396,4 +477,11 @@ Node::InsertionNotificationRequest HTMLAnchorElement::insertedInto(ContainerNode |
| return request; |
| } |
| +HTMLAnchorElement::NavigationHintSender* HTMLAnchorElement::ensureNavigationHintSender() |
| +{ |
| + if (!m_navigationHintsender) |
| + m_navigationHintsender = NavigationHintSender::create(this); |
| + return m_navigationHintsender; |
| +} |
| + |
| } // namespace blink |