Changeset 139020 in webkit


Ignore:
Timestamp:
Jan 7, 2013 5:21:43 PM (11 years ago)
Author:
abarth@webkit.org
Message:

HTMLTreeBuilder should not depend on Frame
https://bugs.webkit.org/show_bug.cgi?id=106256

Reviewed by Eric Seidel.

Source/WebCore:

Rather than have the tree builder ask the Frame whether scripting and
plugins are enabled, we now push that information to the tree builder
via HTMLParserOptions, letting us remove the Frame dependency from the
tree builder.

As a consequence of this change, the "script enabled" bit in the parser
is now locked in when the parser starts. This bit doesn't actually
control when script execute, only how the <noscript> element is parsed.

  • html/parser/HTMLDocumentParser.cpp:

(WebCore::tokenizerStateForContextElement):
(WebCore::HTMLDocumentParser::HTMLDocumentParser):

  • html/parser/HTMLMetaCharsetParser.cpp:

(WebCore::HTMLMetaCharsetParser::HTMLMetaCharsetParser):
(WebCore::HTMLMetaCharsetParser::checkForMetaCharset):

  • html/parser/HTMLParserOptions.cpp:

(WebCore::HTMLParserOptions::HTMLParserOptions):

  • html/parser/HTMLParserOptions.h:

(HTMLParserOptions):
(WebCore::HTMLParserOptions::HTMLParserOptions):

  • html/parser/HTMLPreloadScanner.cpp:

(WebCore::HTMLPreloadScanner::HTMLPreloadScanner):
(WebCore::HTMLPreloadScanner::processToken):

  • html/parser/HTMLTokenizer.cpp:

(WebCore::HTMLTokenizer::HTMLTokenizer):
(WebCore::HTMLTokenizer::nextToken):
(WebCore::HTMLTokenizer::updateStateFor):

  • html/parser/HTMLTokenizer.h:

(WebCore::HTMLTokenizer::create):
(HTMLTokenizer):

  • html/parser/HTMLTreeBuilder.cpp:

(WebCore::HTMLTreeBuilder::processStartTagForInBody):
(WebCore::HTMLTreeBuilder::processStartTagForInHead):

  • html/parser/HTMLTreeBuilder.h:
  • html/parser/HTMLViewSourceParser.cpp:

(WebCore::HTMLViewSourceParser::HTMLViewSourceParser):
(WebCore::HTMLViewSourceParser::updateTokenizerState):

LayoutTests:

I needed to update this test slightly because now we lock in the
"script enabled" bit for the parser when the parser starts. That means
we'll parse the document in a consistent way even if the "script
enabled" bit gets flipped later.

  • fast/parser/noscript-with-javascript-disabled-expected.txt:
  • fast/parser/noscript-with-javascript-disabled.html:
