Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(193)

Side by Side Diff: Source/core/html/HTMLAnchorElement.cpp

Issue 15352003: Trigger preconnect for link anchor tags on pre-click {mouse,gesture} events. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2000 Simon Hausmann <hausmann@kde.org> 4 * (C) 2000 Simon Hausmann <hausmann@kde.org>
5 * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed. 5 * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed.
6 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) 6 * (C) 2006 Graham Dennis (graham.dennis@gmail.com)
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version. 11 * version 2 of the License, or (at your option) any later version.
12 * 12 *
13 * This library is distributed in the hope that it will be useful, 13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details. 16 * Library General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU Library General Public License 18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to 19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA. 21 * Boston, MA 02110-1301, USA.
22 */ 22 */
23 23
24 #include "config.h" 24 #include "config.h"
25 #include "core/html/HTMLAnchorElement.h" 25 #include "core/html/HTMLAnchorElement.h"
26 26
27 #include <public/Platform.h>
28 #include <public/WebPrescientNetworking.h>
29 #include <public/WebURL.h>
27 #include <wtf/text/StringBuilder.h> 30 #include <wtf/text/StringBuilder.h>
28 #include "HTMLNames.h" 31 #include "HTMLNames.h"
29 #include "core/dom/Attribute.h" 32 #include "core/dom/Attribute.h"
30 #include "core/dom/EventNames.h" 33 #include "core/dom/EventNames.h"
31 #include "core/dom/KeyboardEvent.h" 34 #include "core/dom/KeyboardEvent.h"
32 #include "core/dom/MouseEvent.h" 35 #include "core/dom/MouseEvent.h"
33 #include "core/editing/FrameSelection.h" 36 #include "core/editing/FrameSelection.h"
34 #include "core/html/HTMLImageElement.h" 37 #include "core/html/HTMLImageElement.h"
35 #include "core/html/parser/HTMLParserIdioms.h" 38 #include "core/html/parser/HTMLParserIdioms.h"
36 #include "core/loader/FrameLoader.h" 39 #include "core/loader/FrameLoader.h"
37 #include "core/loader/FrameLoaderClient.h" 40 #include "core/loader/FrameLoaderClient.h"
38 #include "core/loader/FrameLoaderTypes.h" 41 #include "core/loader/FrameLoaderTypes.h"
39 #include "core/loader/PingLoader.h" 42 #include "core/loader/PingLoader.h"
40 #include "core/page/Chrome.h" 43 #include "core/page/Chrome.h"
41 #include "core/page/ChromeClient.h" 44 #include "core/page/ChromeClient.h"
42 #include "core/page/Frame.h" 45 #include "core/page/Frame.h"
43 #include "core/page/Page.h" 46 #include "core/page/Page.h"
44 #include "core/page/Settings.h" 47 #include "core/page/Settings.h"
45 #include "core/platform/HistogramSupport.h" 48 #include "core/platform/HistogramSupport.h"
46 #include "core/platform/PlatformMouseEvent.h" 49 #include "core/platform/PlatformMouseEvent.h"
47 #include "core/platform/network/DNS.h" 50 #include "core/platform/network/DNS.h"
48 #include "core/platform/network/ResourceRequest.h" 51 #include "core/platform/network/ResourceRequest.h"
49 #include "core/rendering/RenderImage.h" 52 #include "core/rendering/RenderImage.h"
50 #include "weborigin/KnownPorts.h" 53 #include "weborigin/KnownPorts.h"
51 #include "weborigin/SecurityOrigin.h" 54 #include "weborigin/SecurityOrigin.h"
52 #include "weborigin/SecurityPolicy.h" 55 #include "weborigin/SecurityPolicy.h"
53 56
54 namespace WebCore { 57 namespace WebCore {
55 58
59 namespace {
60
61 void preconnectToURL(const KURL& url, WebKit::WebPreconnectMotivation motivation )
62 {
63 WebKit::WebPrescientNetworking* prescientNetworking = WebKit::Platform::curr ent()->prescientNetworking();
64 if (!prescientNetworking)
65 return;
66
67 prescientNetworking->preconnect(url, motivation);
68 }
69
70 }
71
56 class HTMLAnchorElement::PrefetchEventHandler { 72 class HTMLAnchorElement::PrefetchEventHandler {
57 public: 73 public:
58 static PassOwnPtr<PrefetchEventHandler> create() 74 static PassOwnPtr<PrefetchEventHandler> create(HTMLAnchorElement* anchorElem ent)
59 { 75 {
60 return adoptPtr(new HTMLAnchorElement::PrefetchEventHandler()); 76 return adoptPtr(new HTMLAnchorElement::PrefetchEventHandler(anchorElemen t));
61 } 77 }
62 78
63 void handleEvent(Event* e); 79 void handleEvent(Event* e);
64 80
65 private: 81 private:
66 PrefetchEventHandler(); 82 explicit PrefetchEventHandler(HTMLAnchorElement*);
67 83
68 void reset(); 84 void reset();
69 85
70 void handleMouseOver(Event* event); 86 void handleMouseOver(Event* event);
71 void handleMouseOut(Event* event); 87 void handleMouseOut(Event* event);
72 void handleLeftMouseDown(Event* event); 88 void handleLeftMouseDown(Event* event);
73 void handleGestureTapUnconfirmed(Event*); 89 void handleGestureTapUnconfirmed(Event*);
74 void handleGestureTapDown(Event*); 90 void handleGestureTapDown(Event*);
75 void handleClick(Event* event); 91 void handleClick(Event* event);
76 92
93 bool shouldPrefetch(const KURL&);
94 void prefetch(WebKit::WebPreconnectMotivation);
95
96 HTMLAnchorElement* m_anchorElement;
77 double m_mouseOverTimestamp; 97 double m_mouseOverTimestamp;
78 double m_mouseDownTimestamp; 98 double m_mouseDownTimestamp;
79 double m_tapDownTimestamp; 99 double m_tapDownTimestamp;
80 bool m_hadTapUnconfirmed; 100 bool m_hadTapUnconfirmed;
101 bool m_hasIssuedPreconnect;
81 }; 102 };
82 103
83 using namespace HTMLNames; 104 using namespace HTMLNames;
84 105
85 HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document* doc ument) 106 HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document* doc ument)
86 : HTMLElement(tagName, document) 107 : HTMLElement(tagName, document)
87 , m_hasRootEditableElementForSelectionOnMouseDown(false) 108 , m_hasRootEditableElementForSelectionOnMouseDown(false)
88 , m_wasShiftKeyDownOnMouseDown(false) 109 , m_wasShiftKeyDownOnMouseDown(false)
89 , m_linkRelations(0) 110 , m_linkRelations(0)
90 , m_cachedVisitedLinkHash(0) 111 , m_cachedVisitedLinkHash(0)
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 return; 662 return;
642 } 663 }
643 664
644 rootEditableElementMap().set(this, element); 665 rootEditableElementMap().set(this, element);
645 m_hasRootEditableElementForSelectionOnMouseDown = true; 666 m_hasRootEditableElementForSelectionOnMouseDown = true;
646 } 667 }
647 668
648 HTMLAnchorElement::PrefetchEventHandler* HTMLAnchorElement::prefetchEventHandler () 669 HTMLAnchorElement::PrefetchEventHandler* HTMLAnchorElement::prefetchEventHandler ()
649 { 670 {
650 if (!m_prefetchEventHandler) 671 if (!m_prefetchEventHandler)
651 m_prefetchEventHandler = PrefetchEventHandler::create(); 672 m_prefetchEventHandler = PrefetchEventHandler::create(this);
652 673
653 return m_prefetchEventHandler.get(); 674 return m_prefetchEventHandler.get();
654 } 675 }
655 676
656 HTMLAnchorElement::PrefetchEventHandler::PrefetchEventHandler() 677 HTMLAnchorElement::PrefetchEventHandler::PrefetchEventHandler(HTMLAnchorElement* anchorElement)
678 : m_anchorElement(anchorElement)
657 { 679 {
680 ASSERT(m_anchorElement);
681
658 reset(); 682 reset();
659 } 683 }
660 684
661 void HTMLAnchorElement::PrefetchEventHandler::reset() 685 void HTMLAnchorElement::PrefetchEventHandler::reset()
662 { 686 {
663 m_mouseOverTimestamp = 0; 687 m_mouseOverTimestamp = 0;
664 m_mouseDownTimestamp = 0; 688 m_mouseDownTimestamp = 0;
665 m_hadTapUnconfirmed = false; 689 m_hadTapUnconfirmed = false;
666 m_tapDownTimestamp = 0; 690 m_tapDownTimestamp = 0;
691 m_hasIssuedPreconnect = false;
667 } 692 }
668 693
669 void HTMLAnchorElement::PrefetchEventHandler::handleEvent(Event* event) 694 void HTMLAnchorElement::PrefetchEventHandler::handleEvent(Event* event)
670 { 695 {
696 if (!shouldPrefetch(m_anchorElement->href()))
697 return;
698
671 if (event->type() == eventNames().mouseoverEvent) 699 if (event->type() == eventNames().mouseoverEvent)
672 handleMouseOver(event); 700 handleMouseOver(event);
673 else if (event->type() == eventNames().mouseoutEvent) 701 else if (event->type() == eventNames().mouseoutEvent)
674 handleMouseOut(event); 702 handleMouseOut(event);
675 else if (event->type() == eventNames().mousedownEvent && event->isMouseEvent () && static_cast<MouseEvent*>(event)->button() == LeftButton) 703 else if (event->type() == eventNames().mousedownEvent && event->isMouseEvent () && static_cast<MouseEvent*>(event)->button() == LeftButton)
676 handleLeftMouseDown(event); 704 handleLeftMouseDown(event);
677 else if (event->type() == eventNames().gesturetapdownEvent) 705 else if (event->type() == eventNames().gesturetapdownEvent)
678 handleGestureTapDown(event); 706 handleGestureTapDown(event);
679 else if (event->type() == eventNames().gesturetapunconfirmedEvent) 707 else if (event->type() == eventNames().gesturetapunconfirmedEvent)
680 handleGestureTapUnconfirmed(event); 708 handleGestureTapUnconfirmed(event);
681 else if (isLinkClick(event)) 709 else if (isLinkClick(event))
682 handleClick(event); 710 handleClick(event);
683 } 711 }
684 712
685 void HTMLAnchorElement::PrefetchEventHandler::handleMouseOver(Event* event) 713 void HTMLAnchorElement::PrefetchEventHandler::handleMouseOver(Event* event)
686 { 714 {
687 if (m_mouseOverTimestamp == 0.0) { 715 if (m_mouseOverTimestamp == 0.0) {
688 m_mouseOverTimestamp = event->timeStamp(); 716 m_mouseOverTimestamp = event->timeStamp();
689 717
690 HistogramSupport::histogramEnumeration("MouseEventPrefetch.MouseOvers", 0, 2); 718 HistogramSupport::histogramEnumeration("MouseEventPrefetch.MouseOvers", 0, 2);
719
720 prefetch(WebKit::WebPreconnectMotivationLinkMouseOver);
691 } 721 }
692 } 722 }
693 723
694 void HTMLAnchorElement::PrefetchEventHandler::handleMouseOut(Event* event) 724 void HTMLAnchorElement::PrefetchEventHandler::handleMouseOut(Event* event)
695 { 725 {
696 if (m_mouseOverTimestamp > 0.0) { 726 if (m_mouseOverTimestamp > 0.0) {
697 double mouseOverDuration = convertDOMTimeStampToSeconds(event->timeStamp () - m_mouseOverTimestamp); 727 double mouseOverDuration = convertDOMTimeStampToSeconds(event->timeStamp () - m_mouseOverTimestamp);
698 HistogramSupport::histogramCustomCounts("MouseEventPrefetch.MouseOverDur ation_NoClick", mouseOverDuration * 1000, 0, 10000, 100); 728 HistogramSupport::histogramCustomCounts("MouseEventPrefetch.MouseOverDur ation_NoClick", mouseOverDuration * 1000, 0, 10000, 100);
699 729
700 m_mouseOverTimestamp = 0.0; 730 m_mouseOverTimestamp = 0.0;
701 } 731 }
702 } 732 }
703 733
704 void HTMLAnchorElement::PrefetchEventHandler::handleLeftMouseDown(Event* event) 734 void HTMLAnchorElement::PrefetchEventHandler::handleLeftMouseDown(Event* event)
705 { 735 {
706 m_mouseDownTimestamp = event->timeStamp(); 736 m_mouseDownTimestamp = event->timeStamp();
707 737
708 HistogramSupport::histogramEnumeration("MouseEventPrefetch.MouseDowns", 0, 2 ); 738 HistogramSupport::histogramEnumeration("MouseEventPrefetch.MouseDowns", 0, 2 );
739
740 prefetch(WebKit::WebPreconnectMotivationLinkMouseDown);
709 } 741 }
710 742
711 void HTMLAnchorElement::PrefetchEventHandler::handleGestureTapUnconfirmed(Event* event) 743 void HTMLAnchorElement::PrefetchEventHandler::handleGestureTapUnconfirmed(Event* event)
712 { 744 {
713 m_hadTapUnconfirmed = true; 745 m_hadTapUnconfirmed = true;
714 746
715 HistogramSupport::histogramEnumeration("MouseEventPrefetch.TapUnconfirmeds", 0, 2); 747 HistogramSupport::histogramEnumeration("MouseEventPrefetch.TapUnconfirmeds", 0, 2);
748
749 prefetch(WebKit::WebPreconnectMotivationLinkTapUnconfirmed);
716 } 750 }
717 751
718 void HTMLAnchorElement::PrefetchEventHandler::handleGestureTapDown(Event* event) 752 void HTMLAnchorElement::PrefetchEventHandler::handleGestureTapDown(Event* event)
719 { 753 {
720 m_tapDownTimestamp = event->timeStamp(); 754 m_tapDownTimestamp = event->timeStamp();
721 755
722 HistogramSupport::histogramEnumeration("MouseEventPrefetch.TapDowns", 0, 2); 756 HistogramSupport::histogramEnumeration("MouseEventPrefetch.TapDowns", 0, 2);
757
758 prefetch(WebKit::WebPreconnectMotivationLinkTapDown);
723 } 759 }
724 760
725 void HTMLAnchorElement::PrefetchEventHandler::handleClick(Event* event) 761 void HTMLAnchorElement::PrefetchEventHandler::handleClick(Event* event)
726 { 762 {
727 bool capturedMouseOver = (m_mouseOverTimestamp > 0.0); 763 bool capturedMouseOver = (m_mouseOverTimestamp > 0.0);
728 if (capturedMouseOver) { 764 if (capturedMouseOver) {
729 double mouseOverDuration = convertDOMTimeStampToSeconds(event->timeStamp () - m_mouseOverTimestamp); 765 double mouseOverDuration = convertDOMTimeStampToSeconds(event->timeStamp () - m_mouseOverTimestamp);
730 766
731 HistogramSupport::histogramCustomCounts("MouseEventPrefetch.MouseOverDur ation_Click", mouseOverDuration * 1000, 0, 10000, 100); 767 HistogramSupport::histogramCustomCounts("MouseEventPrefetch.MouseOverDur ation_Click", mouseOverDuration * 1000, 0, 10000, 100);
732 } 768 }
(...skipping 13 matching lines...) Expand all
746 782
747 HistogramSupport::histogramCustomCounts("MouseEventPrefetch.TapDownDurat ion_Click", tapDownDuration * 1000, 0, 10000, 100); 783 HistogramSupport::histogramCustomCounts("MouseEventPrefetch.TapDownDurat ion_Click", tapDownDuration * 1000, 0, 10000, 100);
748 } 784 }
749 785
750 int flags = (m_hadTapUnconfirmed ? 2 : 0) | (capturedTapDown ? 1 : 0); 786 int flags = (m_hadTapUnconfirmed ? 2 : 0) | (capturedTapDown ? 1 : 0);
751 HistogramSupport::histogramEnumeration("MouseEventPrefetch.PreTapEventsFollo wedByClick", flags, 4); 787 HistogramSupport::histogramEnumeration("MouseEventPrefetch.PreTapEventsFollo wedByClick", flags, 4);
752 788
753 reset(); 789 reset();
754 } 790 }
755 791
792 bool HTMLAnchorElement::PrefetchEventHandler::shouldPrefetch(const KURL& url)
793 {
794 Document* document = m_anchorElement->document();
795 if (!document)
796 return false;
797
798 if (!document->securityOrigin()->canDisplay(url))
799 return false;
800
801 if (url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(document- >url(), url))
802 return false;
803
804 Frame* frame = document->frame();
805 if (!frame)
806 return false;
807
808 // Links which create new window/tab are avoided because they may require us er approval interaction.
809 if (!m_anchorElement->target().isEmpty())
810 return false;
811
812 return true;
756 } 813 }
814
815 void HTMLAnchorElement::PrefetchEventHandler::prefetch(WebKit::WebPreconnectMoti vation motivation)
816 {
817 const KURL& url = m_anchorElement->href();
818
819 if (!shouldPrefetch(url))
820 return;
821
822 preconnectToURL(url, motivation);
823 }
824
825 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698