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

Side by Side Diff: third_party/WebKit/Source/core/loader/LinkLoader.cpp

Issue 1577073005: Add <link rel=preload> onload support for scripts and styles (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed lifetime issue of LinkPreloadResourceClients Created 4 years, 11 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 UseCounter::count(document, UseCounter::LinkRelNext); 64 UseCounter::count(document, UseCounter::LinkRelNext);
65 } 65 }
66 66
67 return result; 67 return result;
68 } 68 }
69 69
70 LinkLoader::LinkLoader(LinkLoaderClient* client) 70 LinkLoader::LinkLoader(LinkLoaderClient* client)
71 : m_client(client) 71 : m_client(client)
72 , m_linkLoadTimer(this, &LinkLoader::linkLoadTimerFired) 72 , m_linkLoadTimer(this, &LinkLoader::linkLoadTimerFired)
73 , m_linkLoadingErrorTimer(this, &LinkLoader::linkLoadingErrorTimerFired) 73 , m_linkLoadingErrorTimer(this, &LinkLoader::linkLoadingErrorTimerFired)
74 , m_weakPtrFactory(this)
74 { 75 {
75 } 76 }
76 77
77 LinkLoader::~LinkLoader() 78 LinkLoader::~LinkLoader()
78 { 79 {
79 } 80 }
80 81
81 void LinkLoader::linkLoadTimerFired(Timer<LinkLoader>* timer) 82 void LinkLoader::linkLoadTimerFired(Timer<LinkLoader>* timer)
82 { 83 {
83 ASSERT_UNUSED(timer, timer == &m_linkLoadTimer); 84 ASSERT_UNUSED(timer, timer == &m_linkLoadTimer);
84 m_client->linkLoaded(); 85 m_client->linkLoaded();
85 } 86 }
86 87
87 void LinkLoader::linkLoadingErrorTimerFired(Timer<LinkLoader>* timer) 88 void LinkLoader::linkLoadingErrorTimerFired(Timer<LinkLoader>* timer)
88 { 89 {
89 ASSERT_UNUSED(timer, timer == &m_linkLoadingErrorTimer); 90 ASSERT_UNUSED(timer, timer == &m_linkLoadingErrorTimer);
90 m_client->linkLoadingErrored(); 91 m_client->linkLoadingErrored();
91 } 92 }
92 93
94 void LinkLoader::triggerEvents(Resource* resource)
95 {
96 if (resource->errorOccurred())
97 m_linkLoadingErrorTimer.startOneShot(0, BLINK_FROM_HERE);
98 else
99 m_linkLoadTimer.startOneShot(0, BLINK_FROM_HERE);
100 }
101
93 void LinkLoader::notifyFinished(Resource* resource) 102 void LinkLoader::notifyFinished(Resource* resource)
94 { 103 {
95 ASSERT(this->resource() == resource); 104 ASSERT(this->resource() == resource);
96 105
97 if (resource->errorOccurred()) 106 triggerEvents(resource);
98 m_linkLoadingErrorTimer.startOneShot(0, BLINK_FROM_HERE);
99 else
100 m_linkLoadTimer.startOneShot(0, BLINK_FROM_HERE);
101
102 clearResource(); 107 clearResource();
103 } 108 }
104 109
105 void LinkLoader::didStartPrerender() 110 void LinkLoader::didStartPrerender()
106 { 111 {
107 m_client->didStartLinkPrerender(); 112 m_client->didStartLinkPrerender();
108 } 113 }
109 114
110 void LinkLoader::didStopPrerender() 115 void LinkLoader::didStopPrerender()
111 { 116 {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 if (equalIgnoringCase(as, "font")) 182 if (equalIgnoringCase(as, "font"))
178 return Resource::Font; 183 return Resource::Font;
179 if (equalIgnoringCase(as, "track")) 184 if (equalIgnoringCase(as, "track"))
180 return Resource::TextTrack; 185 return Resource::TextTrack;
181 if (document && !as.isEmpty()) 186 if (document && !as.isEmpty())
182 document->addConsoleMessage(ConsoleMessage::create(OtherMessageSource, W arningMessageLevel, String("<link rel=preload> must have a valid `as` value"))); 187 document->addConsoleMessage(ConsoleMessage::create(OtherMessageSource, W arningMessageLevel, String("<link rel=preload> must have a valid `as` value")));
183 // TODO(yoav): Is this correct? If as is missing or invalid, it should be su bject to "connect-src" CSP directives. 188 // TODO(yoav): Is this correct? If as is missing or invalid, it should be su bject to "connect-src" CSP directives.
184 return Resource::LinkSubresource; 189 return Resource::LinkSubresource;
185 } 190 }
186 191
187 static void preloadIfNeeded(const LinkRelAttribute& relAttribute, const KURL& hr ef, Document& document, const String& as) 192 static void preloadIfNeeded(const LinkRelAttribute& relAttribute, const KURL& hr ef, Document& document, const String& as, LinkLoader* linkLoader)
Nate Chapin 2016/01/13 23:52:23 Should this be a private member of LinkLoader if w
Yoav Weiss 2016/01/14 10:10:02 This has to remain static since it's called from l
188 { 193 {
189 if (!document.loader()) 194 if (!document.loader() || !relAttribute.isLinkPreload())
190 return; 195 return;
191 196
192 if (relAttribute.isLinkPreload()) { 197 UseCounter::count(document, UseCounter::LinkRelPreload);
193 UseCounter::count(document, UseCounter::LinkRelPreload); 198 ASSERT(RuntimeEnabledFeatures::linkPreloadEnabled());
194 ASSERT(RuntimeEnabledFeatures::linkPreloadEnabled()); 199 if (!href.isValid() || href.isEmpty()) {
195 if (!href.isValid() || href.isEmpty()) { 200 document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, Wa rningMessageLevel, String("<link rel=preload> has an invalid `href` value")));
196 document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource , WarningMessageLevel, String("<link rel=preload> has an invalid `href` value")) ); 201 return;
197 return; 202 }
198 } 203 Resource::Type type = LinkLoader::getTypeFromAsAttribute(as, &document);
199 Resource::Type type = LinkLoader::getTypeFromAsAttribute(as, &document); 204 ResourceRequest resourceRequest(document.completeURL(href));
200 ResourceRequest resourceRequest(document.completeURL(href)); 205 ResourceFetcher::determineRequestContext(resourceRequest, type, false);
201 ResourceFetcher::determineRequestContext(resourceRequest, type, false); 206 FetchRequest linkRequest(resourceRequest, FetchInitiatorTypeNames::link);
202 FetchRequest linkRequest(resourceRequest, FetchInitiatorTypeNames::link) ;
203 207
204 linkRequest.setPriority(document.fetcher()->loadPriority(type, linkReque st)); 208 linkRequest.setPriority(document.fetcher()->loadPriority(type, linkRequest)) ;
205 Settings* settings = document.settings(); 209 Settings* settings = document.settings();
206 if (settings && settings->logPreload()) 210 if (settings && settings->logPreload())
207 document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource , DebugMessageLevel, String("Preload triggered for " + href.host() + href.path() ))); 211 document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, De bugMessageLevel, String("Preload triggered for " + href.host() + href.path())));
208 linkRequest.setForPreload(true); 212 linkRequest.setForPreload(true);
209 linkRequest.setAvoidBlockingOnLoad(true); 213 linkRequest.setAvoidBlockingOnLoad(true);
210 document.loader()->startPreload(type, linkRequest); 214 document.loader()->startPreload(type, linkRequest, linkLoader);
211 }
212 } 215 }
213 216
214 bool LinkLoader::loadLinkFromHeader(const String& headerValue, Document* documen t, const NetworkHintsInterface& networkHintsInterface, CanLoadResources canLoadR esources) 217 bool LinkLoader::loadLinkFromHeader(const String& headerValue, Document* documen t, const NetworkHintsInterface& networkHintsInterface, CanLoadResources canLoadR esources)
215 { 218 {
216 if (!document) 219 if (!document)
217 return false; 220 return false;
218 LinkHeaderSet headerSet(headerValue); 221 LinkHeaderSet headerSet(headerValue);
219 for (auto& header : headerSet) { 222 for (auto& header : headerSet) {
220 if (!header.valid() || header.url().isEmpty() || header.rel().isEmpty()) 223 if (!header.valid() || header.url().isEmpty() || header.rel().isEmpty())
221 return false; 224 return false;
222 225
223 LinkRelAttribute relAttribute(header.rel()); 226 LinkRelAttribute relAttribute(header.rel());
224 KURL url = document->completeURL(header.url()); 227 KURL url = document->completeURL(header.url());
225 if (canLoadResources == DoNotLoadResources) { 228 if (canLoadResources == DoNotLoadResources) {
226 if (RuntimeEnabledFeatures::linkHeaderEnabled()) 229 if (RuntimeEnabledFeatures::linkHeaderEnabled())
227 dnsPrefetchIfNeeded(relAttribute, url, *document, networkHintsIn terface, LinkCalledFromHeader); 230 dnsPrefetchIfNeeded(relAttribute, url, *document, networkHintsIn terface, LinkCalledFromHeader);
228 231
229 if (RuntimeEnabledFeatures::linkPreconnectEnabled()) 232 if (RuntimeEnabledFeatures::linkPreconnectEnabled())
230 preconnectIfNeeded(relAttribute, url, *document, header.crossOri gin(), networkHintsInterface, LinkCalledFromHeader); 233 preconnectIfNeeded(relAttribute, url, *document, header.crossOri gin(), networkHintsInterface, LinkCalledFromHeader);
231 } else { 234 } else {
232 if (RuntimeEnabledFeatures::linkPreloadEnabled()) 235 if (RuntimeEnabledFeatures::linkPreloadEnabled())
233 preloadIfNeeded(relAttribute, url, *document, header.as()); 236 preloadIfNeeded(relAttribute, url, *document, header.as(), nullp tr);
Nate Chapin 2016/01/13 23:52:23 Passing nullptr in this case is not immediately ob
Yoav Weiss 2016/01/14 10:10:02 If preloadIfNeeded would not be static, we wouldn'
234 } 237 }
235 // TODO(yoav): Add more supported headers as needed. 238 // TODO(yoav): Add more supported headers as needed.
236 } 239 }
237 return true; 240 return true;
238 } 241 }
239 242
240 bool LinkLoader::loadLink(const LinkRelAttribute& relAttribute, CrossOriginAttri buteValue crossOrigin, const String& type, const String& as, const KURL& href, D ocument& document, const NetworkHintsInterface& networkHintsInterface) 243 bool LinkLoader::loadLink(const LinkRelAttribute& relAttribute, CrossOriginAttri buteValue crossOrigin, const String& type, const String& as, const KURL& href, D ocument& document, const NetworkHintsInterface& networkHintsInterface)
241 { 244 {
242 // TODO(yoav): Do all links need to load only after they're in document??? 245 // TODO(yoav): Do all links need to load only after they're in document???
243 246
244 // TODO(yoav): Convert all uses of the CrossOriginAttribute to CrossOriginAt tributeValue. crbug.com/486689 247 // TODO(yoav): Convert all uses of the CrossOriginAttribute to CrossOriginAt tributeValue. crbug.com/486689
245 // FIXME(crbug.com/463266): We're ignoring type here. Maybe we shouldn't. 248 // FIXME(crbug.com/463266): We're ignoring type here. Maybe we shouldn't.
246 dnsPrefetchIfNeeded(relAttribute, href, document, networkHintsInterface, Lin kCalledFromMarkup); 249 dnsPrefetchIfNeeded(relAttribute, href, document, networkHintsInterface, Lin kCalledFromMarkup);
247 250
248 preconnectIfNeeded(relAttribute, href, document, crossOrigin, networkHintsIn terface, LinkCalledFromMarkup); 251 preconnectIfNeeded(relAttribute, href, document, crossOrigin, networkHintsIn terface, LinkCalledFromMarkup);
249 252
250 if (m_client->shouldLoadLink()) 253 if (m_client->shouldLoadLink())
251 preloadIfNeeded(relAttribute, href, document, as); 254 preloadIfNeeded(relAttribute, href, document, as, this);
252 255
253 // FIXME(crbug.com/323096): Should take care of import. 256 // FIXME(crbug.com/323096): Should take care of import.
254 if ((relAttribute.isLinkPrefetch() || relAttribute.isLinkSubresource()) && h ref.isValid() && document.frame()) { 257 if ((relAttribute.isLinkPrefetch() || relAttribute.isLinkSubresource()) && h ref.isValid() && document.frame()) {
255 if (!m_client->shouldLoadLink()) 258 if (!m_client->shouldLoadLink())
256 return false; 259 return false;
257 Resource::Type type = Resource::LinkPrefetch; 260 Resource::Type type = Resource::LinkPrefetch;
258 if (relAttribute.isLinkSubresource()) { 261 if (relAttribute.isLinkSubresource()) {
259 type = Resource::LinkSubresource; 262 type = Resource::LinkSubresource;
260 UseCounter::count(document, UseCounter::LinkRelSubresource); 263 UseCounter::count(document, UseCounter::LinkRelSubresource);
261 } else { 264 } else {
(...skipping 27 matching lines...) Expand all
289 // atomic (dns prefetch). 292 // atomic (dns prefetch).
290 if (m_prerender) { 293 if (m_prerender) {
291 m_prerender->cancel(); 294 m_prerender->cancel();
292 m_prerender.clear(); 295 m_prerender.clear();
293 } 296 }
294 } 297 }
295 298
296 DEFINE_TRACE(LinkLoader) 299 DEFINE_TRACE(LinkLoader)
297 { 300 {
298 visitor->trace(m_prerender); 301 visitor->trace(m_prerender);
302 visitor->trace(m_linkPreloadResourceClient);
299 } 303 }
300 304
301 } 305 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698