Source/WebCore/WebCore.pro

@@SOURCES += \
792792 html/parser/HTMLParserIdioms.cpp \
793793 html/parser/HTMLParserScheduler.cpp \
794794 html/parser/HTMLPreloadScanner.cpp \
 795 html/parser/HTMLPreloadScannerThread.cpp \
795796 html/parser/HTMLScriptRunner.cpp \
796797 html/parser/HTMLSourceTracker.cpp \
797798 html/parser/HTMLTokenizer.cpp \

@@HEADERS += \
17571758 html/parser/HTMLFormattingElementList.h \
17581759 html/parser/HTMLParserScheduler.h \
17591760 html/parser/HTMLPreloadScanner.h \
 1761 html/parser/HTMLPreloadScannerThread.h \
17601762 html/parser/HTMLScriptRunner.h \
17611763 html/parser/HTMLScriptRunnerHost.h \
17621764 html/parser/HTMLToken.h \

Source/WebCore/html/parser/CSSPreloadScanner.cpp

@@namespace WebCore {
3939CSSPreloadScanner::CSSPreloadScanner(Document* document)
4040 : m_state(Initial)
4141 , m_document(document)
 42 , m_urlsToLoadQueue(HTMLPreloadScanner::htmlPreloadScanner()->m_urlsToLoadQueue)
4243{
4344}
4445

@@void CSSPreloadScanner::reset()
4950 m_ruleValue.clear();
5051}
5152
52 void CSSPreloadScanner::scan(const HTMLToken& token, bool scanningBody)
 53void CSSPreloadScanner::scan(const HTMLToken& token)
5354{
54  m_scanningBody = scanningBody;
55 
5655 const HTMLToken::DataVector& characters = token.characters();
5756 for (HTMLToken::DataVector::const_iterator iter = characters.begin(); iter != characters.end() && m_state != DoneParsingImportRules; ++iter)
5857 tokenize(*iter);

@@void CSSPreloadScanner::emitRule()
194193{
195194 if (equalIgnoringCase("import", m_rule.data(), m_rule.size())) {
196195 String value = parseCSSStringOrURL(m_ruleValue.data(), m_ruleValue.size());
197  if (!value.isEmpty()) {
198  ResourceRequest request(m_document->completeURL(value));
199  m_document->cachedResourceLoader()->preload(CachedResource::CSSStyleSheet, request, String(), m_scanningBody);
200  }
 196
 197 if (!value.isEmpty())
 198 m_urlsToLoadQueue->append(adoptPtr(new Preload(m_document, true, false, false, value, String("import"), String())));
 199
201200 m_state = Initial;
202201 } else if (equalIgnoringCase("charset", m_rule.data(), m_rule.size()))
203202 m_state = Initial;

Source/WebCore/html/parser/CSSPreloadScanner.h

2727#ifndef CSSPreloadScanner_h
2828#define CSSPreloadScanner_h
2929
 30#include "HTMLPreloadScanner.h"
3031#include "PlatformString.h"
 32#include <wtf/MessageQueue.h>
3133#include <wtf/Vector.h>
3234
3335namespace WebCore {
3436
3537class Document;
3638class HTMLToken;
 39class Preload;
3740
3841class CSSPreloadScanner {
3942 WTF_MAKE_NONCOPYABLE(CSSPreloadScanner);

@@public:
4144 CSSPreloadScanner(Document*);
4245
4346 void reset();
44  void scan(const HTMLToken&, bool scanningBody);
 47 void scan(const HTMLToken&);
4548
4649private:
4750 enum State {

@@private:
6467 Vector<UChar, 16> m_rule;
6568 Vector<UChar> m_ruleValue;
6669
67  bool m_scanningBody;
6870 Document* m_document;
 71 MessageQueue<Preload>* m_urlsToLoadQueue;
6972};
7073
7174}

Source/WebCore/html/parser/HTMLDocumentParser.cpp

@@HTMLDocumentParser::~HTMLDocumentParser()
104104{
105105 ASSERT(!m_parserScheduler);
106106 ASSERT(!m_pumpSessionNestingLevel);
107  ASSERT(!m_preloadScanner);
108107}
109108
110109void HTMLDocumentParser::detach()

@@void HTMLDocumentParser::detach()
113112 if (m_scriptRunner)
114113 m_scriptRunner->detach();
115114 m_treeBuilder->detach();
116  // FIXME: It seems wrong that we would have a preload scanner here.
117  // Yet during fast/dom/HTMLScriptElement/script-load-events.html we do.
118  m_preloadScanner.clear();
 115
119116 m_parserScheduler.clear(); // Deleting the scheduler will clear any timers.
120117}
121118

@@void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
289286
290287 if (isWaitingForScripts()) {
291288 ASSERT(m_tokenizer->state() == HTMLTokenizer::DataState);
292  if (!m_preloadScanner) {
293  m_preloadScanner = adoptPtr(new HTMLPreloadScanner(document()));
294  m_preloadScanner->appendToEnd(m_input.current());
295  }
296  m_preloadScanner->scan();
 289 HTMLPreloadScanner::htmlPreloadScanner()->preloadResources(document());
297290 }
298291
299292 InspectorInstrumentation::didWriteHTML(cookie, m_tokenizer->lineNumber());

@@void HTMLDocumentParser::insert(const SegmentedString& source)
322315 excludedLineNumberSource.setExcludeLineNumbers();
323316 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource);
324317 pumpTokenizerIfPossible(ForceSynchronous);
325 
326  if (isWaitingForScripts()) {
327  // Check the document.write() output with a separate preload scanner as
328  // the main scanner can't deal with insertions.
329  HTMLPreloadScanner preloadScanner(document());
330  preloadScanner.appendToEnd(source);
331  preloadScanner.scan();
332  }
 318
 319 HTMLPreloadScanner::htmlPreloadScanner()->addTask(document(), source.toString());
 320
 321 if (isWaitingForScripts())
 322 HTMLPreloadScanner::htmlPreloadScanner()->preloadResources(document());
333323
334324 endIfDelayed();
335325}

