| 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..34cd89af3b5b56974b505a02289d9d00486274ab 100644
|
| --- a/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
|
| +++ b/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
|
| @@ -35,13 +35,90 @@
|
| #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"
|
| +#include "wtf/CurrentTime.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();
|
| + DECLARE_VIRTUAL_TRACE_WRAPPERS();
|
| +
|
| +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);
|
| +}
|
| +
|
| +DEFINE_TRACE_WRAPPERS(HTMLAnchorElement::NavigationHintSender)
|
| +{
|
| + visitor->traceWrappers(m_anchorElement);
|
| +}
|
| +
|
| +HTMLAnchorElement::NavigationHintSender::NavigationHintSender(HTMLAnchorElement* anchorElement)
|
| + : m_anchorElement(anchorElement)
|
| +{
|
| +}
|
| +
|
| +bool HTMLAnchorElement::NavigationHintSender::shouldSendNavigationHint() const
|
| +{
|
| + const KURL& url = m_anchorElement->href();
|
| + if (!url.protocolIsInHTTPFamily())
|
| + 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))
|
| + 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.
|
| + 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;
|
| + blink::sendNavigationHint(m_anchorElement->href(), type);
|
| +}
|
| +
|
| HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document& document)
|
| : HTMLElement(tagName, document)
|
| , m_linkRelations(0)
|
| @@ -59,6 +136,18 @@ HTMLAnchorElement::~HTMLAnchorElement()
|
| {
|
| }
|
|
|
| +DEFINE_TRACE(HTMLAnchorElement)
|
| +{
|
| + visitor->trace(m_navigationHintsender);
|
| + HTMLElement::trace(visitor);
|
| +}
|
| +
|
| +DEFINE_TRACE_WRAPPERS(HTMLAnchorElement)
|
| +{
|
| + visitor->traceWrappers(m_navigationHintsender);
|
| + HTMLElement::traceWrappers(visitor);
|
| +}
|
| +
|
| bool HTMLAnchorElement::supportsFocus() const
|
| {
|
| if (hasEditableStyle())
|
| @@ -162,6 +251,9 @@ void HTMLAnchorElement::defaultEventHandler(Event* event)
|
| return;
|
| }
|
|
|
| + if (RuntimeEnabledFeatures::speculativeLaunchServiceWorkerEnabled())
|
| + navigationHintSender()->handleEvent(event);
|
| +
|
| if (isLinkClick(event) && isLiveLink()) {
|
| handleClick(event);
|
| return;
|
| @@ -396,4 +488,11 @@ Node::InsertionNotificationRequest HTMLAnchorElement::insertedInto(ContainerNode
|
| return request;
|
| }
|
|
|
| +HTMLAnchorElement::NavigationHintSender* HTMLAnchorElement::navigationHintSender()
|
| +{
|
| + if (!m_navigationHintsender)
|
| + m_navigationHintsender = NavigationHintSender::create(this);
|
| + return m_navigationHintsender;
|
| +}
|
| +
|
| } // namespace blink
|
|
|