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

Side by Side Diff: Source/WebCore/html/parser/HTMLPreloadScanner.cpp

Issue 13945017: External Stylesheets preloaded according to their media attribute (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 8 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) 2008 Apple Inc. All Rights Reserved. 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 * Copyright (C) 2009 Torch Mobile, Inc. http://www.torchmobile.com/ 3 * Copyright (C) 2009 Torch Mobile, Inc. http://www.torchmobile.com/
4 * Copyright (C) 2010 Google Inc. All Rights Reserved. 4 * Copyright (C) 2010 Google Inc. All Rights Reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 16 matching lines...) Expand all
27 27
28 #include "config.h" 28 #include "config.h"
29 #include "HTMLPreloadScanner.h" 29 #include "HTMLPreloadScanner.h"
30 30
31 #include "HTMLNames.h" 31 #include "HTMLNames.h"
32 #include "HTMLParserIdioms.h" 32 #include "HTMLParserIdioms.h"
33 #include "HTMLParserOptions.h" 33 #include "HTMLParserOptions.h"
34 #include "HTMLTokenizer.h" 34 #include "HTMLTokenizer.h"
35 #include "InputTypeNames.h" 35 #include "InputTypeNames.h"
36 #include "LinkRelAttribute.h" 36 #include "LinkRelAttribute.h"
37 #include "MediaList.h"
38 #include "MediaQueryEvaluator.h"
39 #include <wtf/Functional.h> 37 #include <wtf/Functional.h>
40 #include <wtf/MainThread.h> 38 #include <wtf/MainThread.h>
41 39
42 namespace WebCore { 40 namespace WebCore {
43 41
44 using namespace HTMLNames; 42 using namespace HTMLNames;
45 43
46 TokenPreloadScanner::TagId TokenPreloadScanner::tagIdFor(const HTMLToken::DataVe ctor& data) 44 TokenPreloadScanner::TagId TokenPreloadScanner::tagIdFor(const HTMLToken::DataVe ctor& data)
47 { 45 {
48 AtomicString tagName(data); 46 AtomicString tagName(data);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 } 102 }
105 ASSERT_NOT_REACHED(); 103 ASSERT_NOT_REACHED();
106 return "unknown"; 104 return "unknown";
107 } 105 }
108 106
109 class TokenPreloadScanner::StartTagScanner { 107 class TokenPreloadScanner::StartTagScanner {
110 public: 108 public:
111 explicit StartTagScanner(TagId tagId) 109 explicit StartTagScanner(TagId tagId)
112 : m_tagId(tagId) 110 : m_tagId(tagId)
113 , m_linkIsStyleSheet(false) 111 , m_linkIsStyleSheet(false)
114 , m_linkMediaAttributeIsScreen(true)
115 , m_inputIsImage(false) 112 , m_inputIsImage(false)
116 { 113 {
117 } 114 }
118 115
119 void processAttributes(const HTMLToken::AttributeList& attributes) 116 void processAttributes(const HTMLToken::AttributeList& attributes)
120 { 117 {
121 ASSERT(isMainThread()); 118 ASSERT(isMainThread());
122 if (m_tagId >= UnknownTagId) 119 if (m_tagId >= UnknownTagId)
123 return; 120 return;
124 for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) { 121 for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
(...skipping 11 matching lines...) Expand all
136 for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attribut es.begin(); iter != attributes.end(); ++iter) 133 for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attribut es.begin(); iter != attributes.end(); ++iter)
137 processAttribute(iter->name, iter->value); 134 processAttribute(iter->name, iter->value);
138 } 135 }
139 #endif 136 #endif
140 137
141 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL ) 138 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL )
142 { 139 {
143 if (!shouldPreload()) 140 if (!shouldPreload())
144 return nullptr; 141 return nullptr;
145 142
146 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t agId), m_urlToLoad, predictedBaseURL, resourceType()); 143 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t agId), m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribute);
147 request->setCrossOriginModeAllowsCookies(crossOriginModeAllowsCookies()) ; 144 request->setCrossOriginModeAllowsCookies(crossOriginModeAllowsCookies()) ;
148 request->setCharset(charset()); 145 request->setCharset(charset());
149 return request.release(); 146 return request.release();
150 } 147 }
151 148
152 static bool match(const AtomicString& name, const QualifiedName& qName) 149 static bool match(const AtomicString& name, const QualifiedName& qName)
153 { 150 {
154 ASSERT(isMainThread()); 151 ASSERT(isMainThread());
155 return qName.localName() == name; 152 return qName.localName() == name;
156 } 153 }
(...skipping 16 matching lines...) Expand all
173 if (match(attributeName, srcAttr)) 170 if (match(attributeName, srcAttr))
174 setUrlToLoad(attributeValue); 171 setUrlToLoad(attributeValue);
175 else if (match(attributeName, crossoriginAttr) && !attributeValue.is Null()) 172 else if (match(attributeName, crossoriginAttr) && !attributeValue.is Null())
176 m_crossOriginMode = stripLeadingAndTrailingHTMLSpaces(attributeV alue); 173 m_crossOriginMode = stripLeadingAndTrailingHTMLSpaces(attributeV alue);
177 } else if (m_tagId == LinkTagId) { 174 } else if (m_tagId == LinkTagId) {
178 if (match(attributeName, hrefAttr)) 175 if (match(attributeName, hrefAttr))
179 setUrlToLoad(attributeValue); 176 setUrlToLoad(attributeValue);
180 else if (match(attributeName, relAttr)) 177 else if (match(attributeName, relAttr))
181 m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue); 178 m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue);
182 else if (match(attributeName, mediaAttr)) 179 else if (match(attributeName, mediaAttr))
183 m_linkMediaAttributeIsScreen = linkMediaAttributeIsScreen(attrib uteValue); 180 m_mediaAttribute = attributeValue;
184 } else if (m_tagId == InputTagId) { 181 } else if (m_tagId == InputTagId) {
185 if (match(attributeName, srcAttr)) 182 if (match(attributeName, srcAttr))
186 setUrlToLoad(attributeValue); 183 setUrlToLoad(attributeValue);
187 else if (match(attributeName, typeAttr)) 184 else if (match(attributeName, typeAttr))
188 m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeName s::image()); 185 m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeName s::image());
189 } 186 }
190 } 187 }
191 188
192 static bool relAttributeIsStyleSheet(const String& attributeValue) 189 static bool relAttributeIsStyleSheet(const String& attributeValue)
193 { 190 {
194 LinkRelAttribute rel(attributeValue); 191 LinkRelAttribute rel(attributeValue);
195 return rel.m_isStyleSheet && !rel.m_isAlternate && rel.m_iconType == Inv alidIcon && !rel.m_isDNSPrefetch; 192 return rel.m_isStyleSheet && !rel.m_isAlternate && rel.m_iconType == Inv alidIcon && !rel.m_isDNSPrefetch;
196 } 193 }
197 194
198 static bool linkMediaAttributeIsScreen(const String& attributeValue)
199 {
200 if (attributeValue.isEmpty())
201 return true;
202 RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::createAllowingDescri ptionSyntax(attributeValue);
203
204 // Only preload screen media stylesheets. Used this way, the evaluator e valuates to true for any
205 // rules containing complex queries (full evaluation is possible but it requires a frame and a style selector which
206 // may be problematic here).
207 MediaQueryEvaluator mediaQueryEvaluator("screen");
208 return mediaQueryEvaluator.eval(mediaQueries.get());
209 }
210
211 void setUrlToLoad(const String& attributeValue) 195 void setUrlToLoad(const String& attributeValue)
212 { 196 {
213 // We only respect the first src/href, per HTML5: 197 // We only respect the first src/href, per HTML5:
214 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenizat ion.html#attribute-name-state 198 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenizat ion.html#attribute-name-state
215 if (!m_urlToLoad.isEmpty()) 199 if (!m_urlToLoad.isEmpty())
216 return; 200 return;
217 m_urlToLoad = stripLeadingAndTrailingHTMLSpaces(attributeValue); 201 m_urlToLoad = stripLeadingAndTrailingHTMLSpaces(attributeValue);
218 } 202 }
219 203
220 const String& charset() const 204 const String& charset() const
221 { 205 {
222 // FIXME: Its not clear that this if is needed, the loader probably igno res charset for image requests anyway. 206 // FIXME: Its not clear that this if is needed, the loader probably igno res charset for image requests anyway.
223 if (m_tagId == ImgTagId) 207 if (m_tagId == ImgTagId)
224 return emptyString(); 208 return emptyString();
225 return m_charset; 209 return m_charset;
226 } 210 }
227 211
228 CachedResource::Type resourceType() const 212 CachedResource::Type resourceType() const
229 { 213 {
230 if (m_tagId == ScriptTagId) 214 if (m_tagId == ScriptTagId)
231 return CachedResource::Script; 215 return CachedResource::Script;
232 if (m_tagId == ImgTagId || (m_tagId == InputTagId && m_inputIsImage)) 216 if (m_tagId == ImgTagId || (m_tagId == InputTagId && m_inputIsImage))
233 return CachedResource::ImageResource; 217 return CachedResource::ImageResource;
234 if (m_tagId == LinkTagId && m_linkIsStyleSheet && m_linkMediaAttributeIs Screen) 218 if (m_tagId == LinkTagId && m_linkIsStyleSheet)
235 return CachedResource::CSSStyleSheet; 219 return CachedResource::CSSStyleSheet;
236 ASSERT_NOT_REACHED(); 220 ASSERT_NOT_REACHED();
237 return CachedResource::RawResource; 221 return CachedResource::RawResource;
238 } 222 }
239 223
240 bool shouldPreload() 224 bool shouldPreload()
241 { 225 {
242 if (m_urlToLoad.isEmpty()) 226 if (m_urlToLoad.isEmpty())
243 return false; 227 return false;
244 228
245 if (m_tagId == LinkTagId && (!m_linkIsStyleSheet || !m_linkMediaAttribut eIsScreen)) 229 if (m_tagId == LinkTagId && !m_linkIsStyleSheet)
246 return false; 230 return false;
247 231
248 if (m_tagId == InputTagId && !m_inputIsImage) 232 if (m_tagId == InputTagId && !m_inputIsImage)
249 return false; 233 return false;
250 234
251 return true; 235 return true;
252 } 236 }
253 237
254 bool crossOriginModeAllowsCookies() 238 bool crossOriginModeAllowsCookies()
255 { 239 {
256 return m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode , "use-credentials"); 240 return m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode , "use-credentials");
257 } 241 }
258 242
259 TagId m_tagId; 243 TagId m_tagId;
260 String m_urlToLoad; 244 String m_urlToLoad;
261 String m_charset; 245 String m_charset;
262 String m_crossOriginMode; 246 String m_crossOriginMode;
263 bool m_linkIsStyleSheet; 247 bool m_linkIsStyleSheet;
264 bool m_linkMediaAttributeIsScreen; 248 String m_mediaAttribute;
265 bool m_inputIsImage; 249 bool m_inputIsImage;
266 }; 250 };
267 251
268 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL) 252 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL)
269 : m_documentURL(documentURL) 253 : m_documentURL(documentURL)
270 , m_inStyle(false) 254 , m_inStyle(false)
271 , m_templateCount(0) 255 , m_templateCount(0)
272 { 256 {
273 } 257 }
274 258
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 if (m_token.type() == HTMLToken::StartTag) 384 if (m_token.type() == HTMLToken::StartTag)
401 m_tokenizer->updateStateFor(AtomicString(m_token.name())); 385 m_tokenizer->updateStateFor(AtomicString(m_token.name()));
402 m_scanner.scan(m_token, requests); 386 m_scanner.scan(m_token, requests);
403 m_token.clear(); 387 m_token.clear();
404 } 388 }
405 389
406 preloader->takeAndPreload(requests); 390 preloader->takeAndPreload(requests);
407 } 391 }
408 392
409 } 393 }
OLDNEW
« no previous file with comments | « LayoutTests/http/tests/loading/resources/small_mq.css ('k') | Source/WebCore/html/parser/HTMLResourcePreloader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698