@jant/core 0.6.12 → 0.6.14

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.
Files changed (120) hide show
  1. package/bin/commands/import-site.js +2 -10
  2. package/bin/commands/migrate-text-attachments.js +1 -3
  3. package/bin/commands/site/export.js +1 -3
  4. package/bin/commands/telegram/register-webhooks.js +9 -3
  5. package/bin/lib/site-snapshot.js +1 -5
  6. package/dist/{app-D-zAhayc.js → app-2i7-WQHg.js} +426 -450
  7. package/dist/app-DZDlmh7C.js +6 -0
  8. package/dist/client/.vite/manifest.json +3 -3
  9. package/dist/client/_assets/{client-S1cdvulk.js → client-BvID5ucz.js} +1 -1
  10. package/dist/client/_assets/client-Cevfpm8H.css +2 -0
  11. package/dist/client/_assets/{client-auth-YW92ZH7u.js → client-auth-v3yvhbgZ.js} +596 -590
  12. package/dist/{export-Ckwh4BiE.js → export-DWn149b7.js} +24 -19
  13. package/dist/{github-sync-BMmK3JZ0.js → github-sync-C0zyF6XS.js} +2 -2
  14. package/dist/{github-sync-Dl9wQMar.js → github-sync-Ckk0sJxK.js} +1 -1
  15. package/dist/index.js +3 -3
  16. package/dist/node.js +4 -4
  17. package/package.json +1 -1
  18. package/src/__tests__/export-service.test.ts +1 -2
  19. package/src/__tests__/helpers/app.ts +3 -0
  20. package/src/__tests__/helpers/export-fixtures.ts +0 -1
  21. package/src/__tests__/import-site-command.test.ts +1 -2
  22. package/src/client/__tests__/site-header-nav.test.ts +36 -2
  23. package/src/client/components/__tests__/compose-title-from-heading.test.ts +57 -0
  24. package/src/client/components/__tests__/jant-command-palette.test.ts +137 -10
  25. package/src/client/components/__tests__/jant-compose-dialog.test.ts +3 -0
  26. package/src/client/components/__tests__/jant-compose-editor.test.ts +94 -2
  27. package/src/client/components/__tests__/jant-nav-manager.test.ts +107 -22
  28. package/src/client/components/__tests__/jant-settings-general.test.ts +1 -0
  29. package/src/client/components/compose-title-from-heading.ts +66 -0
  30. package/src/client/components/compose-types.ts +8 -0
  31. package/src/client/components/inline-image-issues.ts +17 -0
  32. package/src/client/components/jant-command-palette.ts +100 -70
  33. package/src/client/components/jant-compose-dialog.ts +3 -1
  34. package/src/client/components/jant-compose-editor.ts +78 -1
  35. package/src/client/components/jant-compose-fullscreen.ts +2 -0
  36. package/src/client/components/jant-nav-manager.ts +245 -155
  37. package/src/client/components/nav-manager-types.ts +0 -10
  38. package/src/client/site-header-nav.d.ts +1 -0
  39. package/src/client/site-header-nav.js +105 -47
  40. package/src/client/tiptap/__tests__/block-insertion.test.ts +35 -0
  41. package/src/client/tiptap/__tests__/footnotes.test.ts +284 -0
  42. package/src/client/tiptap/__tests__/image-input-rules.test.ts +117 -0
  43. package/src/client/tiptap/__tests__/markdown-clipboard.test.ts +148 -1
  44. package/src/client/tiptap/bubble-menu.ts +3 -3
  45. package/src/client/tiptap/create-editor.ts +7 -0
  46. package/src/client/tiptap/extensions.ts +7 -2
  47. package/src/client/tiptap/footnotes.ts +156 -0
  48. package/src/client/tiptap/image-input-rules.ts +48 -0
  49. package/src/client/tiptap/image-node.ts +189 -7
  50. package/src/client/tiptap/markdown-clipboard.ts +7 -2
  51. package/src/client-auth.ts +0 -1
  52. package/src/i18n/locales/public/en.po +20 -4
  53. package/src/i18n/locales/public/en.ts +1 -1
  54. package/src/i18n/locales/public/zh-Hans.po +20 -4
  55. package/src/i18n/locales/public/zh-Hans.ts +1 -1
  56. package/src/i18n/locales/public/zh-Hant.po +20 -4
  57. package/src/i18n/locales/public/zh-Hant.ts +1 -1
  58. package/src/i18n/locales/settings/en.po +23 -20
  59. package/src/i18n/locales/settings/en.ts +1 -1
  60. package/src/i18n/locales/settings/zh-Hans.po +23 -20
  61. package/src/i18n/locales/settings/zh-Hans.ts +1 -1
  62. package/src/i18n/locales/settings/zh-Hant.po +23 -20
  63. package/src/i18n/locales/settings/zh-Hant.ts +1 -1
  64. package/src/lib/__tests__/markdown-to-tiptap.test.ts +4 -0
  65. package/src/lib/__tests__/navigation.test.ts +4 -37
  66. package/src/lib/__tests__/resolve-config.test.ts +6 -1
  67. package/src/lib/__tests__/view.test.ts +6 -30
  68. package/src/lib/github-sync-site-config.ts +0 -2
  69. package/src/lib/hugo-markdown.ts +1 -1
  70. package/src/lib/markdown-manager.ts +14 -5
  71. package/src/lib/navigation.ts +5 -22
  72. package/src/lib/resolve-config.ts +9 -2
  73. package/src/lib/site-header-fragment.tsx +37 -0
  74. package/src/lib/view.ts +2 -7
  75. package/src/node/__tests__/cli-site-snapshot.test.ts +45 -45
  76. package/src/routes/api/__tests__/nav-items.test.ts +26 -0
  77. package/src/routes/api/export.ts +0 -2
  78. package/src/routes/api/internal/__tests__/uploads.test.ts +9 -13
  79. package/src/routes/api/internal/sites.ts +5 -5
  80. package/src/routes/api/nav-items.ts +25 -4
  81. package/src/routes/dash/settings.tsx +8 -2
  82. package/src/routes/feed/__tests__/feed.test.ts +42 -0
  83. package/src/routes/feed/__tests__/sitemap.test.ts +2 -13
  84. package/src/routes/feed/feed.ts +1 -0
  85. package/src/routes/feed/sitemap.ts +2 -6
  86. package/src/routes/pages/archive.tsx +1 -0
  87. package/src/routes/pages/collection.tsx +1 -0
  88. package/src/routes/pages/featured.tsx +0 -4
  89. package/src/routes/pages/home.tsx +4 -51
  90. package/src/routes/pages/latest.tsx +2 -51
  91. package/src/services/__tests__/github-app-installations.test.ts +10 -10
  92. package/src/services/__tests__/navigation.test.ts +41 -0
  93. package/src/services/__tests__/post-timeline.test.ts +56 -0
  94. package/src/services/__tests__/post.test.ts +33 -0
  95. package/src/services/__tests__/settings.test.ts +5 -20
  96. package/src/services/export-theme/assets/client-site.js +10 -10
  97. package/src/services/export-theme/layouts/_default/rss.xml +5 -15
  98. package/src/services/export-theme/layouts/index.html +26 -39
  99. package/src/services/export.ts +5 -10
  100. package/src/services/github-app-installations.ts +1 -3
  101. package/src/services/navigation.ts +44 -13
  102. package/src/services/post.ts +80 -57
  103. package/src/services/settings.ts +0 -10
  104. package/src/services/site-admin.ts +0 -2
  105. package/src/services/upload-session.ts +4 -18
  106. package/src/styles/tokens.css +2 -2
  107. package/src/styles/ui.css +316 -34
  108. package/src/types/bindings.ts +0 -1
  109. package/src/types/config.ts +3 -7
  110. package/src/ui/compose/ComposeDialog.tsx +28 -0
  111. package/src/ui/dash/appearance/NavigationContent.tsx +1 -1
  112. package/src/ui/dash/settings/AccountMenuContent.tsx +2 -2
  113. package/src/ui/dash/settings/SettingsRootContent.tsx +3 -3
  114. package/src/ui/feed/__tests__/timeline-cards.test.ts +8 -3
  115. package/src/ui/layouts/BaseLayout.tsx +1 -1
  116. package/src/ui/layouts/SiteLayout.tsx +266 -227
  117. package/src/ui/layouts/__tests__/SiteLayout.test.tsx +48 -0
  118. package/dist/app-B5P1b4TF.js +0 -6
  119. package/dist/client/_assets/client-BUxR-E8O.css +0 -2
  120. package/src/client/nav-manager-bridge.ts +0 -54
