1/*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 * Copyright (C) 2010 Google Inc. All Rights Reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#ifndef HTMLPreloadScanner_h
28#define HTMLPreloadScanner_h
29
30#include "CSSPreloadScanner.h"
31#include "HTMLToken.h"
32#include "SegmentedString.h"
33#include <wtf/Vector.h>
34
35namespace WebCore {
36
37typedef size_t TokenPreloadScannerCheckpoint;
38
39class HTMLParserOptions;
40class HTMLTokenizer;
41class SegmentedString;
42class Frame;
43
44class TokenPreloadScanner {
45    WTF_MAKE_NONCOPYABLE(TokenPreloadScanner); WTF_MAKE_FAST_ALLOCATED;
46public:
47    explicit TokenPreloadScanner(const URL& documentURL, float deviceScaleFactor = 1.0);
48    ~TokenPreloadScanner();
49
50    void scan(const HTMLToken&, PreloadRequestStream& requests
51#if ENABLE_PICTURE_SIZES
52        , RenderView*, Frame*
53#endif
54        );
55
56    void setPredictedBaseElementURL(const URL& url) { m_predictedBaseElementURL = url; }
57
58    // A TokenPreloadScannerCheckpoint is valid until the next call to rewindTo,
59    // at which point all outstanding checkpoints are invalidated.
60    TokenPreloadScannerCheckpoint createCheckpoint();
61    void rewindTo(TokenPreloadScannerCheckpoint);
62
63    bool isSafeToSendToAnotherThread()
64    {
65        return m_documentURL.isSafeToSendToAnotherThread()
66            && m_predictedBaseElementURL.isSafeToSendToAnotherThread();
67    }
68
69private:
70    enum class TagId {
71        // These tags are scanned by the StartTagScanner.
72        Img,
73        Input,
74        Link,
75        Script,
76
77        // These tags are not scanned by the StartTagScanner.
78        Unknown,
79        Style,
80        Base,
81        Template,
82    };
83
84    class StartTagScanner;
85
86    static TagId tagIdFor(const HTMLToken::DataVector&);
87
88    static String initiatorFor(TagId);
89
90    template<typename Token>
91    void updatePredictedBaseURL(const Token&);
92
93    struct Checkpoint {
94        Checkpoint(const URL& predictedBaseElementURL, bool inStyle
95#if ENABLE(TEMPLATE_ELEMENT)
96            , size_t templateCount
97#endif
98            )
99            : predictedBaseElementURL(predictedBaseElementURL)
100            , inStyle(inStyle)
101#if ENABLE(TEMPLATE_ELEMENT)
102            , templateCount(templateCount)
103#endif
104        {
105        }
106
107        URL predictedBaseElementURL;
108        bool inStyle;
109#if ENABLE(TEMPLATE_ELEMENT)
110        size_t templateCount;
111#endif
112    };
113
114    CSSPreloadScanner m_cssScanner;
115    const URL m_documentURL;
116    URL m_predictedBaseElementURL;
117    bool m_inStyle;
118    float m_deviceScaleFactor;
119
120#if ENABLE(TEMPLATE_ELEMENT)
121    size_t m_templateCount;
122#endif
123
124    Vector<Checkpoint> m_checkpoints;
125};
126
127class HTMLPreloadScanner {
128    WTF_MAKE_NONCOPYABLE(HTMLPreloadScanner); WTF_MAKE_FAST_ALLOCATED;
129public:
130    HTMLPreloadScanner(const HTMLParserOptions&, const URL& documentURL, float deviceScaleFactor = 1.0);
131    ~HTMLPreloadScanner();
132
133    void appendToEnd(const SegmentedString&);
134    void scan(HTMLResourcePreloader*, const URL& documentBaseElementURL
135#if ENABLE_PICTURE_SIZES
136        , RenderView*, Frame*
137#endif
138        );
139
140private:
141    TokenPreloadScanner m_scanner;
142    SegmentedString m_source;
143    HTMLToken m_token;
144    std::unique_ptr<HTMLTokenizer> m_tokenizer;
145};
146
147}
148
149#endif
150