@@void HTMLDocumentParser::append(const SegmentedString& source)
343333 // but we need to ensure it isn't deleted yet.
344334 RefPtr<HTMLDocumentParser> protect(this);
345335
346  if (m_preloadScanner) {
347  if (m_input.current().isEmpty() && !isWaitingForScripts()) {
348  // We have parsed until the end of the current input and so are now moving ahead of the preload scanner.
349  // Clear the scanner so we know to scan starting from the current input point if we block again.
350  m_preloadScanner.clear();
351  } else {
352  m_preloadScanner->appendToEnd(source);
353  if (isWaitingForScripts())
354  m_preloadScanner->scan();
355  }
356  }
 336 HTMLPreloadScanner::htmlPreloadScanner()->addTask(document(), source.toString());
 337
 338 if (isWaitingForScripts())
 339 HTMLPreloadScanner::htmlPreloadScanner()->preloadResources(document());
357340
358341 m_input.appendToEnd(source);
359342

@@void HTMLDocumentParser::end()
374357 ASSERT(!isDetached());
375358 ASSERT(!isScheduledForResume());
376359
 360 while (OwnPtr<Preload> preloadResource = HTMLPreloadScanner::htmlPreloadScanner()->m_urlsToLoadQueue->tryGetMessage()) {
 361 if (preloadResource->document == document())
 362 preloadResource.clear();
 363 else {
 364 HTMLPreloadScanner::htmlPreloadScanner()->m_urlsToLoadQueue->prepend(preloadResource.release());
 365 break;
 366 }
 367 }
 368
377369 // Informs the the rest of WebCore that parsing is really finished (and deletes this).
378370 m_treeBuilder->finished();
379371}

@@void HTMLDocumentParser::stopWatchingForLoad(CachedResource* cachedScript)
495487
496488void HTMLDocumentParser::appendCurrentInputStreamToPreloadScannerAndScan()
497489{
498  ASSERT(m_preloadScanner);
499  m_preloadScanner->appendToEnd(m_input.current());
500  m_preloadScanner->scan();
 490 ASSERT(HTMLPreloadScanner::htmlPreloadScanner());
 491 HTMLPreloadScanner::htmlPreloadScanner()->addTask(document(), m_input.current().toString());
 492 HTMLPreloadScanner::htmlPreloadScanner()->preloadResources(document());
501493}
502494
503495void HTMLDocumentParser::notifyFinished(CachedResource* cachedResource)

Source/WebCore/html/parser/HTMLDocumentParser.h

3232#include "HTMLScriptRunnerHost.h"
3333#include "HTMLSourceTracker.h"
3434#include "HTMLToken.h"
 35#include "HTMLPreloadScanner.h"
3536#include "ScriptableDocumentParser.h"
3637#include "SegmentedString.h"
3738#include "Timer.h"

@@class HTMLParserScheduler;
4748class HTMLTokenizer;
4849class HTMLScriptRunner;
4950class HTMLTreeBuilder;
50 class HTMLPreloadScanner;
5151class ScriptController;
5252class ScriptSourceCode;
5353

