chromium/third_party/blink/renderer/core/html/parser/html_document_parser.cc

/*
 * 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.
 */

#include "third_party/blink/renderer/core/html/parser/html_document_parser.h"

#include <memory>
#include <utility>

#include "base/feature_list.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_functions.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/strcat.h"
#include "base/synchronization/lock.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/types/optional_util.h"
#include "components/miracle_parameter/common/public/miracle_parameter.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/loader/loading_behavior_flag.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/css/media_values_cached.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/dom/document_fragment.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/execution_context/agent.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/html_meta_element.h"
#include "third_party/blink/renderer/core/html/html_template_element.h"
#include "third_party/blink/renderer/core/html/nesting_level_incrementer.h"
#include "third_party/blink/renderer/core/html/parser/atomic_html_token.h"
#include "third_party/blink/renderer/core/html/parser/background_html_scanner.h"
#include "third_party/blink/renderer/core/html/parser/html_element_stack.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_metrics.h"
#include "third_party/blink/renderer/core/html/parser/html_preload_scanner.h"
#include "third_party/blink/renderer/core/html/parser/html_resource_preloader.h"
#include "third_party/blink/renderer/core/html/parser/html_tree_builder.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/loader/prefetched_signed_exchange_manager.h"
#include "third_party/blink/renderer/core/loader/preload_helper.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/script/html_parser_script_runner.h"
#include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
#include "third_party/blink/renderer/platform/heap/cross_thread_handle.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
#include "third_party/blink/renderer/platform/scheduler/public/non_main_thread.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_base.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
#include "third_party/blink/renderer/platform/wtf/wtf.h"

namespace blink {

// This sets the (default) maximum number of tokens which the foreground HTML
// parser should try to process in one go. Lower values generally mean faster
// first paints, larger values delay first paint, but make sure it's closer to
// the final page. This is the default value to use, if no Finch-provided
// value exists.
constexpr int kDefaultMaxTokenizationBudget =;
constexpr int kInfiniteTokenizationBudget =;
constexpr int kNumYieldsWithDefaultBudget =;

class EndIfDelayedForbiddenScope;
class ShouldCompleteScope;
class AttemptToEndForbiddenScope;

enum class FeatureResetMode {};

const char kHistogramScanAndPreloadTime[] =;

bool ThreadedPreloadScannerEnabled(
    FeatureResetMode reset_mode = FeatureResetMode::kUseCached) {}

bool TimedParserBudgetEnabled() {}

bool CheckParserBudgetLessOften() {}

bool PrecompileInlineScriptsEnabled(
    FeatureResetMode reset_mode = FeatureResetMode::kUseCached) {}

NonMainThread* GetPreloadScannerThread() {}

PreloadProcessingMode GetPreloadProcessingMode() {}

bool BackgroundScanMainFrameOnly() {}

bool IsPreloadScanningEnabled(Document* document) {}

MIRACLE_PARAMETER_FOR_TIME_DELTA(GetDefaultParserBudget,
                                 features::kTimedHTMLParserBudget,
                                 "default-parser-budget",
                                 base::Milliseconds(10))

// These constants were chosen using experiment data from the field to
// optimize Core Web Vitals metrics: https://web.dev/vitals/#core-web-vitals
// Experiments were run on both Android and desktop to determine the values
// that gave the best aggregate CWV pass rate.
constexpr int kNumYieldsWithDefaultBudgetDefaultValue =2
#else
    6
#endif
    ;

MIRACLE_PARAMETER_FOR_INT(GetNumYieldsWithDefaultBudget,
                          features::kTimedHTMLParserBudget,
                          "num-yields-with-default-budget",
                          kNumYieldsWithDefaultBudgetDefaultValue)

// These constants were chosen using experiment data from the field to
// optimize Core Web Vitals metrics: https://web.dev/vitals/#core-web-vitals
// Experiments were run on both Android and desktop to determine the values
// that gave the best aggregate CWV pass rate.
constexpr base::TimeDelta kLongParserBudgetDefaultValue =base::Milliseconds(50)
#else
    base::Milliseconds(500)
#endif
    ;

MIRACLE_PARAMETER_FOR_TIME_DELTA(GetLongParserBudget,
                                 features::kTimedHTMLParserBudget,
                                 "long-parser-budget",
                                 kLongParserBudgetDefaultValue)

base::TimeDelta GetDefaultTimedBudget() {}

base::TimeDelta GetTimedBudget(int times_yielded) {}

class EndIfDelayedForbiddenScope {};

class AttemptToEndForbiddenScope {};

class ShouldCompleteScope {};

// This is a direct transcription of step 4 from:
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
static HTMLTokenizer::State TokenizerStateForContextElement(
    Element* context_element,
    bool report_errors,
    const HTMLParserOptions& options) {}

HTMLDocumentParserState::HTMLDocumentParserState(
    ParserSynchronizationPolicy mode,
    int budget)
    :{}

// Wrap pending preloads in a thread safe and ref-counted object since the
// vector is added to from a background thread and taken from from the main
// thread.
class HTMLDocumentParser::PendingPreloads
    : public ThreadSafeRefCounted<PendingPreloads> {};

HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document,
                                       ParserSynchronizationPolicy sync_policy,
                                       ParserPrefetchPolicy prefetch_policy)
    :{}

HTMLDocumentParser::HTMLDocumentParser(
    DocumentFragment* fragment,
    Element* context_element,
    ParserContentPolicy parser_content_policy,
    ParserPrefetchPolicy parser_prefetch_policy)
    :{}