@@ -31,6 +31,10 @@ import type {
31
31
  ComposeFullscreenOpenDetail,
32
32
  } from "./compose-types.js";
33
33
  import type { ComposeConvertFields } from "./compose-format-convert.js";
34
+ import {
35
+ promoteLeadingH1Title as getLeadingH1TitlePromotion,
36
+ type LeadingH1TitlePromotion,
37
+ } from "./compose-title-from-heading.js";
34
38
  import {
35
39
  UPLOAD_ACCEPT,
36
40
  getMediaCategory,
@@ -59,6 +63,7 @@ import {
59
63
  markSlashCommandDiscovered,
60
64
  scheduleSlashCommandHint,
61
65
  } from "../slash-discovery.js";
66
+ import { getInlineImageNodeLabels } from "./inline-image-issues.js";
62
67
 
63
68
  interface ComposeFilePickerCloseDetail {
64
69
  cancelled: boolean;
@@ -631,6 +636,67 @@ export class JantComposeEditor extends LitElement {
631
636
  return this._isEmptyDoc(json) ? null : json;
632
637
  }
633
638
 
639
+ private _isSelectionInsideTopLevelBlock(index: number): boolean {
640
+ const editor = this._editor;
641
+ if (!editor) return false;
642
+ return editor.state.selection.$from.index(0) === index;
643
+ }
644
+
645
+ private _removedTopLevelSize(promotion: LeadingH1TitlePromotion): number {
646
+ const doc = this._editor?.state.doc;
647
+ if (!doc) return 0;
648
+
649
+ let size = 0;
650
+ for (let index = 0; index <= promotion.headingIndex; index += 1) {
651
+ size += doc.child(index)?.nodeSize ?? 0;
652
+ }
653
+ return size;
654
+ }
655
+
656
+ promoteLeadingH1Title(options: { force?: boolean } = {}): boolean {
657
+ if (this.format !== "note" || this._title.trim()) return false;
658
+
659
+ const currentBodyJson = this._editor?.getJSON() ?? this._bodyJson;
660
+ const promotion = getLeadingH1TitlePromotion(currentBodyJson);
661
+ if (!promotion) return false;
662
+
663
+ if (
664
+ !options.force &&
665
+ this._isSelectionInsideTopLevelBlock(promotion.headingIndex)
666
+ ) {
667
+ return false;
668
+ }
669
+
670
+ const editor = this._editor;
671
+ const wasFocused = Boolean(editor?.isFocused);
672
+ const previousSelectionFrom = editor?.state.selection.from ?? null;
673
+ const removedSize = this._removedTopLevelSize(promotion);
674
+
675
+ this._title = promotion.title;
676
+ this._showTitle = true;
677
+ this._bodyJson = promotion.bodyJson;
678
+
679
+ if (editor) {
680
+ if (promotion.bodyJson) {
681
+ editor.commands.setContent(promotion.bodyJson);
682
+ } else {
683
+ editor.commands.clearContent();
684
+ }
685
+
686
+ if (wasFocused && previousSelectionFrom !== null) {
687
+ const max = editor.state.doc.content.size;
688
+ if (max > 0) {
689
+ editor.commands.setTextSelection(
690
+ Math.max(1, Math.min(previousSelectionFrom - removedSize, max)),
691
+ );
692
+ editor.commands.focus();
693
+ }
694
+ }
695
+ }
696
+
697
+ return true;
698
+ }
699
+
634
700
  getNormalizedBodyJson(): JSONContent | null {
635
701
  return this._normalizeDocJson(this._bodyJson);
636
702
  }
@@ -913,6 +979,7 @@ export class JantComposeEditor extends LitElement {
913
979
  onUpdate: (json) => {
914
980
  this._bodyJson = json;
915
981
  this._ensureScrollBuffer();
982
+ this.promoteLeadingH1Title();
916
983
  hideSlashCommandHint(this);
917
984
  },
918
985
  onFocus: () => {
@@ -921,6 +988,9 @@ export class JantComposeEditor extends LitElement {
921
988
  scheduleSlashCommandHint(this);
922
989
  }
923
990
  },
991
+ onBlur: () => {
992
+ this.promoteLeadingH1Title({ force: true });
993
+ },
924
994
  onSelectionUpdate: (selection) => {
925
995
  this._lastEditorSelection = selection;
926
996
  },
@@ -935,6 +1005,7 @@ export class JantComposeEditor extends LitElement {
935
1005
  shouldRehost: (src) => this.#shouldRehostSrc(src),
936
1006
  rehost: (src) => this.#rehostInlineImage(src),
937
1007
  },
1008
+ imageNodeLabels: getInlineImageNodeLabels(this.labels),
938
1009
  });
939
1010
  this._lastEditorSelection = this._readEditorSelection();
940
1011
 
@@ -1851,11 +1922,14 @@ export class JantComposeEditor extends LitElement {
1851
1922
  }
1852
1923
 
1853
1924
  private _renderAttachmentPreviewFallback(category: "image" | "video") {
1925
+ const unavailableLabel =
1926
+ this.labels.brokenImageUnavailable ?? "Image unavailable";
1927
+
1854
1928
  return html`
1855
1929
  <div
1856
1930
  class="compose-attachment-preview-fallback"
1857
1931
  data-preview-failed=${category}
1858
- aria-hidden="true"
1932
+ aria-label=${unavailableLabel}
1859
1933
  >
1860
1934
  <svg
1861
1935
  width="28"
@@ -1871,6 +1945,9 @@ export class JantComposeEditor extends LitElement {
1871
1945
  <circle cx="9" cy="10" r="1.25" />
1872
1946
  <path d="m7 16 3.4-3.45 2.65 2.45 2.45-3.05 1.95 2.5" />
1873
1947
  </svg>
1948
+ <span class="compose-attachment-preview-fallback-label">
1949
+ ${unavailableLabel}
1950
+ </span>
1874
1951
  ${category === "video"
1875
1952
  ? html`
1876
1953
  <div class="compose-attachment-play-icon">
@@ -21,6 +21,7 @@ import type {
21
21
  } from "./compose-types.js";
22
22
  import { createTiptapEditor } from "../tiptap/create-editor.js";
23
23
  import { uploadAndInsertInlineImage } from "../tiptap/inline-image-upload.js";
24
+ import { getInlineImageNodeLabels } from "./inline-image-issues.js";
24
25
 
25
26
  const ESCAPE_OVERLAY_SELECTOR = ".tiptap-slash-menu, .tiptap-link-input";
26
27
 
@@ -159,6 +160,7 @@ export class JantComposeFullscreen extends LitElement {
159
160
  shouldInsertInline: (file) => file.type.startsWith("image/"),
160
161
  uploadInlineImage: (file) => this._uploadAndInsertImage(file),
161
162
  },
163
+ imageNodeLabels: getInlineImageNodeLabels(this.labels),
162
164
  });
163
165
 
164
166
  const selection = this._selection;