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..f13834a2fa82f9b4098564fa2504f7f20d7a97df 100644 |
--- a/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp |
+++ b/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp |
@@ -35,13 +35,89 @@ |
#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(); |
+ DECLARE_VIRTUAL_TRACE_WRAPPERS(); |
kouhei (in TOK)
2016/06/09 02:31:13
I'm not sure if we need traceWrappers here. harake
haraken
2016/06/09 04:07:29
You don't need to add TRACE_WRAPPERS. It is needed
horo
2016/06/09 05:27:58
Removed.
Thank you.
|
+ |
+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 +135,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 +250,9 @@ void HTMLAnchorElement::defaultEventHandler(Event* event) |
return; |
} |
+ if (RuntimeEnabledFeatures::speculativeLaunchServiceWorkerEnabled()) |
+ navigationHintSender()->handleEvent(event); |
+ |
if (isLinkClick(event) && isLiveLink()) { |
handleClick(event); |
return; |
@@ -396,4 +487,11 @@ Node::InsertionNotificationRequest HTMLAnchorElement::insertedInto(ContainerNode |
return request; |
} |
+HTMLAnchorElement::NavigationHintSender* HTMLAnchorElement::navigationHintSender() |
kouhei (in TOK)
2016/06/09 02:31:13
ensureNavigationHintSender()
horo
2016/06/09 05:27:58
Done.
|
+{ |
+ if (!m_navigationHintsender) |
+ m_navigationHintsender = NavigationHintSender::create(this); |
+ return m_navigationHintsender; |
+} |
+ |
} // namespace blink |