HTMLDocumentParser::HTMLDocumentParser(Document& document,
                                       ParserContentPolicy content_policy,
                                       ParserSynchronizationPolicy sync_policy,
                                       ParserPrefetchPolicy prefetch_policy)
    :{}

HTMLDocumentParser::~HTMLDocumentParser() {}

void HTMLDocumentParser::Trace(Visitor* visitor) const {}

bool HTMLDocumentParser::HasPendingWorkScheduledForTesting() const {}

unsigned HTMLDocumentParser::GetChunkCountForTesting() const {}

void HTMLDocumentParser::Detach() {}

void HTMLDocumentParser::StopParsing() {}

// This kicks off "Once the user agent stops parsing" as described by:
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the-end
void HTMLDocumentParser::PrepareToStopParsing() {}

bool HTMLDocumentParser::IsParsingFragment() const {}

void HTMLDocumentParser::DeferredPumpTokenizerIfPossible(
    bool from_finish_append,
    base::TimeTicks schedule_time) {}

void HTMLDocumentParser::PumpTokenizerIfPossible() {}

void HTMLDocumentParser::RunScriptsForPausedTreeBuilder() {}

void HTMLDocumentParser::ForcePlaintextForTextDocument() {}

bool HTMLDocumentParser::PumpTokenizer() {}

void HTMLDocumentParser::SchedulePumpTokenizer(bool from_finish_append) {}

void HTMLDocumentParser::ScheduleEndIfDelayed() {}

void HTMLDocumentParser::ConstructTreeFromToken(AtomicHTMLToken& atomic_token) {}

bool HTMLDocumentParser::HasInsertionPoint() {}

void HTMLDocumentParser::insert(const String& source) {}

void HTMLDocumentParser::Append(const String& input_source) {}

void HTMLDocumentParser::FinishAppend() {}

void HTMLDocumentParser::CommitPreloadedData() {}

void HTMLDocumentParser::end() {}

void HTMLDocumentParser::AttemptToRunDeferredScriptsAndEnd() {}

bool HTMLDocumentParser::ShouldDelayEnd() const {}

void HTMLDocumentParser::AttemptToEnd() {}

void HTMLDocumentParser::EndIfDelayed() {}

void HTMLDocumentParser::Finish() {}

bool HTMLDocumentParser::IsExecutingScript() const {}

OrdinalNumber HTMLDocumentParser::LineNumber() const {}

TextPosition HTMLDocumentParser::GetTextPosition() const {}

bool HTMLDocumentParser::IsWaitingForScripts() const {}

void HTMLDocumentParser::ResumeParsingAfterPause() {}

void HTMLDocumentParser::AppendCurrentInputStreamToPreloadScannerAndScan() {}

void HTMLDocumentParser::NotifyScriptLoaded() {}

// static
void HTMLDocumentParser::ResetCachedFeaturesForTesting() {}

// static
void HTMLDocumentParser::FlushPreloadScannerThreadForTesting() {}

void HTMLDocumentParser::ExecuteScriptsWaitingForResources() {}

void HTMLDocumentParser::DidAddPendingParserBlockingStylesheet() {}

void HTMLDocumentParser::DidLoadAllPendingParserBlockingStylesheets() {}

void HTMLDocumentParser::CheckIfBlockingStylesheetAdded() {}

void HTMLDocumentParser::ParseDocumentFragment(
    const String& source,
    DocumentFragment* fragment,
    Element* context_element,
    ParserContentPolicy parser_content_policy) {}

void HTMLDocumentParser::AppendBytes(base::span<const uint8_t> data) {}

void HTMLDocumentParser::Flush() {}

void HTMLDocumentParser::SetDecoder(
    std::unique_ptr<TextResourceDecoder> decoder) {}

void HTMLDocumentParser::DocumentElementAvailable() {}

std::unique_ptr<HTMLPreloadScanner> HTMLDocumentParser::CreatePreloadScanner(
    TokenPreloadScanner::ScannerType scanner_type) {}

void HTMLDocumentParser::ScanAndPreload(HTMLPreloadScanner* scanner) {}

void HTMLDocumentParser::ProcessPreloadData(
    std::unique_ptr<PendingPreloadData> preload_data) {}

void HTMLDocumentParser::FetchQueuedPreloads() {}

std::string HTMLDocumentParser::GetPreloadHistogramSuffix() {}

DocumentParser::BackgroundScanCallback
HTMLDocumentParser::TakeBackgroundScanCallback() {}

void HTMLDocumentParser::ScanInBackground(const String& source) {}

// static
void HTMLDocumentParser::AddPreloadDataOnBackgroundThread(
    CrossThreadWeakHandle<HTMLDocumentParser> parser_handle,
    scoped_refptr<PendingPreloads> pending_preloads,
    scoped_refptr<base::SequencedTaskRunner> task_runner,
    std::unique_ptr<PendingPreloadData> preload_data) {}

bool HTMLDocumentParser::HasPendingPreloads() {}

void HTMLDocumentParser::FlushPendingPreloads() {}

bool HTMLDocumentParser::ShouldPumpTokenizerNowForFinishAppend() const {}

ALWAYS_INLINE bool HTMLDocumentParser::ShouldCheckTimeBudget(
    NextTokenStatus next_token_status,
    html_names::HTMLTag tag,
    int newly_consumed_characters,
    int tokens_parsed) const {}

}  // namespace blink