mirror of
				https://github.com/LadybirdBrowser/ladybird.git
				synced 2025-11-03 23:00:58 +00:00 
			
		
		
		
	This first pass only applies to the following two cases: - Public functions returning a view type into an object they own - Public ctors storing a view type This catches a grand total of one (1) issue, which is fixed in the previous commit.
		
			
				
	
	
		
			165 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			165 lines
		
	
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
 | 
						|
 * Copyright (c) 2024, Sam Atkins <sam@ladybird.org>
 | 
						|
 *
 | 
						|
 * SPDX-License-Identifier: BSD-2-Clause
 | 
						|
 */
 | 
						|
 | 
						|
#pragma once
 | 
						|
 | 
						|
#include <AK/OwnPtr.h>
 | 
						|
#include <AK/String.h>
 | 
						|
#include <AK/StringView.h>
 | 
						|
#include <LibSyntax/Document.h>
 | 
						|
#include <LibSyntax/HighlighterClient.h>
 | 
						|
#include <LibSyntax/Language.h>
 | 
						|
#include <LibURL/Forward.h>
 | 
						|
#include <LibWebView/Forward.h>
 | 
						|
 | 
						|
namespace WebView {
 | 
						|
 | 
						|
enum class HighlightOutputMode {
 | 
						|
    FullDocument, // Include HTML header, title, style sheet, etc
 | 
						|
    SourceOnly,   // Just the highlighted source
 | 
						|
};
 | 
						|
 | 
						|
class WEBVIEW_API SourceDocument final : public Syntax::Document {
 | 
						|
public:
 | 
						|
    static NonnullRefPtr<SourceDocument> create(String const& source)
 | 
						|
    {
 | 
						|
        return adopt_ref(*new (nothrow) SourceDocument(source));
 | 
						|
    }
 | 
						|
    virtual ~SourceDocument() = default;
 | 
						|
 | 
						|
    StringView text() const LIFETIME_BOUND { return m_source; }
 | 
						|
    size_t line_count() const { return m_lines.size(); }
 | 
						|
 | 
						|
    // ^ Syntax::Document
 | 
						|
    virtual Syntax::TextDocumentLine const& line(size_t line_index) const override;
 | 
						|
    virtual Syntax::TextDocumentLine& line(size_t line_index) override;
 | 
						|
 | 
						|
private:
 | 
						|
    SourceDocument(String const& source);
 | 
						|
 | 
						|
    // ^ Syntax::Document
 | 
						|
    virtual void update_views(Badge<Syntax::TextDocumentLine>) override { }
 | 
						|
 | 
						|
    String m_source;
 | 
						|
    Vector<Syntax::TextDocumentLine> m_lines;
 | 
						|
};
 | 
						|
 | 
						|
class WEBVIEW_API SourceHighlighterClient final : public Syntax::HighlighterClient {
 | 
						|
public:
 | 
						|
    SourceHighlighterClient(String const& source, Syntax::Language);
 | 
						|
    virtual ~SourceHighlighterClient() = default;
 | 
						|
 | 
						|
    String to_html_string(Optional<URL::URL> const&, URL::URL const& base_url, HighlightOutputMode) const;
 | 
						|
 | 
						|
private:
 | 
						|
    // ^ Syntax::HighlighterClient
 | 
						|
    virtual Vector<Syntax::TextDocumentSpan> const& spans() const override;
 | 
						|
    virtual void set_span_at_index(size_t index, Syntax::TextDocumentSpan span) override;
 | 
						|
    virtual Vector<Syntax::TextDocumentFoldingRegion>& folding_regions() override;
 | 
						|
    virtual Vector<Syntax::TextDocumentFoldingRegion> const& folding_regions() const override;
 | 
						|
    virtual ByteString highlighter_did_request_text() const override;
 | 
						|
    virtual void highlighter_did_request_update() override;
 | 
						|
    virtual Syntax::Document& highlighter_did_request_document() override;
 | 
						|
    virtual Syntax::TextPosition highlighter_did_request_cursor() const override;
 | 
						|
    virtual void highlighter_did_set_spans(Vector<Syntax::TextDocumentSpan>) override;
 | 
						|
    virtual void highlighter_did_set_folding_regions(Vector<Syntax::TextDocumentFoldingRegion>) override;
 | 
						|
 | 
						|
    StringView class_for_token(u64 token_type) const;
 | 
						|
 | 
						|
    SourceDocument& document() const { return *m_document; }
 | 
						|
 | 
						|
    NonnullRefPtr<SourceDocument> m_document;
 | 
						|
    OwnPtr<Syntax::Highlighter> m_highlighter;
 | 
						|
};
 | 
						|
 | 
						|
WEBVIEW_API String highlight_source(Optional<URL::URL> const&, URL::URL const& base_url, String const& source, Syntax::Language, HighlightOutputMode);
 | 
						|
 | 
						|
constexpr inline StringView HTML_HIGHLIGHTER_STYLE = R"~~~(
 | 
						|
    @media (prefers-color-scheme: dark) {
 | 
						|
        :root {
 | 
						|
            --comment-color: lightgreen;
 | 
						|
            --keyword-color: orangered;
 | 
						|
            --name-color: orange;
 | 
						|
            --value-color: deepskyblue;
 | 
						|
            --internal-color: darkgrey;
 | 
						|
            --string-color: goldenrod;
 | 
						|
            --error-color: red;
 | 
						|
            --line-number-color: darkgrey;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    @media (prefers-color-scheme: light) {
 | 
						|
        :root {
 | 
						|
            --comment-color: green;
 | 
						|
            --keyword-color: red;
 | 
						|
            --name-color: darkorange;
 | 
						|
            --value-color: blue;
 | 
						|
            --internal-color: dimgrey;
 | 
						|
            --string-color: darkgoldenrod;
 | 
						|
            --error-color: darkred;
 | 
						|
            --line-number-color: dimgrey;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    html {
 | 
						|
        color-scheme: light dark;
 | 
						|
    }
 | 
						|
 | 
						|
    .html {
 | 
						|
        font-size: 10pt;
 | 
						|
        font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
 | 
						|
    }
 | 
						|
 | 
						|
    .line {
 | 
						|
        counter-increment: line;
 | 
						|
        white-space: pre;
 | 
						|
    }
 | 
						|
 | 
						|
    .line::before {
 | 
						|
        content: counter(line) " ";
 | 
						|
 | 
						|
        display: inline-block;
 | 
						|
        width: 2.5em;
 | 
						|
 | 
						|
        padding-right: 0.5em;
 | 
						|
        text-align: right;
 | 
						|
 | 
						|
        color: var(--line-number-color);
 | 
						|
    }
 | 
						|
 | 
						|
    .tag {
 | 
						|
        font-weight: 600;
 | 
						|
        color: var(--keyword-color);
 | 
						|
    }
 | 
						|
    .comment {
 | 
						|
        color: var(--comment-color);
 | 
						|
    }
 | 
						|
    .attribute-name {
 | 
						|
        color: var(--name-color);
 | 
						|
    }
 | 
						|
    .attribute-value {
 | 
						|
        color: var(--value-color);
 | 
						|
    }
 | 
						|
    .internal {
 | 
						|
        color: var(--internal-color);
 | 
						|
    }
 | 
						|
    .invalid {
 | 
						|
        color: var(--error-color);
 | 
						|
        text-decoration: currentColor wavy underline;
 | 
						|
    }
 | 
						|
    .at-keyword, .function, .keyword, .control-keyword, .url {
 | 
						|
        color: var(--keyword-color);
 | 
						|
    }
 | 
						|
    .number, .hash {
 | 
						|
        color: var(--value-color);
 | 
						|
    }
 | 
						|
    .string {
 | 
						|
        color: var(--string-color);
 | 
						|
    }
 | 
						|
)~~~"sv;
 | 
						|
 | 
						|
}
 |