@@private:
110110 virtual void watchForLoad(CachedResource*);
111111 virtual void stopWatchingForLoad(CachedResource*);
112112 virtual HTMLInputStream& inputStream() { return m_input; }
113  virtual bool hasPreloadScanner() const { return m_preloadScanner.get(); }
 113 virtual bool hasPreloadScanner() const { return HTMLPreloadScanner::htmlPreloadScanner(); }
114114 virtual void appendCurrentInputStreamToPreloadScannerAndScan();
115115
116116 // CachedResourceClient

@@private:
149149 OwnPtr<HTMLTokenizer> m_tokenizer;
150150 OwnPtr<HTMLScriptRunner> m_scriptRunner;
151151 OwnPtr<HTMLTreeBuilder> m_treeBuilder;
152  OwnPtr<HTMLPreloadScanner> m_preloadScanner;
153152 OwnPtr<HTMLParserScheduler> m_parserScheduler;
154153 HTMLSourceTracker m_sourceTracker;
155154 XSSAuditor m_xssAuditor;

Source/WebCore/html/parser/HTMLPreloadScanner.cpp

3030
3131#include "CachedResourceLoader.h"
3232#include "Document.h"
33 #include "InputType.h"
34 #include "HTMLDocumentParser.h"
35 #include "HTMLTokenizer.h"
3633#include "HTMLNames.h"
37 #include "HTMLParserIdioms.h"
38 #include "LinkRelAttribute.h"
39 #include "MediaList.h"
40 #include "MediaQueryEvaluator.h"
 34#include "HTMLPreloadScannerThread.h"
4135
4236namespace WebCore {
4337
4438using namespace HTMLNames;
4539
46 namespace {
47 
48 class PreloadTask {
49 public:
50  PreloadTask(const HTMLToken& token)
51  : m_tagName(token.name().data(), token.name().size())
52  , m_linkIsStyleSheet(false)
53  , m_linkMediaAttributeIsScreen(true)
54  , m_inputIsImage(false)
55  {
56  processAttributes(token.attributes());
57  }
58 
59  void processAttributes(const HTMLToken::AttributeList& attributes)
60  {
61  if (m_tagName != imgTag
62  && m_tagName != inputTag
63  && m_tagName != linkTag
64  && m_tagName != scriptTag)
65  return;
66 
67  for (HTMLToken::AttributeList::const_iterator iter = attributes.begin();
68  iter != attributes.end(); ++iter) {
69  AtomicString attributeName(iter->m_name.data(), iter->m_name.size());
70  String attributeValue(iter->m_value.data(), iter->m_value.size());
71 
72  if (attributeName == charsetAttr)
73  m_charset = attributeValue;
74 
75  if (m_tagName == scriptTag || m_tagName == imgTag) {
76  if (attributeName == srcAttr)
77  setUrlToLoad(attributeValue);
78  } else if (m_tagName == linkTag) {
79  if (attributeName == hrefAttr)
80  setUrlToLoad(attributeValue);
81  else if (attributeName == relAttr)
82  m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue);
83  else if (attributeName == mediaAttr)
84  m_linkMediaAttributeIsScreen = linkMediaAttributeIsScreen(attributeValue);
85  } else if (m_tagName == inputTag) {
86  if (attributeName == srcAttr)
87  setUrlToLoad(attributeValue);
88  else if (attributeName == typeAttr)
89  m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::image());
90  }
91  }
92  }
93 
94  static bool relAttributeIsStyleSheet(const String& attributeValue)
95  {
96  LinkRelAttribute rel(attributeValue);
97  return rel.m_isStyleSheet && !rel.m_isAlternate && rel.m_iconType == InvalidIcon && !rel.m_isDNSPrefetch;
98  }
 40HTMLPreloadScannerThread* HTMLPreloadScanner::s_preloadScannerThread;
9941
100  static bool linkMediaAttributeIsScreen(const String& attributeValue)
101  {
102  if (attributeValue.isEmpty())
103  return true;
104  RefPtr<MediaList> mediaList = MediaList::createAllowingDescriptionSyntax(attributeValue);
105 
106  // Only preload screen media stylesheets. Used this way, the evaluator evaluates to true for any
107  // rules containing complex queries (full evaluation is possible but it requires a frame and a style selector which
108  // may be problematic here).
109  MediaQueryEvaluator mediaQueryEvaluator("screen");
110  return mediaQueryEvaluator.eval(mediaList.get());
111  }
112 
113  void setUrlToLoad(const String& attributeValue)
114  {
115  // We only respect the first src/href, per HTML5:
116  // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#attribute-name-state
117  if (!m_urlToLoad.isEmpty())
118  return;
119  m_urlToLoad = stripLeadingAndTrailingHTMLSpaces(attributeValue);
120  }
121 
122  void preload(Document* document, bool scanningBody)
123  {
124  if (m_urlToLoad.isEmpty())
125  return;
126 
127  CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
128  ResourceRequest request = document->completeURL(m_urlToLoad);
129  if (m_tagName == scriptTag)
130  cachedResourceLoader->preload(CachedResource::Script, request, m_charset, scanningBody);
131  else if (m_tagName == imgTag || (m_tagName == inputTag && m_inputIsImage))
132  cachedResourceLoader->preload(CachedResource::ImageResource, request, String(), scanningBody);
133  else if (m_tagName == linkTag && m_linkIsStyleSheet && m_linkMediaAttributeIsScreen)
134  cachedResourceLoader->preload(CachedResource::CSSStyleSheet, request, m_charset, scanningBody);
 42HTMLPreloadScanner* HTMLPreloadScanner::htmlPreloadScanner()
 43{
 44 DEFINE_STATIC_LOCAL(HTMLPreloadScanner, globalHTMLPreloadScanner, ());
 45 if (!HTMLPreloadScanner::s_preloadScannerThread) {
 46 WTF::initializeThreading();
 47 globalHTMLPreloadScanner.createPreloadThread();
13548 }
 49 return &globalHTMLPreloadScanner;
 50}
13651
137  const AtomicString& tagName() const { return m_tagName; }
138 
139 private:
140  AtomicString m_tagName;
141  String m_urlToLoad;
142  String m_charset;
143  bool m_linkIsStyleSheet;
144  bool m_linkMediaAttributeIsScreen;
145  bool m_inputIsImage;
146 };
147 
148 } // namespace
149 
150 HTMLPreloadScanner::HTMLPreloadScanner(Document* document)
151  : m_document(document)
152  , m_cssScanner(document)
153  , m_tokenizer(HTMLTokenizer::create(HTMLDocumentParser::usePreHTML5ParserQuirks(document)))
154  , m_bodySeen(false)
155  , m_inStyle(false)
 52HTMLPreloadScanner::HTMLPreloadScanner()
 53 : m_urlsToLoadQueue(new MessageQueue<Preload>())