Location:
trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r139016 r139020  
     12013-01-07  Adam Barth  <abarth@webkit.org>
     2
     3        HTMLTreeBuilder should not depend on Frame
     4        https://bugs.webkit.org/show_bug.cgi?id=106256
     5
     6        Reviewed by Eric Seidel.
     7
     8        I needed to update this test slightly because now we lock in the
     9        "script enabled" bit for the parser when the parser starts. That means
     10        we'll parse the document in a consistent way even if the "script
     11        enabled" bit gets flipped later.
     12
     13        * fast/parser/noscript-with-javascript-disabled-expected.txt:
     14        * fast/parser/noscript-with-javascript-disabled.html:
     15
    1162013-01-07  Tony Chang  <tony@chromium.org>
    217
  • trunk/LayoutTests/fast/parser/noscript-with-javascript-disabled-expected.txt

    r52609 r139020  
    1 This test case verifies that contents inside <noscript> are rendered when Javascript is disabled.
    2 Succeeded!
     1The text inside the 'noscript' tag inside the iframe should render: 
     2
     3--------
     4Frame: '<!--framePath //<!--frame0-->-->'
     5--------
     6PASS: This test case verifies that contents inside are rendered when Javascript is disabled.
  • trunk/LayoutTests/fast/parser/noscript-with-javascript-disabled.html

    r124410 r139020  
    22
    33<script>
    4 if (window.testRunner)
     4if (window.testRunner) {
    55    testRunner.dumpAsText();
     6    testRunner.dumpChildFramesAsText();
    67    testRunner.overridePreference("WebKitJavaScriptEnabled", false);
     8}
    79</script>
    810
    911<noscript>
    1012<body>
    11     This test case verifies that contents inside &lt;noscript&gt; are rendered when Javascript is disabled.
     13    FAIL: This content should not render because whether scripting is enabled
     14    (for the purposes of the 'noscript' tag) is locked in when the parser starts.
     15</noscript>
    1216
    13     <p>Succeeded!</p>
    14 </noscript>
     17The text inside the 'noscript' tag inside the iframe should render:
     18
     19<iframe
     20    src="data:text/html,<noscript><body>PASS: This test case verifies that contents inside &lt;noscript&gt; are rendered when Javascript is disabled.</body></noscript>">
     21</iframe>
    1522
    1623</body>
  • trunk/Source/WebCore/ChangeLog

    r139016 r139020  
     12013-01-07  Adam Barth  <abarth@webkit.org>
     2
     3        HTMLTreeBuilder should not depend on Frame
     4        https://bugs.webkit.org/show_bug.cgi?id=106256
     5
     6        Reviewed by Eric Seidel.
     7
     8        Rather than have the tree builder ask the Frame whether scripting and
     9        plugins are enabled, we now push that information to the tree builder
     10        via HTMLParserOptions, letting us remove the Frame dependency from the
     11        tree builder.
     12
     13        As a consequence of this change, the "script enabled" bit in the parser
     14        is now locked in when the parser starts. This bit doesn't actually
     15        control when script execute, only how the <noscript> element is parsed.
     16
     17        * html/parser/HTMLDocumentParser.cpp:
     18        (WebCore::tokenizerStateForContextElement):
     19        (WebCore::HTMLDocumentParser::HTMLDocumentParser):
     20        * html/parser/HTMLMetaCharsetParser.cpp:
     21        (WebCore::HTMLMetaCharsetParser::HTMLMetaCharsetParser):
     22        (WebCore::HTMLMetaCharsetParser::checkForMetaCharset):
     23        * html/parser/HTMLParserOptions.cpp:
     24        (WebCore::HTMLParserOptions::HTMLParserOptions):
     25        * html/parser/HTMLParserOptions.h:
     26        (HTMLParserOptions):
     27        (WebCore::HTMLParserOptions::HTMLParserOptions):
     28        * html/parser/HTMLPreloadScanner.cpp:
     29        (WebCore::HTMLPreloadScanner::HTMLPreloadScanner):
     30        (WebCore::HTMLPreloadScanner::processToken):
     31        * html/parser/HTMLTokenizer.cpp:
     32        (WebCore::HTMLTokenizer::HTMLTokenizer):
     33        (WebCore::HTMLTokenizer::nextToken):
     34        (WebCore::HTMLTokenizer::updateStateFor):
     35        * html/parser/HTMLTokenizer.h:
     36        (WebCore::HTMLTokenizer::create):
     37        (HTMLTokenizer):
     38        * html/parser/HTMLTreeBuilder.cpp:
     39        (WebCore::HTMLTreeBuilder::processStartTagForInBody):
     40        (WebCore::HTMLTreeBuilder::processStartTagForInHead):
     41        * html/parser/HTMLTreeBuilder.h:
     42        * html/parser/HTMLViewSourceParser.cpp:
     43        (WebCore::HTMLViewSourceParser::HTMLViewSourceParser):
     44        (WebCore::HTMLViewSourceParser::updateTokenizerState):
     45
    1462013-01-07  Tony Chang  <tony@chromium.org>
    247
  • trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp

    r139008 r139020  
    4848// This is a direct transcription of step 4 from:
    4949// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
    50 static HTMLTokenizerState::State tokenizerStateForContextElement(Element* contextElement, bool reportErrors)
     50static HTMLTokenizerState::State tokenizerStateForContextElement(Element* contextElement, bool reportErrors, const HTMLParserOptions& options)
    5151{
    5252    if (!contextElement)
     
    6060        || contextTag.matches(xmpTag)
    6161        || contextTag.matches(iframeTag)
    62         || (contextTag.matches(noembedTag) && HTMLTreeBuilder::pluginsEnabled(contextElement->document()->frame()))
    63         || (contextTag.matches(noscriptTag) && HTMLTreeBuilder::scriptEnabled(contextElement->document()->frame()))
     62        || (contextTag.matches(noembedTag) && options.pluginsEnabled)
     63        || (contextTag.matches(noscriptTag) && options.scriptEnabled)
    6464        || contextTag.matches(noframesTag))
    6565        return reportErrors ? HTMLTokenizerState::RAWTEXTState : HTMLTokenizerState::PLAINTEXTState;
     
    7474    : ScriptableDocumentParser(document)
    7575    , m_options(document)
    76     , m_tokenizer(HTMLTokenizer::create(m_options.usePreHTML5ParserQuirks))
     76    , m_tokenizer(HTMLTokenizer::create(m_options))
    7777    , m_scriptRunner(HTMLScriptRunner::create(document, this))
    7878    , m_treeBuilder(HTMLTreeBuilder::create(this, document, reportErrors, m_options))
     
    8989    : ScriptableDocumentParser(fragment->document())
    9090    , m_options(fragment->document())
    91     , m_tokenizer(HTMLTokenizer::create(m_options.usePreHTML5ParserQuirks))
     91    , m_tokenizer(HTMLTokenizer::create(m_options))
    9292    , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, scriptingPermission, m_options))
    9393    , m_xssAuditor(this)
     
    9696{
    9797    bool reportErrors = false; // For now document fragment parsing never reports errors.
    98     m_tokenizer->setState(tokenizerStateForContextElement(contextElement, reportErrors));
     98    m_tokenizer->setState(tokenizerStateForContextElement(contextElement, reportErrors, m_options));
    9999}
    100100
  • trunk/Source/WebCore/html/parser/HTMLMetaCharsetParser.cpp

    r134116 r139020  
    2929#include "HTMLNames.h"
    3030#include "HTMLParserIdioms.h"
     31#include "HTMLParserOptions.h"
    3132#include "HTMLTokenizer.h"
    3233#include "TextCodec.h"
     
    4142
    4243HTMLMetaCharsetParser::HTMLMetaCharsetParser()
    43     : m_tokenizer(HTMLTokenizer::create(false)) // No pre-HTML5 parser quirks.
     44    : m_tokenizer(HTMLTokenizer::create(HTMLParserOptions(0)))
    4445    , m_assumedCodec(newTextCodec(Latin1Encoding()))
    4546    , m_inHeadSection(true)
     
    180181            AtomicString tagName(m_token.name().data(), m_token.name().size());
    181182            if (!end) {
    182                 m_tokenizer->updateStateFor(tagName, 0);
     183                m_tokenizer->updateStateFor(tagName);
    183184                if (tagName == metaTag && processMeta()) {
    184185                    m_doneChecking = true;
  • trunk/Source/WebCore/html/parser/HTMLParserOptions.cpp

    r139008 r139020  
    2828
    2929#include "Document.h"
     30#include "Frame.h"
    3031#include "Settings.h"
    3132
     
    3435HTMLParserOptions::HTMLParserOptions(Document* document)
    3536{
    36     ASSERT(document);
    37     Settings* settings = document->settings();
     37    Frame* frame = document ? document->frame() : 0;
     38    scriptEnabled = frame && frame->script()->canExecuteScripts(NotAboutToExecuteScript);
     39    pluginsEnabled = frame && frame->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin);
     40
     41    Settings* settings = document ? document->settings() : 0;
    3842    usePreHTML5ParserQuirks = settings && settings->usePreHTML5ParserQuirks();
    3943    maximumDOMTreeDepth = settings ? settings->maximumHTMLParserDOMTreeDepth() : Settings::defaultMaximumHTMLParserDOMTreeDepth;
  • trunk/Source/WebCore/html/parser/HTMLParserOptions.h

    r139008 r139020  
    3333class HTMLParserOptions {
    3434public:
     35    bool scriptEnabled;
     36    bool pluginsEnabled;
    3537    bool usePreHTML5ParserQuirks;
    3638    unsigned maximumDOMTreeDepth;
    37 
    38     HTMLParserOptions()
    39         : usePreHTML5ParserQuirks(false)
    40         , maximumDOMTreeDepth(0)
    41     {
    42     }
    4339
    4440    explicit HTMLParserOptions(Document*);
  • trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp

    r139008 r139020  
    166166    : m_document(document)
    167167    , m_cssScanner(document)
    168     , m_tokenizer(HTMLTokenizer::create(options.usePreHTML5ParserQuirks))
     168    , m_tokenizer(HTMLTokenizer::create(options))
    169169    , m_inStyle(false)
    170170{
     
    204204
    205205    PreloadTask task(m_token);
    206     m_tokenizer->updateStateFor(task.tagName(), m_document->frame());
     206    m_tokenizer->updateStateFor(task.tagName());
    207207
    208208    if (task.tagName() == styleTag)
  • trunk/Source/WebCore/html/parser/HTMLTokenizer.cpp

    r138227 r139020  
    108108#define HTML_SWITCH_TO(stateName) SWITCH_TO(HTMLTokenizerState, stateName)
    109109
    110 HTMLTokenizer::HTMLTokenizer(bool usePreHTML5ParserQuirks)
    111     : m_usePreHTML5ParserQuirks(usePreHTML5ParserQuirks)
     110HTMLTokenizer::HTMLTokenizer(const HTMLParserOptions& options)
     111    : m_options(options)
    112112{
    113113    reset();
     
    344344        else if (cc == '>')
    345345            return emitAndResumeIn(source, HTMLTokenizerState::DataState);
    346         else if (m_usePreHTML5ParserQuirks && cc == '<')
     346        else if (m_options.usePreHTML5ParserQuirks && cc == '<')
    347347            return emitAndReconsumeIn(source, HTMLTokenizerState::DataState);
    348348        else if (isASCIIUpper(cc)) {
     
    815815        else if (cc == '>')
    816816            return emitAndResumeIn(source, HTMLTokenizerState::DataState);
    817         else if (m_usePreHTML5ParserQuirks && cc == '<')
     817        else if (m_options.usePreHTML5ParserQuirks && cc == '<')
    818818            return emitAndReconsumeIn(source, HTMLTokenizerState::DataState);
    819819        else if (isASCIIUpper(cc)) {
     
    849849            m_token->endAttributeName(source.numberOfCharactersConsumed());
    850850            return emitAndResumeIn(source, HTMLTokenizerState::DataState);
    851         } else if (m_usePreHTML5ParserQuirks && cc == '<') {
     851        } else if (m_options.usePreHTML5ParserQuirks && cc == '<') {
    852852            m_token->endAttributeName(source.numberOfCharactersConsumed());
    853853            return emitAndReconsumeIn(source, HTMLTokenizerState::DataState);
     
    877877        else if (cc == '>')
    878878            return emitAndResumeIn(source, HTMLTokenizerState::DataState);
    879         else if (m_usePreHTML5ParserQuirks && cc == '<')
     879        else if (m_options.usePreHTML5ParserQuirks && cc == '<')
    880880            return emitAndReconsumeIn(source, HTMLTokenizerState::DataState);
    881881        else if (isASCIIUpper(cc)) {
     
    10201020        else if (cc == '>')
    10211021            return emitAndResumeIn(source, HTMLTokenizerState::DataState);
    1022         else if (m_usePreHTML5ParserQuirks && cc == '<')
     1022        else if (m_options.usePreHTML5ParserQuirks && cc == '<')
    10231023            return emitAndReconsumeIn(source, HTMLTokenizerState::DataState);
    10241024        else if (cc == InputStreamPreprocessor::endOfFileMarker) {
     
    15901590}
    15911591
    1592 void HTMLTokenizer::updateStateFor(const AtomicString& tagName, Frame* frame)
     1592void HTMLTokenizer::updateStateFor(const AtomicString& tagName)
    15931593{
    15941594    if (tagName == textareaTag || tagName == titleTag)
     
    16011601        || tagName == iframeTag
    16021602        || tagName == xmpTag
    1603         || (tagName == noembedTag && HTMLTreeBuilder::pluginsEnabled(frame))
     1603        || (tagName == noembedTag && m_options.pluginsEnabled)
    16041604        || tagName == noframesTag
    1605         || (tagName == noscriptTag && HTMLTreeBuilder::scriptEnabled(frame)))
     1605        || (tagName == noscriptTag && m_options.scriptEnabled))
    16061606        setState(HTMLTokenizerState::RAWTEXTState);
    16071607}
  • trunk/Source/WebCore/html/parser/HTMLTokenizer.h

    r132165 r139020  
    2828#define HTMLTokenizer_h
    2929
     30#include "HTMLParserOptions.h"
    3031#include "HTMLToken.h"
    3132#include "MarkupTokenizerBase.h"
     
    3334
    3435namespace WebCore {
    35 
    36 class Frame;
    3736
    3837class HTMLTokenizerState {
     
    121120    WTF_MAKE_FAST_ALLOCATED;
    122121public:
    123     static PassOwnPtr<HTMLTokenizer> create(bool usePreHTML5ParserQuirks) { return adoptPtr(new HTMLTokenizer(usePreHTML5ParserQuirks)); }
     122    static PassOwnPtr<HTMLTokenizer> create(const HTMLParserOptions& options) { return adoptPtr(new HTMLTokenizer(options)); }
    124123    ~HTMLTokenizer();
    125124
     
    158157    //    instead of as character tokens.
    159158    //
    160     void updateStateFor(const AtomicString& tagName, Frame*);
     159    void updateStateFor(const AtomicString& tagName);
    161160
    162161    bool forceNullCharacterReplacement() const { return m_forceNullCharacterReplacement; }
     
    167166
    168167private:
    169     explicit HTMLTokenizer(bool usePreHTML5ParserQuirks);
     168    explicit HTMLTokenizer(const HTMLParserOptions&);
    170169
    171170    inline bool processEntity(SegmentedString&);
     
    217216    Vector<LChar, 32> m_bufferedEndTagName;
    218217
    219     bool m_usePreHTML5ParserQuirks;
     218    HTMLParserOptions m_options;
    220219};
    221220
  • trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp

    r139008 r139020  
    3232#include "DocumentFragment.h"
    3333#include "DocumentType.h"
    34 #include "Frame.h"
    3534#include "HTMLDocument.h"
    3635#include "HTMLDocumentParser.h"
     
    895894        return;
    896895    }
    897     if (token->name() == noembedTag && pluginsEnabled(m_document->frame())) {
     896    if (token->name() == noembedTag && m_options.pluginsEnabled) {
    898897        processGenericRawTextStartTag(token);
    899898        return;
    900899    }
    901     if (token->name() == noscriptTag && scriptEnabled(m_document->frame())) {
     900    if (token->name() == noscriptTag && m_options.scriptEnabled) {
    902901        processGenericRawTextStartTag(token);
    903902        return;
     
    26912690    }
    26922691    if (token->name() == noscriptTag) {
    2693         if (scriptEnabled(m_document->frame())) {
     2692        if (m_options.scriptEnabled) {
    26942693            processGenericRawTextStartTag(token);
    26952694            return true;
     
    29142913}
    29152914
    2916 bool HTMLTreeBuilder::scriptEnabled(Frame* frame)
    2917 {
    2918     if (!frame)
    2919         return false;
    2920     return frame->script()->canExecuteScripts(NotAboutToExecuteScript);
    2921 }
    2922 
    2923 bool HTMLTreeBuilder::pluginsEnabled(Frame* frame)
    2924 {
    2925     if (!frame)
    2926         return false;
    2927     return frame->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin);
    2928 }
    2929 
    2930 }
     2915}
  • trunk/Source/WebCore/html/parser/HTMLTreeBuilder.h

    r139008 r139020  
    9191
    9292    void setShouldSkipLeadingNewline(bool shouldSkip) { m_shouldSkipLeadingNewline = shouldSkip; }
    93 
    94     static bool scriptEnabled(Frame*);
    95     static bool pluginsEnabled(Frame*);
    9693
    9794private:
  • trunk/Source/WebCore/html/parser/HTMLViewSourceParser.cpp

    r139008 r139020  
    3636HTMLViewSourceParser::HTMLViewSourceParser(HTMLViewSourceDocument* document)
    3737    : DecodedDataDocumentParser(document)
    38     , m_tokenizer(HTMLTokenizer::create(HTMLParserOptions(document).usePreHTML5ParserQuirks))
     38    , m_tokenizer(HTMLTokenizer::create(HTMLParserOptions(document)))
    3939{
    4040}
     
    8181
    8282    AtomicString tagName(m_token.name().data(), m_token.name().size());
    83     m_tokenizer->updateStateFor(tagName, document()->frame());
     83    m_tokenizer->updateStateFor(tagName);
    8484}
    8585
Note: See TracChangeset for help on using the changeset viewer.