flutter_flutter/engine/core/html/parser/HTMLDocumentParser.h
Eric Seidel c78cea7e54 Allow multiple dart <script> tags in .sky files
This does several things:
1.  Teaches sky about asynchronous script execution. Previously once all imports
were loaded and the script text was available, we executed a script and assumed
it completed synchronously.  We left the parser loop to do so, but that was fine
as the next chunk from the background thread would resume the parser.  In this
change scripts now load and execute separately.  The "load" step may trigger
further dart import loads which may cause the execution to happen asynchronously
which required teaching both the DartController and the HTMLScriptRunner to
take callbacks to allow HTMLDocumentParser to know to continue parsing after
the Dart script has resolved its imports and executed.

This required re-working some of how the parser executes scripts and I
re-purposed isWaitingForScripts to include "is the parser blocked" where
as before it was limited only to "does the treebuilder have a script", even
though the imports system may have had pending scripts as well.

I made HTMLScriptRunner live only as long as the script it was executing
since it only contained per-script state at this point.

2.  Fixed an error reporting bug whereby we would not show errors when "init"
failed to execute, only "main".  This required using the dart_mirrors_api.h
which required adding an include path to the core build. :(

3.  Made it possible for a single sky file to contain multiple dart <script>
tags.  Each <script> is a separate library and executes as
soon as </script> is seen.  main or init is called for each.  This required
mangling "urls" for these script blocks since Dart unique's libraries by urls.
Before this change it may have been possible to do <import 'foo.sky'> and then
<script>import 'foo.sky'</script> and have it work!?

R=abarth@chromium.org
BUG=

Review URL: https://codereview.chromium.org/938623005
2015-02-20 11:08:28 -08:00

140 lines
4.9 KiB
C++

/*
* Copyright (C) 2010 Google, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SKY_ENGINE_CORE_HTML_PARSER_HTMLDOCUMENTPARSER_H_
#define SKY_ENGINE_CORE_HTML_PARSER_HTMLDOCUMENTPARSER_H_
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "sky/engine/core/dom/DocumentParser.h"
#include "sky/engine/core/fetch/ResourceClient.h"
#include "sky/engine/core/html/parser/CompactHTMLToken.h"
#include "sky/engine/core/html/parser/HTMLInputStream.h"
#include "sky/engine/core/html/parser/HTMLScriptRunner.h"
#include "sky/engine/core/html/parser/HTMLToken.h"
#include "sky/engine/core/html/parser/HTMLTokenizer.h"
#include "sky/engine/core/html/parser/TextResourceDecoder.h"
#include "sky/engine/platform/text/SegmentedString.h"
#include "sky/engine/wtf/Deque.h"
#include "sky/engine/wtf/OwnPtr.h"
#include "sky/engine/wtf/WeakPtr.h"
#include "sky/engine/wtf/text/TextPosition.h"
namespace blink {
class BackgroundHTMLParser;
class CompactHTMLToken;
class Document;
class Element;
class HTMLParserScheduler;
class HTMLTreeBuilder;
class ScriptSourceCode;
class PumpSession;
class HTMLDocumentParser : public DocumentParser, public HTMLScriptRunnerHost {
WTF_MAKE_FAST_ALLOCATED;
public:
static PassRefPtr<HTMLDocumentParser> create(Document& document, bool reportErrors)
{
return adoptRef(new HTMLDocumentParser(document, reportErrors));
}
virtual ~HTMLDocumentParser();
void parse(mojo::ScopedDataPipeConsumerHandle,
const base::Closure& completionCallback) override;
// Exposed for HTMLParserScheduler
void resumeParsingAfterYield();
TextPosition textPosition() const;
OrdinalNumber lineNumber() const;
struct ParsedChunk {
OwnPtr<CompactHTMLTokenStream> tokens;
};
void didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<ParsedChunk>);
// From DocumentParser:
void detach() override final;
void prepareToStopParsing() override final;
void stopParsing() override final;
bool isWaitingForScripts() const override final;
bool isExecutingScript() const override final;
void resumeAfterWaitingForImports() override final;
// From HTMLScriptRunnerHost:
void scriptExecutionCompleted();
private:
HTMLDocumentParser(Document&, bool reportErrors);
HTMLTreeBuilder* treeBuilder() const { return m_treeBuilder.get(); }
bool hasInsertionPoint();
void stopBackgroundParser();
void processParsedChunkFromBackgroundParser(PassOwnPtr<ParsedChunk>);
void pumpPendingChunks();
Document* contextForParsingSession();
void constructTreeFromHTMLToken(HTMLToken&);
void constructTreeFromCompactHTMLToken(const CompactHTMLToken&);
void runScriptsForPausedTreeBuilder();
void attemptToEnd();
void endIfDelayed();
void end();
bool isParsingFragment() const;
bool isScheduledForResume() const;
bool inPumpSession() const { return m_pumpSessionNestingLevel > 0; }
bool shouldDelayEnd() const { return inPumpSession() || isWaitingForScripts() || isScheduledForResume() || isExecutingScript(); }
OwnPtr<HTMLTreeBuilder> m_treeBuilder;
OwnPtr<HTMLParserScheduler> m_parserScheduler;
TextPosition m_textPosition;
OwnPtr<HTMLScriptRunner> m_scriptRunner;
OwnPtr<ParsedChunk> m_lastChunkBeforeScript;
Deque<OwnPtr<ParsedChunk> > m_pendingChunks;
base::WeakPtrFactory<HTMLDocumentParser> m_weakFactory;
base::WeakPtr<BackgroundHTMLParser> m_backgroundParser;
base::Closure m_completionCallback;
bool m_isFragment;
bool m_endWasDelayed;
bool m_haveBackgroundParser;
unsigned m_pumpSessionNestingLevel;
};
}
#endif // SKY_ENGINE_CORE_HTML_PARSER_HTMLDOCUMENTPARSER_H_