markstream-angular 2.0.14 → 2.0.16

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.
@@ -2405,6 +2405,20 @@ function extractRenderedSvg(renderResult) {
2405
2405
  return '';
2406
2406
  }
2407
2407
 
2408
+ // D2 derives the ids and style-scope classes of its SVG output from a hash of the
2409
+ // diagram source, so two identical diagrams would otherwise emit duplicate
2410
+ // `id`/`url(#…)` targets and two document-level `.d2-<hash>` style scopes — one
2411
+ // of them then wins and the diagrams get each other's colours. D2 exposes
2412
+ // `RenderOptions.salt` for exactly this case ("useful when generating multiple
2413
+ // identical diagrams to be included in the same HTML doc"). Every render takes a
2414
+ // fresh salt from this module-scoped counter, which the block component and
2415
+ // `enhanceRenderedHtml` share, so both render paths stay unique on one page.
2416
+ let d2RenderSaltSequence = 0;
2417
+ function createD2RenderSalt(prefix = 'markstream-angular-d2') {
2418
+ d2RenderSaltSequence += 1;
2419
+ return `${prefix}-${d2RenderSaltSequence}`;
2420
+ }
2421
+
2408
2422
  async function copyTextToClipboard(source) {
2409
2423
  try {
2410
2424
  if (typeof navigator !== 'undefined' && navigator.clipboard?.writeText) {
@@ -2661,6 +2675,7 @@ class D2BlockNodeComponent {
2661
2675
  ...DARK_THEME_OVERRIDES$1,
2662
2676
  };
2663
2677
  }
2678
+ renderOptions.salt = renderOptions.salt ?? createD2RenderSalt();
2664
2679
  const renderResult = await instance.render(diagram, renderOptions);
2665
2680
  if (this.destroyed || token !== this.renderToken)
2666
2681
  return;
@@ -3235,6 +3250,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.26", ngImpo
3235
3250
  type: Input
3236
3251
  }] } });
3237
3252
 
3253
+ // Footnote ids are derived from the markdown label (`fnref-<label>` / `fnref--<label>`), so the
3254
+ // same id can exist in several renderer trees on one page. Resolve the target inside the tree the
3255
+ // clicked element belongs to, and only fall back to the document when that tree has no match.
3256
+ const RENDERER_ROOT_SELECTOR = '.markdown-renderer';
3257
+ function toIdSelector(id) {
3258
+ return `[id="${id.replace(/["\\]/g, '\\$&')}"]`;
3259
+ }
3260
+ function findFootnoteElement(source, id) {
3261
+ if (typeof document === 'undefined' || typeof Element === 'undefined')
3262
+ return null;
3263
+ const selector = toIdSelector(id);
3264
+ let scope = source instanceof Element ? source.closest(RENDERER_ROOT_SELECTOR) : null;
3265
+ while (scope) {
3266
+ const found = scope.querySelector(selector);
3267
+ if (found)
3268
+ return found;
3269
+ scope = scope.parentElement?.closest(RENDERER_ROOT_SELECTOR) ?? null;
3270
+ }
3271
+ return document.querySelector(selector);
3272
+ }
3273
+
3238
3274
  class FootnoteAnchorNodeComponent {
3239
3275
  get id() {
3240
3276
  return getString$1(this.node?.id);
@@ -3245,12 +3281,20 @@ class FootnoteAnchorNodeComponent {
3245
3281
  get title() {
3246
3282
  return `Back to reference ${this.id}`;
3247
3283
  }
3284
+ handleClick(event) {
3285
+ event.preventDefault();
3286
+ if (typeof document === 'undefined')
3287
+ return;
3288
+ const target = findFootnoteElement(event.currentTarget, `fnref-${this.id}`);
3289
+ target?.scrollIntoView({ behavior: 'smooth' });
3290
+ }
3248
3291
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.26", ngImport: i0, type: FootnoteAnchorNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3249
3292
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.26", type: FootnoteAnchorNodeComponent, isStandalone: true, selector: "markstream-angular-footnote-anchor-node", inputs: { node: "node" }, ngImport: i0, template: `
3250
3293
  <a
3251
3294
  class="footnote-anchor text-sm text-[#0366d6] hover:underline cursor-pointer"
3252
3295
  [attr.href]="href"
3253
3296
  [attr.title]="title"
3297
+ (click)="handleClick($event)"
3254
3298
  >
3255
3299
  ↩︎
3256
3300
  </a>
@@ -3266,6 +3310,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.26", ngImpo
3266
3310
  class="footnote-anchor text-sm text-[#0366d6] hover:underline cursor-pointer"
3267
3311
  [attr.href]="href"
3268
3312
  [attr.title]="title"
3313
+ (click)="handleClick($event)"
3269
3314
  >
3270
3315
  ↩︎
3271
3316
  </a>
@@ -3334,10 +3379,17 @@ class FootnoteReferenceNodeComponent {
3334
3379
  get referenceId() {
3335
3380
  return `fnref-${this.id}`;
3336
3381
  }
3382
+ handleClick(event) {
3383
+ event.preventDefault();
3384
+ if (typeof document === 'undefined')
3385
+ return;
3386
+ const target = findFootnoteElement(event.currentTarget, `fnref--${this.id}`);
3387
+ target?.scrollIntoView({ behavior: 'smooth' });
3388
+ }
3337
3389
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.26", ngImport: i0, type: FootnoteReferenceNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3338
3390
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.26", type: FootnoteReferenceNodeComponent, isStandalone: true, selector: "markstream-angular-footnote-reference-node", inputs: { node: "node" }, ngImport: i0, template: `
3339
3391
  <sup [attr.id]="referenceId" class="markstream-nested-footnote-ref">
3340
- <a [attr.href]="href">[{{ id }}]</a>
3392
+ <a [attr.href]="href" (click)="handleClick($event)">[{{ id }}]</a>
3341
3393
  </sup>
3342
3394
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3343
3395
  }
@@ -3348,7 +3400,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.26", ngImpo
3348
3400
  standalone: true,
3349
3401
  template: `
3350
3402
  <sup [attr.id]="referenceId" class="markstream-nested-footnote-ref">
3351
- <a [attr.href]="href">[{{ id }}]</a>
3403
+ <a [attr.href]="href" (click)="handleClick($event)">[{{ id }}]</a>
3352
3404
  </sup>
3353
3405
  `,
3354
3406
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -6685,6 +6737,20 @@ async function getMermaid(initConfig) {
6685
6737
  }
6686
6738
  }
6687
6739
 
6740
+ // Mermaid keys both its temporary render container (`#d<id>`) and the produced
6741
+ // `<svg id>` by the id handed to `mermaid.render`, then resolves that id again
6742
+ // when it binds interactions. The id therefore has to be unique across every
6743
+ // diagram on the page, not only inside one render path: the block component and
6744
+ // `enhanceRenderedHtml` used to keep separate counters that both started at
6745
+ // `markstream-angular-mermaid-1`, so mixing the two paths on one page made
6746
+ // Mermaid delete the other render's container and leave a blank preview
6747
+ // (issue #775). Both now share this module-scoped counter.
6748
+ let mermaidRenderSequence = 0;
6749
+ function createMermaidRenderId(prefix = 'markstream-angular-mermaid') {
6750
+ mermaidRenderSequence += 1;
6751
+ return `${prefix}-${mermaidRenderSequence}`;
6752
+ }
6753
+
6688
6754
  let worker = null;
6689
6755
  let workerInitError = null;
6690
6756
  const rpcMap = new Map();
@@ -6852,7 +6918,6 @@ function terminateWorker() {
6852
6918
  }
6853
6919
  }
6854
6920
 
6855
- let mermaidRenderSequence = 0;
6856
6921
  let mermaidRenderQueue = Promise.resolve();
6857
6922
  function enqueueMermaidRender(run) {
6858
6923
  const next = mermaidRenderQueue.then(run, run);
@@ -7169,7 +7234,7 @@ class MermaidBlockNodeComponent {
7169
7234
  return;
7170
7235
  }
7171
7236
  }
7172
- const renderId = `markstream-angular-mermaid-${++mermaidRenderSequence}`;
7237
+ const renderId = createMermaidRenderId();
7173
7238
  const themedSource = this.applyThemeTo(renderSource, theme);
7174
7239
  const rendered = await enqueueMermaidRender(() => this.withTimeout(() => Promise.resolve(mermaid.render(renderId, themedSource)), this.resolvedLoading && this.resolvedProgressiveRender
7175
7240
  ? this.resolvedRenderTimeout
@@ -7265,7 +7330,7 @@ class MermaidBlockNodeComponent {
7265
7330
  throw new DOMException('Aborted', 'AbortError');
7266
7331
  return true;
7267
7332
  }
7268
- const renderId = `markstream-angular-mermaid-parse-${++mermaidRenderSequence}`;
7333
+ const renderId = createMermaidRenderId('markstream-angular-mermaid-parse');
7269
7334
  await this.withTimeout(() => Promise.resolve(anyMermaid.render(renderId, themedSource)), this.resolvedParseTimeout);
7270
7335
  if (this.destroyed || token !== this.renderToken)
7271
7336
  throw new DOMException('Aborted', 'AbortError');
@@ -8967,7 +9032,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.26", ngImpo
8967
9032
  type: Input
8968
9033
  }] } });