15654{
15755}
15856
159 void HTMLPreloadScanner::appendToEnd(const SegmentedString& source)
 57void HTMLPreloadScanner::createPreloadThread()
16058{
161  m_source.append(source);
 59 createThread(htmlPreloadScannerThreadStart, this, "WebCore: PreloadScannerThread");
16260}
16361
164 void HTMLPreloadScanner::scan()
 62void HTMLPreloadScanner::addTask(Document* document, String source)
16563{
166  // FIXME: We should save and re-use these tokens in HTMLDocumentParser if
167  // the pending script doesn't end up calling document.write.
168  while (m_tokenizer->nextToken(m_source, m_token)) {
169  processToken();
170  m_token.clear();
171  }
 64 if (!s_preloadScannerThread || source.isEmpty())
 65 return;
 66 s_preloadScannerThread->addTask(document, source.threadsafeCopy());
17267}
17368
174 void HTMLPreloadScanner::processToken()
 69void HTMLPreloadScanner::preload(PassOwnPtr<Preload> preloadDocument)
17570{
176  if (m_inStyle) {
177  if (m_token.type() == HTMLToken::Character)
178  m_cssScanner.scan(m_token, scanningBody());
179  else if (m_token.type() == HTMLToken::EndTag) {
180  m_inStyle = false;
181  m_cssScanner.reset();
182  }
183  }
 71 OwnPtr<Preload> preload(preloadDocument);
18472
185  if (m_token.type() != HTMLToken::StartTag)
186  return;
 73 CachedResourceLoader* cachedResourceLoader = preload->document->cachedResourceLoader();
18774
188  PreloadTask task(m_token);
189  m_tokenizer->updateStateFor(task.tagName(), m_document->frame());
 75 if (!cachedResourceLoader)
 76 return;
19077
191  if (task.tagName() == bodyTag)
192  m_bodySeen = true;
 78 ResourceRequest request = preload->document->completeURL(preload->url);
19379
194  if (task.tagName() == styleTag)
195  m_inStyle = true;
 80 if (preload->tagName == scriptTag)
 81 cachedResourceLoader->preload(CachedResource::Script, request, preload->charset);
 82 else if (preload->tagName == imgTag || (preload->tagName == inputTag && preload->inputIsImage))
 83 cachedResourceLoader->preload(CachedResource::ImageResource, request, preload->charset);
 84 else if ((preload->tagName == linkTag && preload->linkIsStyleSheet && preload->linkMediaAttributeIsScreen) || preload->tagName == String("import"))
 85 cachedResourceLoader->preload(CachedResource::CSSStyleSheet, request, preload->charset);
19686
197  task.preload(m_document, scanningBody());
 87 preload.clear();
19888}
19989
200 bool HTMLPreloadScanner::scanningBody() const
 90void HTMLPreloadScanner::preloadResources(Document* document)
