Radish alpha
r
rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5
Radicle web interface
Radicle
Git
Add InlineTitle component
Sebastian Martinez committed 1 year ago
commit 4b579d13a917b37b9a586f914e046f0953163f6a
parent beaf6ad
14 files changed +67 -47
modified src/components/InlineMarkdown.svelte
@@ -7,16 +7,13 @@
  import { Renderer } from "@app/lib/markdown";

  export let content: string;
-
  export let stripEmphasizedStyling: boolean = false;
  export let fontSize: "tiny" | "small" | "regular" | "medium" | "large" =
    "small";

  const render = (content: string): string =>
    dompurify.sanitize(
      markdown.parseInline(content, {
-
        renderer: new Renderer($activeUnloadedRouteStore, {
-
          stripEmphasizedStyling,
-
        }),
+
        renderer: new Renderer($activeUnloadedRouteStore),
      }) as string,
    );
</script>
modified src/components/Markdown.svelte
@@ -93,9 +93,7 @@
  function render(content: string): string {
    return dompurify.sanitize(
      markdownWithExtensions.parse(content, {
-
        renderer: new Renderer($activeUnloadedRouteStore, {
-
          stripEmphasizedStyling: false,
-
        }),
+
        renderer: new Renderer($activeUnloadedRouteStore),
        breaks,
      }) as string,
    );
modified src/lib/markdown.ts
@@ -40,19 +40,14 @@ const anchorMarkedExtension = {

export class Renderer extends BaseRenderer {
  #route: Route;
-
  #stripEmphasizedStyling: boolean | undefined;

  /**
   * If `baseUrl` is provided, all hrefs attributes in anchor tags, except those
   * starting with `#`, are resolved with respect to `baseUrl`
   */
-
  constructor(
-
    activeUnloadedRoute: Route,
-
    { stripEmphasizedStyling }: { stripEmphasizedStyling: boolean },
-
  ) {
+
  constructor(activeUnloadedRoute: Route) {
    super();
    this.#route = activeUnloadedRoute;
-
    this.#stripEmphasizedStyling = stripEmphasizedStyling;
  }
  // Overwrites the rendering of heading tokens.
  // Since there are possible non ASCII characters in headings,
@@ -69,16 +64,6 @@ export class Renderer extends BaseRenderer {
    return `<h${depth} id="${escapedText}">${text}</h${depth}>`;
  }

-
  strong({ tokens }: Tokens.Strong) {
-
    const text = this.parser.parseInline(tokens);
-
    return this.#stripEmphasizedStyling ? text : `<strong>${text}</strong>`;
-
  }
-

-
  em({ tokens }: Tokens.Em) {
-
    const text = this.parser.parseInline(tokens);
-
    return this.#stripEmphasizedStyling ? text : `<em>${text}</em>`;
-
  }
-

  link({ href, title, tokens }: Tokens.Link): string {
    const text = this.parser.parseInline(tokens);
    if (href.startsWith("#")) {
modified src/lib/utils.ts
@@ -26,6 +26,10 @@ export function formatUserAgent(agent: string): string {
  return agent.slice(1, -1);
}

+
export function formatInlineTitle(input: string): string {
+
  return input.replaceAll(/`([^`]+)`/g, "<code>$1</code>");
+
}
+

export function parseNodeId(
  nid: string,
): { prefix: string; pubkey: string } | undefined {
modified src/views/projects/Cob/CobCommitTeaser.svelte
@@ -8,7 +8,7 @@
  import IconButton from "@app/components/IconButton.svelte";
  import IconSmall from "@app/components/IconSmall.svelte";
  import Id from "@app/components/Id.svelte";
-
  import InlineMarkdown from "@app/components/InlineMarkdown.svelte";
+
  import InlineTitle from "@app/views/projects/components/InlineTitle.svelte";
  import Link from "@app/components/Link.svelte";

  export let baseUrl: BaseUrl;
@@ -68,7 +68,7 @@
          commit: commit.id,
        }}>
        <div class="summary" use:twemoji>
-
          <InlineMarkdown fontSize="small" content={commit.summary} />
+
          <InlineTitle fontSize="small" content={commit.summary} />
        </div>
      </Link>
      {#if commit.description}
modified src/views/projects/Commit.svelte
@@ -5,7 +5,7 @@
  import Changeset from "@app/views/projects/Changeset.svelte";
  import CommitAuthorship from "@app/views/projects/Commit/CommitAuthorship.svelte";
  import IconSmall from "@app/components/IconSmall.svelte";
-
  import InlineMarkdown from "@app/components/InlineMarkdown.svelte";
+
  import InlineTitle from "@app/views/projects/components/InlineTitle.svelte";
  import Layout from "./Layout.svelte";
  import Link from "@app/components/Link.svelte";
  import Share from "./Share.svelte";
@@ -50,10 +50,7 @@
    <div class="header">
      <div style="display:flex; flex-direction: column; gap: 0.5rem;">
        <span class="title">
-
          <InlineMarkdown
-
            stripEmphasizedStyling
-
            fontSize="large"
-
            content={header.summary} />
+
          <InlineTitle fontSize="large" content={header.summary} />
          <div class="button-container">
            <Link
              route={{
modified src/views/projects/Commit/CommitTeaser.svelte
@@ -7,7 +7,7 @@
  import ExpandButton from "@app/components/ExpandButton.svelte";
  import IconButton from "@app/components/IconButton.svelte";
  import IconSmall from "@app/components/IconSmall.svelte";
-
  import InlineMarkdown from "@app/components/InlineMarkdown.svelte";
+
  import InlineTitle from "@app/views/projects/components/InlineTitle.svelte";
  import Link from "@app/components/Link.svelte";
  import Id from "@app/components/Id.svelte";

@@ -86,7 +86,7 @@
        }}>
        <div style="position: relative;">
          <div class="summary" use:twemoji>
-
            <InlineMarkdown fontSize="regular" content={commit.summary} />
+
            <InlineTitle fontSize="regular" content={commit.summary} />
          </div>
        </div>
      </Link>
modified src/views/projects/Issue.svelte
@@ -37,7 +37,7 @@
  import ExtendedTextarea from "@app/components/ExtendedTextarea.svelte";
  import IconSmall from "@app/components/IconSmall.svelte";
  import Id from "@app/components/Id.svelte";
-
  import InlineMarkdown from "@app/components/InlineMarkdown.svelte";
+
  import InlineTitle from "@app/views/projects/components/InlineTitle.svelte";
  import LabelInput from "./Cob/LabelInput.svelte";
  import Layout from "./Layout.svelte";
  import Markdown from "@app/components/Markdown.svelte";
@@ -499,10 +499,7 @@
              <span class="txt-missing">No title</span>
            {:else}
              <div class="title">
-
                <InlineMarkdown
-
                  stripEmphasizedStyling
-
                  fontSize="large"
-
                  content={newTitle} />
+
                <InlineTitle fontSize="large" content={newTitle} />
              </div>
            {/if}
          </div>
modified src/views/projects/Issue/IssueTeaser.svelte
@@ -4,7 +4,7 @@
  import { absoluteTimestamp, formatTimestamp } from "@app/lib/utils";

  import IconSmall from "@app/components/IconSmall.svelte";
-
  import InlineMarkdown from "@app/components/InlineMarkdown.svelte";
+
  import InlineTitle from "@app/views/projects/components/InlineTitle.svelte";
  import Link from "@app/components/Link.svelte";
  import NodeId from "@app/components/NodeId.svelte";

@@ -93,7 +93,7 @@
          {#if !issue.title}
            <span class="txt-missing">No title</span>
          {:else}
-
            <InlineMarkdown fontSize="regular" content={issue.title} />
+
            <InlineTitle fontSize="regular" content={issue.title} />
          {/if}
        </Link>
      </span>
modified src/views/projects/Patch.svelte
@@ -75,7 +75,7 @@
  import ExtendedTextarea from "@app/components/ExtendedTextarea.svelte";
  import IconSmall from "@app/components/IconSmall.svelte";
  import Id from "@app/components/Id.svelte";
-
  import InlineMarkdown from "@app/components/InlineMarkdown.svelte";
+
  import InlineTitle from "@app/views/projects/components/InlineTitle.svelte";
  import LabelInput from "@app/views/projects/Cob/LabelInput.svelte";
  import Layout from "@app/views/projects/Layout.svelte";
  import Link from "@app/components/Link.svelte";
@@ -724,10 +724,7 @@
              <span class="txt-missing">No title</span>
            {:else}
              <div class="title">
-
                <InlineMarkdown
-
                  stripEmphasizedStyling
-
                  fontSize="large"
-
                  content={patch.title} />
+
                <InlineTitle fontSize="large" content={patch.title} />
              </div>
            {/if}
          </div>
modified src/views/projects/Patch/PatchTeaser.svelte
@@ -5,7 +5,7 @@
  import { absoluteTimestamp, formatTimestamp } from "@app/lib/utils";

  import IconSmall from "@app/components/IconSmall.svelte";
-
  import InlineMarkdown from "@app/components/InlineMarkdown.svelte";
+
  import InlineTitle from "@app/views/projects/components/InlineTitle.svelte";
  import Link from "@app/components/Link.svelte";
  import NodeId from "@app/components/NodeId.svelte";

@@ -105,7 +105,7 @@
          node: baseUrl,
          patch: patch.id,
        }}>
-
        <InlineMarkdown fontSize="regular" content={patch.title} />
+
        <InlineTitle fontSize="regular" content={patch.title} />
      </Link>
      {#if patch.labels.length > 0}
        <span
added src/views/projects/components/InlineTitle.svelte
@@ -0,0 +1,28 @@
+
<script lang="ts">
+
  import dompurify from "dompurify";
+
  import escape from "lodash/escape";
+
  import { formatInlineTitle } from "@app/lib/utils";
+

+
  export let content: string;
+
  export let fontSize: "tiny" | "small" | "regular" | "medium" | "large" =
+
    "small";
+
</script>
+

+
<style>
+
  .content :global(code) {
+
    font-family: var(--font-family-monospace);
+
    background-color: var(--color-fill-ghost);
+
    border-radius: var(--border-radius-tiny);
+
    padding: 0.125rem 0.25rem;
+
  }
+
</style>
+

+
<span
+
  class="content"
+
  class:txt-large={fontSize === "large"}
+
  class:txt-medium={fontSize === "medium"}
+
  class:txt-regular={fontSize === "regular"}
+
  class:txt-small={fontSize === "small"}
+
  class:txt-tiny={fontSize === "tiny"}>
+
  {@html dompurify.sanitize(formatInlineTitle(escape(content)))}
+
</span>
modified tests/e2e/project/issue.spec.ts
@@ -2,7 +2,7 @@ import { test, cobUrl, expect } from "@tests/support/fixtures.js";

test("navigate single issue", async ({ page }) => {
  await page.goto(`${cobUrl}/issues`);
-
  await page.getByText("This title has markdown").click();
+
  await page.getByText("This title has **markdown**").click();

  await expect(page).toHaveURL(/\/issues\/[0-9a-f]{40}/);
});
modified tests/unit/utils.test.ts
@@ -34,6 +34,23 @@ describe("Format functions", () => {

  test.each([
    {
+
      input: "<TR> Hello `new` world",
+
      expected: "<TR> Hello <code>new</code> world",
+
    },
+
    { input: "Hello `new` world", expected: "Hello <code>new</code> world" },
+
    {
+
      input: "Hello `new` world `radicle`",
+
      expected: "Hello <code>new</code> world <code>radicle</code>",
+
    },
+
    { input: "Hello `` world", expected: "Hello `` world" },
+
    { input: "Hello `", expected: "Hello `" },
+
    { input: "Hello", expected: "Hello" },
+
  ])("formatInlineTitle $input => $expected", ({ input, expected }) => {
+
    expect(utils.formatInlineTitle(input)).toEqual(expected);
+
  });
+

+
  test.each([
+
    {
      id: "did:key:z6MkmzRwg47UWQxczLLLFfkEwpBGitjzJ1vKPE8U9ymd6fz6",
      expected: "did:key:z6Mkmz…md6fz6",
    },