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

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 =
64 WebKit::Platform::current()->prescientNetworking();
abarth-chromium 2013/05/24 05:58:12 There's no 80 col limit, so you can put this on on
kouhei (in TOK) 2013/05/24 06:17:10 Done.
65 if (!prescientNetworking)
66 return;
67
68 prescientNetworking->preconnect(WebKit::WebURL(url), motivation);
abarth-chromium 2013/05/24 05:58:12 No need to call WebKit::WebURL explicitly. The co
kouhei (in TOK) 2013/05/24 06:17:10 Done.
69 }
70
71 }
72
56 class HTMLAnchorElement::PrefetchEventHandler { 73 class HTMLAnchorElement::PrefetchEventHandler {
57 public: 74 public:
58 static PassOwnPtr<PrefetchEventHandler> create() 75 static PassOwnPtr<PrefetchEventHandler> create(HTMLAnchorElement* anchorElem ent)
59 { 76 {
60 return adoptPtr(new HTMLAnchorElement::PrefetchEventHandler()); 77 return adoptPtr(new HTMLAnchorElement::PrefetchEventHandler(anchorElemen t));
61 } 78 }
62 79
63 void handleEvent(Event* e); 80 void handleEvent(Event* e);
64 81
65 private: 82 private:
66 PrefetchEventHandler(); 83 PrefetchEventHandler(HTMLAnchorElement*);
abarth-chromium 2013/05/24 05:58:12 Please use the "explicit" keyword for one-argument
kouhei (in TOK) 2013/05/24 06:17:10 Done.
67 84
68 void reset(); 85 void reset();
69 86
70 void handleMouseOver(Event* event); 87 void handleMouseOver(Event* event);
71 void handleMouseOut(Event* event); 88 void handleMouseOut(Event* event);
72 void handleLeftMouseDown(Event* event); 89 void handleLeftMouseDown(Event* event);
73 void handleGestureTapUnconfirmed(Event*); 90 void handleGestureTapUnconfirmed(Event*);
74 void handleGestureTapDown(Event*); 91 void handleGestureTapDown(Event*);
75 void handleClick(Event* event); 92 void handleClick(Event* event);
76 93
94 bool shouldPrefetch(const KURL&);
95 void prefetch(WebKit::WebPreconnectMotivation);
96
97 HTMLAnchorElement* m_anchorElement;
77 double m_mouseOverTimestamp; 98 double m_mouseOverTimestamp;
78 double m_mouseDownTimestamp; 99 double m_mouseDownTimestamp;
79 double m_tapDownTimestamp; 100 double m_tapDownTimestamp;
80 bool m_hadTapUnconfirmed; 101 bool m_hadTapUnconfirmed;
102 bool m_hasIssuedPreconnect;
81 }; 103 };
82 104
83 using namespace HTMLNames; 105 using namespace HTMLNames;
84 106
85 HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document* doc ument) 107 HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document* doc ument)
86 : HTMLElement(tagName, document) 108 : HTMLElement(tagName, document)
87 , m_hasRootEditableElementForSelectionOnMouseDown(false) 109 , m_hasRootEditableElementForSelectionOnMouseDown(false)
88 , m_wasShiftKeyDownOnMouseDown(false) 110 , m_wasShiftKeyDownOnMouseDown(false)
89 , m_linkRelations(0) 111 , m_linkRelations(0)
90 , m_cachedVisitedLinkHash(0) 112 , m_cachedVisitedLinkHash(0)
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 return; 663 return;
642 } 664 }
643 665
644 rootEditableElementMap().set(this, element); 666 rootEditableElementMap().set(this, element);
645 m_hasRootEditableElementForSelectionOnMouseDown = true; 667 m_hasRootEditableElementForSelectionOnMouseDown = true;
646 } 668 }
647 669
648 HTMLAnchorElement::PrefetchEventHandler* HTMLAnchorElement::prefetchEventHandler () 670 HTMLAnchorElement::PrefetchEventHandler* HTMLAnchorElement::prefetchEventHandler ()
649 { 671 {
650 if (!m_prefetchEventHandler) 672 if (!m_prefetchEventHandler)
651 m_prefetchEventHandler = PrefetchEventHandler::create(); 673 m_prefetchEventHandler = PrefetchEventHandler::create(this);
652 674
653 return m_prefetchEventHandler.get(); 675 return m_prefetchEventHandler.get();
654 } 676 }
655 677
656 HTMLAnchorElement::PrefetchEventHandler::PrefetchEventHandler() 678 HTMLAnchorElement::PrefetchEventHandler::PrefetchEventHandler(
679 HTMLAnchorElement* anchorElement)
abarth-chromium 2013/05/24 05:58:12 This line should be combined with the previous one
kouhei (in TOK) 2013/05/24 06:17:10 Done.
680 : m_anchorElement(anchorElement)
657 { 681 {
682 ASSERT(m_anchorElement);
683
658 reset(); 684 reset();
659 } 685 }
660 686
661 void HTMLAnchorElement::PrefetchEventHandler::reset() 687 void HTMLAnchorElement::PrefetchEventHandler::reset()
662 { 688 {
663 m_mouseOverTimestamp = 0; 689 m_mouseOverTimestamp = 0;
664 m_mouseDownTimestamp = 0; 690 m_mouseDownTimestamp = 0;
665 m_hadTapUnconfirmed = false; 691 m_hadTapUnconfirmed = false;
666 m_tapDownTimestamp = 0; 692 m_tapDownTimestamp = 0;
693 m_hasIssuedPreconnect = false;
667 } 694 }
668 695
669 void HTMLAnchorElement::PrefetchEventHandler::handleEvent(Event* event) 696 void HTMLAnchorElement::PrefetchEventHandler::handleEvent(Event* event)
670 { 697 {
698 if (!shouldPrefetch(m_anchorElement->href()))
699 return;
700
671 if (event->type() == eventNames().mouseoverEvent) 701 if (event->type() == eventNames().mouseoverEvent)
672 handleMouseOver(event); 702 handleMouseOver(event);
673 else if (event->type() == eventNames().mouseoutEvent) 703 else if (event->type() == eventNames().mouseoutEvent)
674 handleMouseOut(event); 704 handleMouseOut(event);
675 else if (event->type() == eventNames().mousedownEvent && event->isMouseEvent () && static_cast<MouseEvent*>(event)->button() == LeftButton) 705 else if (event->type() == eventNames().mousedownEvent && event->isMouseEvent () && static_cast<MouseEvent*>(event)->button() == LeftButton)
676 handleLeftMouseDown(event); 706 handleLeftMouseDown(event);
677 else if (event->type() == eventNames().gesturetapdownEvent) 707 else if (event->type() == eventNames().gesturetapdownEvent)
678 handleGestureTapDown(event); 708 handleGestureTapDown(event);
679 else if (event->type() == eventNames().gesturetapunconfirmedEvent) 709 else if (event->type() == eventNames().gesturetapunconfirmedEvent)
680 handleGestureTapUnconfirmed(event); 710 handleGestureTapUnconfirmed(event);
681 else if (isLinkClick(event)) 711 else if (isLinkClick(event))
682 handleClick(event); 712 handleClick(event);
683 } 713 }
684 714
685 void HTMLAnchorElement::PrefetchEventHandler::handleMouseOver(Event* event) 715 void HTMLAnchorElement::PrefetchEventHandler::handleMouseOver(Event* event)
686 { 716 {
687 if (m_mouseOverTimestamp == 0.0) { 717 if (m_mouseOverTimestamp == 0.0) {
688 m_mouseOverTimestamp = event->timeStamp(); 718 m_mouseOverTimestamp = event->timeStamp();
689 719
690 HistogramSupport::histogramEnumeration("MouseEventPrefetch.MouseOvers", 0, 2); 720 HistogramSupport::histogramEnumeration("MouseEventPrefetch.MouseOvers", 0, 2);
721
722 prefetch(WebKit::WebPreconnectMotivationLinkMouseOver);
691 } 723 }
692 } 724 }
693 725
694 void HTMLAnchorElement::PrefetchEventHandler::handleMouseOut(Event* event) 726 void HTMLAnchorElement::PrefetchEventHandler::handleMouseOut(Event* event)
695 { 727 {
696 if (m_mouseOverTimestamp > 0.0) { 728 if (m_mouseOverTimestamp > 0.0) {
697 double mouseOverDuration = convertDOMTimeStampToSeconds(event->timeStamp () - m_mouseOverTimestamp); 729 double mouseOverDuration = convertDOMTimeStampToSeconds(event->timeStamp () - m_mouseOverTimestamp);
698 HistogramSupport::histogramCustomCounts("MouseEventPrefetch.MouseOverDur ation_NoClick", mouseOverDuration * 1000, 0, 10000, 100); 730 HistogramSupport::histogramCustomCounts("MouseEventPrefetch.MouseOverDur ation_NoClick", mouseOverDuration * 1000, 0, 10000, 100);
699 731
700 m_mouseOverTimestamp = 0.0; 732 m_mouseOverTimestamp = 0.0;
701 } 733 }
702 } 734 }
703 735
704 void HTMLAnchorElement::PrefetchEventHandler::handleLeftMouseDown(Event* event) 736 void HTMLAnchorElement::PrefetchEventHandler::handleLeftMouseDown(Event* event)
705 { 737 {
706 m_mouseDownTimestamp = event->timeStamp(); 738 m_mouseDownTimestamp = event->timeStamp();
707 739
708 HistogramSupport::histogramEnumeration("MouseEventPrefetch.MouseDowns", 0, 2 ); 740 HistogramSupport::histogramEnumeration("MouseEventPrefetch.MouseDowns", 0, 2 );
741
742 prefetch(WebKit::WebPreconnectMotivationLinkMouseDown);
709 } 743 }
710 744
711 void HTMLAnchorElement::PrefetchEventHandler::handleGestureTapUnconfirmed(Event* event) 745 void HTMLAnchorElement::PrefetchEventHandler::handleGestureTapUnconfirmed(Event* event)
712 { 746 {
713 m_hadTapUnconfirmed = true; 747 m_hadTapUnconfirmed = true;
714 748
715 HistogramSupport::histogramEnumeration("MouseEventPrefetch.TapUnconfirmeds", 0, 2); 749 HistogramSupport::histogramEnumeration("MouseEventPrefetch.TapUnconfirmeds", 0, 2);
750
751 prefetch(WebKit::WebPreconnectMotivationLinkTapUnconfirmed);
716 } 752 }
717 753
718 void HTMLAnchorElement::PrefetchEventHandler::handleGestureTapDown(Event* event) 754 void HTMLAnchorElement::PrefetchEventHandler::handleGestureTapDown(Event* event)
719 { 755 {
720 m_tapDownTimestamp = event->timeStamp(); 756 m_tapDownTimestamp = event->timeStamp();
721 757
722 HistogramSupport::histogramEnumeration("MouseEventPrefetch.TapDowns", 0, 2); 758 HistogramSupport::histogramEnumeration("MouseEventPrefetch.TapDowns", 0, 2);
759
760 prefetch(WebKit::WebPreconnectMotivationLinkTapDown);
723 } 761 }
724 762
725 void HTMLAnchorElement::PrefetchEventHandler::handleClick(Event* event) 763 void HTMLAnchorElement::PrefetchEventHandler::handleClick(Event* event)
726 { 764 {
727 bool capturedMouseOver = (m_mouseOverTimestamp > 0.0); 765 bool capturedMouseOver = (m_mouseOverTimestamp > 0.0);
728 if (capturedMouseOver) { 766 if (capturedMouseOver) {
729 double mouseOverDuration = convertDOMTimeStampToSeconds(event->timeStamp () - m_mouseOverTimestamp); 767 double mouseOverDuration = convertDOMTimeStampToSeconds(event->timeStamp () - m_mouseOverTimestamp);
730 768
731 HistogramSupport::histogramCustomCounts("MouseEventPrefetch.MouseOverDur ation_Click", mouseOverDuration * 1000, 0, 10000, 100); 769 HistogramSupport::histogramCustomCounts("MouseEventPrefetch.MouseOverDur ation_Click", mouseOverDuration * 1000, 0, 10000, 100);
732 } 770 }
(...skipping 13 matching lines...) Expand all
746 784
747 HistogramSupport::histogramCustomCounts("MouseEventPrefetch.TapDownDurat ion_Click", tapDownDuration * 1000, 0, 10000, 100); 785 HistogramSupport::histogramCustomCounts("MouseEventPrefetch.TapDownDurat ion_Click", tapDownDuration * 1000, 0, 10000, 100);
748 } 786 }
749 787
750 int flags = (m_hadTapUnconfirmed ? 2 : 0) | (capturedTapDown ? 1 : 0); 788 int flags = (m_hadTapUnconfirmed ? 2 : 0) | (capturedTapDown ? 1 : 0);
751 HistogramSupport::histogramEnumeration("MouseEventPrefetch.PreTapEventsFollo wedByClick", flags, 4); 789 HistogramSupport::histogramEnumeration("MouseEventPrefetch.PreTapEventsFollo wedByClick", flags, 4);
752 790
753 reset(); 791 reset();
754 } 792 }
755 793
794 bool HTMLAnchorElement::PrefetchEventHandler::shouldPrefetch(const KURL& url)
795 {
796 Document* doc = m_anchorElement->document();
abarth-chromium 2013/05/24 05:58:12 doc -> document (please use complete words in vari
kouhei (in TOK) 2013/05/24 06:17:10 Done.
797 if (!doc)
798 return false;
799
800 // is valid url?
abarth-chromium 2013/05/24 05:58:12 We prefer skipping these sorts of comments. Good
kouhei (in TOK) 2013/05/24 06:17:10 Done.
801 if (!doc->securityOrigin()->canDisplay(url))
802 return false;
803
804 // is same url w/ fragment id?
805 if (url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(doc->url( ), url))
806 return false;
807
808 Frame* frame = doc->frame();
809 if (!frame)
810 return false;
811
812 // is creating new window/tab?
813 // Note: This is avoided because creating new window/tab
814 // may require user approval interaction.
815 String targetStr = m_anchorElement->target();
abarth-chromium 2013/05/24 05:58:12 targetStr -> target (The "str" postfix isn't a com
kouhei (in TOK) 2013/05/24 06:17:10 Done.
816 if (!targetStr.isEmpty() && !frame->loader()->findFrameForNavigation(targetS tr))
817 return false;
818
819 return true;
756 } 820 }
821
822 void HTMLAnchorElement::PrefetchEventHandler::prefetch(
823 WebKit::WebPreconnectMotivation motivation)
abarth-chromium 2013/05/24 05:58:12 Please combine this line with the previous line.
kouhei (in TOK) 2013/05/24 06:17:10 Done.
824 {
825 KURL url = m_anchorElement->href();
abarth-chromium 2013/05/24 05:58:12 KURL -> const KURL&
kouhei (in TOK) 2013/05/24 06:17:10 Done.
826
827 if (!shouldPrefetch(url))
828 return;
829
830 preconnectToURL(url, motivation);
831 }
832
833 }
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