| Index: Source/core/html/HTMLAnchorElement.cpp
|
| diff --git a/Source/core/html/HTMLAnchorElement.cpp b/Source/core/html/HTMLAnchorElement.cpp
|
| index 7c955b5f483163f1c02db18f6e40fc6e05e78ba7..c3fcb72933e5eb0d2eb6b70839c38cdd0f4ff0ad 100644
|
| --- a/Source/core/html/HTMLAnchorElement.cpp
|
| +++ b/Source/core/html/HTMLAnchorElement.cpp
|
| @@ -50,62 +50,11 @@
|
| #include "platform/weborigin/SecurityOrigin.h"
|
| #include "platform/weborigin/SecurityPolicy.h"
|
| #include "public/platform/Platform.h"
|
| -#include "public/platform/WebPrescientNetworking.h"
|
| #include "public/platform/WebURL.h"
|
| #include "wtf/text/StringBuilder.h"
|
|
|
| namespace WebCore {
|
|
|
| -namespace {
|
| -
|
| -void preconnectToURL(const KURL& url, blink::WebPreconnectMotivation motivation)
|
| -{
|
| - blink::WebPrescientNetworking* prescientNetworking = blink::Platform::current()->prescientNetworking();
|
| - if (!prescientNetworking)
|
| - return;
|
| -
|
| - prescientNetworking->preconnect(url, motivation);
|
| -}
|
| -
|
| -}
|
| -
|
| -class HTMLAnchorElement::PrefetchEventHandler FINAL : public NoBaseWillBeGarbageCollected<HTMLAnchorElement::PrefetchEventHandler> {
|
| -public:
|
| - static PassOwnPtrWillBeRawPtr<PrefetchEventHandler> create(HTMLAnchorElement* anchorElement)
|
| - {
|
| - return adoptPtrWillBeNoop(new HTMLAnchorElement::PrefetchEventHandler(anchorElement));
|
| - }
|
| -
|
| - void reset();
|
| -
|
| - void handleEvent(Event* e);
|
| - void didChangeHREF() { m_hadHREFChanged = true; }
|
| - bool hasIssuedPreconnect() const { return m_hasIssuedPreconnect; }
|
| -
|
| - void trace(Visitor* visitor) { visitor->trace(m_anchorElement); }
|
| -
|
| -private:
|
| - explicit PrefetchEventHandler(HTMLAnchorElement*);
|
| -
|
| - void handleMouseOver(Event* event);
|
| - void handleMouseOut(Event* event);
|
| - void handleLeftMouseDown(Event* event);
|
| - void handleGestureTapUnconfirmed(Event*);
|
| - void handleGestureShowPress(Event*);
|
| - void handleClick(Event* event);
|
| -
|
| - bool shouldPrefetch(const KURL&);
|
| - void prefetch(blink::WebPreconnectMotivation);
|
| -
|
| - RawPtrWillBeMember<HTMLAnchorElement> m_anchorElement;
|
| - double m_mouseOverTimestamp;
|
| - double m_mouseDownTimestamp;
|
| - double m_tapDownTimestamp;
|
| - bool m_hadHREFChanged;
|
| - bool m_hadTapUnconfirmed;
|
| - bool m_hasIssuedPreconnect;
|
| -};
|
| -
|
| using namespace HTMLNames;
|
|
|
| HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document& document)
|
| @@ -193,11 +142,8 @@ void HTMLAnchorElement::defaultEventHandler(Event* event)
|
| return;
|
| }
|
|
|
| - prefetchEventHandler()->handleEvent(event);
|
| -
|
| if (isLinkClick(event) && isLiveLink()) {
|
| handleClick(event);
|
| - prefetchEventHandler()->reset();
|
| return;
|
| }
|
| }
|
| @@ -232,9 +178,6 @@ void HTMLAnchorElement::parseAttribute(const QualifiedName& name, const AtomicSt
|
| if (protocolIs(parsedURL, "http") || protocolIs(parsedURL, "https") || parsedURL.startsWith("//"))
|
| prefetchDNS(document().completeURL(parsedURL).host());
|
| }
|
| -
|
| - if (wasLink)
|
| - prefetchEventHandler()->didChangeHREF();
|
| }
|
| invalidateCachedVisitedLinkHash();
|
| } else if (name == nameAttr || name == titleAttr) {
|
| @@ -374,8 +317,6 @@ void HTMLAnchorElement::handleClick(Event* event)
|
| sendPings(completedURL);
|
|
|
| ResourceRequest request(completedURL);
|
| - if (prefetchEventHandler()->hasIssuedPreconnect())
|
| - frame->loader().client()->dispatchWillRequestAfterPreconnect(request);
|
| if (hasAttribute(downloadAttr)) {
|
| if (!hasRel(RelationNoReferrer)) {
|
| String referrer = SecurityPolicy::generateReferrerHeader(document().referrerPolicy(), completedURL, document().outgoingReferrer());
|
| @@ -411,182 +352,9 @@ bool HTMLAnchorElement::willRespondToMouseClickEvents()
|
| return isLink() || HTMLElement::willRespondToMouseClickEvents();
|
| }
|
|
|
| -HTMLAnchorElement::PrefetchEventHandler* HTMLAnchorElement::prefetchEventHandler()
|
| -{
|
| - if (!m_prefetchEventHandler)
|
| - m_prefetchEventHandler = PrefetchEventHandler::create(this);
|
| -
|
| - return m_prefetchEventHandler.get();
|
| -}
|
| -
|
| -HTMLAnchorElement::PrefetchEventHandler::PrefetchEventHandler(HTMLAnchorElement* anchorElement)
|
| - : m_anchorElement(anchorElement)
|
| -{
|
| - ASSERT(m_anchorElement);
|
| -
|
| - reset();
|
| -}
|
| -
|
| -void HTMLAnchorElement::PrefetchEventHandler::reset()
|
| -{
|
| - m_hadHREFChanged = false;
|
| - m_mouseOverTimestamp = 0;
|
| - m_mouseDownTimestamp = 0;
|
| - m_hadTapUnconfirmed = false;
|
| - m_tapDownTimestamp = 0;
|
| - m_hasIssuedPreconnect = false;
|
| -}
|
| -
|
| -void HTMLAnchorElement::PrefetchEventHandler::handleEvent(Event* event)
|
| -{
|
| - if (!shouldPrefetch(m_anchorElement->href()))
|
| - return;
|
| -
|
| - if (event->type() == EventTypeNames::mouseover)
|
| - handleMouseOver(event);
|
| - else if (event->type() == EventTypeNames::mouseout)
|
| - handleMouseOut(event);
|
| - else if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton)
|
| - handleLeftMouseDown(event);
|
| - else if (event->type() == EventTypeNames::gestureshowpress)
|
| - handleGestureShowPress(event);
|
| - else if (event->type() == EventTypeNames::gesturetapunconfirmed)
|
| - handleGestureTapUnconfirmed(event);
|
| - else if (isLinkClick(event))
|
| - handleClick(event);
|
| -}
|
| -
|
| -void HTMLAnchorElement::PrefetchEventHandler::handleMouseOver(Event* event)
|
| -{
|
| - if (m_mouseOverTimestamp == 0.0) {
|
| - m_mouseOverTimestamp = event->timeStamp();
|
| -
|
| - blink::Platform::current()->histogramEnumeration("MouseEventPrefetch.MouseOvers", 0, 2);
|
| -
|
| - prefetch(blink::WebPreconnectMotivationLinkMouseOver);
|
| - }
|
| -}
|
| -
|
| -void HTMLAnchorElement::PrefetchEventHandler::handleMouseOut(Event* event)
|
| -{
|
| - if (m_mouseOverTimestamp > 0.0) {
|
| - double mouseOverDuration = convertDOMTimeStampToSeconds(event->timeStamp() - m_mouseOverTimestamp);
|
| - blink::Platform::current()->histogramCustomCounts("MouseEventPrefetch.MouseOverDuration_NoClick", mouseOverDuration * 1000, 0, 10000, 100);
|
| -
|
| - m_mouseOverTimestamp = 0.0;
|
| - }
|
| -}
|
| -
|
| -void HTMLAnchorElement::PrefetchEventHandler::handleLeftMouseDown(Event* event)
|
| -{
|
| - m_mouseDownTimestamp = event->timeStamp();
|
| -
|
| - blink::Platform::current()->histogramEnumeration("MouseEventPrefetch.MouseDowns", 0, 2);
|
| -
|
| - prefetch(blink::WebPreconnectMotivationLinkMouseDown);
|
| -}
|
| -
|
| -void HTMLAnchorElement::PrefetchEventHandler::handleGestureTapUnconfirmed(Event* event)
|
| -{
|
| - m_hadTapUnconfirmed = true;
|
| -
|
| - blink::Platform::current()->histogramEnumeration("MouseEventPrefetch.TapUnconfirmeds", 0, 2);
|
| -
|
| - prefetch(blink::WebPreconnectMotivationLinkTapUnconfirmed);
|
| -}
|
| -
|
| -void HTMLAnchorElement::PrefetchEventHandler::handleGestureShowPress(Event* event)
|
| -{
|
| - m_tapDownTimestamp = event->timeStamp();
|
| -
|
| - blink::Platform::current()->histogramEnumeration("MouseEventPrefetch.TapDowns", 0, 2);
|
| -
|
| - prefetch(blink::WebPreconnectMotivationLinkTapDown);
|
| -}
|
| -
|
| -void HTMLAnchorElement::PrefetchEventHandler::handleClick(Event* event)
|
| -{
|
| - bool capturedMouseOver = (m_mouseOverTimestamp > 0.0);
|
| - if (capturedMouseOver) {
|
| - double mouseOverDuration = convertDOMTimeStampToSeconds(event->timeStamp() - m_mouseOverTimestamp);
|
| -
|
| - blink::Platform::current()->histogramCustomCounts("MouseEventPrefetch.MouseOverDuration_Click", mouseOverDuration * 1000, 0, 10000, 100);
|
| - }
|
| -
|
| - bool capturedMouseDown = (m_mouseDownTimestamp > 0.0);
|
| - blink::Platform::current()->histogramEnumeration("MouseEventPrefetch.MouseDownFollowedByClick", capturedMouseDown, 2);
|
| -
|
| - if (capturedMouseDown) {
|
| - double mouseDownDuration = convertDOMTimeStampToSeconds(event->timeStamp() - m_mouseDownTimestamp);
|
| -
|
| - blink::Platform::current()->histogramCustomCounts("MouseEventPrefetch.MouseDownDuration_Click", mouseDownDuration * 1000, 0, 10000, 100);
|
| - }
|
| -
|
| - bool capturedTapDown = (m_tapDownTimestamp > 0.0);
|
| - if (capturedTapDown) {
|
| - double tapDownDuration = convertDOMTimeStampToSeconds(event->timeStamp() - m_tapDownTimestamp);
|
| -
|
| - blink::Platform::current()->histogramCustomCounts("MouseEventPrefetch.TapDownDuration_Click", tapDownDuration * 1000, 0, 10000, 100);
|
| - }
|
| -
|
| - int flags = (m_hadTapUnconfirmed ? 2 : 0) | (capturedTapDown ? 1 : 0);
|
| - blink::Platform::current()->histogramEnumeration("MouseEventPrefetch.PreTapEventsFollowedByClick", flags, 4);
|
| -}
|
| -
|
| -bool HTMLAnchorElement::PrefetchEventHandler::shouldPrefetch(const KURL& url)
|
| -{
|
| - if (m_hadHREFChanged)
|
| - return false;
|
| -
|
| - if (m_anchorElement->hasEventListeners(EventTypeNames::click))
|
| - return false;
|
| -
|
| - if (!url.protocolIsInHTTPFamily())
|
| - return false;
|
| -
|
| - Document& document = m_anchorElement->document();
|
| -
|
| - if (!document.securityOrigin()->canDisplay(url))
|
| - return false;
|
| -
|
| - if (url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(document.url(), url))
|
| - return false;
|
| -
|
| - LocalFrame* frame = document.frame();
|
| - if (!frame)
|
| - return false;
|
| -
|
| - // Links which create new window/tab are avoided because they may require user approval interaction.
|
| - if (!m_anchorElement->target().isEmpty())
|
| - return false;
|
| -
|
| - return true;
|
| -}
|
| -
|
| -void HTMLAnchorElement::PrefetchEventHandler::prefetch(blink::WebPreconnectMotivation motivation)
|
| -{
|
| - const KURL& url = m_anchorElement->href();
|
| -
|
| - if (!shouldPrefetch(url))
|
| - return;
|
| -
|
| - // The precision of current MouseOver trigger is too low to actually trigger preconnects.
|
| - if (motivation == blink::WebPreconnectMotivationLinkMouseOver)
|
| - return;
|
| -
|
| - preconnectToURL(url, motivation);
|
| - m_hasIssuedPreconnect = true;
|
| -}
|
| -
|
| bool HTMLAnchorElement::isInteractiveContent() const
|
| {
|
| return isLink();
|
| }
|
|
|
| -void HTMLAnchorElement::trace(Visitor* visitor)
|
| -{
|
| - visitor->trace(m_prefetchEventHandler);
|
| - HTMLElement::trace(visitor);
|
| -}
|
| -
|
| }
|
|
|