SourceHighlighter.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
  3. * Copyright (c) 2024, Sam Atkins <sam@ladybird.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/String.h>
  9. #include <AK/StringView.h>
  10. #include <LibSyntax/Document.h>
  11. #include <LibSyntax/HighlighterClient.h>
  12. #include <LibSyntax/Language.h>
  13. namespace WebView {
  14. class SourceDocument final : public Syntax::Document {
  15. public:
  16. static NonnullRefPtr<SourceDocument> create(StringView source)
  17. {
  18. return adopt_ref(*new (nothrow) SourceDocument(source));
  19. }
  20. virtual ~SourceDocument() = default;
  21. StringView text() const { return m_source; }
  22. size_t line_count() const { return m_lines.size(); }
  23. // ^ Syntax::Document
  24. virtual Syntax::TextDocumentLine const& line(size_t line_index) const override;
  25. virtual Syntax::TextDocumentLine& line(size_t line_index) override;
  26. private:
  27. SourceDocument(StringView source);
  28. // ^ Syntax::Document
  29. virtual void update_views(Badge<Syntax::TextDocumentLine>) override { }
  30. StringView m_source;
  31. Vector<Syntax::TextDocumentLine> m_lines;
  32. };
  33. class SourceHighlighterClient final : public Syntax::HighlighterClient {
  34. public:
  35. SourceHighlighterClient(StringView source, Syntax::Language);
  36. virtual ~SourceHighlighterClient() = default;
  37. String to_html_string(URL::URL const&) const;
  38. private:
  39. // ^ Syntax::HighlighterClient
  40. virtual Vector<Syntax::TextDocumentSpan> const& spans() const override;
  41. virtual void set_span_at_index(size_t index, Syntax::TextDocumentSpan span) override;
  42. virtual Vector<Syntax::TextDocumentFoldingRegion>& folding_regions() override;
  43. virtual Vector<Syntax::TextDocumentFoldingRegion> const& folding_regions() const override;
  44. virtual ByteString highlighter_did_request_text() const override;
  45. virtual void highlighter_did_request_update() override;
  46. virtual Syntax::Document& highlighter_did_request_document() override;
  47. virtual Syntax::TextPosition highlighter_did_request_cursor() const override;
  48. virtual void highlighter_did_set_spans(Vector<Syntax::TextDocumentSpan>) override;
  49. virtual void highlighter_did_set_folding_regions(Vector<Syntax::TextDocumentFoldingRegion>) override;
  50. StringView class_for_token(u64 token_type) const;
  51. SourceDocument& document() const { return *m_document; }
  52. NonnullRefPtr<SourceDocument> m_document;
  53. OwnPtr<Syntax::Highlighter> m_highlighter;
  54. };
  55. String highlight_source(URL::URL const&, StringView);
  56. constexpr inline StringView HTML_HIGHLIGHTER_STYLE = R"~~~(
  57. @media (prefers-color-scheme: dark) {
  58. /* FIXME: We should be able to remove the HTML style when "color-scheme" is supported */
  59. html {
  60. background-color: rgb(30, 30, 30);
  61. color: white;
  62. }
  63. :root {
  64. --comment-color: lightgreen;
  65. --keyword-color: orangered;
  66. --name-color: orange;
  67. --value-color: deepskyblue;
  68. --internal-color: darkgrey;
  69. }
  70. }
  71. @media (prefers-color-scheme: light) {
  72. :root {
  73. --comment-color: green;
  74. --keyword-color: red;
  75. --name-color: darkorange;
  76. --value-color: blue;
  77. --internal-color: dimgrey;
  78. }
  79. }
  80. .html {
  81. font-size: 10pt;
  82. font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  83. }
  84. .tag {
  85. font-weight: 600;
  86. color: var(--keyword-color);
  87. }
  88. .comment {
  89. color: var(--comment-color);
  90. }
  91. .attribute-name {
  92. color: var(--name-color);
  93. }
  94. .attribute-value {
  95. color: var(--value-color);
  96. }
  97. .internal {
  98. color: var(--internal-color);
  99. }
  100. )~~~"sv;
  101. }