collavre 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 617bf6c7eda577396e21384c92f4655c44eb0f433ef2cfeba05f6c47ab00f2c9
4
- data.tar.gz: b3cd87f98abf7a7cd2e1c1876a33d8eab6c993993933d23c021c59c6663cb525
3
+ metadata.gz: d6bf5cb5904041bc150792f274d44ce65f7b659bebf346a0f27dc00a1cbc0067
4
+ data.tar.gz: 33a8b19ecb1e5e2a02a8144ef7038d825c8d0d2cc9cd7195ea7fdc21230f9cd3
5
5
  SHA512:
6
- metadata.gz: bcdda91582a8b87d3ba5f890f22a0df72c9aed567860c14e06eb85dca5980c2adc735a29a0fa1bbcd9aea3e8b8bdf79d8d88aa6ee88b7231afc9dbdc11edc6d8
7
- data.tar.gz: 289e1667b14dd0b578c46d7623fc751489ddb4c8d9dfd09f6024d4355fe69a4b5e375275c3395c541c6f97c26e7ce953b378c1e44d2fd8eda03e5346fa319b8c
6
+ metadata.gz: 95e7f7877a88161151e55b26d9a46503a3889ed940443ba9436dc7fff063fc75cdd7ae554bc6a5c144bd5246dbf1822476fde15a925663d040ae6b54e59b6af3
7
+ data.tar.gz: 443e491e30ec68060e75b18a4f3abce13b764ce23d049b0f9be4081f322b99964313f29d46cb4d477f93aa75275bfb8dec7870bfb56dc74699fea747cb9e160c
@@ -74,6 +74,19 @@ body.dark-mode {
74
74
  }
75
75
  }
76
76
 
77
+ /* ============================================================================
78
+ * MERMAID DIAGRAM CONTAINER
79
+ * ============================================================================ */
80
+ .comment-content .mermaid-chart {
81
+ margin: var(--space-2) 0;
82
+ overflow-x: auto;
83
+ text-align: center;
84
+ }
85
+
86
+ .comment-content .mermaid-chart svg {
87
+ max-width: 100%;
88
+ }
89
+
77
90
  /* ============================================================================
78
91
  * CODE BLOCK CONTAINER
79
92
  * ============================================================================ */
@@ -1,5 +1,5 @@
1
1
  import { Controller } from "@hotwired/stimulus"
2
- import { renderCommentMarkdown } from '../lib/utils/markdown'
2
+ import { renderCommentMarkdown, renderMermaidDiagrams } from '../lib/utils/markdown'
3
3
  import { addTableDownloadButtons } from '../lib/utils/table_download'
4
4
  import CommonPopup from '../lib/common_popup'
5
5
 
@@ -112,6 +112,7 @@ export default class extends Controller {
112
112
  } else {
113
113
  contentElement.innerHTML = renderCommentMarkdown(text)
114
114
  addTableDownloadButtons(contentElement)
115
+ renderMermaidDiagrams(contentElement)
115
116
  contentElement.classList.remove('streaming')
116
117
  if (this._isStreaming) this._cleanupStreaming()
117
118
  }
@@ -1,5 +1,5 @@
1
1
  import { Controller } from "@hotwired/stimulus"
2
- import { renderCommentMarkdown } from "../lib/utils/markdown"
2
+ import { renderCommentMarkdown, renderMermaidDiagrams } from "../lib/utils/markdown"
3
3
 
4
4
  export default class extends Controller {
5
5
  static targets = ["prevBtn", "nextBtn", "indicator", "deleteBtn", "selectBtn"]
@@ -127,6 +127,7 @@ export default class extends Controller {
127
127
  if (target) {
128
128
  target.innerHTML = renderCommentMarkdown(text)
129
129
  target.dataset.rendered = "true"
130
+ renderMermaidDiagrams(target)
130
131
  }
131
132
  }
132
133
 
@@ -68,11 +68,15 @@ function sanitizeLang(lang) {
68
68
  return lang.replace(/[^a-zA-Z0-9_-]/g, '')
69
69
  }
70
70
 
71
- // Custom renderer for code blocks with syntax highlighting
71
+ // Custom renderer for code blocks with syntax highlighting + mermaid
72
72
  marked.use({
73
73
  renderer: {
74
74
  code({ text, lang }) {
75
75
  const safeLang = sanitizeLang(lang)
76
+ if (safeLang === 'mermaid') {
77
+ const escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
78
+ return `<div class="mermaid-chart">${escaped}</div>`
79
+ }
76
80
  const highlighted = highlightCode(text, safeLang)
77
81
  const langClass = safeLang ? ` language-${safeLang}` : ''
78
82
  return `<pre><code class="hljs${langClass}">${highlighted}</code></pre>`
@@ -99,6 +103,14 @@ DOMPurify.addHook('uponSanitizeAttribute', (node, data) => {
99
103
  data.forceKeepAttr = true
100
104
  }
101
105
  }
106
+ // Allow mermaid-chart class on div elements
107
+ if (node.tagName === 'DIV' && data.attrName === 'class') {
108
+ const classes = data.attrValue.split(/\s+/)
109
+ if (classes.includes('mermaid-chart')) {
110
+ data.attrValue = 'mermaid-chart'
111
+ data.forceKeepAttr = true
112
+ }
113
+ }
102
114
  })
103
115
 
104
116
  const PURIFY_CONFIG = {
@@ -125,6 +137,24 @@ export function renderCommentMarkdown(text) {
125
137
  return sanitize(html.trim())
126
138
  }
127
139
 
140
+ // Lazy-load mermaid and render diagrams in a container
141
+ let mermaidReady = false
142
+
143
+ export async function renderMermaidDiagrams(container) {
144
+ const charts = container.querySelectorAll('.mermaid-chart:not([data-processed])')
145
+ if (charts.length === 0) return
146
+ const { default: mermaid } = await import('mermaid')
147
+ if (!mermaidReady) {
148
+ mermaid.initialize({ startOnLoad: false, securityLevel: 'strict' })
149
+ mermaidReady = true
150
+ }
151
+ try {
152
+ await mermaid.run({ nodes: Array.from(charts) })
153
+ } catch (e) {
154
+ console.warn('Mermaid rendering failed:', e)
155
+ }
156
+ }
157
+
128
158
  export function renderMarkdownInContainer(container) {
129
159
  container.querySelectorAll('.comment-content').forEach((element) => {
130
160
  if (element.dataset.rendered === 'true') return
@@ -132,4 +162,5 @@ export function renderMarkdownInContainer(container) {
132
162
  element.dataset.rendered = 'true'
133
163
  addTableDownloadButtons(element)
134
164
  })
165
+ renderMermaidDiagrams(container)
135
166
  }
@@ -1,3 +1,3 @@
1
1
  module Collavre
2
- VERSION = "0.15.0"
2
+ VERSION = "0.16.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: collavre
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Collavre