8969
9034
 
8970
- let mermaidRenderId = 0;
8971
9035
  const rootHandles = new WeakMap();
8972
9036
  const DARK_THEME_OVERRIDES = {
8973
9037
  N1: '#E5E7EB',
@@ -9193,7 +9257,7 @@ async function renderMermaid(root, cleanupFns, options, isActive) {
9193
9257
  sourceToRender = prefix;
9194
9258
  }
9195
9259
  }
9196
- const renderId = `markstream-angular-mermaid-${++mermaidRenderId}`;
9260
+ const renderId = createMermaidRenderId();
9197
9261
  const rendered = await withTimeout(() => Promise.resolve(mermaid.render(renderId, applyMermaidThemeTo(sourceToRender, theme))), options.final === false
9198
9262
  ? Number(options.mermaidProps?.renderTimeoutMs ?? 2500)
9199
9263
  : Number(options.mermaidProps?.fullRenderTimeoutMs ?? 4000));
@@ -9248,7 +9312,7 @@ async function canParseMermaidWithFallback(source, theme, mermaid, options) {
9248
9312
  await withTimeout(() => Promise.resolve(mermaid.parse(themedSource)), parseTimeout);
9249
9313
  return true;
9250
9314
  }
9251
- const renderId = `markstream-angular-mermaid-parse-${++mermaidRenderId}`;
9315
+ const renderId = createMermaidRenderId('markstream-angular-mermaid-parse');
9252
9316
  await withTimeout(() => Promise.resolve(mermaid.render(renderId, themedSource)), parseTimeout);
9253
9317
  return true;
9254
9318
  }
@@ -9401,6 +9465,7 @@ async function renderD2(root, cleanupFns, options, isActive) {
9401
9465
  ...(baseOverrides || {}),
9402
9466
  };
9403
9467
  }
9468
+ renderOptions.salt = renderOptions.salt ?? createD2RenderSalt();
9404
9469
  const renderResult = await instance.render(diagram, renderOptions);
9405
9470
  if (!isActive())
9406
9471
  return;