20191{
202  return m_document->body() || m_bodySeen;
 92 if (!m_urlsToLoadQueue)
 93 return;
 94
 95 while (OwnPtr<Preload> preloadResource = m_urlsToLoadQueue->tryGetMessage()) {
 96 if (preloadResource->document != document) {
 97 preloadResource.clear();
 98 continue;
 99 }
 100 preload(preloadResource.release());
 101 }
203102}
204103
205104}

Source/WebCore/html/parser/HTMLPreloadScanner.h

3131#include "HTMLToken.h"
3232#include "SegmentedString.h"
3333
 34#include <wtf/MessageQueue.h>
 35
3436namespace WebCore {
3537
3638class Document;
37 class HTMLToken;
38 class HTMLTokenizer;
39 class SegmentedString;
 39class HTMLPreloadScannerThread;
 40
 41class Preload {
 42public:
 43 Preload(Document* doc, bool linkIsStyleSheet, bool linkMediaAttributeIsScreen,
 44 bool inputIsImage, String urlString, String tagNameString, String charset)
 45 : document(doc)
 46 , linkIsStyleSheet(linkIsStyleSheet)
 47 , linkMediaAttributeIsScreen(linkMediaAttributeIsScreen)
 48 , inputIsImage(inputIsImage)
 49 , url(urlString)
 50 , tagName(tagNameString)
 51 , charset(charset)
 52 { }
 53 Document* document;
 54 bool linkIsStyleSheet;
 55 bool linkMediaAttributeIsScreen;
 56 bool inputIsImage;
 57 String url;
 58 String tagName;
 59 String charset;
 60};
4061
4162class HTMLPreloadScanner {
4263 WTF_MAKE_NONCOPYABLE(HTMLPreloadScanner); WTF_MAKE_FAST_ALLOCATED;
4364public:
44  HTMLPreloadScanner(Document*);
 65 HTMLPreloadScanner();
4566
46  void appendToEnd(const SegmentedString&);
47  void scan();
 67 void addTask(Document*, String);
 68 void preloadResources(Document*);
4869
49 private:
50  void processToken();
51  bool scanningBody() const;
 70 static HTMLPreloadScanner* htmlPreloadScanner();
 71 void createPreloadThread();
 72
 73 MessageQueue<Preload>* m_urlsToLoadQueue;
 74 static HTMLPreloadScannerThread* s_preloadScannerThread;
5275
53  Document* m_document;
54  SegmentedString m_source;
55  CSSPreloadScanner m_cssScanner;
56  OwnPtr<HTMLTokenizer> m_tokenizer;
57  HTMLToken m_token;
58  bool m_bodySeen;
59  bool m_inStyle;
 76private:
 77 void preload(PassOwnPtr<Preload>);
6078};
6179
6280}

