@alwith/module-editor 0.0.0-stage → 0.1.0-rc.13

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 (66) hide show
  1. package/LICENSE +94 -0
  2. package/README.md +47 -2
  3. package/THIRD_PARTY_NOTICES.md +3 -0
  4. package/dist/core.d.ts +56 -0
  5. package/dist/core.js +8 -0
  6. package/dist/index.d.ts +89 -0
  7. package/dist/index.js +1 -0
  8. package/dist/monaco.d.ts +16 -0
  9. package/dist/monaco.js +1 -0
  10. package/dist/new-tab.d.ts +43 -0
  11. package/dist/new-tab.js +1 -0
  12. package/dist/preview-source-mode-toggle.d.ts +8 -0
  13. package/dist/preview-source-mode-toggle.js +1 -0
  14. package/dist/previews/excel-data.d.ts +20 -0
  15. package/dist/previews/excel-data.js +3 -0
  16. package/dist/previews/excel-navigation.d.ts +4 -0
  17. package/dist/previews/excel-navigation.js +1 -0
  18. package/dist/previews/excel.d.ts +3 -0
  19. package/dist/previews/excel.js +1 -0
  20. package/dist/previews/html-resources.d.ts +3 -0
  21. package/dist/previews/html-resources.js +2 -0
  22. package/dist/previews/html-session.d.ts +8 -0
  23. package/dist/previews/html-session.js +1 -0
  24. package/dist/previews/html.d.ts +3 -0
  25. package/dist/previews/html.js +1 -0
  26. package/dist/previews/index.d.ts +83 -0
  27. package/dist/previews/index.js +1 -0
  28. package/dist/previews/markdown-outline.d.ts +6 -0
  29. package/dist/previews/markdown-outline.js +1 -0
  30. package/dist/previews/markdown-readonly.d.ts +4 -0
  31. package/dist/previews/markdown-readonly.js +2 -0
  32. package/dist/previews/markdown.css +918 -0
  33. package/dist/previews/markdown.d.ts +5 -0
  34. package/dist/previews/markdown.js +1 -0
  35. package/dist/previews/media-types.d.ts +1 -0
  36. package/dist/previews/media-types.js +1 -0
  37. package/dist/previews/media.d.ts +2 -0
  38. package/dist/previews/media.js +1 -0
  39. package/dist/previews/pdf-controls.d.ts +1 -0
  40. package/dist/previews/pdf-controls.js +1 -0
  41. package/dist/previews/pdf.d.ts +2 -0
  42. package/dist/previews/pdf.js +1 -0
  43. package/dist/previews/shared.d.ts +7 -0
  44. package/dist/previews/shared.js +1 -0
  45. package/dist/previews/styles.css +142 -0
  46. package/dist/previews/tiff.d.ts +2 -0
  47. package/dist/previews/tiff.js +1 -0
  48. package/dist/previews/viewers.css +221 -0
  49. package/dist/previews/word.d.ts +2 -0
  50. package/dist/previews/word.js +1 -0
  51. package/dist/quick-start-assets.d.ts +4 -0
  52. package/dist/quick-start-assets.js +1 -0
  53. package/dist/quick-start-data.d.ts +11 -0
  54. package/dist/quick-start-data.js +1 -0
  55. package/dist/quick-start-icons.d.ts +9 -0
  56. package/dist/quick-start-icons.js +1 -0
  57. package/dist/shortcut-hint.d.ts +4 -0
  58. package/dist/shortcut-hint.js +0 -0
  59. package/dist/styles.css +726 -0
  60. package/dist/workspace-assets.d.ts +2 -0
  61. package/dist/workspace-assets.js +1 -0
  62. package/dist/workspace-tabs.d.ts +27 -0
  63. package/dist/workspace-tabs.js +1 -0
  64. package/dist/workspace.d.ts +31 -0
  65. package/dist/workspace.js +1 -0
  66. package/package.json +163 -4
