| 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 eccde4647c675b1b06ae3b1f500fc036e4c5ac65..a20266fcdd1ef15fa79106752a7fa66fdd4fd095 100644 | 
| --- a/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp | 
| +++ b/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp | 
| @@ -42,6 +42,83 @@ namespace blink { | 
|  | 
| using namespace HTMLNames; | 
|  | 
| +class HTMLAnchorElement::NavigationHintSender : public GarbageCollected<HTMLAnchorElement::NavigationHintSender> { | 
| +public: | 
| +    // TODO(horo): Move WebNavigationHintType to public/ directory. | 
| +    enum class WebNavigationHintType { | 
| +        Unknown, | 
| +        LinkMouseDown, | 
| +        LinkTapUnconfirmed, | 
| +        LinkTapDown, | 
| +        Last = LinkTapDown | 
| +    }; | 
| + | 
| +    static NavigationHintSender* create(HTMLAnchorElement* anchorElement) | 
| +    { | 
| +        return new NavigationHintSender(anchorElement); | 
| +    } | 
| +    void handleEvent(Event*); | 
| + | 
| +    DECLARE_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(); | 
| +    // Currently the navigation hint only supports HTTP and HTTPS. | 
| +    if (!url.protocolIsInHTTPFamily()) | 
| +        return false; | 
| + | 
| +    Document& document = m_anchorElement->document(); | 
| +    // If the element was detached from the frame, handleClick() doesn't cause | 
| +    // the navigation. | 
| +    if (!document.frame()) | 
| +        return false; | 
| + | 
| +    // When the user clicks a link which is to the current document with a hash, | 
| +    // the network request is not fetched. So we don't send the navigation hint | 
| +    // to the browser process. | 
| +    if (url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(document.url(), url)) | 
| +        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 +136,12 @@ HTMLAnchorElement::~HTMLAnchorElement() | 
| { | 
| } | 
|  | 
| +DEFINE_TRACE(HTMLAnchorElement) | 
| +{ | 
| +    visitor->trace(m_navigationHintSender); | 
| +    HTMLElement::trace(visitor); | 
| +} | 
| + | 
| bool HTMLAnchorElement::supportsFocus() const | 
| { | 
| if (hasEditableStyle()) | 
| @@ -162,6 +245,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 +483,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 | 
|  |