Source/WebCore/html/parser/HTMLPreloadScannerThread.cpp

 1/*
 2 * Copyright (C) 2008 Apple Inc.
 3 * Copyright (C) 2010 Google Inc.
 4 * Copyright (C) 2011 Zoltan Horvath (hzoltan@inf.u-szeged.hu) University of Szeged
 5 *
 6 * All Rights Reserved.
 7 *
 8 * Redistribution and use in source and binary forms, with or without
 9 * modification, are permitted provided that the following conditions
 10 * are met:
 11 * 1. Redistributions of source code must retain the above copyright
 12 * notice, this list of conditions and the following disclaimer.
 13 * 2. Redistributions in binary form must reproduce the above copyright
 14 * notice, this list of conditions and the following disclaimer in the
 15 * documentation and/or other materials provided with the distribution.
 16 *
 17 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 25 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28 */
 29
 30#include "config.h"
 31#include "HTMLPreloadScannerThread.h"
 32
 33#include "Document.h"
 34#include "HTMLDocumentParser.h"
 35#include "HTMLLinkElement.h"
 36#include "HTMLNames.h"
 37#include "HTMLParserIdioms.h"
 38#include "HTMLPreloadScanner.h"
 39#include "InputType.h"
 40#include "MediaList.h"
 41#include "MediaQueryEvaluator.h"
 42
 43namespace WebCore {
 44
 45using namespace HTMLNames;
 46
 47static String bodyTagString;
 48static String charsetAttrString;
 49static String hrefAttrString;
 50static String imgTagString;
 51static String inputTagString;
 52static String linkTagString;
 53
 54static String mediaAttrString;
 55static String relAttrString;
 56static String scriptTagString;
 57static String srcAttrString;
 58static String styleTagString;
 59static String typeAttrString;
 60
 61class Task {
 62public:
 63 Task(const HTMLToken& token)
 64 : m_linkIsStyleSheet(false)
 65 , m_linkMediaAttributeIsScreen(true)
 66 , m_inputIsImage(false)
 67 {
 68 m_tagName = String(token.name().data(), token.name().size()).threadsafeCopy();
 69 processAttributes(token.attributes());
 70 }
 71
 72 void processAttributes(const HTMLToken::AttributeList& attributes)
 73 {
 74 if (m_tagName != imgTagString
 75 && m_tagName != inputTagString
 76 && m_tagName != linkTagString
 77 && m_tagName != scriptTagString)
 78 return;
 79
 80 for (HTMLToken::AttributeList::const_iterator iter = attributes.begin();
 81 iter != attributes.end(); ++iter) {
 82
 83 String attributeName(iter->m_name.data(), iter->m_name.size());
 84 String attributeValue(iter->m_value.data(), iter->m_value.size());
 85
 86 if (attributeName == charsetAttrString)
 87 m_charset = attributeValue;
 88
 89 if (m_tagName == scriptTagString || m_tagName == imgTagString) {
 90 if (attributeName == srcAttrString)
 91 setUrlToLoad(attributeValue);
 92 } else if (m_tagName == linkTagString) {
 93 if (attributeName == hrefAttrString)
 94 setUrlToLoad(attributeValue);
 95 else if (attributeName == relAttrString)
 96 m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue);
 97 else if (attributeName == mediaAttrString)
 98 m_linkMediaAttributeIsScreen = linkMediaAttributeIsScreen(attributeValue);
 99 } else if (m_tagName == inputTagString) {
 100 if (attributeName == srcAttrString)
 101 setUrlToLoad(attributeValue);
 102 else if (attributeName == typeAttrString)
 103 m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::image());
 104 }
 105 }
 106 }
 107
 108 static bool relAttributeIsStyleSheet(const String& attributeValue)
 109 {
 110 LinkRelAttribute rel(attributeValue);
 111 return rel.m_isStyleSheet && !rel.m_isAlternate && rel.m_iconType == InvalidIcon && !rel.m_isDNSPrefetch;
 112 }
 113
 114 static bool linkMediaAttributeIsScreen(const String& attributeValue)
 115 {
 116 if (attributeValue.isEmpty())
 117 return true;
 118 RefPtr<MediaList> mediaList = MediaList::createAllowingDescriptionSyntax(attributeValue);
 119
 120 // Only preload screen media stylesheets. Used this way, the evaluator evaluates to true for any
 121 // rules containing complex queries (full evaluation is possible but it requires a frame and a style selector which
 122 // may be problematic here).
 123 MediaQueryEvaluator mediaQueryEvaluator("screen");
 124 return mediaQueryEvaluator.eval(mediaList.get());
 125 }
 126
 127 void setUrlToLoad(const String& attributeValue)
 128 {
 129 // We only respect the first src/href, per HTML5:
 130 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#attribute-name-state
 131 if (!m_urlToLoad.isEmpty())
 132 return;
 133 m_urlToLoad = stripLeadingAndTrailingHTMLSpaces(attributeValue);
 134 }
 135
 136 const String& tagName() const { return m_tagName; }
 137 const String& urlToLoad() const { return m_urlToLoad; }
 138 const String& charset() const { return m_charset; }
 139 bool linkIsStyleSheet() const { return m_linkIsStyleSheet; }
 140 bool linkMediaAttributeIsScreen() const { return m_linkMediaAttributeIsScreen; }
 141 bool inputIsImage() const { return m_inputIsImage; }
 142
 143private:
 144 String m_tagName;
 145 String m_urlToLoad;
 146 String m_charset;
 147 bool m_linkIsStyleSheet;
 148 bool m_linkMediaAttributeIsScreen;
 149 bool m_inputIsImage;
 150};
 151
 152void* htmlPreloadScannerThreadStart(void* arg)
 153{
 154 HTMLPreloadScannerThread* thread = new HTMLPreloadScannerThread;
 155 HTMLPreloadScanner* preloader = static_cast<HTMLPreloadScanner*>(arg);
 156
 157 preloader->s_preloadScannerThread = thread;
 158 thread->m_urlsToLoadQueue = preloader->m_urlsToLoadQueue;
 159
 160 bodyTagString = bodyTag.toString();
 161 imgTagString = imgTag.toString();
 162 inputTagString = inputTag.toString();
 163 linkTagString = linkTag.toString();
 164 scriptTagString = scriptTag.toString();
 165
 166 charsetAttrString = charsetAttr.toString();
 167 hrefAttrString = hrefAttr.toString();
 168 mediaAttrString = mediaAttr.toString();
 169 relAttrString = relAttr.toString();
 170 srcAttrString = srcAttr.toString();
 171 styleTagString = styleTag.toString();
 172 typeAttrString = typeAttr.toString();
 173
 174 while (PassOwnPtr<DocumentToScan> docToScan = thread->m_documentsToScan->waitForMessage())
 175 thread->scan(docToScan);
 176
 177 return arg;
 178}
 179
 180HTMLPreloadScannerThread::HTMLPreloadScannerThread()
 181 : m_documentsToScan(new MessageQueue<DocumentToScan>())
 182{
 183}
 184
 185void HTMLPreloadScannerThread::scan(PassOwnPtr<DocumentToScan> doc)
 186{
 187 OwnPtr<DocumentToScan> docToScan(doc);
 188
 189 if (docToScan->source.isEmpty())
 190 return;
 191
 192 while (docToScan->tokenizer->nextToken(docToScan->source, docToScan->token)) {
 193 processToken(docToScan.get());
 194 docToScan->token.clear();
 195 }
 196
 197 docToScan.clear();
 198}
 199
 200void HTMLPreloadScannerThread::processToken(DocumentToScan* docToScan)
 201{
 202 if (docToScan->token.type() == HTMLToken::Character)
 203 docToScan->cssScanner.scan(docToScan->token);
 204 else if (docToScan->token.type() == HTMLToken::EndTag)
 205 docToScan->cssScanner.reset();
 206
 207 if (docToScan->token.type() != HTMLToken::StartTag)
 208 return;
 209
 210 Task task(docToScan->token);
 211
 212 if (task.urlToLoad().isEmpty())
 213 return;
 214
 215 m_urlsToLoadQueue->append(adoptPtr(new Preload(docToScan->document, task.linkIsStyleSheet(),
 216 task.linkMediaAttributeIsScreen(),
 217 task.inputIsImage(), task.urlToLoad().threadsafeCopy(),
 218 task.tagName().threadsafeCopy(), task.charset().threadsafeCopy())));
 219}
 220
 221void HTMLPreloadScannerThread::addTask(Document* document, String source)
 222{
 223 m_documentsToScan->append(adoptPtr(new DocumentToScan(document, source)));
 224}
 225
 226}