@@ -0,0 +1,83 @@
1
+ import type { Editor } from "@milkdown/core";
2
+ import { type ReactNode } from "react";
3
+ import type { WorkBook } from "xlsx";
4
+ import type { EditorDocument } from "../core.js";
5
+ import type { ImagePreviewLabels, PreviewProvider } from "../index.js";
6
+ export type SpreadsheetWorkbook = WorkBook;
7
+ export interface PreviewLabels {
8
+ previousSheet: string;
9
+ nextSheet: string;
10
+ outlineEmpty: string;
11
+ editMarkdown: string;
12
+ copyCode: string;
13
+ toggleWrap: string;
14
+ loading: string;
15
+ openExternal: string;
16
+ legacyWord: string;
17
+ mediaUnsupported: string;
18
+ emptySheet: string;
19
+ worksheets: string;
20
+ bold: string;
21
+ italic: string;
22
+ outline: string;
23
+ page: string;
24
+ thumbnails: string;
25
+ zoomIn: string;
26
+ zoomOut: string;
27
+ resetZoom: string;
28
+ }
29
+ export declare const defaultPreviewLabels: PreviewLabels;
30
+ export declare function previewLabel(host: PreviewHost, key: keyof PreviewLabels): string;
31
+ export interface PreviewContext {
32
+ setToolbarActions?: (actions: ReactNode | null) => void;
33
+ readOnly: boolean;
34
+ onChange: (text: string) => void;
35
+ onSave: () => void;
36
+ onError: (error: unknown) => void;
37
+ }
38
+ export interface PreviewResource {
39
+ bytes: Uint8Array;
40
+ mimeType: string;
41
+ path: string;
42
+ }
43
+ export interface PreviewHost {
44
+ openLink?: (href: string) => Promise<void>;
45
+ htmlPreview?: {
46
+ open: (path: string, source: string) => Promise<{
47
+ url: string;
48
+ dispose: () => Promise<void>;
49
+ }>;
50
+ subscribe: (path: string, onChange: () => void, onError: (error: unknown) => void) => Promise<() => void>;
51
+ };
52
+ createMarkdownIntegration?: (document: EditorDocument, context: PreviewContext) => MarkdownIntegration;
53
+ htmlIntegration?: {
54
+ transform: (source: string, path: string) => string;
55
+ render: (iframe: {
56
+ current: HTMLIFrameElement | null;
57
+ }) => ReactNode;
58
+ };
59
+ allowRemoteResources?: boolean;
60
+ autoSaveDelay?: number;
61
+ labels?: Partial<PreviewLabels>;
62
+ imageLabels?: Partial<ImagePreviewLabels>;
63
+ parseSpreadsheet?: (bytes: Uint8Array, signal?: AbortSignal) => Promise<SpreadsheetWorkbook>;
64
+ pdfWorkerSrc: string;
65
+ resolveResource: (documentPath: string, reference: string) => Promise<PreviewResource>;
66
+ openExternal?: (path: string) => Promise<void>;
67
+ }
68
+ export interface MarkdownIntegration {
69
+ configure: (editor: Editor) => void;
70
+ ready: (editor: Editor) => Promise<void>;
71
+ dispose: () => void;
72
+ editable: () => boolean;
73
+ serialize: (markdown: string) => string;
74
+ applyExternal: (editor: Editor, document: EditorDocument) => boolean;
75
+ render: () => ReactNode;
76
+ }
77
+ export interface PreviewProps {
78
+ document: EditorDocument;
79
+ context: PreviewContext;
80
+ host: PreviewHost;
81
+ }
82
+ export declare function createPreviewProviders(host: PreviewHost): PreviewProvider[];
83
+ export { prepareHtmlPreview, previewCsp } from "./html-resources.js";
@@ -0,0 +1 @@
1
+ import{jsx as r}from"react/jsx-runtime";import{lazy as e,Suspense as l}from"react";import{prepareHtmlPreview as T,previewCsp as z}from"./html-resources.js";var p={previousSheet:"Previous sheet",nextSheet:"Next sheet",outlineEmpty:"No headings",editMarkdown:"Edit Markdown",copyCode:"Copy code",toggleWrap:"Toggle line wrapping",loading:"Loading preview…",openExternal:"Open externally",legacyWord:"Legacy .doc files require an external application.",mediaUnsupported:"This media format cannot be played. Open it externally.",emptySheet:"This sheet is empty.",worksheets:"Worksheets",bold:"Bold",italic:"Italic",outline:"Document outline",page:"Page",thumbnails:"Thumbnails",zoomIn:"Zoom in",zoomOut:"Zoom out",resetZoom:"Reset zoom"};function d(o,t){return o.labels?.[t]??p[t]}var c=e(()=>import("./pdf.js")),f=e(()=>import("./word.js")),u=e(()=>import("./excel.js")),x=e(()=>import("./html.js")),h=e(()=>import("./markdown.js")),w=e(()=>import("./tiff.js")),g=e(()=>import("./media.js"));function y(o){return[["pdf",/\.pdf$/i,c],["word",/\.(docx?|docm|dotx?|dotm)$/i,f],["excel",/\.(xlsx?|xlsm|xlsb|ods|csv)$/i,u],["html",/\.(html?|xhtml)$/i,x],["markdown",/\.(md|markdown|mdown|mdx)$/i,h],["tiff",/\.tiff?$/i,w],["media",/\.(mp3|mp4|m4a|m4v|aac|wav|wave|ogg|oga|ogv|webm|mov|flac|opus|aiff|aif)$/i,g]].map(([a,n,s])=>({id:a,supports:(i)=>n.test(i.path),render:(i,m)=>r(l,{fallback:r("div",{className:"alwith-preview-status",role:"status",children:d(o,"loading")}),children:r(s,{document:i,context:m,host:o})})}))}export{y as createPreviewProviders,p as defaultPreviewLabels,T as prepareHtmlPreview,z as previewCsp,d as previewLabel};
@@ -0,0 +1,6 @@
1
+ import { type PreviewHost } from "./index.js";
2
+ export declare function MarkdownOutline({ host, container }: {
3
+ host: PreviewHost;
4
+ container: HTMLElement | null;
5
+ revision: number;
6
+ }): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as p}from"react/jsx-runtime";import{Popover as o}from"@base-ui/react/popover";import{ListTreeIcon as c}from"lucide-react";import{useState as h}from"react";import{previewLabel as l}from"./index.js";function k({host:i,container:n}){let[r,a]=h(!1),s=r&&n?[...n.querySelectorAll("h1,h2,h3,h4,h5,h6")].filter((t)=>t.textContent?.trim()):[];return p(o.Root,{open:r,onOpenChange:a,children:[e(o.Trigger,{className:"alwith-markdown-action",title:l(i,"outline"),"aria-label":l(i,"outline"),children:e(c,{size:14})}),e(o.Portal,{children:e(o.Positioner,{align:"end",sideOffset:4,className:"alwith-markdown-outline-positioner",children:e(o.Popup,{className:"alwith-markdown-outline-popup","aria-label":l(i,"outline"),children:s.length===0?e("div",{className:"alwith-markdown-outline-empty",children:l(i,"outlineEmpty")}):e("ul",{children:s.map((t,m)=>e("li",{children:e("button",{type:"button",style:{paddingInlineStart:(Number(t.tagName.slice(1))-1)*12+8},onClick:()=>{t.scrollIntoView({block:"start",behavior:"smooth"}),a(!1)},children:t.textContent})},m))})})})})]})}export{k as MarkdownOutline};
@@ -0,0 +1,4 @@
1
+ import { type PreviewProps } from "./index.js";
2
+ export declare function MarkdownReadonly(props: PreviewProps & {
3
+ onSwitchToEditor: () => void;
4
+ }): import("react").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import{jsx as g,Fragment as z,jsxs as H}from"react/jsx-runtime";import{createChatMarkdown as D}from"@alwith/module-chat/markdown-rules";import F from"dompurify";import I from"katex";import{PencilIcon as W}from"lucide-react";import{useEffect as C,useEffectEvent as j,useRef as q,useState as N}from"react";import{createHighlighter as G}from"shiki";import{previewLabel as p}from"./index.js";import{MarkdownOutline as V}from"./markdown-outline.js";import{ErrorMessage as J,errorText as K}from"./shared.js";var B=D();B.use({extensions:[{name:"math",renderer(t){let m=t,f=m.text.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;");return`<span class="${m.display?"md-math-display":"md-math-inline"}">${f}</span>`}}]});var M=null;function Q(){return M??=G({themes:["github-dark","github-light"],langs:["typescript","javascript","tsx","jsx","python","rust","go","java","c","cpp","css","html","json","yaml","toml","bash","sh","xml","markdown","sql","ruby","php","swift","kotlin","scala","r","lua","vim","dockerfile","graphql"]}).catch((t)=>{throw M=null,t}),M}function ce(t){let m=q(null),f=q(t);f.current=t;let[O,T]=N(null),[E,P]=N(0),U=j(()=>t.document.path);C(()=>{if(!m.current)throw Error("Markdown preview container is missing");let d=m.current,w=!1,L=new Set,b=new Set,u=(n)=>{if(!w)T(K(n)),f.current.context.onError(n)};T(null);try{let n=document.createElement("template");n.innerHTML=B.parse(t.document.text.trim(),{async:!1});for(let e of n.content.querySelectorAll("img"))e.dataset.markdownSource=e.getAttribute("src")??"",e.removeAttribute("src"),e.removeAttribute("srcset");d.innerHTML=F.sanitize(n.innerHTML,{FORBID_TAGS:["style"],FORBID_ATTR:["style"]});for(let e of d.querySelectorAll(".md-math-display,.md-math-inline"))I.render(e.textContent??"",e,{displayMode:e.classList.contains("md-math-display"),throwOnError:!1});for(let e of d.querySelectorAll("img")){let r=e.dataset.markdownSource??"";if(delete e.dataset.markdownSource,e.removeAttribute("srcset"),e.removeAttribute("src"),!r)continue;if(/^data:image\//i.test(r)){e.src=r;continue}if(/^https:\/\//i.test(r)&&t.host.allowRemoteResources){e.referrerPolicy="no-referrer",e.src=r;continue}if(/^(?:[a-z][a-z\d+.-]*:|\/\/)/i.test(r)){u(Error(`Remote Markdown image is blocked: ${r}`));continue}t.host.resolveResource(U(),r).then((c)=>{if(w)return;if(!c.mimeType.startsWith("image/"))throw Error("Markdown resource is not an image");let i=URL.createObjectURL(new Blob([new Uint8Array(c.bytes).buffer],{type:c.mimeType}));L.add(i),e.src=i}).catch(u)}let h=[];for(let e of d.querySelectorAll("pre")){let r=e.querySelector("code");if(!r)continue;let c=r.textContent??"",i=[...r.classList].find((o)=>o.startsWith("language-"))?.slice(9)??"",a=document.createElement("div");if(a.className="alwith-markdown-code-block",e.before(a),a.append(e),i&&i!=="text"&&i!=="plaintext"){let o=document.createElement("div");o.className="alwith-markdown-code-language",o.textContent=i,a.prepend(o)}let k=c.split(`
2
+ `),R=k.at(-1)===""?k.length-1:k.length;if(R>1){let o=document.createElement("span");o.className="alwith-markdown-line-numbers",o.setAttribute("aria-hidden","true");for(let y=1;y<=R;y++){let x=document.createElement("span");x.className="alwith-markdown-line-number",x.textContent=String(y),o.append(x)}r.prepend(o)}let v=document.createElement("div");v.className="alwith-markdown-code-toolbar";let l=document.createElement("button");l.type="button",l.title=p(t.host,"toggleWrap"),l.setAttribute("aria-label",l.title),l.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18M3 12h15a3 3 0 1 1 0 6h-4m2-2-2 2 2 2M3 18h7"/></svg>',l.onclick=()=>{a.dataset.wrap=a.dataset.wrap==="true"?"false":"true",l.setAttribute("aria-pressed",a.dataset.wrap),l.dataset.active=a.dataset.wrap};let s=document.createElement("button");s.type="button",s.title=p(t.host,"copyCode"),s.setAttribute("aria-label",s.title),s.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>';let _=s.innerHTML;s.onclick=()=>{navigator.clipboard.writeText(c).then(()=>{if(w)return;s.innerHTML='<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6 9 17l-5-5"/></svg>';let o=setTimeout(()=>{b.delete(o),s.innerHTML=_},2000);b.add(o)}).catch(u)},v.append(l,s),a.append(v),h.push({code:r,text:c,language:i})}if(h.some((e)=>e.language))Q().then((e)=>{if(w)return;for(let r of h){if(!e.getLoadedLanguages().includes(r.language))continue;let c=document.createElement("div");c.innerHTML=e.codeToHtml(r.text,{lang:r.language,themes:{light:"github-light",dark:"github-dark"}});let i=c.querySelector("code");if(i){let a=r.code.querySelector(".alwith-markdown-line-numbers");if(r.code.replaceChildren(...i.childNodes),a)r.code.prepend(a)}}}).catch(u);P((e)=>e+1)}catch(n){u(n)}let S=(n)=>{let h=n.target.closest("a");if(!h)return;n.preventDefault();let e=h.getAttribute("href");if(e)f.current.host.openLink?.(e).catch(u)};return d.addEventListener("click",S),()=>{w=!0;for(let n of b)clearTimeout(n);d.removeEventListener("click",S);for(let n of L)URL.revokeObjectURL(n)}},[t.document.id,t.document.text,t.host]);let A=j((d)=>t.context.setToolbarActions?.(d));return C(()=>(A(H(z,{children:[g(V,{host:t.host,container:m.current,revision:E}),g("button",{type:"button",className:"alwith-markdown-action",title:p(t.host,"editMarkdown"),"aria-label":p(t.host,"editMarkdown"),onClick:t.onSwitchToEditor,children:g(W,{size:14})})]})),()=>A(null)),[t.context.setToolbarActions,t.host,t.onSwitchToEditor,E]),H("div",{className:"alwith-preview-markdown alwith-markdown-view",children:[g(J,{error:O}),g("div",{className:"alwith-markdown-scroll alwith-markdown-readonly",ref:m})]})}export{ce as MarkdownReadonly};