Source/WebCore/html/parser/HTMLPreloadScannerThread.h

 1/*
 2 * Copyright (C) 2008 Apple Inc.
 3 * Copyright (C) 2010 Google Inc.
 4 * Copyright (C) 2011 Zoltan Horvath (hzoltan@inf.u-szeged.hu) University of Szeged
 5 *
 6 * All Rights Reserved.
 7 *
 8 * Redistribution and use in source and binary forms, with or without
 9 * modification, are permitted provided that the following conditions
 10 * are met:
 11 * 1. Redistributions of source code must retain the above copyright
 12 * notice, this list of conditions and the following disclaimer.
 13 * 2. Redistributions in binary form must reproduce the above copyright
 14 * notice, this list of conditions and the following disclaimer in the
 15 * documentation and/or other materials provided with the distribution.
 16 *
 17 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 25 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28 */
 29
 30#ifndef HTMLPreloadScannerThread_H
 31#define HTMLPreloadScannerThread_h
 32
 33#include "HTMLDocumentParser.h"
 34#include "HTMLPreloadScanner.h"
 35#include "HTMLToken.h"
 36#include "HTMLTokenizer.h"
 37#include <wtf/MessageQueue.h>
 38#include <wtf/Vector.h>
 39#include <wtf/text/WTFString.h>
 40
 41namespace WebCore {
 42
 43class Document;
 44class HTMLToken;
 45class HTMLTokenizer;
 46class SegmentedString;
 47
 48void* htmlPreloadScannerThreadStart(void *);
 49
 50struct DocumentToScan {
 51
 52 DocumentToScan(Document* doc, String source)
 53 : document(doc)
 54 , cssScanner(doc)
 55 , source(source)
 56 , tokenizer(HTMLTokenizer::create(HTMLDocumentParser::usePreHTML5ParserQuirks(doc)))
 57 , token()
 58 {
 59 }
 60
 61 ~DocumentToScan()
 62 {
 63 tokenizer.clear();
 64 }
 65
 66 Document* document;
 67 CSSPreloadScanner cssScanner;
 68 SegmentedString source;
 69 OwnPtr<HTMLTokenizer> tokenizer;
 70 HTMLToken token;
 71};
 72
 73class HTMLPreloadScannerThread {
 74public:
 75 HTMLPreloadScannerThread();
 76
 77 void addTask(Document*, String);
 78 void scan(PassOwnPtr<DocumentToScan>);
 79
 80 MessageQueue<Preload>* m_urlsToLoadQueue;
 81 MessageQueue<DocumentToScan>* m_documentsToScan;
 82private:
 83 void processToken(DocumentToScan*);
 84};
 85
 86}
 87
 88#endif

Source/WebCore/html/parser/HTMLTokenizer.cpp

@@bool HTMLTokenizer::nextToken(SegmentedString& source, HTMLToken& token)
16451645 return false;
16461646}
16471647
1648 void HTMLTokenizer::updateStateFor(const AtomicString& tagName, Frame* frame)
 1648void HTMLTokenizer::updateStateFor(const String& tagName, Frame* frame)
16491649{
1650  if (tagName == textareaTag || tagName == titleTag)
 1650 if (tagName == textareaTag.toString() || tagName == titleTag.toString())
16511651 setState(RCDATAState);
1652  else if (tagName == plaintextTag)
 1652 else if (tagName == plaintextTag.toString())
16531653 setState(PLAINTEXTState);
1654  else if (tagName == scriptTag)
 1654 else if (tagName == scriptTag.toString())
16551655 setState(ScriptDataState);
1656  else if (tagName == styleTag
1657  || tagName == iframeTag
1658  || tagName == xmpTag
1659  || (tagName == noembedTag && HTMLTreeBuilder::pluginsEnabled(frame))
1660  || tagName == noframesTag
1661  || (tagName == noscriptTag && HTMLTreeBuilder::scriptEnabled(frame)))
 1656 else if (tagName == styleTag.toString()
 1657 || tagName == iframeTag.toString()
 1658 || tagName == xmpTag.toString()
 1659 || (tagName == noembedTag.toString() && HTMLTreeBuilder::pluginsEnabled(frame))
 1660 || tagName == noframesTag.toString()
 1661 || (tagName == noscriptTag.toString() && HTMLTreeBuilder::scriptEnabled(frame)))
16621662 setState(RAWTEXTState);
16631663}
16641664

Source/WebCore/html/parser/HTMLTokenizer.h

@@public:
150150 // * CDATA sections in foreign content will be tokenized as bogus comments
151151 // instead of as character tokens.
152152 //
153  void updateStateFor(const AtomicString& tagName, Frame*);
 153 void updateStateFor(const String& tagName, Frame*);
154154
155155 // Hack to skip leading newline in <pre>/<listing> for authoring ease.
156156 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#parsing-main-inbody

Source/WebCore/loader/cache/CachedResourceLoader.cpp

4747#include "ResourceLoadScheduler.h"
4848#include "SecurityOrigin.h"
4949#include "Settings.h"
50 #include <wtf/UnusedParam.h>
5150#include <wtf/text/CString.h>
5251#include <wtf/text/WTFString.h>
5352

@@int CachedResourceLoader::requestCount()
602601 return m_requestCount;
603602}
604603
605 void CachedResourceLoader::preload(CachedResource::Type type, ResourceRequest& request, const String& charset, bool referencedFromBody)
 604void CachedResourceLoader::preload(CachedResource::Type type, ResourceRequest& request, const String& charset)
606605{
607  // FIXME: Rip this out when we are sure it is no longer necessary (even for mobile).
608  UNUSED_PARAM(referencedFromBody);
609 
610606 bool hasRendering = m_document->body() && m_document->body()->renderer();
611607 bool canBlockParser = type == CachedResource::Script || type == CachedResource::CSSStyleSheet;
612608 if (!hasRendering && !canBlockParser) {

@@void CachedResourceLoader::printPreloadStats()
747743 printf("IMAGES: %d (%d hits, hit rate %d%%)\n", images, images - imageMisses, (images - imageMisses) * 100 / images);
748744}
749745#endif
750 
 746
751747}

Source/WebCore/loader/cache/CachedResourceLoader.h

@@public:
100100 bool isPreloaded(const String& urlString) const;
101101 void clearPreloads();
102102 void clearPendingPreloads();
103  void preload(CachedResource::Type, ResourceRequest&, const String& charset, bool referencedFromBody);
 103 void preload(CachedResource::Type, ResourceRequest&, const String& charset);
104104 void checkForPendingPreloads();
105105 void printPreloadStats();
106106 bool checkInsecureContent(CachedResource::Type, const KURL&) const;