mf2dom 0.1.12 → 0.1.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.
- package/dist/mf2dom.cjs +1 -1
- package/dist/mf2dom.cjs.map +3 -3
- package/dist/mf2dom.esm.js +1 -1
- package/dist/mf2dom.esm.js.map +3 -3
- package/dist/mf2dom.min.js +1 -1
- package/dist/mf2dom.min.js.map +3 -3
- package/package.json +1 -1
package/dist/mf2dom.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var O=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var
|
|
1
|
+
"use strict";var O=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var Z=Object.prototype.hasOwnProperty;var q=(e,n)=>{for(var t in n)O(e,t,{get:n[t],enumerable:!0})},B=(e,n,t,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of z(n))!Z.call(e,r)&&r!==t&&O(e,r,{get:()=>n[r],enumerable:!(i=K(n,r))||i.enumerable});return e};var G=e=>B(O({},"__esModule",{value:!0}),e);var ye={};q(ye,{parseHtmlFragment:()=>U,render:()=>ge,renderItemElement:()=>me,renderItems:()=>he});module.exports=G(ye);var V={"h-entry":"article","h-feed":"section","h-event":"article","h-product":"article","h-recipe":"article","h-review":"article","h-resume":"article","h-adr":"address","h-cite":"blockquote","h-geo":"data"},J={"p-adr":"address","p-street-address":"span","p-extended-address":"span","p-locality":"span","p-region":"span","p-postal-code":"span","p-country-name":"span","p-name":"strong","p-summary":"p","p-note":"p","p-content":"p","p-description":"p","p-lyrics":"pre","p-author":"span"},P=new Set(["url","uid","photo","logo","video","audio","syndication","in-reply-to","like-of","repost-of","bookmark-of","follow-of","read-of","tag-of","location"]),k=new Set(["email"]),$=new Set(["tel"]),I=new Set(["published","updated","start","end","duration","bday","anniversary","rev"]),v=["photo","logo","featured","video","audio","name","honorific-prefix","given-name","additional-name","family-name","sort-string","honorific-suffix","nickname","ipa","author","summary","note","content","lyrics","description","published","updated","start","end","duration","bday","anniversary","rev","location","url","uid","syndication","in-reply-to","like-of","repost-of","bookmark-of","follow-of","read-of","read-status","email","tel","impp","adr","geo","latitude","longitude","altitude","street-address","extended-address","locality","region","postal-code","country-name","label","org","job-title","role","category","rsvp","attendee","key","sex","gender-identity"];function a(e,n,t){let i=document.createElement(e);if(n)for(let[r,d]of Object.entries(n))d!=null&&i.setAttribute(r,d);if(t)for(let r of t)i.append(r);return i}function w(e){return document.createTextNode(e)}function U(e){let n=document.createElement("template");return n.innerHTML=e,n.content}function Q(e){return typeof e=="object"&&e!==null&&"type"in e&&"properties"in e}function X(e){return typeof e=="object"&&e!==null&&"html"in e}function Y(e){return typeof e=="object"&&e!==null&&"value"in e&&("alt"in e||"srcset"in e)}var ee=/^(?:[a-zA-Z][a-zA-Z0-9+\-.]*:\/\/|\/)/;function C(e){return ee.test(e)}function N(e){let n=v.indexOf(e);return n>=0?n:v.length}function A(e){return Object.keys(e).sort((n,t)=>N(n)-N(t))}function g(...e){return e.filter(Boolean).join(" ")||void 0}function _(e,n){let t=n?.[e]?.rels;return t?.length?t.join(" "):void 0}function ne(e){for(let n of e)if(n in V)return V[n];return"div"}function te(e,n,t){return a("img",{class:t,src:n})}function re(e,n,t){return a("video",{class:t,src:n,controls:""})}function ie(e,n,t){return a("audio",{class:t,src:n,controls:""})}function se(e,n,t,i){return a("a",{class:n,href:e,rel:i},[t??e])}function oe(e,n){let t=e.startsWith("mailto:")?e:`mailto:${e}`,i=e.replace(/^mailto:/,"");return a("a",{class:n,href:t},[i])}function ae(e,n){let t=e.startsWith("tel:")?e:`tel:${e}`;return a("a",{class:n,href:t},[e])}function le(e,n){return a("time",{class:n,datetime:e},[e])}function de(e,n,t){let i=J[`p-${e}`]??"span";return a(i,{class:t},[n])}function ce(e,n){let t={class:`u-${e}`,src:n.value,alt:n.alt};return n.srcset&&Object.keys(n.srcset).length&&(t.srcset=Object.entries(n.srcset).sort(([i],[r])=>i.localeCompare(r)).map(([i,r])=>`${r} ${i}`).join(", ")),a("img",t)}function pe(e,n){let t=a("div",{class:`e-${e}`});return n.html?t.appendChild(U(n.html)):n.value&&(t.textContent=n.value),t}function ue(e,n){let t=a("ruby",{"aria-hidden":"true"});t.appendChild(a("strong",{class:"p-name"},[e])),t.appendChild(a("rp",void 0,["("]));let i=a("rt");return i.append(w("/ "),a("span",{class:"p-ipa"},[n]),w(" /")),t.appendChild(i),t.appendChild(a("rp",void 0,[")"])),t}function D(e,n,t,i){let r=e[0];if(r==="photo"||r==="logo")return te(r,n,g(...e.map(s=>`u-${s}`)));if(r==="video")return re(r,n,g(...e.map(s=>`u-${s}`)));if(r==="audio")return ie(r,n,g(...e.map(s=>`u-${s}`)));if(P.has(r)&&C(n))return se(n,g(...e.map(s=>`u-${s}`)),n,_(n,t));if(k.has(r))return oe(n,g(...e.map(s=>`u-${s}`)));if($.has(r))return ae(n,g(...e.map(s=>`p-${s}`)));if(I.has(r))return le(n,g(...e.map(s=>`dt-${s}`)));let d=g(...e.map(s=>`p-${s}`));return r==="name"&&i!=null?a(`h${i}`,{class:d},[n]):de(r,n,d)}function fe(e){return typeof e.html=="string"?"e":typeof e.value=="object"&&e.value!==null?"u":"p"}function H(e,n={}){let{extraClasses:t=[],asProperty:i=!1,propertyPrefix:r,relUrls:d,headingLevel:s}=n,u=e.properties,F=e.children??[],c=a(ne(e.type),{id:e.id,class:g(...t,...e.type)});if(i&&(r==="p"||r==="dt")&&"value"in e&&typeof e.value!="object"&&c.appendChild(a("data",{class:"value",value:String(e.value)})),i&&r==="e"&&typeof e.html=="string")return c.appendChild(U(e.html)),c;let j=i?e.value:void 0,m=new Set,T=null,E=u.name??[],x=u.ipa??[];if(E.length&&x.length){let l=typeof E[0]=="string"?E[0]:null,h=typeof x[0]=="string"?x[0]:null;l&&h&&(T=[l,h],m.add("name"),m.add("ipa"))}let L=null;if(!T&&!i){let l=u.url??[];if(E.length===1&&l.length===1){let h=typeof E[0]=="string"?E[0]:null,o=typeof l[0]=="string"?l[0]:null;if(h&&o&&C(o)){let p=["url"],y=u.uid??[];y.length===1&&y[0]===o&&(p.push("uid"),m.add("uid")),m.add("name"),m.add("url"),L=[h,o,p]}}}let S=new Set;for(let l of A(u)){if(l==="name"&&T){let o=ue(...T);if(s!=null){let p=a(`h${s}`);p.appendChild(o),c.appendChild(p)}else c.appendChild(o);T=null}if(l==="name"&&L){let[o,p,y]=L,b=g("p-name",...y.map(R=>`u-${R}`)),f=_(p,d),M=a("a",{class:b,href:p,rel:f},[o]);if(s!=null){let R=a(`h${s}`);R.appendChild(M),c.appendChild(R)}else c.appendChild(M);L=null}if(m.has(l))continue;let h=s!=null?Math.min(s+1,6):void 0;for(let o of u[l]){if(Q(o)){let p=fe(o);c.appendChild(H(o,{extraClasses:[`${p}-${l}`],asProperty:!0,propertyPrefix:p,relUrls:d,headingLevel:h}));continue}if(X(o)){c.appendChild(pe(l,o));continue}if(Y(o)){c.appendChild(ce(l,o));continue}if(i&&r==="p"&&l==="name"&&typeof j=="string"&&typeof o=="string"&&o!==j&&!o.startsWith("http://")&&!o.startsWith("https://")){c.appendChild(a("time",{class:"dt-name"},[o]));continue}if(typeof o=="string"){let p=P.has(l)&&C(o)?"url":k.has(l)?"email":$.has(l)?"tel":I.has(l)?"datetime":`text:${l}`,y=`${o}\0${p}`;if(S.has(y))continue;S.add(y);let b=[];for(let f of A(u))if(!m.has(f))for(let M of u[f]){if(typeof M!="string"||M!==o)continue;(P.has(f)&&C(M)?"url":k.has(f)?"email":$.has(f)?"tel":I.has(f)?"datetime":`text:${f}`)===p&&!b.includes(f)&&b.push(f)}c.appendChild(D(b,o,d,s));continue}c.appendChild(D([l],String(o),d,s))}}let W=s!=null?Math.min(s+1,6):void 0;for(let l of F)c.appendChild(H(l,{relUrls:d,headingLevel:W}));return c}function ge(e,n={}){let t=e["rel-urls"],{topHeading:i}=n,r=a("main");for(let d of e.items)r.appendChild(H(d,{relUrls:t,headingLevel:i}));if(t&&Object.keys(t).length){let d=a("nav");for(let s of Object.keys(t).sort()){let u=t[s];d.appendChild(a("a",{href:s,rel:u.rels?.length?u.rels.join(" "):void 0},[u.text??s]))}r.appendChild(d)}return n.asElement?r:r.outerHTML}function me(e,n={}){let{relUrls:t,topHeading:i}=n;return H(e,{relUrls:t,headingLevel:i})}function he(e,n={}){let{relUrls:t,topHeading:i}=n,r=document.createDocumentFragment();for(let d of e)r.appendChild(H(d,{relUrls:t,headingLevel:i}));return r}
|
|
2
2
|
//# sourceMappingURL=mf2dom.cjs.map
|
package/dist/mf2dom.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../renderer.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Microformats2 Renderer - Pure Programmatic DOM Building\n *\n * Renders mf2 JSON to semantic HTML by building the DOM tree programmatically.\n * Uses DocumentFragment for efficient batch updates with minimal reflows.\n */\n\nimport type {\n Mf2Document,\n Mf2Item,\n PropertyValue,\n EValue,\n UrlObject,\n RelUrl,\n} from \"./types.js\";\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\nconst SEMANTIC_ROOTS: Record<string, string> = {\n \"h-entry\": \"article\",\n \"h-feed\": \"section\",\n \"h-event\": \"article\",\n \"h-product\": \"article\",\n \"h-recipe\": \"article\",\n \"h-review\": \"article\",\n \"h-resume\": \"article\",\n \"h-adr\": \"address\",\n \"h-cite\": \"blockquote\",\n \"h-geo\": \"data\",\n};\n\nconst SEMANTIC_PROPS: Record<string, string> = {\n // Address components use address element\n \"p-adr\": \"address\",\n \"p-street-address\": \"span\",\n \"p-extended-address\": \"span\",\n \"p-locality\": \"span\",\n \"p-region\": \"span\",\n \"p-postal-code\": \"span\",\n \"p-country-name\": \"span\",\n // Name properties use strong for emphasis\n \"p-name\": \"strong\",\n // Paragraph-like properties\n \"p-summary\": \"p\",\n \"p-note\": \"p\",\n \"p-content\": \"p\",\n \"p-description\": \"p\",\n // Preformatted text (preserve line breaks)\n \"p-lyrics\": \"pre\",\n // Author info\n \"p-author\": \"span\",\n};\n\nconst URL_PROPS = new Set([\n \"url\", \"uid\", \"photo\", \"logo\", \"video\", \"audio\",\n \"syndication\", \"in-reply-to\", \"like-of\", \"repost-of\", \"bookmark-of\",\n \"follow-of\", \"read-of\", \"tag-of\", \"location\",\n]);\nconst EMAIL_PROPS = new Set([\"email\"]);\nconst TEL_PROPS = new Set([\"tel\"]);\nconst DT_PROPS = new Set([\n \"published\", \"updated\", \"start\", \"end\", \"duration\", \"bday\", \"anniversary\", \"rev\",\n]);\n\n// Semantic property ordering based on microformats.org wiki\n// Properties are grouped by semantic meaning for good display across types:\n// 1. Visual identity (photo, logo)\n// 2. Name/identity\n// 3. Author (for h-entry)\n// 4. Description/content\n// 5. Dates (important for h-entry, h-event)\n// 6. Location (for h-event, h-card)\n// 7. URLs and links\n// 8. Contact info (email, tel)\n// 9. Address details\n// 10. Organization/role\n// 11. Categories and other metadata\nconst PROP_ORDER = [\n // Visual/media first\n \"photo\",\n \"logo\",\n \"featured\",\n \"video\",\n \"audio\",\n // Name properties\n \"name\",\n \"honorific-prefix\",\n \"given-name\",\n \"additional-name\",\n \"family-name\",\n \"sort-string\",\n \"honorific-suffix\",\n \"nickname\",\n \"ipa\",\n // Author (important for h-entry)\n \"author\",\n // Description/content\n \"summary\",\n \"note\",\n \"content\",\n \"lyrics\",\n \"description\",\n // Dates (prominent for h-entry, h-event)\n \"published\",\n \"updated\",\n \"start\",\n \"end\",\n \"duration\",\n \"bday\",\n \"anniversary\",\n \"rev\",\n // Location (for h-event)\n \"location\",\n // URLs and links\n \"url\",\n \"uid\",\n \"syndication\",\n \"in-reply-to\",\n \"like-of\",\n \"repost-of\",\n \"bookmark-of\",\n \"follow-of\",\n \"read-of\",\n \"read-status\",\n // Contact info\n \"email\",\n \"tel\",\n \"impp\",\n // Address details\n \"adr\",\n \"geo\",\n \"latitude\",\n \"longitude\",\n \"altitude\",\n \"street-address\",\n \"extended-address\",\n \"locality\",\n \"region\",\n \"postal-code\",\n \"country-name\",\n \"label\",\n // Organization/role\n \"org\",\n \"job-title\",\n \"role\",\n // Categories and metadata\n \"category\",\n \"rsvp\",\n \"attendee\",\n \"key\",\n \"sex\",\n \"gender-identity\",\n];\n\n// ============================================================================\n// DOM Builder Helpers\n// ============================================================================\n\n/** Create an element with attributes */\nfunction h<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElementTagNameMap[K];\nfunction h(\n tag: string,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElement;\nfunction h(\n tag: string,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElement {\n const el = document.createElement(tag);\n\n if (attrs) {\n for (const [k, v] of Object.entries(attrs)) {\n if (v != null) el.setAttribute(k, v);\n }\n }\n\n if (children) {\n for (const child of children) {\n el.append(child);\n }\n }\n\n return el;\n}\n\n/** Create a text node */\nfunction text(content: string): Text {\n return document.createTextNode(content);\n}\n\n/** Parse HTML string to DocumentFragment (only for e-* content) */\nfunction parseHtml(html: string): DocumentFragment {\n const tpl = document.createElement(\"template\");\n tpl.innerHTML = html;\n return tpl.content;\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nfunction isMf2Item(v: unknown): v is Mf2Item {\n return typeof v === \"object\" && v !== null && \"type\" in v && \"properties\" in v;\n}\n\nfunction isEValue(v: unknown): v is EValue {\n return typeof v === \"object\" && v !== null && \"html\" in v;\n}\n\nfunction isUrlObject(v: unknown): v is UrlObject {\n return typeof v === \"object\" && v !== null && \"value\" in v && (\"alt\" in v || \"srcset\" in v);\n}\n\nfunction isUrl(s: string): boolean {\n return s.startsWith(\"http://\") || s.startsWith(\"https://\") || s.startsWith(\"/\");\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction propOrder(p: string): number {\n const i = PROP_ORDER.indexOf(p);\n return i >= 0 ? i : PROP_ORDER.length;\n}\n\nfunction sortProps(props: Record<string, PropertyValue[]>): string[] {\n return Object.keys(props).sort((a, b) => propOrder(a) - propOrder(b));\n}\n\nfunction classes(...parts: (string | undefined)[]): string | undefined {\n const cls = parts.filter(Boolean).join(\" \");\n return cls || undefined;\n}\n\nfunction getRels(url: string, relUrls?: Record<string, RelUrl>): string | undefined {\n const rels = relUrls?.[url]?.rels;\n return rels?.length ? rels.join(\" \") : undefined;\n}\n\nfunction getTag(types: string[]): string {\n for (const t of types) {\n if (t in SEMANTIC_ROOTS) return SEMANTIC_ROOTS[t];\n }\n return \"div\";\n}\n\n// ============================================================================\n// Property Renderers\n// ============================================================================\n\nfunction renderPhoto(prop: string, url: string, cls: string): HTMLImageElement {\n // Don't include alt=\"\" - it changes the parsed output from string to {value, alt}\n return h(\"img\", { class: cls, src: url });\n}\n\nfunction renderVideo(prop: string, url: string, cls: string): HTMLVideoElement {\n return h(\"video\", { class: cls, src: url, controls: \"\" });\n}\n\nfunction renderAudio(prop: string, url: string, cls: string): HTMLAudioElement {\n return h(\"audio\", { class: cls, src: url, controls: \"\" });\n}\n\nfunction renderLink(\n url: string,\n cls: string,\n displayText?: string,\n rel?: string\n): HTMLAnchorElement {\n return h(\"a\", { class: cls, href: url, rel }, [displayText ?? url]);\n}\n\nfunction renderEmail(value: string, cls: string): HTMLAnchorElement {\n const href = value.startsWith(\"mailto:\") ? value : `mailto:${value}`;\n const display = value.replace(/^mailto:/, \"\");\n return h(\"a\", { class: cls, href }, [display]);\n}\n\nfunction renderTel(value: string, cls: string): HTMLAnchorElement {\n const href = value.startsWith(\"tel:\") ? value : `tel:${value}`;\n return h(\"a\", { class: cls, href }, [value]);\n}\n\nfunction renderTime(value: string, cls: string): HTMLTimeElement {\n return h(\"time\", { class: cls, datetime: value }, [value]);\n}\n\nfunction renderText(prop: string, value: string, cls: string): HTMLElement {\n const tag = SEMANTIC_PROPS[`p-${prop}`] ?? \"span\";\n return h(tag, { class: cls }, [value]);\n}\n\nfunction renderUrlObject(prop: string, obj: UrlObject): HTMLImageElement {\n const attrs: Record<string, string | undefined> = {\n class: `u-${prop}`,\n src: obj.value,\n alt: obj.alt,\n };\n\n if (obj.srcset && Object.keys(obj.srcset).length) {\n attrs.srcset = Object.entries(obj.srcset)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([k, v]) => `${v} ${k}`)\n .join(\", \");\n }\n\n return h(\"img\", attrs);\n}\n\nfunction renderEProperty(prop: string, value: EValue): HTMLDivElement {\n const div = h(\"div\", { class: `e-${prop}` });\n if (value.html) {\n div.appendChild(parseHtml(value.html));\n } else if (value.value) {\n div.textContent = value.value;\n }\n return div;\n}\n\nfunction renderRuby(name: string, ipa: string): HTMLElement {\n const ruby = h(\"ruby\", { \"aria-hidden\": \"true\" });\n\n ruby.appendChild(h(\"strong\", { class: \"p-name\" }, [name]));\n ruby.appendChild(h(\"rp\", undefined, [\"(\"]));\n\n const rt = h(\"rt\");\n rt.append(text(\"/ \"), h(\"span\", { class: \"p-ipa\" }, [ipa]), text(\" /\"));\n ruby.appendChild(rt);\n\n ruby.appendChild(h(\"rp\", undefined, [\")\"]));\n\n return ruby;\n}\n\n/** Render a string property value */\nfunction renderStringProp(\n props: string[],\n value: string,\n relUrls?: Record<string, RelUrl>,\n headingLevel?: number\n): HTMLElement {\n const prop = props[0];\n\n // Media elements\n if (prop === \"photo\" || prop === \"logo\") {\n return renderPhoto(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n if (prop === \"video\") {\n return renderVideo(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n if (prop === \"audio\") {\n return renderAudio(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n\n // URL properties\n if (URL_PROPS.has(prop) && isUrl(value)) {\n return renderLink(\n value,\n classes(...props.map(p => `u-${p}`))!,\n value,\n getRels(value, relUrls)\n );\n }\n\n // Email\n if (EMAIL_PROPS.has(prop)) {\n return renderEmail(value, classes(...props.map(p => `u-${p}`))!);\n }\n\n // Telephone\n if (TEL_PROPS.has(prop)) {\n return renderTel(value, classes(...props.map(p => `p-${p}`))!);\n }\n\n // Datetime\n if (DT_PROPS.has(prop)) {\n return renderTime(value, classes(...props.map(p => `dt-${p}`))!);\n }\n\n // Default text - use heading tag for name property if headingLevel is set\n const cls = classes(...props.map(p => `p-${p}`))!;\n if (prop === \"name\" && headingLevel != null) {\n return h(`h${headingLevel}` as keyof HTMLElementTagNameMap, { class: cls }, [value]);\n }\n return renderText(prop, value, cls);\n}\n\n// ============================================================================\n// Item Renderer\n// ============================================================================\n\ninterface ItemOptions {\n extraClasses?: string[];\n asProperty?: boolean;\n propertyPrefix?: string;\n relUrls?: Record<string, RelUrl>;\n headingLevel?: number;\n}\n\nfunction embeddedPrefix(item: Mf2Item): string {\n if (typeof item.html === \"string\") return \"e\";\n if (typeof item.value === \"object\" && item.value !== null) return \"u\";\n return \"p\";\n}\n\nfunction renderItem(item: Mf2Item, opts: ItemOptions = {}): HTMLElement {\n const { extraClasses = [], asProperty = false, propertyPrefix, relUrls, headingLevel } = opts;\n const props = item.properties;\n const children = item.children ?? [];\n\n // Create root element\n const el = h(getTag(item.type), {\n id: item.id,\n class: classes(...extraClasses, ...item.type),\n });\n\n // VCP data node for p/dt embedded items\n if (asProperty && (propertyPrefix === \"p\" || propertyPrefix === \"dt\")) {\n if (\"value\" in item && typeof item.value !== \"object\") {\n el.appendChild(h(\"data\", { class: \"value\", value: String(item.value) }));\n }\n }\n\n // e-* property with HTML\n if (asProperty && propertyPrefix === \"e\" && typeof item.html === \"string\") {\n el.appendChild(parseHtml(item.html));\n return el;\n }\n\n // Get embedded value for special name handling\n const embeddedValue = asProperty ? item.value : undefined;\n\n // Check for name+ipa ruby rendering\n const consumed = new Set<string>();\n let ruby: [string, string] | null = null;\n\n const names = props.name ?? [];\n const ipas = props.ipa ?? [];\n if (names.length && ipas.length) {\n const name = typeof names[0] === \"string\" ? names[0] : null;\n const ipa = typeof ipas[0] === \"string\" ? ipas[0] : null;\n if (name && ipa) {\n ruby = [name, ipa];\n consumed.add(\"name\");\n consumed.add(\"ipa\");\n }\n }\n\n // Check if name should be rendered as a link (single name + single URL, no ruby)\n // Don't apply when rendering as a property (changes value extraction on re-parse)\n // (name, url, list of url properties to include in class)\n let linkedName: [string, string, string[]] | null = null;\n if (!ruby && !asProperty) {\n const urls = props.url ?? [];\n if (names.length === 1 && urls.length === 1) {\n const nameVal = typeof names[0] === \"string\" ? names[0] : null;\n const urlVal = typeof urls[0] === \"string\" ? urls[0] : null;\n if (nameVal && urlVal && isUrl(urlVal)) {\n // Collect URL properties that share this URL value (like uid)\n const urlProps = [\"url\"];\n const uids = props.uid ?? [];\n if (uids.length === 1 && uids[0] === urlVal) {\n urlProps.push(\"uid\");\n consumed.add(\"uid\");\n }\n consumed.add(\"name\");\n consumed.add(\"url\");\n linkedName = [nameVal, urlVal, urlProps];\n }\n }\n }\n\n // Track rendered (value, category) pairs for grouping\n const rendered = new Set<string>();\n\n for (const prop of sortProps(props)) {\n // Insert ruby at name position\n if (prop === \"name\" && ruby) {\n const rubyEl = renderRuby(...ruby);\n if (headingLevel != null) {\n const heading = h(`h${headingLevel}` as keyof HTMLElementTagNameMap);\n heading.appendChild(rubyEl);\n el.appendChild(heading);\n } else {\n el.appendChild(rubyEl);\n }\n ruby = null;\n }\n\n // Render linked name at the position where \"name\" would appear\n if (prop === \"name\" && linkedName) {\n const [nameVal, urlVal, urlProps] = linkedName;\n const cls = classes(\"p-name\", ...urlProps.map(p => `u-${p}`));\n const rel = getRels(urlVal, relUrls);\n const linkEl = h(\"a\", { class: cls, href: urlVal, rel }, [nameVal]);\n if (headingLevel != null) {\n const heading = h(`h${headingLevel}` as keyof HTMLElementTagNameMap);\n heading.appendChild(linkEl);\n el.appendChild(heading);\n } else {\n el.appendChild(linkEl);\n }\n linkedName = null;\n }\n\n if (consumed.has(prop)) continue;\n\n // Calculate next heading level for embedded items (increment, cap at 6)\n const childHeading = headingLevel != null ? Math.min(headingLevel + 1, 6) : undefined;\n\n for (const v of props[prop]) {\n // Embedded mf2 item\n if (isMf2Item(v)) {\n const prefix = embeddedPrefix(v);\n el.appendChild(renderItem(v, {\n extraClasses: [`${prefix}-${prop}`],\n asProperty: true,\n propertyPrefix: prefix,\n relUrls,\n headingLevel: childHeading,\n }));\n continue;\n }\n\n // e-* HTML content\n if (isEValue(v)) {\n el.appendChild(renderEProperty(prop, v));\n continue;\n }\n\n // URL object (img with alt/srcset)\n if (isUrlObject(v)) {\n el.appendChild(renderUrlObject(prop, v));\n continue;\n }\n\n // If this item is itself embedded as a property, prefer dt-* for `name`\n // when its representative value differs from its `properties.name[0]`.\n if (\n asProperty &&\n propertyPrefix === \"p\" &&\n prop === \"name\" &&\n typeof embeddedValue === \"string\" &&\n typeof v === \"string\" &&\n v !== embeddedValue &&\n !v.startsWith(\"http://\") &&\n !v.startsWith(\"https://\")\n ) {\n // Render as time element with dt-name class (no datetime attribute)\n el.appendChild(h(\"time\", { class: \"dt-name\" }, [v]));\n continue;\n }\n\n // String value - group by value for merged classes\n if (typeof v === \"string\") {\n const cat = URL_PROPS.has(prop) && isUrl(v) ? \"url\"\n : EMAIL_PROPS.has(prop) ? \"email\"\n : TEL_PROPS.has(prop) ? \"tel\"\n : DT_PROPS.has(prop) ? \"datetime\"\n : `text:${prop}`;\n\n const key = `${v}\\0${cat}`;\n if (rendered.has(key)) continue;\n rendered.add(key);\n\n // Collect all props with same value+category\n const group: string[] = [];\n for (const p of sortProps(props)) {\n if (consumed.has(p)) continue;\n for (const pv of props[p]) {\n if (typeof pv !== \"string\" || pv !== v) continue;\n const pCat = URL_PROPS.has(p) && isUrl(pv) ? \"url\"\n : EMAIL_PROPS.has(p) ? \"email\"\n : TEL_PROPS.has(p) ? \"tel\"\n : DT_PROPS.has(p) ? \"datetime\"\n : `text:${p}`;\n if (pCat === cat && !group.includes(p)) {\n group.push(p);\n }\n }\n }\n\n el.appendChild(renderStringProp(group, v, relUrls, headingLevel));\n continue;\n }\n\n // Fallback\n el.appendChild(renderStringProp([prop], String(v), relUrls, headingLevel));\n }\n }\n\n // Render children - calculate next heading level (increment, cap at 6)\n const childrenHeading = headingLevel != null ? Math.min(headingLevel + 1, 6) : undefined;\n for (const child of children) {\n el.appendChild(renderItem(child, { relUrls, headingLevel: childrenHeading }));\n }\n\n return el;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface RenderOptions {\n /** Return HTMLElement instead of string */\n asElement?: boolean;\n /** If set, render name properties as heading elements starting at this level (1-6).\n * Names in nested items use incrementing levels (capped at h6).\n * Default is undefined (render as <strong>). */\n topHeading?: number;\n}\n\n/**\n * Render an mf2 document to HTML.\n */\nexport function render(doc: Mf2Document, opts?: { asElement: true; topHeading?: number }): HTMLElement;\nexport function render(doc: Mf2Document, opts?: { asElement?: false; topHeading?: number }): string;\nexport function render(doc: Mf2Document, opts: RenderOptions = {}): string | HTMLElement {\n const relUrls = doc[\"rel-urls\"];\n const { topHeading } = opts;\n const main = h(\"main\");\n\n // Render items\n for (const item of doc.items) {\n main.appendChild(renderItem(item, { relUrls, headingLevel: topHeading }));\n }\n\n // Render rel-urls as nav\n if (relUrls && Object.keys(relUrls).length) {\n const nav = h(\"nav\");\n for (const url of Object.keys(relUrls).sort()) {\n const info = relUrls[url];\n nav.appendChild(h(\"a\", {\n href: url,\n rel: info.rels?.length ? info.rels.join(\" \") : undefined,\n }, [info.text ?? url]));\n }\n main.appendChild(nav);\n }\n\n return opts.asElement ? main : main.outerHTML;\n}\n\nexport interface RenderItemElementOptions {\n relUrls?: Record<string, RelUrl>;\n topHeading?: number;\n}\n\n/**\n * Render a single mf2 item to an HTMLElement.\n */\nexport function renderItemElement(\n item: Mf2Item,\n options: RenderItemElementOptions = {}\n): HTMLElement {\n const { relUrls, topHeading } = options;\n return renderItem(item, { relUrls, headingLevel: topHeading });\n}\n\nexport interface RenderItemsOptions {\n relUrls?: Record<string, RelUrl>;\n topHeading?: number;\n}\n\n/**\n * Render multiple items efficiently using DocumentFragment.\n */\nexport function renderItems(\n items: Mf2Item[],\n options: RenderItemsOptions = {}\n): DocumentFragment {\n const { relUrls, topHeading } = options;\n const fragment = document.createDocumentFragment();\n for (const item of items) {\n fragment.appendChild(renderItem(item, { relUrls, headingLevel: topHeading }));\n }\n return fragment;\n}\n\nexport { parseHtml as parseHtmlFragment };\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["renderer_exports", "__export", "parseHtml", "render", "renderItemElement", "renderItems", "__toCommonJS", "SEMANTIC_ROOTS", "SEMANTIC_PROPS", "URL_PROPS", "EMAIL_PROPS", "TEL_PROPS", "DT_PROPS", "PROP_ORDER", "h", "tag", "attrs", "children", "el", "k", "v", "child", "text", "content", "html", "tpl", "isMf2Item", "isEValue", "isUrlObject", "isUrl", "s", "propOrder", "p", "i", "sortProps", "props", "a", "b", "classes", "parts", "getRels", "url", "relUrls", "rels", "getTag", "types", "t", "renderPhoto", "prop", "cls", "renderVideo", "renderAudio", "renderLink", "displayText", "rel", "renderEmail", "value", "href", "display", "renderTel", "renderTime", "renderText", "renderUrlObject", "obj", "renderEProperty", "div", "renderRuby", "name", "ipa", "ruby", "rt", "renderStringProp", "headingLevel", "embeddedPrefix", "item", "renderItem", "opts", "extraClasses", "asProperty", "propertyPrefix", "embeddedValue", "consumed", "names", "ipas", "linkedName", "urls", "nameVal", "urlVal", "urlProps", "uids", "rendered", "rubyEl", "heading", "linkEl", "childHeading", "prefix", "cat", "key", "group", "pv", "childrenHeading", "doc", "topHeading", "main", "nav", "info", "options", "items", "fragment"]
|
|
4
|
+
"sourcesContent": ["/**\n * Microformats2 Renderer - Pure Programmatic DOM Building\n *\n * Renders mf2 JSON to semantic HTML by building the DOM tree programmatically.\n * Uses DocumentFragment for efficient batch updates with minimal reflows.\n */\n\nimport type {\n Mf2Document,\n Mf2Item,\n PropertyValue,\n EValue,\n UrlObject,\n RelUrl,\n} from \"./types.js\";\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\nconst SEMANTIC_ROOTS: Record<string, string> = {\n \"h-entry\": \"article\",\n \"h-feed\": \"section\",\n \"h-event\": \"article\",\n \"h-product\": \"article\",\n \"h-recipe\": \"article\",\n \"h-review\": \"article\",\n \"h-resume\": \"article\",\n \"h-adr\": \"address\",\n \"h-cite\": \"blockquote\",\n \"h-geo\": \"data\",\n};\n\nconst SEMANTIC_PROPS: Record<string, string> = {\n // Address components use address element\n \"p-adr\": \"address\",\n \"p-street-address\": \"span\",\n \"p-extended-address\": \"span\",\n \"p-locality\": \"span\",\n \"p-region\": \"span\",\n \"p-postal-code\": \"span\",\n \"p-country-name\": \"span\",\n // Name properties use strong for emphasis\n \"p-name\": \"strong\",\n // Paragraph-like properties\n \"p-summary\": \"p\",\n \"p-note\": \"p\",\n \"p-content\": \"p\",\n \"p-description\": \"p\",\n // Preformatted text (preserve line breaks)\n \"p-lyrics\": \"pre\",\n // Author info\n \"p-author\": \"span\",\n};\n\nconst URL_PROPS = new Set([\n \"url\", \"uid\", \"photo\", \"logo\", \"video\", \"audio\",\n \"syndication\", \"in-reply-to\", \"like-of\", \"repost-of\", \"bookmark-of\",\n \"follow-of\", \"read-of\", \"tag-of\", \"location\",\n]);\nconst EMAIL_PROPS = new Set([\"email\"]);\nconst TEL_PROPS = new Set([\"tel\"]);\nconst DT_PROPS = new Set([\n \"published\", \"updated\", \"start\", \"end\", \"duration\", \"bday\", \"anniversary\", \"rev\",\n]);\n\n// Semantic property ordering based on microformats.org wiki\n// Properties are grouped by semantic meaning for good display across types:\n// 1. Visual identity (photo, logo)\n// 2. Name/identity\n// 3. Author (for h-entry)\n// 4. Description/content\n// 5. Dates (important for h-entry, h-event)\n// 6. Location (for h-event, h-card)\n// 7. URLs and links\n// 8. Contact info (email, tel)\n// 9. Address details\n// 10. Organization/role\n// 11. Categories and other metadata\nconst PROP_ORDER = [\n // Visual/media first\n \"photo\",\n \"logo\",\n \"featured\",\n \"video\",\n \"audio\",\n // Name properties\n \"name\",\n \"honorific-prefix\",\n \"given-name\",\n \"additional-name\",\n \"family-name\",\n \"sort-string\",\n \"honorific-suffix\",\n \"nickname\",\n \"ipa\",\n // Author (important for h-entry)\n \"author\",\n // Description/content\n \"summary\",\n \"note\",\n \"content\",\n \"lyrics\",\n \"description\",\n // Dates (prominent for h-entry, h-event)\n \"published\",\n \"updated\",\n \"start\",\n \"end\",\n \"duration\",\n \"bday\",\n \"anniversary\",\n \"rev\",\n // Location (for h-event)\n \"location\",\n // URLs and links\n \"url\",\n \"uid\",\n \"syndication\",\n \"in-reply-to\",\n \"like-of\",\n \"repost-of\",\n \"bookmark-of\",\n \"follow-of\",\n \"read-of\",\n \"read-status\",\n // Contact info\n \"email\",\n \"tel\",\n \"impp\",\n // Address details\n \"adr\",\n \"geo\",\n \"latitude\",\n \"longitude\",\n \"altitude\",\n \"street-address\",\n \"extended-address\",\n \"locality\",\n \"region\",\n \"postal-code\",\n \"country-name\",\n \"label\",\n // Organization/role\n \"org\",\n \"job-title\",\n \"role\",\n // Categories and metadata\n \"category\",\n \"rsvp\",\n \"attendee\",\n \"key\",\n \"sex\",\n \"gender-identity\",\n];\n\n// ============================================================================\n// DOM Builder Helpers\n// ============================================================================\n\n/** Create an element with attributes */\nfunction h<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElementTagNameMap[K];\nfunction h(\n tag: string,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElement;\nfunction h(\n tag: string,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElement {\n const el = document.createElement(tag);\n\n if (attrs) {\n for (const [k, v] of Object.entries(attrs)) {\n if (v != null) el.setAttribute(k, v);\n }\n }\n\n if (children) {\n for (const child of children) {\n el.append(child);\n }\n }\n\n return el;\n}\n\n/** Create a text node */\nfunction text(content: string): Text {\n return document.createTextNode(content);\n}\n\n/** Parse HTML string to DocumentFragment (only for e-* content) */\nfunction parseHtml(html: string): DocumentFragment {\n const tpl = document.createElement(\"template\");\n tpl.innerHTML = html;\n return tpl.content;\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nfunction isMf2Item(v: unknown): v is Mf2Item {\n return typeof v === \"object\" && v !== null && \"type\" in v && \"properties\" in v;\n}\n\nfunction isEValue(v: unknown): v is EValue {\n return typeof v === \"object\" && v !== null && \"html\" in v;\n}\n\nfunction isUrlObject(v: unknown): v is UrlObject {\n return typeof v === \"object\" && v !== null && \"value\" in v && (\"alt\" in v || \"srcset\" in v);\n}\n\nconst URL_RE = /^(?:[a-zA-Z][a-zA-Z0-9+\\-.]*:\\/\\/|\\/)/;\n\nfunction isUrl(s: string): boolean {\n return URL_RE.test(s);\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction propOrder(p: string): number {\n const i = PROP_ORDER.indexOf(p);\n return i >= 0 ? i : PROP_ORDER.length;\n}\n\nfunction sortProps(props: Record<string, PropertyValue[]>): string[] {\n return Object.keys(props).sort((a, b) => propOrder(a) - propOrder(b));\n}\n\nfunction classes(...parts: (string | undefined)[]): string | undefined {\n const cls = parts.filter(Boolean).join(\" \");\n return cls || undefined;\n}\n\nfunction getRels(url: string, relUrls?: Record<string, RelUrl>): string | undefined {\n const rels = relUrls?.[url]?.rels;\n return rels?.length ? rels.join(\" \") : undefined;\n}\n\nfunction getTag(types: string[]): string {\n for (const t of types) {\n if (t in SEMANTIC_ROOTS) return SEMANTIC_ROOTS[t];\n }\n return \"div\";\n}\n\n// ============================================================================\n// Property Renderers\n// ============================================================================\n\nfunction renderPhoto(prop: string, url: string, cls: string): HTMLImageElement {\n // Don't include alt=\"\" - it changes the parsed output from string to {value, alt}\n return h(\"img\", { class: cls, src: url });\n}\n\nfunction renderVideo(prop: string, url: string, cls: string): HTMLVideoElement {\n return h(\"video\", { class: cls, src: url, controls: \"\" });\n}\n\nfunction renderAudio(prop: string, url: string, cls: string): HTMLAudioElement {\n return h(\"audio\", { class: cls, src: url, controls: \"\" });\n}\n\nfunction renderLink(\n url: string,\n cls: string,\n displayText?: string,\n rel?: string\n): HTMLAnchorElement {\n return h(\"a\", { class: cls, href: url, rel }, [displayText ?? url]);\n}\n\nfunction renderEmail(value: string, cls: string): HTMLAnchorElement {\n const href = value.startsWith(\"mailto:\") ? value : `mailto:${value}`;\n const display = value.replace(/^mailto:/, \"\");\n return h(\"a\", { class: cls, href }, [display]);\n}\n\nfunction renderTel(value: string, cls: string): HTMLAnchorElement {\n const href = value.startsWith(\"tel:\") ? value : `tel:${value}`;\n return h(\"a\", { class: cls, href }, [value]);\n}\n\nfunction renderTime(value: string, cls: string): HTMLTimeElement {\n return h(\"time\", { class: cls, datetime: value }, [value]);\n}\n\nfunction renderText(prop: string, value: string, cls: string): HTMLElement {\n const tag = SEMANTIC_PROPS[`p-${prop}`] ?? \"span\";\n return h(tag, { class: cls }, [value]);\n}\n\nfunction renderUrlObject(prop: string, obj: UrlObject): HTMLImageElement {\n const attrs: Record<string, string | undefined> = {\n class: `u-${prop}`,\n src: obj.value,\n alt: obj.alt,\n };\n\n if (obj.srcset && Object.keys(obj.srcset).length) {\n attrs.srcset = Object.entries(obj.srcset)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([k, v]) => `${v} ${k}`)\n .join(\", \");\n }\n\n return h(\"img\", attrs);\n}\n\nfunction renderEProperty(prop: string, value: EValue): HTMLDivElement {\n const div = h(\"div\", { class: `e-${prop}` });\n if (value.html) {\n div.appendChild(parseHtml(value.html));\n } else if (value.value) {\n div.textContent = value.value;\n }\n return div;\n}\n\nfunction renderRuby(name: string, ipa: string): HTMLElement {\n const ruby = h(\"ruby\", { \"aria-hidden\": \"true\" });\n\n ruby.appendChild(h(\"strong\", { class: \"p-name\" }, [name]));\n ruby.appendChild(h(\"rp\", undefined, [\"(\"]));\n\n const rt = h(\"rt\");\n rt.append(text(\"/ \"), h(\"span\", { class: \"p-ipa\" }, [ipa]), text(\" /\"));\n ruby.appendChild(rt);\n\n ruby.appendChild(h(\"rp\", undefined, [\")\"]));\n\n return ruby;\n}\n\n/** Render a string property value */\nfunction renderStringProp(\n props: string[],\n value: string,\n relUrls?: Record<string, RelUrl>,\n headingLevel?: number\n): HTMLElement {\n const prop = props[0];\n\n // Media elements\n if (prop === \"photo\" || prop === \"logo\") {\n return renderPhoto(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n if (prop === \"video\") {\n return renderVideo(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n if (prop === \"audio\") {\n return renderAudio(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n\n // URL properties\n if (URL_PROPS.has(prop) && isUrl(value)) {\n return renderLink(\n value,\n classes(...props.map(p => `u-${p}`))!,\n value,\n getRels(value, relUrls)\n );\n }\n\n // Email\n if (EMAIL_PROPS.has(prop)) {\n return renderEmail(value, classes(...props.map(p => `u-${p}`))!);\n }\n\n // Telephone\n if (TEL_PROPS.has(prop)) {\n return renderTel(value, classes(...props.map(p => `p-${p}`))!);\n }\n\n // Datetime\n if (DT_PROPS.has(prop)) {\n return renderTime(value, classes(...props.map(p => `dt-${p}`))!);\n }\n\n // Default text - use heading tag for name property if headingLevel is set\n const cls = classes(...props.map(p => `p-${p}`))!;\n if (prop === \"name\" && headingLevel != null) {\n return h(`h${headingLevel}` as keyof HTMLElementTagNameMap, { class: cls }, [value]);\n }\n return renderText(prop, value, cls);\n}\n\n// ============================================================================\n// Item Renderer\n// ============================================================================\n\ninterface ItemOptions {\n extraClasses?: string[];\n asProperty?: boolean;\n propertyPrefix?: string;\n relUrls?: Record<string, RelUrl>;\n headingLevel?: number;\n}\n\nfunction embeddedPrefix(item: Mf2Item): string {\n if (typeof item.html === \"string\") return \"e\";\n if (typeof item.value === \"object\" && item.value !== null) return \"u\";\n return \"p\";\n}\n\nfunction renderItem(item: Mf2Item, opts: ItemOptions = {}): HTMLElement {\n const { extraClasses = [], asProperty = false, propertyPrefix, relUrls, headingLevel } = opts;\n const props = item.properties;\n const children = item.children ?? [];\n\n // Create root element\n const el = h(getTag(item.type), {\n id: item.id,\n class: classes(...extraClasses, ...item.type),\n });\n\n // VCP data node for p/dt embedded items\n if (asProperty && (propertyPrefix === \"p\" || propertyPrefix === \"dt\")) {\n if (\"value\" in item && typeof item.value !== \"object\") {\n el.appendChild(h(\"data\", { class: \"value\", value: String(item.value) }));\n }\n }\n\n // e-* property with HTML\n if (asProperty && propertyPrefix === \"e\" && typeof item.html === \"string\") {\n el.appendChild(parseHtml(item.html));\n return el;\n }\n\n // Get embedded value for special name handling\n const embeddedValue = asProperty ? item.value : undefined;\n\n // Check for name+ipa ruby rendering\n const consumed = new Set<string>();\n let ruby: [string, string] | null = null;\n\n const names = props.name ?? [];\n const ipas = props.ipa ?? [];\n if (names.length && ipas.length) {\n const name = typeof names[0] === \"string\" ? names[0] : null;\n const ipa = typeof ipas[0] === \"string\" ? ipas[0] : null;\n if (name && ipa) {\n ruby = [name, ipa];\n consumed.add(\"name\");\n consumed.add(\"ipa\");\n }\n }\n\n // Check if name should be rendered as a link (single name + single URL, no ruby)\n // Don't apply when rendering as a property (changes value extraction on re-parse)\n // (name, url, list of url properties to include in class)\n let linkedName: [string, string, string[]] | null = null;\n if (!ruby && !asProperty) {\n const urls = props.url ?? [];\n if (names.length === 1 && urls.length === 1) {\n const nameVal = typeof names[0] === \"string\" ? names[0] : null;\n const urlVal = typeof urls[0] === \"string\" ? urls[0] : null;\n if (nameVal && urlVal && isUrl(urlVal)) {\n // Collect URL properties that share this URL value (like uid)\n const urlProps = [\"url\"];\n const uids = props.uid ?? [];\n if (uids.length === 1 && uids[0] === urlVal) {\n urlProps.push(\"uid\");\n consumed.add(\"uid\");\n }\n consumed.add(\"name\");\n consumed.add(\"url\");\n linkedName = [nameVal, urlVal, urlProps];\n }\n }\n }\n\n // Track rendered (value, category) pairs for grouping\n const rendered = new Set<string>();\n\n for (const prop of sortProps(props)) {\n // Insert ruby at name position\n if (prop === \"name\" && ruby) {\n const rubyEl = renderRuby(...ruby);\n if (headingLevel != null) {\n const heading = h(`h${headingLevel}` as keyof HTMLElementTagNameMap);\n heading.appendChild(rubyEl);\n el.appendChild(heading);\n } else {\n el.appendChild(rubyEl);\n }\n ruby = null;\n }\n\n // Render linked name at the position where \"name\" would appear\n if (prop === \"name\" && linkedName) {\n const [nameVal, urlVal, urlProps] = linkedName;\n const cls = classes(\"p-name\", ...urlProps.map(p => `u-${p}`));\n const rel = getRels(urlVal, relUrls);\n const linkEl = h(\"a\", { class: cls, href: urlVal, rel }, [nameVal]);\n if (headingLevel != null) {\n const heading = h(`h${headingLevel}` as keyof HTMLElementTagNameMap);\n heading.appendChild(linkEl);\n el.appendChild(heading);\n } else {\n el.appendChild(linkEl);\n }\n linkedName = null;\n }\n\n if (consumed.has(prop)) continue;\n\n // Calculate next heading level for embedded items (increment, cap at 6)\n const childHeading = headingLevel != null ? Math.min(headingLevel + 1, 6) : undefined;\n\n for (const v of props[prop]) {\n // Embedded mf2 item\n if (isMf2Item(v)) {\n const prefix = embeddedPrefix(v);\n el.appendChild(renderItem(v, {\n extraClasses: [`${prefix}-${prop}`],\n asProperty: true,\n propertyPrefix: prefix,\n relUrls,\n headingLevel: childHeading,\n }));\n continue;\n }\n\n // e-* HTML content\n if (isEValue(v)) {\n el.appendChild(renderEProperty(prop, v));\n continue;\n }\n\n // URL object (img with alt/srcset)\n if (isUrlObject(v)) {\n el.appendChild(renderUrlObject(prop, v));\n continue;\n }\n\n // If this item is itself embedded as a property, prefer dt-* for `name`\n // when its representative value differs from its `properties.name[0]`.\n if (\n asProperty &&\n propertyPrefix === \"p\" &&\n prop === \"name\" &&\n typeof embeddedValue === \"string\" &&\n typeof v === \"string\" &&\n v !== embeddedValue &&\n !v.startsWith(\"http://\") &&\n !v.startsWith(\"https://\")\n ) {\n // Render as time element with dt-name class (no datetime attribute)\n el.appendChild(h(\"time\", { class: \"dt-name\" }, [v]));\n continue;\n }\n\n // String value - group by value for merged classes\n if (typeof v === \"string\") {\n const cat = URL_PROPS.has(prop) && isUrl(v) ? \"url\"\n : EMAIL_PROPS.has(prop) ? \"email\"\n : TEL_PROPS.has(prop) ? \"tel\"\n : DT_PROPS.has(prop) ? \"datetime\"\n : `text:${prop}`;\n\n const key = `${v}\\0${cat}`;\n if (rendered.has(key)) continue;\n rendered.add(key);\n\n // Collect all props with same value+category\n const group: string[] = [];\n for (const p of sortProps(props)) {\n if (consumed.has(p)) continue;\n for (const pv of props[p]) {\n if (typeof pv !== \"string\" || pv !== v) continue;\n const pCat = URL_PROPS.has(p) && isUrl(pv) ? \"url\"\n : EMAIL_PROPS.has(p) ? \"email\"\n : TEL_PROPS.has(p) ? \"tel\"\n : DT_PROPS.has(p) ? \"datetime\"\n : `text:${p}`;\n if (pCat === cat && !group.includes(p)) {\n group.push(p);\n }\n }\n }\n\n el.appendChild(renderStringProp(group, v, relUrls, headingLevel));\n continue;\n }\n\n // Fallback\n el.appendChild(renderStringProp([prop], String(v), relUrls, headingLevel));\n }\n }\n\n // Render children - calculate next heading level (increment, cap at 6)\n const childrenHeading = headingLevel != null ? Math.min(headingLevel + 1, 6) : undefined;\n for (const child of children) {\n el.appendChild(renderItem(child, { relUrls, headingLevel: childrenHeading }));\n }\n\n return el;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface RenderOptions {\n /** Return HTMLElement instead of string */\n asElement?: boolean;\n /** If set, render name properties as heading elements starting at this level (1-6).\n * Names in nested items use incrementing levels (capped at h6).\n * Default is undefined (render as <strong>). */\n topHeading?: number;\n}\n\n/**\n * Render an mf2 document to HTML.\n */\nexport function render(doc: Mf2Document, opts?: { asElement: true; topHeading?: number }): HTMLElement;\nexport function render(doc: Mf2Document, opts?: { asElement?: false; topHeading?: number }): string;\nexport function render(doc: Mf2Document, opts: RenderOptions = {}): string | HTMLElement {\n const relUrls = doc[\"rel-urls\"];\n const { topHeading } = opts;\n const main = h(\"main\");\n\n // Render items\n for (const item of doc.items) {\n main.appendChild(renderItem(item, { relUrls, headingLevel: topHeading }));\n }\n\n // Render rel-urls as nav\n if (relUrls && Object.keys(relUrls).length) {\n const nav = h(\"nav\");\n for (const url of Object.keys(relUrls).sort()) {\n const info = relUrls[url];\n nav.appendChild(h(\"a\", {\n href: url,\n rel: info.rels?.length ? info.rels.join(\" \") : undefined,\n }, [info.text ?? url]));\n }\n main.appendChild(nav);\n }\n\n return opts.asElement ? main : main.outerHTML;\n}\n\nexport interface RenderItemElementOptions {\n relUrls?: Record<string, RelUrl>;\n topHeading?: number;\n}\n\n/**\n * Render a single mf2 item to an HTMLElement.\n */\nexport function renderItemElement(\n item: Mf2Item,\n options: RenderItemElementOptions = {}\n): HTMLElement {\n const { relUrls, topHeading } = options;\n return renderItem(item, { relUrls, headingLevel: topHeading });\n}\n\nexport interface RenderItemsOptions {\n relUrls?: Record<string, RelUrl>;\n topHeading?: number;\n}\n\n/**\n * Render multiple items efficiently using DocumentFragment.\n */\nexport function renderItems(\n items: Mf2Item[],\n options: RenderItemsOptions = {}\n): DocumentFragment {\n const { relUrls, topHeading } = options;\n const fragment = document.createDocumentFragment();\n for (const item of items) {\n fragment.appendChild(renderItem(item, { relUrls, headingLevel: topHeading }));\n }\n return fragment;\n}\n\nexport { parseHtml as parseHtmlFragment };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["renderer_exports", "__export", "parseHtml", "render", "renderItemElement", "renderItems", "__toCommonJS", "SEMANTIC_ROOTS", "SEMANTIC_PROPS", "URL_PROPS", "EMAIL_PROPS", "TEL_PROPS", "DT_PROPS", "PROP_ORDER", "h", "tag", "attrs", "children", "el", "k", "v", "child", "text", "content", "html", "tpl", "isMf2Item", "isEValue", "isUrlObject", "URL_RE", "isUrl", "s", "propOrder", "p", "i", "sortProps", "props", "a", "b", "classes", "parts", "getRels", "url", "relUrls", "rels", "getTag", "types", "t", "renderPhoto", "prop", "cls", "renderVideo", "renderAudio", "renderLink", "displayText", "rel", "renderEmail", "value", "href", "display", "renderTel", "renderTime", "renderText", "renderUrlObject", "obj", "renderEProperty", "div", "renderRuby", "name", "ipa", "ruby", "rt", "renderStringProp", "headingLevel", "embeddedPrefix", "item", "renderItem", "opts", "extraClasses", "asProperty", "propertyPrefix", "embeddedValue", "consumed", "names", "ipas", "linkedName", "urls", "nameVal", "urlVal", "urlProps", "uids", "rendered", "rubyEl", "heading", "linkEl", "childHeading", "prefix", "cat", "key", "group", "pv", "childrenHeading", "doc", "topHeading", "main", "nav", "info", "options", "items", "fragment"]
|
|
7
7
|
}
|
package/dist/mf2dom.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var j={"h-entry":"article","h-feed":"section","h-event":"article","h-product":"article","h-recipe":"article","h-review":"article","h-resume":"article","h-adr":"address","h-cite":"blockquote","h-geo":"data"},
|
|
1
|
+
var j={"h-entry":"article","h-feed":"section","h-event":"article","h-product":"article","h-recipe":"article","h-review":"article","h-resume":"article","h-adr":"address","h-cite":"blockquote","h-geo":"data"},W={"p-adr":"address","p-street-address":"span","p-extended-address":"span","p-locality":"span","p-region":"span","p-postal-code":"span","p-country-name":"span","p-name":"strong","p-summary":"p","p-note":"p","p-content":"p","p-description":"p","p-lyrics":"pre","p-author":"span"},O=new Set(["url","uid","photo","logo","video","audio","syndication","in-reply-to","like-of","repost-of","bookmark-of","follow-of","read-of","tag-of","location"]),P=new Set(["email"]),k=new Set(["tel"]),$=new Set(["published","updated","start","end","duration","bday","anniversary","rev"]),S=["photo","logo","featured","video","audio","name","honorific-prefix","given-name","additional-name","family-name","sort-string","honorific-suffix","nickname","ipa","author","summary","note","content","lyrics","description","published","updated","start","end","duration","bday","anniversary","rev","location","url","uid","syndication","in-reply-to","like-of","repost-of","bookmark-of","follow-of","read-of","read-status","email","tel","impp","adr","geo","latitude","longitude","altitude","street-address","extended-address","locality","region","postal-code","country-name","label","org","job-title","role","category","rsvp","attendee","key","sex","gender-identity"];function a(e,n,t){let i=document.createElement(e);if(n)for(let[r,d]of Object.entries(n))d!=null&&i.setAttribute(r,d);if(t)for(let r of t)i.append(r);return i}function V(e){return document.createTextNode(e)}function A(e){let n=document.createElement("template");return n.innerHTML=e,n.content}function K(e){return typeof e=="object"&&e!==null&&"type"in e&&"properties"in e}function z(e){return typeof e=="object"&&e!==null&&"html"in e}function Z(e){return typeof e=="object"&&e!==null&&"value"in e&&("alt"in e||"srcset"in e)}var q=/^(?:[a-zA-Z][a-zA-Z0-9+\-.]*:\/\/|\/)/;function C(e){return q.test(e)}function v(e){let n=S.indexOf(e);return n>=0?n:S.length}function w(e){return Object.keys(e).sort((n,t)=>v(n)-v(t))}function g(...e){return e.filter(Boolean).join(" ")||void 0}function D(e,n){let t=n?.[e]?.rels;return t?.length?t.join(" "):void 0}function B(e){for(let n of e)if(n in j)return j[n];return"div"}function G(e,n,t){return a("img",{class:t,src:n})}function J(e,n,t){return a("video",{class:t,src:n,controls:""})}function Q(e,n,t){return a("audio",{class:t,src:n,controls:""})}function X(e,n,t,i){return a("a",{class:n,href:e,rel:i},[t??e])}function Y(e,n){let t=e.startsWith("mailto:")?e:`mailto:${e}`,i=e.replace(/^mailto:/,"");return a("a",{class:n,href:t},[i])}function ee(e,n){let t=e.startsWith("tel:")?e:`tel:${e}`;return a("a",{class:n,href:t},[e])}function ne(e,n){return a("time",{class:n,datetime:e},[e])}function te(e,n,t){let i=W[`p-${e}`]??"span";return a(i,{class:t},[n])}function re(e,n){let t={class:`u-${e}`,src:n.value,alt:n.alt};return n.srcset&&Object.keys(n.srcset).length&&(t.srcset=Object.entries(n.srcset).sort(([i],[r])=>i.localeCompare(r)).map(([i,r])=>`${r} ${i}`).join(", ")),a("img",t)}function ie(e,n){let t=a("div",{class:`e-${e}`});return n.html?t.appendChild(A(n.html)):n.value&&(t.textContent=n.value),t}function se(e,n){let t=a("ruby",{"aria-hidden":"true"});t.appendChild(a("strong",{class:"p-name"},[e])),t.appendChild(a("rp",void 0,["("]));let i=a("rt");return i.append(V("/ "),a("span",{class:"p-ipa"},[n]),V(" /")),t.appendChild(i),t.appendChild(a("rp",void 0,[")"])),t}function N(e,n,t,i){let r=e[0];if(r==="photo"||r==="logo")return G(r,n,g(...e.map(s=>`u-${s}`)));if(r==="video")return J(r,n,g(...e.map(s=>`u-${s}`)));if(r==="audio")return Q(r,n,g(...e.map(s=>`u-${s}`)));if(O.has(r)&&C(n))return X(n,g(...e.map(s=>`u-${s}`)),n,D(n,t));if(P.has(r))return Y(n,g(...e.map(s=>`u-${s}`)));if(k.has(r))return ee(n,g(...e.map(s=>`p-${s}`)));if($.has(r))return ne(n,g(...e.map(s=>`dt-${s}`)));let d=g(...e.map(s=>`p-${s}`));return r==="name"&&i!=null?a(`h${i}`,{class:d},[n]):te(r,n,d)}function oe(e){return typeof e.html=="string"?"e":typeof e.value=="object"&&e.value!==null?"u":"p"}function H(e,n={}){let{extraClasses:t=[],asProperty:i=!1,propertyPrefix:r,relUrls:d,headingLevel:s}=n,u=e.properties,_=e.children??[],c=a(B(e.type),{id:e.id,class:g(...t,...e.type)});if(i&&(r==="p"||r==="dt")&&"value"in e&&typeof e.value!="object"&&c.appendChild(a("data",{class:"value",value:String(e.value)})),i&&r==="e"&&typeof e.html=="string")return c.appendChild(A(e.html)),c;let I=i?e.value:void 0,m=new Set,T=null,E=u.name??[],x=u.ipa??[];if(E.length&&x.length){let l=typeof E[0]=="string"?E[0]:null,h=typeof x[0]=="string"?x[0]:null;l&&h&&(T=[l,h],m.add("name"),m.add("ipa"))}let L=null;if(!T&&!i){let l=u.url??[];if(E.length===1&&l.length===1){let h=typeof E[0]=="string"?E[0]:null,o=typeof l[0]=="string"?l[0]:null;if(h&&o&&C(o)){let p=["url"],y=u.uid??[];y.length===1&&y[0]===o&&(p.push("uid"),m.add("uid")),m.add("name"),m.add("url"),L=[h,o,p]}}}let U=new Set;for(let l of w(u)){if(l==="name"&&T){let o=se(...T);if(s!=null){let p=a(`h${s}`);p.appendChild(o),c.appendChild(p)}else c.appendChild(o);T=null}if(l==="name"&&L){let[o,p,y]=L,b=g("p-name",...y.map(R=>`u-${R}`)),f=D(p,d),M=a("a",{class:b,href:p,rel:f},[o]);if(s!=null){let R=a(`h${s}`);R.appendChild(M),c.appendChild(R)}else c.appendChild(M);L=null}if(m.has(l))continue;let h=s!=null?Math.min(s+1,6):void 0;for(let o of u[l]){if(K(o)){let p=oe(o);c.appendChild(H(o,{extraClasses:[`${p}-${l}`],asProperty:!0,propertyPrefix:p,relUrls:d,headingLevel:h}));continue}if(z(o)){c.appendChild(ie(l,o));continue}if(Z(o)){c.appendChild(re(l,o));continue}if(i&&r==="p"&&l==="name"&&typeof I=="string"&&typeof o=="string"&&o!==I&&!o.startsWith("http://")&&!o.startsWith("https://")){c.appendChild(a("time",{class:"dt-name"},[o]));continue}if(typeof o=="string"){let p=O.has(l)&&C(o)?"url":P.has(l)?"email":k.has(l)?"tel":$.has(l)?"datetime":`text:${l}`,y=`${o}\0${p}`;if(U.has(y))continue;U.add(y);let b=[];for(let f of w(u))if(!m.has(f))for(let M of u[f]){if(typeof M!="string"||M!==o)continue;(O.has(f)&&C(M)?"url":P.has(f)?"email":k.has(f)?"tel":$.has(f)?"datetime":`text:${f}`)===p&&!b.includes(f)&&b.push(f)}c.appendChild(N(b,o,d,s));continue}c.appendChild(N([l],String(o),d,s))}}let F=s!=null?Math.min(s+1,6):void 0;for(let l of _)c.appendChild(H(l,{relUrls:d,headingLevel:F}));return c}function ae(e,n={}){let t=e["rel-urls"],{topHeading:i}=n,r=a("main");for(let d of e.items)r.appendChild(H(d,{relUrls:t,headingLevel:i}));if(t&&Object.keys(t).length){let d=a("nav");for(let s of Object.keys(t).sort()){let u=t[s];d.appendChild(a("a",{href:s,rel:u.rels?.length?u.rels.join(" "):void 0},[u.text??s]))}r.appendChild(d)}return n.asElement?r:r.outerHTML}function le(e,n={}){let{relUrls:t,topHeading:i}=n;return H(e,{relUrls:t,headingLevel:i})}function de(e,n={}){let{relUrls:t,topHeading:i}=n,r=document.createDocumentFragment();for(let d of e)r.appendChild(H(d,{relUrls:t,headingLevel:i}));return r}export{A as parseHtmlFragment,ae as render,le as renderItemElement,de as renderItems};
|
|
2
2
|
//# sourceMappingURL=mf2dom.esm.js.map
|
package/dist/mf2dom.esm.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../renderer.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Microformats2 Renderer - Pure Programmatic DOM Building\n *\n * Renders mf2 JSON to semantic HTML by building the DOM tree programmatically.\n * Uses DocumentFragment for efficient batch updates with minimal reflows.\n */\n\nimport type {\n Mf2Document,\n Mf2Item,\n PropertyValue,\n EValue,\n UrlObject,\n RelUrl,\n} from \"./types.js\";\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\nconst SEMANTIC_ROOTS: Record<string, string> = {\n \"h-entry\": \"article\",\n \"h-feed\": \"section\",\n \"h-event\": \"article\",\n \"h-product\": \"article\",\n \"h-recipe\": \"article\",\n \"h-review\": \"article\",\n \"h-resume\": \"article\",\n \"h-adr\": \"address\",\n \"h-cite\": \"blockquote\",\n \"h-geo\": \"data\",\n};\n\nconst SEMANTIC_PROPS: Record<string, string> = {\n // Address components use address element\n \"p-adr\": \"address\",\n \"p-street-address\": \"span\",\n \"p-extended-address\": \"span\",\n \"p-locality\": \"span\",\n \"p-region\": \"span\",\n \"p-postal-code\": \"span\",\n \"p-country-name\": \"span\",\n // Name properties use strong for emphasis\n \"p-name\": \"strong\",\n // Paragraph-like properties\n \"p-summary\": \"p\",\n \"p-note\": \"p\",\n \"p-content\": \"p\",\n \"p-description\": \"p\",\n // Preformatted text (preserve line breaks)\n \"p-lyrics\": \"pre\",\n // Author info\n \"p-author\": \"span\",\n};\n\nconst URL_PROPS = new Set([\n \"url\", \"uid\", \"photo\", \"logo\", \"video\", \"audio\",\n \"syndication\", \"in-reply-to\", \"like-of\", \"repost-of\", \"bookmark-of\",\n \"follow-of\", \"read-of\", \"tag-of\", \"location\",\n]);\nconst EMAIL_PROPS = new Set([\"email\"]);\nconst TEL_PROPS = new Set([\"tel\"]);\nconst DT_PROPS = new Set([\n \"published\", \"updated\", \"start\", \"end\", \"duration\", \"bday\", \"anniversary\", \"rev\",\n]);\n\n// Semantic property ordering based on microformats.org wiki\n// Properties are grouped by semantic meaning for good display across types:\n// 1. Visual identity (photo, logo)\n// 2. Name/identity\n// 3. Author (for h-entry)\n// 4. Description/content\n// 5. Dates (important for h-entry, h-event)\n// 6. Location (for h-event, h-card)\n// 7. URLs and links\n// 8. Contact info (email, tel)\n// 9. Address details\n// 10. Organization/role\n// 11. Categories and other metadata\nconst PROP_ORDER = [\n // Visual/media first\n \"photo\",\n \"logo\",\n \"featured\",\n \"video\",\n \"audio\",\n // Name properties\n \"name\",\n \"honorific-prefix\",\n \"given-name\",\n \"additional-name\",\n \"family-name\",\n \"sort-string\",\n \"honorific-suffix\",\n \"nickname\",\n \"ipa\",\n // Author (important for h-entry)\n \"author\",\n // Description/content\n \"summary\",\n \"note\",\n \"content\",\n \"lyrics\",\n \"description\",\n // Dates (prominent for h-entry, h-event)\n \"published\",\n \"updated\",\n \"start\",\n \"end\",\n \"duration\",\n \"bday\",\n \"anniversary\",\n \"rev\",\n // Location (for h-event)\n \"location\",\n // URLs and links\n \"url\",\n \"uid\",\n \"syndication\",\n \"in-reply-to\",\n \"like-of\",\n \"repost-of\",\n \"bookmark-of\",\n \"follow-of\",\n \"read-of\",\n \"read-status\",\n // Contact info\n \"email\",\n \"tel\",\n \"impp\",\n // Address details\n \"adr\",\n \"geo\",\n \"latitude\",\n \"longitude\",\n \"altitude\",\n \"street-address\",\n \"extended-address\",\n \"locality\",\n \"region\",\n \"postal-code\",\n \"country-name\",\n \"label\",\n // Organization/role\n \"org\",\n \"job-title\",\n \"role\",\n // Categories and metadata\n \"category\",\n \"rsvp\",\n \"attendee\",\n \"key\",\n \"sex\",\n \"gender-identity\",\n];\n\n// ============================================================================\n// DOM Builder Helpers\n// ============================================================================\n\n/** Create an element with attributes */\nfunction h<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElementTagNameMap[K];\nfunction h(\n tag: string,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElement;\nfunction h(\n tag: string,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElement {\n const el = document.createElement(tag);\n\n if (attrs) {\n for (const [k, v] of Object.entries(attrs)) {\n if (v != null) el.setAttribute(k, v);\n }\n }\n\n if (children) {\n for (const child of children) {\n el.append(child);\n }\n }\n\n return el;\n}\n\n/** Create a text node */\nfunction text(content: string): Text {\n return document.createTextNode(content);\n}\n\n/** Parse HTML string to DocumentFragment (only for e-* content) */\nfunction parseHtml(html: string): DocumentFragment {\n const tpl = document.createElement(\"template\");\n tpl.innerHTML = html;\n return tpl.content;\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nfunction isMf2Item(v: unknown): v is Mf2Item {\n return typeof v === \"object\" && v !== null && \"type\" in v && \"properties\" in v;\n}\n\nfunction isEValue(v: unknown): v is EValue {\n return typeof v === \"object\" && v !== null && \"html\" in v;\n}\n\nfunction isUrlObject(v: unknown): v is UrlObject {\n return typeof v === \"object\" && v !== null && \"value\" in v && (\"alt\" in v || \"srcset\" in v);\n}\n\nfunction isUrl(s: string): boolean {\n return s.startsWith(\"http://\") || s.startsWith(\"https://\") || s.startsWith(\"/\");\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction propOrder(p: string): number {\n const i = PROP_ORDER.indexOf(p);\n return i >= 0 ? i : PROP_ORDER.length;\n}\n\nfunction sortProps(props: Record<string, PropertyValue[]>): string[] {\n return Object.keys(props).sort((a, b) => propOrder(a) - propOrder(b));\n}\n\nfunction classes(...parts: (string | undefined)[]): string | undefined {\n const cls = parts.filter(Boolean).join(\" \");\n return cls || undefined;\n}\n\nfunction getRels(url: string, relUrls?: Record<string, RelUrl>): string | undefined {\n const rels = relUrls?.[url]?.rels;\n return rels?.length ? rels.join(\" \") : undefined;\n}\n\nfunction getTag(types: string[]): string {\n for (const t of types) {\n if (t in SEMANTIC_ROOTS) return SEMANTIC_ROOTS[t];\n }\n return \"div\";\n}\n\n// ============================================================================\n// Property Renderers\n// ============================================================================\n\nfunction renderPhoto(prop: string, url: string, cls: string): HTMLImageElement {\n // Don't include alt=\"\" - it changes the parsed output from string to {value, alt}\n return h(\"img\", { class: cls, src: url });\n}\n\nfunction renderVideo(prop: string, url: string, cls: string): HTMLVideoElement {\n return h(\"video\", { class: cls, src: url, controls: \"\" });\n}\n\nfunction renderAudio(prop: string, url: string, cls: string): HTMLAudioElement {\n return h(\"audio\", { class: cls, src: url, controls: \"\" });\n}\n\nfunction renderLink(\n url: string,\n cls: string,\n displayText?: string,\n rel?: string\n): HTMLAnchorElement {\n return h(\"a\", { class: cls, href: url, rel }, [displayText ?? url]);\n}\n\nfunction renderEmail(value: string, cls: string): HTMLAnchorElement {\n const href = value.startsWith(\"mailto:\") ? value : `mailto:${value}`;\n const display = value.replace(/^mailto:/, \"\");\n return h(\"a\", { class: cls, href }, [display]);\n}\n\nfunction renderTel(value: string, cls: string): HTMLAnchorElement {\n const href = value.startsWith(\"tel:\") ? value : `tel:${value}`;\n return h(\"a\", { class: cls, href }, [value]);\n}\n\nfunction renderTime(value: string, cls: string): HTMLTimeElement {\n return h(\"time\", { class: cls, datetime: value }, [value]);\n}\n\nfunction renderText(prop: string, value: string, cls: string): HTMLElement {\n const tag = SEMANTIC_PROPS[`p-${prop}`] ?? \"span\";\n return h(tag, { class: cls }, [value]);\n}\n\nfunction renderUrlObject(prop: string, obj: UrlObject): HTMLImageElement {\n const attrs: Record<string, string | undefined> = {\n class: `u-${prop}`,\n src: obj.value,\n alt: obj.alt,\n };\n\n if (obj.srcset && Object.keys(obj.srcset).length) {\n attrs.srcset = Object.entries(obj.srcset)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([k, v]) => `${v} ${k}`)\n .join(\", \");\n }\n\n return h(\"img\", attrs);\n}\n\nfunction renderEProperty(prop: string, value: EValue): HTMLDivElement {\n const div = h(\"div\", { class: `e-${prop}` });\n if (value.html) {\n div.appendChild(parseHtml(value.html));\n } else if (value.value) {\n div.textContent = value.value;\n }\n return div;\n}\n\nfunction renderRuby(name: string, ipa: string): HTMLElement {\n const ruby = h(\"ruby\", { \"aria-hidden\": \"true\" });\n\n ruby.appendChild(h(\"strong\", { class: \"p-name\" }, [name]));\n ruby.appendChild(h(\"rp\", undefined, [\"(\"]));\n\n const rt = h(\"rt\");\n rt.append(text(\"/ \"), h(\"span\", { class: \"p-ipa\" }, [ipa]), text(\" /\"));\n ruby.appendChild(rt);\n\n ruby.appendChild(h(\"rp\", undefined, [\")\"]));\n\n return ruby;\n}\n\n/** Render a string property value */\nfunction renderStringProp(\n props: string[],\n value: string,\n relUrls?: Record<string, RelUrl>,\n headingLevel?: number\n): HTMLElement {\n const prop = props[0];\n\n // Media elements\n if (prop === \"photo\" || prop === \"logo\") {\n return renderPhoto(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n if (prop === \"video\") {\n return renderVideo(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n if (prop === \"audio\") {\n return renderAudio(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n\n // URL properties\n if (URL_PROPS.has(prop) && isUrl(value)) {\n return renderLink(\n value,\n classes(...props.map(p => `u-${p}`))!,\n value,\n getRels(value, relUrls)\n );\n }\n\n // Email\n if (EMAIL_PROPS.has(prop)) {\n return renderEmail(value, classes(...props.map(p => `u-${p}`))!);\n }\n\n // Telephone\n if (TEL_PROPS.has(prop)) {\n return renderTel(value, classes(...props.map(p => `p-${p}`))!);\n }\n\n // Datetime\n if (DT_PROPS.has(prop)) {\n return renderTime(value, classes(...props.map(p => `dt-${p}`))!);\n }\n\n // Default text - use heading tag for name property if headingLevel is set\n const cls = classes(...props.map(p => `p-${p}`))!;\n if (prop === \"name\" && headingLevel != null) {\n return h(`h${headingLevel}` as keyof HTMLElementTagNameMap, { class: cls }, [value]);\n }\n return renderText(prop, value, cls);\n}\n\n// ============================================================================\n// Item Renderer\n// ============================================================================\n\ninterface ItemOptions {\n extraClasses?: string[];\n asProperty?: boolean;\n propertyPrefix?: string;\n relUrls?: Record<string, RelUrl>;\n headingLevel?: number;\n}\n\nfunction embeddedPrefix(item: Mf2Item): string {\n if (typeof item.html === \"string\") return \"e\";\n if (typeof item.value === \"object\" && item.value !== null) return \"u\";\n return \"p\";\n}\n\nfunction renderItem(item: Mf2Item, opts: ItemOptions = {}): HTMLElement {\n const { extraClasses = [], asProperty = false, propertyPrefix, relUrls, headingLevel } = opts;\n const props = item.properties;\n const children = item.children ?? [];\n\n // Create root element\n const el = h(getTag(item.type), {\n id: item.id,\n class: classes(...extraClasses, ...item.type),\n });\n\n // VCP data node for p/dt embedded items\n if (asProperty && (propertyPrefix === \"p\" || propertyPrefix === \"dt\")) {\n if (\"value\" in item && typeof item.value !== \"object\") {\n el.appendChild(h(\"data\", { class: \"value\", value: String(item.value) }));\n }\n }\n\n // e-* property with HTML\n if (asProperty && propertyPrefix === \"e\" && typeof item.html === \"string\") {\n el.appendChild(parseHtml(item.html));\n return el;\n }\n\n // Get embedded value for special name handling\n const embeddedValue = asProperty ? item.value : undefined;\n\n // Check for name+ipa ruby rendering\n const consumed = new Set<string>();\n let ruby: [string, string] | null = null;\n\n const names = props.name ?? [];\n const ipas = props.ipa ?? [];\n if (names.length && ipas.length) {\n const name = typeof names[0] === \"string\" ? names[0] : null;\n const ipa = typeof ipas[0] === \"string\" ? ipas[0] : null;\n if (name && ipa) {\n ruby = [name, ipa];\n consumed.add(\"name\");\n consumed.add(\"ipa\");\n }\n }\n\n // Check if name should be rendered as a link (single name + single URL, no ruby)\n // Don't apply when rendering as a property (changes value extraction on re-parse)\n // (name, url, list of url properties to include in class)\n let linkedName: [string, string, string[]] | null = null;\n if (!ruby && !asProperty) {\n const urls = props.url ?? [];\n if (names.length === 1 && urls.length === 1) {\n const nameVal = typeof names[0] === \"string\" ? names[0] : null;\n const urlVal = typeof urls[0] === \"string\" ? urls[0] : null;\n if (nameVal && urlVal && isUrl(urlVal)) {\n // Collect URL properties that share this URL value (like uid)\n const urlProps = [\"url\"];\n const uids = props.uid ?? [];\n if (uids.length === 1 && uids[0] === urlVal) {\n urlProps.push(\"uid\");\n consumed.add(\"uid\");\n }\n consumed.add(\"name\");\n consumed.add(\"url\");\n linkedName = [nameVal, urlVal, urlProps];\n }\n }\n }\n\n // Track rendered (value, category) pairs for grouping\n const rendered = new Set<string>();\n\n for (const prop of sortProps(props)) {\n // Insert ruby at name position\n if (prop === \"name\" && ruby) {\n const rubyEl = renderRuby(...ruby);\n if (headingLevel != null) {\n const heading = h(`h${headingLevel}` as keyof HTMLElementTagNameMap);\n heading.appendChild(rubyEl);\n el.appendChild(heading);\n } else {\n el.appendChild(rubyEl);\n }\n ruby = null;\n }\n\n // Render linked name at the position where \"name\" would appear\n if (prop === \"name\" && linkedName) {\n const [nameVal, urlVal, urlProps] = linkedName;\n const cls = classes(\"p-name\", ...urlProps.map(p => `u-${p}`));\n const rel = getRels(urlVal, relUrls);\n const linkEl = h(\"a\", { class: cls, href: urlVal, rel }, [nameVal]);\n if (headingLevel != null) {\n const heading = h(`h${headingLevel}` as keyof HTMLElementTagNameMap);\n heading.appendChild(linkEl);\n el.appendChild(heading);\n } else {\n el.appendChild(linkEl);\n }\n linkedName = null;\n }\n\n if (consumed.has(prop)) continue;\n\n // Calculate next heading level for embedded items (increment, cap at 6)\n const childHeading = headingLevel != null ? Math.min(headingLevel + 1, 6) : undefined;\n\n for (const v of props[prop]) {\n // Embedded mf2 item\n if (isMf2Item(v)) {\n const prefix = embeddedPrefix(v);\n el.appendChild(renderItem(v, {\n extraClasses: [`${prefix}-${prop}`],\n asProperty: true,\n propertyPrefix: prefix,\n relUrls,\n headingLevel: childHeading,\n }));\n continue;\n }\n\n // e-* HTML content\n if (isEValue(v)) {\n el.appendChild(renderEProperty(prop, v));\n continue;\n }\n\n // URL object (img with alt/srcset)\n if (isUrlObject(v)) {\n el.appendChild(renderUrlObject(prop, v));\n continue;\n }\n\n // If this item is itself embedded as a property, prefer dt-* for `name`\n // when its representative value differs from its `properties.name[0]`.\n if (\n asProperty &&\n propertyPrefix === \"p\" &&\n prop === \"name\" &&\n typeof embeddedValue === \"string\" &&\n typeof v === \"string\" &&\n v !== embeddedValue &&\n !v.startsWith(\"http://\") &&\n !v.startsWith(\"https://\")\n ) {\n // Render as time element with dt-name class (no datetime attribute)\n el.appendChild(h(\"time\", { class: \"dt-name\" }, [v]));\n continue;\n }\n\n // String value - group by value for merged classes\n if (typeof v === \"string\") {\n const cat = URL_PROPS.has(prop) && isUrl(v) ? \"url\"\n : EMAIL_PROPS.has(prop) ? \"email\"\n : TEL_PROPS.has(prop) ? \"tel\"\n : DT_PROPS.has(prop) ? \"datetime\"\n : `text:${prop}`;\n\n const key = `${v}\\0${cat}`;\n if (rendered.has(key)) continue;\n rendered.add(key);\n\n // Collect all props with same value+category\n const group: string[] = [];\n for (const p of sortProps(props)) {\n if (consumed.has(p)) continue;\n for (const pv of props[p]) {\n if (typeof pv !== \"string\" || pv !== v) continue;\n const pCat = URL_PROPS.has(p) && isUrl(pv) ? \"url\"\n : EMAIL_PROPS.has(p) ? \"email\"\n : TEL_PROPS.has(p) ? \"tel\"\n : DT_PROPS.has(p) ? \"datetime\"\n : `text:${p}`;\n if (pCat === cat && !group.includes(p)) {\n group.push(p);\n }\n }\n }\n\n el.appendChild(renderStringProp(group, v, relUrls, headingLevel));\n continue;\n }\n\n // Fallback\n el.appendChild(renderStringProp([prop], String(v), relUrls, headingLevel));\n }\n }\n\n // Render children - calculate next heading level (increment, cap at 6)\n const childrenHeading = headingLevel != null ? Math.min(headingLevel + 1, 6) : undefined;\n for (const child of children) {\n el.appendChild(renderItem(child, { relUrls, headingLevel: childrenHeading }));\n }\n\n return el;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface RenderOptions {\n /** Return HTMLElement instead of string */\n asElement?: boolean;\n /** If set, render name properties as heading elements starting at this level (1-6).\n * Names in nested items use incrementing levels (capped at h6).\n * Default is undefined (render as <strong>). */\n topHeading?: number;\n}\n\n/**\n * Render an mf2 document to HTML.\n */\nexport function render(doc: Mf2Document, opts?: { asElement: true; topHeading?: number }): HTMLElement;\nexport function render(doc: Mf2Document, opts?: { asElement?: false; topHeading?: number }): string;\nexport function render(doc: Mf2Document, opts: RenderOptions = {}): string | HTMLElement {\n const relUrls = doc[\"rel-urls\"];\n const { topHeading } = opts;\n const main = h(\"main\");\n\n // Render items\n for (const item of doc.items) {\n main.appendChild(renderItem(item, { relUrls, headingLevel: topHeading }));\n }\n\n // Render rel-urls as nav\n if (relUrls && Object.keys(relUrls).length) {\n const nav = h(\"nav\");\n for (const url of Object.keys(relUrls).sort()) {\n const info = relUrls[url];\n nav.appendChild(h(\"a\", {\n href: url,\n rel: info.rels?.length ? info.rels.join(\" \") : undefined,\n }, [info.text ?? url]));\n }\n main.appendChild(nav);\n }\n\n return opts.asElement ? main : main.outerHTML;\n}\n\nexport interface RenderItemElementOptions {\n relUrls?: Record<string, RelUrl>;\n topHeading?: number;\n}\n\n/**\n * Render a single mf2 item to an HTMLElement.\n */\nexport function renderItemElement(\n item: Mf2Item,\n options: RenderItemElementOptions = {}\n): HTMLElement {\n const { relUrls, topHeading } = options;\n return renderItem(item, { relUrls, headingLevel: topHeading });\n}\n\nexport interface RenderItemsOptions {\n relUrls?: Record<string, RelUrl>;\n topHeading?: number;\n}\n\n/**\n * Render multiple items efficiently using DocumentFragment.\n */\nexport function renderItems(\n items: Mf2Item[],\n options: RenderItemsOptions = {}\n): DocumentFragment {\n const { relUrls, topHeading } = options;\n const fragment = document.createDocumentFragment();\n for (const item of items) {\n fragment.appendChild(renderItem(item, { relUrls, headingLevel: topHeading }));\n }\n return fragment;\n}\n\nexport { parseHtml as parseHtmlFragment };\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["SEMANTIC_ROOTS", "SEMANTIC_PROPS", "URL_PROPS", "EMAIL_PROPS", "TEL_PROPS", "DT_PROPS", "PROP_ORDER", "h", "tag", "attrs", "children", "el", "k", "v", "child", "text", "content", "parseHtml", "html", "tpl", "isMf2Item", "isEValue", "isUrlObject", "isUrl", "s", "propOrder", "p", "i", "sortProps", "props", "a", "b", "classes", "parts", "getRels", "url", "relUrls", "rels", "getTag", "types", "t", "renderPhoto", "prop", "cls", "renderVideo", "renderAudio", "renderLink", "displayText", "rel", "renderEmail", "value", "href", "display", "renderTel", "renderTime", "renderText", "renderUrlObject", "obj", "renderEProperty", "div", "renderRuby", "name", "ipa", "ruby", "rt", "renderStringProp", "headingLevel", "embeddedPrefix", "item", "renderItem", "opts", "extraClasses", "asProperty", "propertyPrefix", "embeddedValue", "consumed", "names", "ipas", "linkedName", "urls", "nameVal", "urlVal", "urlProps", "uids", "rendered", "rubyEl", "heading", "linkEl", "childHeading", "prefix", "cat", "key", "group", "pv", "childrenHeading", "render", "doc", "topHeading", "main", "nav", "info", "renderItemElement", "options", "renderItems", "items", "fragment"]
|
|
4
|
+
"sourcesContent": ["/**\n * Microformats2 Renderer - Pure Programmatic DOM Building\n *\n * Renders mf2 JSON to semantic HTML by building the DOM tree programmatically.\n * Uses DocumentFragment for efficient batch updates with minimal reflows.\n */\n\nimport type {\n Mf2Document,\n Mf2Item,\n PropertyValue,\n EValue,\n UrlObject,\n RelUrl,\n} from \"./types.js\";\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\nconst SEMANTIC_ROOTS: Record<string, string> = {\n \"h-entry\": \"article\",\n \"h-feed\": \"section\",\n \"h-event\": \"article\",\n \"h-product\": \"article\",\n \"h-recipe\": \"article\",\n \"h-review\": \"article\",\n \"h-resume\": \"article\",\n \"h-adr\": \"address\",\n \"h-cite\": \"blockquote\",\n \"h-geo\": \"data\",\n};\n\nconst SEMANTIC_PROPS: Record<string, string> = {\n // Address components use address element\n \"p-adr\": \"address\",\n \"p-street-address\": \"span\",\n \"p-extended-address\": \"span\",\n \"p-locality\": \"span\",\n \"p-region\": \"span\",\n \"p-postal-code\": \"span\",\n \"p-country-name\": \"span\",\n // Name properties use strong for emphasis\n \"p-name\": \"strong\",\n // Paragraph-like properties\n \"p-summary\": \"p\",\n \"p-note\": \"p\",\n \"p-content\": \"p\",\n \"p-description\": \"p\",\n // Preformatted text (preserve line breaks)\n \"p-lyrics\": \"pre\",\n // Author info\n \"p-author\": \"span\",\n};\n\nconst URL_PROPS = new Set([\n \"url\", \"uid\", \"photo\", \"logo\", \"video\", \"audio\",\n \"syndication\", \"in-reply-to\", \"like-of\", \"repost-of\", \"bookmark-of\",\n \"follow-of\", \"read-of\", \"tag-of\", \"location\",\n]);\nconst EMAIL_PROPS = new Set([\"email\"]);\nconst TEL_PROPS = new Set([\"tel\"]);\nconst DT_PROPS = new Set([\n \"published\", \"updated\", \"start\", \"end\", \"duration\", \"bday\", \"anniversary\", \"rev\",\n]);\n\n// Semantic property ordering based on microformats.org wiki\n// Properties are grouped by semantic meaning for good display across types:\n// 1. Visual identity (photo, logo)\n// 2. Name/identity\n// 3. Author (for h-entry)\n// 4. Description/content\n// 5. Dates (important for h-entry, h-event)\n// 6. Location (for h-event, h-card)\n// 7. URLs and links\n// 8. Contact info (email, tel)\n// 9. Address details\n// 10. Organization/role\n// 11. Categories and other metadata\nconst PROP_ORDER = [\n // Visual/media first\n \"photo\",\n \"logo\",\n \"featured\",\n \"video\",\n \"audio\",\n // Name properties\n \"name\",\n \"honorific-prefix\",\n \"given-name\",\n \"additional-name\",\n \"family-name\",\n \"sort-string\",\n \"honorific-suffix\",\n \"nickname\",\n \"ipa\",\n // Author (important for h-entry)\n \"author\",\n // Description/content\n \"summary\",\n \"note\",\n \"content\",\n \"lyrics\",\n \"description\",\n // Dates (prominent for h-entry, h-event)\n \"published\",\n \"updated\",\n \"start\",\n \"end\",\n \"duration\",\n \"bday\",\n \"anniversary\",\n \"rev\",\n // Location (for h-event)\n \"location\",\n // URLs and links\n \"url\",\n \"uid\",\n \"syndication\",\n \"in-reply-to\",\n \"like-of\",\n \"repost-of\",\n \"bookmark-of\",\n \"follow-of\",\n \"read-of\",\n \"read-status\",\n // Contact info\n \"email\",\n \"tel\",\n \"impp\",\n // Address details\n \"adr\",\n \"geo\",\n \"latitude\",\n \"longitude\",\n \"altitude\",\n \"street-address\",\n \"extended-address\",\n \"locality\",\n \"region\",\n \"postal-code\",\n \"country-name\",\n \"label\",\n // Organization/role\n \"org\",\n \"job-title\",\n \"role\",\n // Categories and metadata\n \"category\",\n \"rsvp\",\n \"attendee\",\n \"key\",\n \"sex\",\n \"gender-identity\",\n];\n\n// ============================================================================\n// DOM Builder Helpers\n// ============================================================================\n\n/** Create an element with attributes */\nfunction h<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElementTagNameMap[K];\nfunction h(\n tag: string,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElement;\nfunction h(\n tag: string,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElement {\n const el = document.createElement(tag);\n\n if (attrs) {\n for (const [k, v] of Object.entries(attrs)) {\n if (v != null) el.setAttribute(k, v);\n }\n }\n\n if (children) {\n for (const child of children) {\n el.append(child);\n }\n }\n\n return el;\n}\n\n/** Create a text node */\nfunction text(content: string): Text {\n return document.createTextNode(content);\n}\n\n/** Parse HTML string to DocumentFragment (only for e-* content) */\nfunction parseHtml(html: string): DocumentFragment {\n const tpl = document.createElement(\"template\");\n tpl.innerHTML = html;\n return tpl.content;\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nfunction isMf2Item(v: unknown): v is Mf2Item {\n return typeof v === \"object\" && v !== null && \"type\" in v && \"properties\" in v;\n}\n\nfunction isEValue(v: unknown): v is EValue {\n return typeof v === \"object\" && v !== null && \"html\" in v;\n}\n\nfunction isUrlObject(v: unknown): v is UrlObject {\n return typeof v === \"object\" && v !== null && \"value\" in v && (\"alt\" in v || \"srcset\" in v);\n}\n\nconst URL_RE = /^(?:[a-zA-Z][a-zA-Z0-9+\\-.]*:\\/\\/|\\/)/;\n\nfunction isUrl(s: string): boolean {\n return URL_RE.test(s);\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction propOrder(p: string): number {\n const i = PROP_ORDER.indexOf(p);\n return i >= 0 ? i : PROP_ORDER.length;\n}\n\nfunction sortProps(props: Record<string, PropertyValue[]>): string[] {\n return Object.keys(props).sort((a, b) => propOrder(a) - propOrder(b));\n}\n\nfunction classes(...parts: (string | undefined)[]): string | undefined {\n const cls = parts.filter(Boolean).join(\" \");\n return cls || undefined;\n}\n\nfunction getRels(url: string, relUrls?: Record<string, RelUrl>): string | undefined {\n const rels = relUrls?.[url]?.rels;\n return rels?.length ? rels.join(\" \") : undefined;\n}\n\nfunction getTag(types: string[]): string {\n for (const t of types) {\n if (t in SEMANTIC_ROOTS) return SEMANTIC_ROOTS[t];\n }\n return \"div\";\n}\n\n// ============================================================================\n// Property Renderers\n// ============================================================================\n\nfunction renderPhoto(prop: string, url: string, cls: string): HTMLImageElement {\n // Don't include alt=\"\" - it changes the parsed output from string to {value, alt}\n return h(\"img\", { class: cls, src: url });\n}\n\nfunction renderVideo(prop: string, url: string, cls: string): HTMLVideoElement {\n return h(\"video\", { class: cls, src: url, controls: \"\" });\n}\n\nfunction renderAudio(prop: string, url: string, cls: string): HTMLAudioElement {\n return h(\"audio\", { class: cls, src: url, controls: \"\" });\n}\n\nfunction renderLink(\n url: string,\n cls: string,\n displayText?: string,\n rel?: string\n): HTMLAnchorElement {\n return h(\"a\", { class: cls, href: url, rel }, [displayText ?? url]);\n}\n\nfunction renderEmail(value: string, cls: string): HTMLAnchorElement {\n const href = value.startsWith(\"mailto:\") ? value : `mailto:${value}`;\n const display = value.replace(/^mailto:/, \"\");\n return h(\"a\", { class: cls, href }, [display]);\n}\n\nfunction renderTel(value: string, cls: string): HTMLAnchorElement {\n const href = value.startsWith(\"tel:\") ? value : `tel:${value}`;\n return h(\"a\", { class: cls, href }, [value]);\n}\n\nfunction renderTime(value: string, cls: string): HTMLTimeElement {\n return h(\"time\", { class: cls, datetime: value }, [value]);\n}\n\nfunction renderText(prop: string, value: string, cls: string): HTMLElement {\n const tag = SEMANTIC_PROPS[`p-${prop}`] ?? \"span\";\n return h(tag, { class: cls }, [value]);\n}\n\nfunction renderUrlObject(prop: string, obj: UrlObject): HTMLImageElement {\n const attrs: Record<string, string | undefined> = {\n class: `u-${prop}`,\n src: obj.value,\n alt: obj.alt,\n };\n\n if (obj.srcset && Object.keys(obj.srcset).length) {\n attrs.srcset = Object.entries(obj.srcset)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([k, v]) => `${v} ${k}`)\n .join(\", \");\n }\n\n return h(\"img\", attrs);\n}\n\nfunction renderEProperty(prop: string, value: EValue): HTMLDivElement {\n const div = h(\"div\", { class: `e-${prop}` });\n if (value.html) {\n div.appendChild(parseHtml(value.html));\n } else if (value.value) {\n div.textContent = value.value;\n }\n return div;\n}\n\nfunction renderRuby(name: string, ipa: string): HTMLElement {\n const ruby = h(\"ruby\", { \"aria-hidden\": \"true\" });\n\n ruby.appendChild(h(\"strong\", { class: \"p-name\" }, [name]));\n ruby.appendChild(h(\"rp\", undefined, [\"(\"]));\n\n const rt = h(\"rt\");\n rt.append(text(\"/ \"), h(\"span\", { class: \"p-ipa\" }, [ipa]), text(\" /\"));\n ruby.appendChild(rt);\n\n ruby.appendChild(h(\"rp\", undefined, [\")\"]));\n\n return ruby;\n}\n\n/** Render a string property value */\nfunction renderStringProp(\n props: string[],\n value: string,\n relUrls?: Record<string, RelUrl>,\n headingLevel?: number\n): HTMLElement {\n const prop = props[0];\n\n // Media elements\n if (prop === \"photo\" || prop === \"logo\") {\n return renderPhoto(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n if (prop === \"video\") {\n return renderVideo(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n if (prop === \"audio\") {\n return renderAudio(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n\n // URL properties\n if (URL_PROPS.has(prop) && isUrl(value)) {\n return renderLink(\n value,\n classes(...props.map(p => `u-${p}`))!,\n value,\n getRels(value, relUrls)\n );\n }\n\n // Email\n if (EMAIL_PROPS.has(prop)) {\n return renderEmail(value, classes(...props.map(p => `u-${p}`))!);\n }\n\n // Telephone\n if (TEL_PROPS.has(prop)) {\n return renderTel(value, classes(...props.map(p => `p-${p}`))!);\n }\n\n // Datetime\n if (DT_PROPS.has(prop)) {\n return renderTime(value, classes(...props.map(p => `dt-${p}`))!);\n }\n\n // Default text - use heading tag for name property if headingLevel is set\n const cls = classes(...props.map(p => `p-${p}`))!;\n if (prop === \"name\" && headingLevel != null) {\n return h(`h${headingLevel}` as keyof HTMLElementTagNameMap, { class: cls }, [value]);\n }\n return renderText(prop, value, cls);\n}\n\n// ============================================================================\n// Item Renderer\n// ============================================================================\n\ninterface ItemOptions {\n extraClasses?: string[];\n asProperty?: boolean;\n propertyPrefix?: string;\n relUrls?: Record<string, RelUrl>;\n headingLevel?: number;\n}\n\nfunction embeddedPrefix(item: Mf2Item): string {\n if (typeof item.html === \"string\") return \"e\";\n if (typeof item.value === \"object\" && item.value !== null) return \"u\";\n return \"p\";\n}\n\nfunction renderItem(item: Mf2Item, opts: ItemOptions = {}): HTMLElement {\n const { extraClasses = [], asProperty = false, propertyPrefix, relUrls, headingLevel } = opts;\n const props = item.properties;\n const children = item.children ?? [];\n\n // Create root element\n const el = h(getTag(item.type), {\n id: item.id,\n class: classes(...extraClasses, ...item.type),\n });\n\n // VCP data node for p/dt embedded items\n if (asProperty && (propertyPrefix === \"p\" || propertyPrefix === \"dt\")) {\n if (\"value\" in item && typeof item.value !== \"object\") {\n el.appendChild(h(\"data\", { class: \"value\", value: String(item.value) }));\n }\n }\n\n // e-* property with HTML\n if (asProperty && propertyPrefix === \"e\" && typeof item.html === \"string\") {\n el.appendChild(parseHtml(item.html));\n return el;\n }\n\n // Get embedded value for special name handling\n const embeddedValue = asProperty ? item.value : undefined;\n\n // Check for name+ipa ruby rendering\n const consumed = new Set<string>();\n let ruby: [string, string] | null = null;\n\n const names = props.name ?? [];\n const ipas = props.ipa ?? [];\n if (names.length && ipas.length) {\n const name = typeof names[0] === \"string\" ? names[0] : null;\n const ipa = typeof ipas[0] === \"string\" ? ipas[0] : null;\n if (name && ipa) {\n ruby = [name, ipa];\n consumed.add(\"name\");\n consumed.add(\"ipa\");\n }\n }\n\n // Check if name should be rendered as a link (single name + single URL, no ruby)\n // Don't apply when rendering as a property (changes value extraction on re-parse)\n // (name, url, list of url properties to include in class)\n let linkedName: [string, string, string[]] | null = null;\n if (!ruby && !asProperty) {\n const urls = props.url ?? [];\n if (names.length === 1 && urls.length === 1) {\n const nameVal = typeof names[0] === \"string\" ? names[0] : null;\n const urlVal = typeof urls[0] === \"string\" ? urls[0] : null;\n if (nameVal && urlVal && isUrl(urlVal)) {\n // Collect URL properties that share this URL value (like uid)\n const urlProps = [\"url\"];\n const uids = props.uid ?? [];\n if (uids.length === 1 && uids[0] === urlVal) {\n urlProps.push(\"uid\");\n consumed.add(\"uid\");\n }\n consumed.add(\"name\");\n consumed.add(\"url\");\n linkedName = [nameVal, urlVal, urlProps];\n }\n }\n }\n\n // Track rendered (value, category) pairs for grouping\n const rendered = new Set<string>();\n\n for (const prop of sortProps(props)) {\n // Insert ruby at name position\n if (prop === \"name\" && ruby) {\n const rubyEl = renderRuby(...ruby);\n if (headingLevel != null) {\n const heading = h(`h${headingLevel}` as keyof HTMLElementTagNameMap);\n heading.appendChild(rubyEl);\n el.appendChild(heading);\n } else {\n el.appendChild(rubyEl);\n }\n ruby = null;\n }\n\n // Render linked name at the position where \"name\" would appear\n if (prop === \"name\" && linkedName) {\n const [nameVal, urlVal, urlProps] = linkedName;\n const cls = classes(\"p-name\", ...urlProps.map(p => `u-${p}`));\n const rel = getRels(urlVal, relUrls);\n const linkEl = h(\"a\", { class: cls, href: urlVal, rel }, [nameVal]);\n if (headingLevel != null) {\n const heading = h(`h${headingLevel}` as keyof HTMLElementTagNameMap);\n heading.appendChild(linkEl);\n el.appendChild(heading);\n } else {\n el.appendChild(linkEl);\n }\n linkedName = null;\n }\n\n if (consumed.has(prop)) continue;\n\n // Calculate next heading level for embedded items (increment, cap at 6)\n const childHeading = headingLevel != null ? Math.min(headingLevel + 1, 6) : undefined;\n\n for (const v of props[prop]) {\n // Embedded mf2 item\n if (isMf2Item(v)) {\n const prefix = embeddedPrefix(v);\n el.appendChild(renderItem(v, {\n extraClasses: [`${prefix}-${prop}`],\n asProperty: true,\n propertyPrefix: prefix,\n relUrls,\n headingLevel: childHeading,\n }));\n continue;\n }\n\n // e-* HTML content\n if (isEValue(v)) {\n el.appendChild(renderEProperty(prop, v));\n continue;\n }\n\n // URL object (img with alt/srcset)\n if (isUrlObject(v)) {\n el.appendChild(renderUrlObject(prop, v));\n continue;\n }\n\n // If this item is itself embedded as a property, prefer dt-* for `name`\n // when its representative value differs from its `properties.name[0]`.\n if (\n asProperty &&\n propertyPrefix === \"p\" &&\n prop === \"name\" &&\n typeof embeddedValue === \"string\" &&\n typeof v === \"string\" &&\n v !== embeddedValue &&\n !v.startsWith(\"http://\") &&\n !v.startsWith(\"https://\")\n ) {\n // Render as time element with dt-name class (no datetime attribute)\n el.appendChild(h(\"time\", { class: \"dt-name\" }, [v]));\n continue;\n }\n\n // String value - group by value for merged classes\n if (typeof v === \"string\") {\n const cat = URL_PROPS.has(prop) && isUrl(v) ? \"url\"\n : EMAIL_PROPS.has(prop) ? \"email\"\n : TEL_PROPS.has(prop) ? \"tel\"\n : DT_PROPS.has(prop) ? \"datetime\"\n : `text:${prop}`;\n\n const key = `${v}\\0${cat}`;\n if (rendered.has(key)) continue;\n rendered.add(key);\n\n // Collect all props with same value+category\n const group: string[] = [];\n for (const p of sortProps(props)) {\n if (consumed.has(p)) continue;\n for (const pv of props[p]) {\n if (typeof pv !== \"string\" || pv !== v) continue;\n const pCat = URL_PROPS.has(p) && isUrl(pv) ? \"url\"\n : EMAIL_PROPS.has(p) ? \"email\"\n : TEL_PROPS.has(p) ? \"tel\"\n : DT_PROPS.has(p) ? \"datetime\"\n : `text:${p}`;\n if (pCat === cat && !group.includes(p)) {\n group.push(p);\n }\n }\n }\n\n el.appendChild(renderStringProp(group, v, relUrls, headingLevel));\n continue;\n }\n\n // Fallback\n el.appendChild(renderStringProp([prop], String(v), relUrls, headingLevel));\n }\n }\n\n // Render children - calculate next heading level (increment, cap at 6)\n const childrenHeading = headingLevel != null ? Math.min(headingLevel + 1, 6) : undefined;\n for (const child of children) {\n el.appendChild(renderItem(child, { relUrls, headingLevel: childrenHeading }));\n }\n\n return el;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface RenderOptions {\n /** Return HTMLElement instead of string */\n asElement?: boolean;\n /** If set, render name properties as heading elements starting at this level (1-6).\n * Names in nested items use incrementing levels (capped at h6).\n * Default is undefined (render as <strong>). */\n topHeading?: number;\n}\n\n/**\n * Render an mf2 document to HTML.\n */\nexport function render(doc: Mf2Document, opts?: { asElement: true; topHeading?: number }): HTMLElement;\nexport function render(doc: Mf2Document, opts?: { asElement?: false; topHeading?: number }): string;\nexport function render(doc: Mf2Document, opts: RenderOptions = {}): string | HTMLElement {\n const relUrls = doc[\"rel-urls\"];\n const { topHeading } = opts;\n const main = h(\"main\");\n\n // Render items\n for (const item of doc.items) {\n main.appendChild(renderItem(item, { relUrls, headingLevel: topHeading }));\n }\n\n // Render rel-urls as nav\n if (relUrls && Object.keys(relUrls).length) {\n const nav = h(\"nav\");\n for (const url of Object.keys(relUrls).sort()) {\n const info = relUrls[url];\n nav.appendChild(h(\"a\", {\n href: url,\n rel: info.rels?.length ? info.rels.join(\" \") : undefined,\n }, [info.text ?? url]));\n }\n main.appendChild(nav);\n }\n\n return opts.asElement ? main : main.outerHTML;\n}\n\nexport interface RenderItemElementOptions {\n relUrls?: Record<string, RelUrl>;\n topHeading?: number;\n}\n\n/**\n * Render a single mf2 item to an HTMLElement.\n */\nexport function renderItemElement(\n item: Mf2Item,\n options: RenderItemElementOptions = {}\n): HTMLElement {\n const { relUrls, topHeading } = options;\n return renderItem(item, { relUrls, headingLevel: topHeading });\n}\n\nexport interface RenderItemsOptions {\n relUrls?: Record<string, RelUrl>;\n topHeading?: number;\n}\n\n/**\n * Render multiple items efficiently using DocumentFragment.\n */\nexport function renderItems(\n items: Mf2Item[],\n options: RenderItemsOptions = {}\n): DocumentFragment {\n const { relUrls, topHeading } = options;\n const fragment = document.createDocumentFragment();\n for (const item of items) {\n fragment.appendChild(renderItem(item, { relUrls, headingLevel: topHeading }));\n }\n return fragment;\n}\n\nexport { parseHtml as parseHtmlFragment };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["SEMANTIC_ROOTS", "SEMANTIC_PROPS", "URL_PROPS", "EMAIL_PROPS", "TEL_PROPS", "DT_PROPS", "PROP_ORDER", "h", "tag", "attrs", "children", "el", "k", "v", "child", "text", "content", "parseHtml", "html", "tpl", "isMf2Item", "isEValue", "isUrlObject", "URL_RE", "isUrl", "s", "propOrder", "p", "i", "sortProps", "props", "a", "b", "classes", "parts", "getRels", "url", "relUrls", "rels", "getTag", "types", "t", "renderPhoto", "prop", "cls", "renderVideo", "renderAudio", "renderLink", "displayText", "rel", "renderEmail", "value", "href", "display", "renderTel", "renderTime", "renderText", "renderUrlObject", "obj", "renderEProperty", "div", "renderRuby", "name", "ipa", "ruby", "rt", "renderStringProp", "headingLevel", "embeddedPrefix", "item", "renderItem", "opts", "extraClasses", "asProperty", "propertyPrefix", "embeddedValue", "consumed", "names", "ipas", "linkedName", "urls", "nameVal", "urlVal", "urlProps", "uids", "rendered", "rubyEl", "heading", "linkEl", "childHeading", "prefix", "cat", "key", "group", "pv", "childrenHeading", "render", "doc", "topHeading", "main", "nav", "info", "renderItemElement", "options", "renderItems", "items", "fragment"]
|
|
7
7
|
}
|
package/dist/mf2dom.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var mf2dom=(()=>{var O=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var
|
|
1
|
+
"use strict";var mf2dom=(()=>{var O=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var Z=Object.prototype.hasOwnProperty;var q=(e,n)=>{for(var t in n)O(e,t,{get:n[t],enumerable:!0})},B=(e,n,t,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of z(n))!Z.call(e,r)&&r!==t&&O(e,r,{get:()=>n[r],enumerable:!(i=K(n,r))||i.enumerable});return e};var G=e=>B(O({},"__esModule",{value:!0}),e);var ye={};q(ye,{parseHtmlFragment:()=>U,render:()=>ge,renderItemElement:()=>me,renderItems:()=>he});var V={"h-entry":"article","h-feed":"section","h-event":"article","h-product":"article","h-recipe":"article","h-review":"article","h-resume":"article","h-adr":"address","h-cite":"blockquote","h-geo":"data"},J={"p-adr":"address","p-street-address":"span","p-extended-address":"span","p-locality":"span","p-region":"span","p-postal-code":"span","p-country-name":"span","p-name":"strong","p-summary":"p","p-note":"p","p-content":"p","p-description":"p","p-lyrics":"pre","p-author":"span"},P=new Set(["url","uid","photo","logo","video","audio","syndication","in-reply-to","like-of","repost-of","bookmark-of","follow-of","read-of","tag-of","location"]),k=new Set(["email"]),$=new Set(["tel"]),I=new Set(["published","updated","start","end","duration","bday","anniversary","rev"]),v=["photo","logo","featured","video","audio","name","honorific-prefix","given-name","additional-name","family-name","sort-string","honorific-suffix","nickname","ipa","author","summary","note","content","lyrics","description","published","updated","start","end","duration","bday","anniversary","rev","location","url","uid","syndication","in-reply-to","like-of","repost-of","bookmark-of","follow-of","read-of","read-status","email","tel","impp","adr","geo","latitude","longitude","altitude","street-address","extended-address","locality","region","postal-code","country-name","label","org","job-title","role","category","rsvp","attendee","key","sex","gender-identity"];function a(e,n,t){let i=document.createElement(e);if(n)for(let[r,d]of Object.entries(n))d!=null&&i.setAttribute(r,d);if(t)for(let r of t)i.append(r);return i}function w(e){return document.createTextNode(e)}function U(e){let n=document.createElement("template");return n.innerHTML=e,n.content}function Q(e){return typeof e=="object"&&e!==null&&"type"in e&&"properties"in e}function X(e){return typeof e=="object"&&e!==null&&"html"in e}function Y(e){return typeof e=="object"&&e!==null&&"value"in e&&("alt"in e||"srcset"in e)}var ee=/^(?:[a-zA-Z][a-zA-Z0-9+\-.]*:\/\/|\/)/;function C(e){return ee.test(e)}function N(e){let n=v.indexOf(e);return n>=0?n:v.length}function A(e){return Object.keys(e).sort((n,t)=>N(n)-N(t))}function g(...e){return e.filter(Boolean).join(" ")||void 0}function _(e,n){let t=n?.[e]?.rels;return t?.length?t.join(" "):void 0}function ne(e){for(let n of e)if(n in V)return V[n];return"div"}function te(e,n,t){return a("img",{class:t,src:n})}function re(e,n,t){return a("video",{class:t,src:n,controls:""})}function ie(e,n,t){return a("audio",{class:t,src:n,controls:""})}function se(e,n,t,i){return a("a",{class:n,href:e,rel:i},[t??e])}function oe(e,n){let t=e.startsWith("mailto:")?e:`mailto:${e}`,i=e.replace(/^mailto:/,"");return a("a",{class:n,href:t},[i])}function ae(e,n){let t=e.startsWith("tel:")?e:`tel:${e}`;return a("a",{class:n,href:t},[e])}function le(e,n){return a("time",{class:n,datetime:e},[e])}function de(e,n,t){let i=J[`p-${e}`]??"span";return a(i,{class:t},[n])}function ce(e,n){let t={class:`u-${e}`,src:n.value,alt:n.alt};return n.srcset&&Object.keys(n.srcset).length&&(t.srcset=Object.entries(n.srcset).sort(([i],[r])=>i.localeCompare(r)).map(([i,r])=>`${r} ${i}`).join(", ")),a("img",t)}function pe(e,n){let t=a("div",{class:`e-${e}`});return n.html?t.appendChild(U(n.html)):n.value&&(t.textContent=n.value),t}function ue(e,n){let t=a("ruby",{"aria-hidden":"true"});t.appendChild(a("strong",{class:"p-name"},[e])),t.appendChild(a("rp",void 0,["("]));let i=a("rt");return i.append(w("/ "),a("span",{class:"p-ipa"},[n]),w(" /")),t.appendChild(i),t.appendChild(a("rp",void 0,[")"])),t}function D(e,n,t,i){let r=e[0];if(r==="photo"||r==="logo")return te(r,n,g(...e.map(s=>`u-${s}`)));if(r==="video")return re(r,n,g(...e.map(s=>`u-${s}`)));if(r==="audio")return ie(r,n,g(...e.map(s=>`u-${s}`)));if(P.has(r)&&C(n))return se(n,g(...e.map(s=>`u-${s}`)),n,_(n,t));if(k.has(r))return oe(n,g(...e.map(s=>`u-${s}`)));if($.has(r))return ae(n,g(...e.map(s=>`p-${s}`)));if(I.has(r))return le(n,g(...e.map(s=>`dt-${s}`)));let d=g(...e.map(s=>`p-${s}`));return r==="name"&&i!=null?a(`h${i}`,{class:d},[n]):de(r,n,d)}function fe(e){return typeof e.html=="string"?"e":typeof e.value=="object"&&e.value!==null?"u":"p"}function H(e,n={}){let{extraClasses:t=[],asProperty:i=!1,propertyPrefix:r,relUrls:d,headingLevel:s}=n,u=e.properties,F=e.children??[],c=a(ne(e.type),{id:e.id,class:g(...t,...e.type)});if(i&&(r==="p"||r==="dt")&&"value"in e&&typeof e.value!="object"&&c.appendChild(a("data",{class:"value",value:String(e.value)})),i&&r==="e"&&typeof e.html=="string")return c.appendChild(U(e.html)),c;let j=i?e.value:void 0,m=new Set,T=null,E=u.name??[],x=u.ipa??[];if(E.length&&x.length){let l=typeof E[0]=="string"?E[0]:null,h=typeof x[0]=="string"?x[0]:null;l&&h&&(T=[l,h],m.add("name"),m.add("ipa"))}let L=null;if(!T&&!i){let l=u.url??[];if(E.length===1&&l.length===1){let h=typeof E[0]=="string"?E[0]:null,o=typeof l[0]=="string"?l[0]:null;if(h&&o&&C(o)){let p=["url"],y=u.uid??[];y.length===1&&y[0]===o&&(p.push("uid"),m.add("uid")),m.add("name"),m.add("url"),L=[h,o,p]}}}let S=new Set;for(let l of A(u)){if(l==="name"&&T){let o=ue(...T);if(s!=null){let p=a(`h${s}`);p.appendChild(o),c.appendChild(p)}else c.appendChild(o);T=null}if(l==="name"&&L){let[o,p,y]=L,b=g("p-name",...y.map(R=>`u-${R}`)),f=_(p,d),M=a("a",{class:b,href:p,rel:f},[o]);if(s!=null){let R=a(`h${s}`);R.appendChild(M),c.appendChild(R)}else c.appendChild(M);L=null}if(m.has(l))continue;let h=s!=null?Math.min(s+1,6):void 0;for(let o of u[l]){if(Q(o)){let p=fe(o);c.appendChild(H(o,{extraClasses:[`${p}-${l}`],asProperty:!0,propertyPrefix:p,relUrls:d,headingLevel:h}));continue}if(X(o)){c.appendChild(pe(l,o));continue}if(Y(o)){c.appendChild(ce(l,o));continue}if(i&&r==="p"&&l==="name"&&typeof j=="string"&&typeof o=="string"&&o!==j&&!o.startsWith("http://")&&!o.startsWith("https://")){c.appendChild(a("time",{class:"dt-name"},[o]));continue}if(typeof o=="string"){let p=P.has(l)&&C(o)?"url":k.has(l)?"email":$.has(l)?"tel":I.has(l)?"datetime":`text:${l}`,y=`${o}\0${p}`;if(S.has(y))continue;S.add(y);let b=[];for(let f of A(u))if(!m.has(f))for(let M of u[f]){if(typeof M!="string"||M!==o)continue;(P.has(f)&&C(M)?"url":k.has(f)?"email":$.has(f)?"tel":I.has(f)?"datetime":`text:${f}`)===p&&!b.includes(f)&&b.push(f)}c.appendChild(D(b,o,d,s));continue}c.appendChild(D([l],String(o),d,s))}}let W=s!=null?Math.min(s+1,6):void 0;for(let l of F)c.appendChild(H(l,{relUrls:d,headingLevel:W}));return c}function ge(e,n={}){let t=e["rel-urls"],{topHeading:i}=n,r=a("main");for(let d of e.items)r.appendChild(H(d,{relUrls:t,headingLevel:i}));if(t&&Object.keys(t).length){let d=a("nav");for(let s of Object.keys(t).sort()){let u=t[s];d.appendChild(a("a",{href:s,rel:u.rels?.length?u.rels.join(" "):void 0},[u.text??s]))}r.appendChild(d)}return n.asElement?r:r.outerHTML}function me(e,n={}){let{relUrls:t,topHeading:i}=n;return H(e,{relUrls:t,headingLevel:i})}function he(e,n={}){let{relUrls:t,topHeading:i}=n,r=document.createDocumentFragment();for(let d of e)r.appendChild(H(d,{relUrls:t,headingLevel:i}));return r}return G(ye);})();
|
|
2
2
|
//# sourceMappingURL=mf2dom.min.js.map
|
package/dist/mf2dom.min.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../renderer.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Microformats2 Renderer - Pure Programmatic DOM Building\n *\n * Renders mf2 JSON to semantic HTML by building the DOM tree programmatically.\n * Uses DocumentFragment for efficient batch updates with minimal reflows.\n */\n\nimport type {\n Mf2Document,\n Mf2Item,\n PropertyValue,\n EValue,\n UrlObject,\n RelUrl,\n} from \"./types.js\";\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\nconst SEMANTIC_ROOTS: Record<string, string> = {\n \"h-entry\": \"article\",\n \"h-feed\": \"section\",\n \"h-event\": \"article\",\n \"h-product\": \"article\",\n \"h-recipe\": \"article\",\n \"h-review\": \"article\",\n \"h-resume\": \"article\",\n \"h-adr\": \"address\",\n \"h-cite\": \"blockquote\",\n \"h-geo\": \"data\",\n};\n\nconst SEMANTIC_PROPS: Record<string, string> = {\n // Address components use address element\n \"p-adr\": \"address\",\n \"p-street-address\": \"span\",\n \"p-extended-address\": \"span\",\n \"p-locality\": \"span\",\n \"p-region\": \"span\",\n \"p-postal-code\": \"span\",\n \"p-country-name\": \"span\",\n // Name properties use strong for emphasis\n \"p-name\": \"strong\",\n // Paragraph-like properties\n \"p-summary\": \"p\",\n \"p-note\": \"p\",\n \"p-content\": \"p\",\n \"p-description\": \"p\",\n // Preformatted text (preserve line breaks)\n \"p-lyrics\": \"pre\",\n // Author info\n \"p-author\": \"span\",\n};\n\nconst URL_PROPS = new Set([\n \"url\", \"uid\", \"photo\", \"logo\", \"video\", \"audio\",\n \"syndication\", \"in-reply-to\", \"like-of\", \"repost-of\", \"bookmark-of\",\n \"follow-of\", \"read-of\", \"tag-of\", \"location\",\n]);\nconst EMAIL_PROPS = new Set([\"email\"]);\nconst TEL_PROPS = new Set([\"tel\"]);\nconst DT_PROPS = new Set([\n \"published\", \"updated\", \"start\", \"end\", \"duration\", \"bday\", \"anniversary\", \"rev\",\n]);\n\n// Semantic property ordering based on microformats.org wiki\n// Properties are grouped by semantic meaning for good display across types:\n// 1. Visual identity (photo, logo)\n// 2. Name/identity\n// 3. Author (for h-entry)\n// 4. Description/content\n// 5. Dates (important for h-entry, h-event)\n// 6. Location (for h-event, h-card)\n// 7. URLs and links\n// 8. Contact info (email, tel)\n// 9. Address details\n// 10. Organization/role\n// 11. Categories and other metadata\nconst PROP_ORDER = [\n // Visual/media first\n \"photo\",\n \"logo\",\n \"featured\",\n \"video\",\n \"audio\",\n // Name properties\n \"name\",\n \"honorific-prefix\",\n \"given-name\",\n \"additional-name\",\n \"family-name\",\n \"sort-string\",\n \"honorific-suffix\",\n \"nickname\",\n \"ipa\",\n // Author (important for h-entry)\n \"author\",\n // Description/content\n \"summary\",\n \"note\",\n \"content\",\n \"lyrics\",\n \"description\",\n // Dates (prominent for h-entry, h-event)\n \"published\",\n \"updated\",\n \"start\",\n \"end\",\n \"duration\",\n \"bday\",\n \"anniversary\",\n \"rev\",\n // Location (for h-event)\n \"location\",\n // URLs and links\n \"url\",\n \"uid\",\n \"syndication\",\n \"in-reply-to\",\n \"like-of\",\n \"repost-of\",\n \"bookmark-of\",\n \"follow-of\",\n \"read-of\",\n \"read-status\",\n // Contact info\n \"email\",\n \"tel\",\n \"impp\",\n // Address details\n \"adr\",\n \"geo\",\n \"latitude\",\n \"longitude\",\n \"altitude\",\n \"street-address\",\n \"extended-address\",\n \"locality\",\n \"region\",\n \"postal-code\",\n \"country-name\",\n \"label\",\n // Organization/role\n \"org\",\n \"job-title\",\n \"role\",\n // Categories and metadata\n \"category\",\n \"rsvp\",\n \"attendee\",\n \"key\",\n \"sex\",\n \"gender-identity\",\n];\n\n// ============================================================================\n// DOM Builder Helpers\n// ============================================================================\n\n/** Create an element with attributes */\nfunction h<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElementTagNameMap[K];\nfunction h(\n tag: string,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElement;\nfunction h(\n tag: string,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElement {\n const el = document.createElement(tag);\n\n if (attrs) {\n for (const [k, v] of Object.entries(attrs)) {\n if (v != null) el.setAttribute(k, v);\n }\n }\n\n if (children) {\n for (const child of children) {\n el.append(child);\n }\n }\n\n return el;\n}\n\n/** Create a text node */\nfunction text(content: string): Text {\n return document.createTextNode(content);\n}\n\n/** Parse HTML string to DocumentFragment (only for e-* content) */\nfunction parseHtml(html: string): DocumentFragment {\n const tpl = document.createElement(\"template\");\n tpl.innerHTML = html;\n return tpl.content;\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nfunction isMf2Item(v: unknown): v is Mf2Item {\n return typeof v === \"object\" && v !== null && \"type\" in v && \"properties\" in v;\n}\n\nfunction isEValue(v: unknown): v is EValue {\n return typeof v === \"object\" && v !== null && \"html\" in v;\n}\n\nfunction isUrlObject(v: unknown): v is UrlObject {\n return typeof v === \"object\" && v !== null && \"value\" in v && (\"alt\" in v || \"srcset\" in v);\n}\n\nfunction isUrl(s: string): boolean {\n return s.startsWith(\"http://\") || s.startsWith(\"https://\") || s.startsWith(\"/\");\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction propOrder(p: string): number {\n const i = PROP_ORDER.indexOf(p);\n return i >= 0 ? i : PROP_ORDER.length;\n}\n\nfunction sortProps(props: Record<string, PropertyValue[]>): string[] {\n return Object.keys(props).sort((a, b) => propOrder(a) - propOrder(b));\n}\n\nfunction classes(...parts: (string | undefined)[]): string | undefined {\n const cls = parts.filter(Boolean).join(\" \");\n return cls || undefined;\n}\n\nfunction getRels(url: string, relUrls?: Record<string, RelUrl>): string | undefined {\n const rels = relUrls?.[url]?.rels;\n return rels?.length ? rels.join(\" \") : undefined;\n}\n\nfunction getTag(types: string[]): string {\n for (const t of types) {\n if (t in SEMANTIC_ROOTS) return SEMANTIC_ROOTS[t];\n }\n return \"div\";\n}\n\n// ============================================================================\n// Property Renderers\n// ============================================================================\n\nfunction renderPhoto(prop: string, url: string, cls: string): HTMLImageElement {\n // Don't include alt=\"\" - it changes the parsed output from string to {value, alt}\n return h(\"img\", { class: cls, src: url });\n}\n\nfunction renderVideo(prop: string, url: string, cls: string): HTMLVideoElement {\n return h(\"video\", { class: cls, src: url, controls: \"\" });\n}\n\nfunction renderAudio(prop: string, url: string, cls: string): HTMLAudioElement {\n return h(\"audio\", { class: cls, src: url, controls: \"\" });\n}\n\nfunction renderLink(\n url: string,\n cls: string,\n displayText?: string,\n rel?: string\n): HTMLAnchorElement {\n return h(\"a\", { class: cls, href: url, rel }, [displayText ?? url]);\n}\n\nfunction renderEmail(value: string, cls: string): HTMLAnchorElement {\n const href = value.startsWith(\"mailto:\") ? value : `mailto:${value}`;\n const display = value.replace(/^mailto:/, \"\");\n return h(\"a\", { class: cls, href }, [display]);\n}\n\nfunction renderTel(value: string, cls: string): HTMLAnchorElement {\n const href = value.startsWith(\"tel:\") ? value : `tel:${value}`;\n return h(\"a\", { class: cls, href }, [value]);\n}\n\nfunction renderTime(value: string, cls: string): HTMLTimeElement {\n return h(\"time\", { class: cls, datetime: value }, [value]);\n}\n\nfunction renderText(prop: string, value: string, cls: string): HTMLElement {\n const tag = SEMANTIC_PROPS[`p-${prop}`] ?? \"span\";\n return h(tag, { class: cls }, [value]);\n}\n\nfunction renderUrlObject(prop: string, obj: UrlObject): HTMLImageElement {\n const attrs: Record<string, string | undefined> = {\n class: `u-${prop}`,\n src: obj.value,\n alt: obj.alt,\n };\n\n if (obj.srcset && Object.keys(obj.srcset).length) {\n attrs.srcset = Object.entries(obj.srcset)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([k, v]) => `${v} ${k}`)\n .join(\", \");\n }\n\n return h(\"img\", attrs);\n}\n\nfunction renderEProperty(prop: string, value: EValue): HTMLDivElement {\n const div = h(\"div\", { class: `e-${prop}` });\n if (value.html) {\n div.appendChild(parseHtml(value.html));\n } else if (value.value) {\n div.textContent = value.value;\n }\n return div;\n}\n\nfunction renderRuby(name: string, ipa: string): HTMLElement {\n const ruby = h(\"ruby\", { \"aria-hidden\": \"true\" });\n\n ruby.appendChild(h(\"strong\", { class: \"p-name\" }, [name]));\n ruby.appendChild(h(\"rp\", undefined, [\"(\"]));\n\n const rt = h(\"rt\");\n rt.append(text(\"/ \"), h(\"span\", { class: \"p-ipa\" }, [ipa]), text(\" /\"));\n ruby.appendChild(rt);\n\n ruby.appendChild(h(\"rp\", undefined, [\")\"]));\n\n return ruby;\n}\n\n/** Render a string property value */\nfunction renderStringProp(\n props: string[],\n value: string,\n relUrls?: Record<string, RelUrl>,\n headingLevel?: number\n): HTMLElement {\n const prop = props[0];\n\n // Media elements\n if (prop === \"photo\" || prop === \"logo\") {\n return renderPhoto(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n if (prop === \"video\") {\n return renderVideo(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n if (prop === \"audio\") {\n return renderAudio(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n\n // URL properties\n if (URL_PROPS.has(prop) && isUrl(value)) {\n return renderLink(\n value,\n classes(...props.map(p => `u-${p}`))!,\n value,\n getRels(value, relUrls)\n );\n }\n\n // Email\n if (EMAIL_PROPS.has(prop)) {\n return renderEmail(value, classes(...props.map(p => `u-${p}`))!);\n }\n\n // Telephone\n if (TEL_PROPS.has(prop)) {\n return renderTel(value, classes(...props.map(p => `p-${p}`))!);\n }\n\n // Datetime\n if (DT_PROPS.has(prop)) {\n return renderTime(value, classes(...props.map(p => `dt-${p}`))!);\n }\n\n // Default text - use heading tag for name property if headingLevel is set\n const cls = classes(...props.map(p => `p-${p}`))!;\n if (prop === \"name\" && headingLevel != null) {\n return h(`h${headingLevel}` as keyof HTMLElementTagNameMap, { class: cls }, [value]);\n }\n return renderText(prop, value, cls);\n}\n\n// ============================================================================\n// Item Renderer\n// ============================================================================\n\ninterface ItemOptions {\n extraClasses?: string[];\n asProperty?: boolean;\n propertyPrefix?: string;\n relUrls?: Record<string, RelUrl>;\n headingLevel?: number;\n}\n\nfunction embeddedPrefix(item: Mf2Item): string {\n if (typeof item.html === \"string\") return \"e\";\n if (typeof item.value === \"object\" && item.value !== null) return \"u\";\n return \"p\";\n}\n\nfunction renderItem(item: Mf2Item, opts: ItemOptions = {}): HTMLElement {\n const { extraClasses = [], asProperty = false, propertyPrefix, relUrls, headingLevel } = opts;\n const props = item.properties;\n const children = item.children ?? [];\n\n // Create root element\n const el = h(getTag(item.type), {\n id: item.id,\n class: classes(...extraClasses, ...item.type),\n });\n\n // VCP data node for p/dt embedded items\n if (asProperty && (propertyPrefix === \"p\" || propertyPrefix === \"dt\")) {\n if (\"value\" in item && typeof item.value !== \"object\") {\n el.appendChild(h(\"data\", { class: \"value\", value: String(item.value) }));\n }\n }\n\n // e-* property with HTML\n if (asProperty && propertyPrefix === \"e\" && typeof item.html === \"string\") {\n el.appendChild(parseHtml(item.html));\n return el;\n }\n\n // Get embedded value for special name handling\n const embeddedValue = asProperty ? item.value : undefined;\n\n // Check for name+ipa ruby rendering\n const consumed = new Set<string>();\n let ruby: [string, string] | null = null;\n\n const names = props.name ?? [];\n const ipas = props.ipa ?? [];\n if (names.length && ipas.length) {\n const name = typeof names[0] === \"string\" ? names[0] : null;\n const ipa = typeof ipas[0] === \"string\" ? ipas[0] : null;\n if (name && ipa) {\n ruby = [name, ipa];\n consumed.add(\"name\");\n consumed.add(\"ipa\");\n }\n }\n\n // Check if name should be rendered as a link (single name + single URL, no ruby)\n // Don't apply when rendering as a property (changes value extraction on re-parse)\n // (name, url, list of url properties to include in class)\n let linkedName: [string, string, string[]] | null = null;\n if (!ruby && !asProperty) {\n const urls = props.url ?? [];\n if (names.length === 1 && urls.length === 1) {\n const nameVal = typeof names[0] === \"string\" ? names[0] : null;\n const urlVal = typeof urls[0] === \"string\" ? urls[0] : null;\n if (nameVal && urlVal && isUrl(urlVal)) {\n // Collect URL properties that share this URL value (like uid)\n const urlProps = [\"url\"];\n const uids = props.uid ?? [];\n if (uids.length === 1 && uids[0] === urlVal) {\n urlProps.push(\"uid\");\n consumed.add(\"uid\");\n }\n consumed.add(\"name\");\n consumed.add(\"url\");\n linkedName = [nameVal, urlVal, urlProps];\n }\n }\n }\n\n // Track rendered (value, category) pairs for grouping\n const rendered = new Set<string>();\n\n for (const prop of sortProps(props)) {\n // Insert ruby at name position\n if (prop === \"name\" && ruby) {\n const rubyEl = renderRuby(...ruby);\n if (headingLevel != null) {\n const heading = h(`h${headingLevel}` as keyof HTMLElementTagNameMap);\n heading.appendChild(rubyEl);\n el.appendChild(heading);\n } else {\n el.appendChild(rubyEl);\n }\n ruby = null;\n }\n\n // Render linked name at the position where \"name\" would appear\n if (prop === \"name\" && linkedName) {\n const [nameVal, urlVal, urlProps] = linkedName;\n const cls = classes(\"p-name\", ...urlProps.map(p => `u-${p}`));\n const rel = getRels(urlVal, relUrls);\n const linkEl = h(\"a\", { class: cls, href: urlVal, rel }, [nameVal]);\n if (headingLevel != null) {\n const heading = h(`h${headingLevel}` as keyof HTMLElementTagNameMap);\n heading.appendChild(linkEl);\n el.appendChild(heading);\n } else {\n el.appendChild(linkEl);\n }\n linkedName = null;\n }\n\n if (consumed.has(prop)) continue;\n\n // Calculate next heading level for embedded items (increment, cap at 6)\n const childHeading = headingLevel != null ? Math.min(headingLevel + 1, 6) : undefined;\n\n for (const v of props[prop]) {\n // Embedded mf2 item\n if (isMf2Item(v)) {\n const prefix = embeddedPrefix(v);\n el.appendChild(renderItem(v, {\n extraClasses: [`${prefix}-${prop}`],\n asProperty: true,\n propertyPrefix: prefix,\n relUrls,\n headingLevel: childHeading,\n }));\n continue;\n }\n\n // e-* HTML content\n if (isEValue(v)) {\n el.appendChild(renderEProperty(prop, v));\n continue;\n }\n\n // URL object (img with alt/srcset)\n if (isUrlObject(v)) {\n el.appendChild(renderUrlObject(prop, v));\n continue;\n }\n\n // If this item is itself embedded as a property, prefer dt-* for `name`\n // when its representative value differs from its `properties.name[0]`.\n if (\n asProperty &&\n propertyPrefix === \"p\" &&\n prop === \"name\" &&\n typeof embeddedValue === \"string\" &&\n typeof v === \"string\" &&\n v !== embeddedValue &&\n !v.startsWith(\"http://\") &&\n !v.startsWith(\"https://\")\n ) {\n // Render as time element with dt-name class (no datetime attribute)\n el.appendChild(h(\"time\", { class: \"dt-name\" }, [v]));\n continue;\n }\n\n // String value - group by value for merged classes\n if (typeof v === \"string\") {\n const cat = URL_PROPS.has(prop) && isUrl(v) ? \"url\"\n : EMAIL_PROPS.has(prop) ? \"email\"\n : TEL_PROPS.has(prop) ? \"tel\"\n : DT_PROPS.has(prop) ? \"datetime\"\n : `text:${prop}`;\n\n const key = `${v}\\0${cat}`;\n if (rendered.has(key)) continue;\n rendered.add(key);\n\n // Collect all props with same value+category\n const group: string[] = [];\n for (const p of sortProps(props)) {\n if (consumed.has(p)) continue;\n for (const pv of props[p]) {\n if (typeof pv !== \"string\" || pv !== v) continue;\n const pCat = URL_PROPS.has(p) && isUrl(pv) ? \"url\"\n : EMAIL_PROPS.has(p) ? \"email\"\n : TEL_PROPS.has(p) ? \"tel\"\n : DT_PROPS.has(p) ? \"datetime\"\n : `text:${p}`;\n if (pCat === cat && !group.includes(p)) {\n group.push(p);\n }\n }\n }\n\n el.appendChild(renderStringProp(group, v, relUrls, headingLevel));\n continue;\n }\n\n // Fallback\n el.appendChild(renderStringProp([prop], String(v), relUrls, headingLevel));\n }\n }\n\n // Render children - calculate next heading level (increment, cap at 6)\n const childrenHeading = headingLevel != null ? Math.min(headingLevel + 1, 6) : undefined;\n for (const child of children) {\n el.appendChild(renderItem(child, { relUrls, headingLevel: childrenHeading }));\n }\n\n return el;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface RenderOptions {\n /** Return HTMLElement instead of string */\n asElement?: boolean;\n /** If set, render name properties as heading elements starting at this level (1-6).\n * Names in nested items use incrementing levels (capped at h6).\n * Default is undefined (render as <strong>). */\n topHeading?: number;\n}\n\n/**\n * Render an mf2 document to HTML.\n */\nexport function render(doc: Mf2Document, opts?: { asElement: true; topHeading?: number }): HTMLElement;\nexport function render(doc: Mf2Document, opts?: { asElement?: false; topHeading?: number }): string;\nexport function render(doc: Mf2Document, opts: RenderOptions = {}): string | HTMLElement {\n const relUrls = doc[\"rel-urls\"];\n const { topHeading } = opts;\n const main = h(\"main\");\n\n // Render items\n for (const item of doc.items) {\n main.appendChild(renderItem(item, { relUrls, headingLevel: topHeading }));\n }\n\n // Render rel-urls as nav\n if (relUrls && Object.keys(relUrls).length) {\n const nav = h(\"nav\");\n for (const url of Object.keys(relUrls).sort()) {\n const info = relUrls[url];\n nav.appendChild(h(\"a\", {\n href: url,\n rel: info.rels?.length ? info.rels.join(\" \") : undefined,\n }, [info.text ?? url]));\n }\n main.appendChild(nav);\n }\n\n return opts.asElement ? main : main.outerHTML;\n}\n\nexport interface RenderItemElementOptions {\n relUrls?: Record<string, RelUrl>;\n topHeading?: number;\n}\n\n/**\n * Render a single mf2 item to an HTMLElement.\n */\nexport function renderItemElement(\n item: Mf2Item,\n options: RenderItemElementOptions = {}\n): HTMLElement {\n const { relUrls, topHeading } = options;\n return renderItem(item, { relUrls, headingLevel: topHeading });\n}\n\nexport interface RenderItemsOptions {\n relUrls?: Record<string, RelUrl>;\n topHeading?: number;\n}\n\n/**\n * Render multiple items efficiently using DocumentFragment.\n */\nexport function renderItems(\n items: Mf2Item[],\n options: RenderItemsOptions = {}\n): DocumentFragment {\n const { relUrls, topHeading } = options;\n const fragment = document.createDocumentFragment();\n for (const item of items) {\n fragment.appendChild(renderItem(item, { relUrls, headingLevel: topHeading }));\n }\n return fragment;\n}\n\nexport { parseHtml as parseHtmlFragment };\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["renderer_exports", "__export", "parseHtml", "render", "renderItemElement", "renderItems", "SEMANTIC_ROOTS", "SEMANTIC_PROPS", "URL_PROPS", "EMAIL_PROPS", "TEL_PROPS", "DT_PROPS", "PROP_ORDER", "h", "tag", "attrs", "children", "el", "k", "v", "child", "text", "content", "html", "tpl", "isMf2Item", "isEValue", "isUrlObject", "isUrl", "s", "propOrder", "p", "i", "sortProps", "props", "a", "b", "classes", "parts", "getRels", "url", "relUrls", "rels", "getTag", "types", "t", "renderPhoto", "prop", "cls", "renderVideo", "renderAudio", "renderLink", "displayText", "rel", "renderEmail", "value", "href", "display", "renderTel", "renderTime", "renderText", "renderUrlObject", "obj", "renderEProperty", "div", "renderRuby", "name", "ipa", "ruby", "rt", "renderStringProp", "headingLevel", "embeddedPrefix", "item", "renderItem", "opts", "extraClasses", "asProperty", "propertyPrefix", "embeddedValue", "consumed", "names", "ipas", "linkedName", "urls", "nameVal", "urlVal", "urlProps", "uids", "rendered", "rubyEl", "heading", "linkEl", "childHeading", "prefix", "cat", "key", "group", "pv", "childrenHeading", "doc", "topHeading", "main", "nav", "info", "options", "items", "fragment"]
|
|
4
|
+
"sourcesContent": ["/**\n * Microformats2 Renderer - Pure Programmatic DOM Building\n *\n * Renders mf2 JSON to semantic HTML by building the DOM tree programmatically.\n * Uses DocumentFragment for efficient batch updates with minimal reflows.\n */\n\nimport type {\n Mf2Document,\n Mf2Item,\n PropertyValue,\n EValue,\n UrlObject,\n RelUrl,\n} from \"./types.js\";\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\nconst SEMANTIC_ROOTS: Record<string, string> = {\n \"h-entry\": \"article\",\n \"h-feed\": \"section\",\n \"h-event\": \"article\",\n \"h-product\": \"article\",\n \"h-recipe\": \"article\",\n \"h-review\": \"article\",\n \"h-resume\": \"article\",\n \"h-adr\": \"address\",\n \"h-cite\": \"blockquote\",\n \"h-geo\": \"data\",\n};\n\nconst SEMANTIC_PROPS: Record<string, string> = {\n // Address components use address element\n \"p-adr\": \"address\",\n \"p-street-address\": \"span\",\n \"p-extended-address\": \"span\",\n \"p-locality\": \"span\",\n \"p-region\": \"span\",\n \"p-postal-code\": \"span\",\n \"p-country-name\": \"span\",\n // Name properties use strong for emphasis\n \"p-name\": \"strong\",\n // Paragraph-like properties\n \"p-summary\": \"p\",\n \"p-note\": \"p\",\n \"p-content\": \"p\",\n \"p-description\": \"p\",\n // Preformatted text (preserve line breaks)\n \"p-lyrics\": \"pre\",\n // Author info\n \"p-author\": \"span\",\n};\n\nconst URL_PROPS = new Set([\n \"url\", \"uid\", \"photo\", \"logo\", \"video\", \"audio\",\n \"syndication\", \"in-reply-to\", \"like-of\", \"repost-of\", \"bookmark-of\",\n \"follow-of\", \"read-of\", \"tag-of\", \"location\",\n]);\nconst EMAIL_PROPS = new Set([\"email\"]);\nconst TEL_PROPS = new Set([\"tel\"]);\nconst DT_PROPS = new Set([\n \"published\", \"updated\", \"start\", \"end\", \"duration\", \"bday\", \"anniversary\", \"rev\",\n]);\n\n// Semantic property ordering based on microformats.org wiki\n// Properties are grouped by semantic meaning for good display across types:\n// 1. Visual identity (photo, logo)\n// 2. Name/identity\n// 3. Author (for h-entry)\n// 4. Description/content\n// 5. Dates (important for h-entry, h-event)\n// 6. Location (for h-event, h-card)\n// 7. URLs and links\n// 8. Contact info (email, tel)\n// 9. Address details\n// 10. Organization/role\n// 11. Categories and other metadata\nconst PROP_ORDER = [\n // Visual/media first\n \"photo\",\n \"logo\",\n \"featured\",\n \"video\",\n \"audio\",\n // Name properties\n \"name\",\n \"honorific-prefix\",\n \"given-name\",\n \"additional-name\",\n \"family-name\",\n \"sort-string\",\n \"honorific-suffix\",\n \"nickname\",\n \"ipa\",\n // Author (important for h-entry)\n \"author\",\n // Description/content\n \"summary\",\n \"note\",\n \"content\",\n \"lyrics\",\n \"description\",\n // Dates (prominent for h-entry, h-event)\n \"published\",\n \"updated\",\n \"start\",\n \"end\",\n \"duration\",\n \"bday\",\n \"anniversary\",\n \"rev\",\n // Location (for h-event)\n \"location\",\n // URLs and links\n \"url\",\n \"uid\",\n \"syndication\",\n \"in-reply-to\",\n \"like-of\",\n \"repost-of\",\n \"bookmark-of\",\n \"follow-of\",\n \"read-of\",\n \"read-status\",\n // Contact info\n \"email\",\n \"tel\",\n \"impp\",\n // Address details\n \"adr\",\n \"geo\",\n \"latitude\",\n \"longitude\",\n \"altitude\",\n \"street-address\",\n \"extended-address\",\n \"locality\",\n \"region\",\n \"postal-code\",\n \"country-name\",\n \"label\",\n // Organization/role\n \"org\",\n \"job-title\",\n \"role\",\n // Categories and metadata\n \"category\",\n \"rsvp\",\n \"attendee\",\n \"key\",\n \"sex\",\n \"gender-identity\",\n];\n\n// ============================================================================\n// DOM Builder Helpers\n// ============================================================================\n\n/** Create an element with attributes */\nfunction h<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElementTagNameMap[K];\nfunction h(\n tag: string,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElement;\nfunction h(\n tag: string,\n attrs?: Record<string, string | undefined>,\n children?: (Node | string)[]\n): HTMLElement {\n const el = document.createElement(tag);\n\n if (attrs) {\n for (const [k, v] of Object.entries(attrs)) {\n if (v != null) el.setAttribute(k, v);\n }\n }\n\n if (children) {\n for (const child of children) {\n el.append(child);\n }\n }\n\n return el;\n}\n\n/** Create a text node */\nfunction text(content: string): Text {\n return document.createTextNode(content);\n}\n\n/** Parse HTML string to DocumentFragment (only for e-* content) */\nfunction parseHtml(html: string): DocumentFragment {\n const tpl = document.createElement(\"template\");\n tpl.innerHTML = html;\n return tpl.content;\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nfunction isMf2Item(v: unknown): v is Mf2Item {\n return typeof v === \"object\" && v !== null && \"type\" in v && \"properties\" in v;\n}\n\nfunction isEValue(v: unknown): v is EValue {\n return typeof v === \"object\" && v !== null && \"html\" in v;\n}\n\nfunction isUrlObject(v: unknown): v is UrlObject {\n return typeof v === \"object\" && v !== null && \"value\" in v && (\"alt\" in v || \"srcset\" in v);\n}\n\nconst URL_RE = /^(?:[a-zA-Z][a-zA-Z0-9+\\-.]*:\\/\\/|\\/)/;\n\nfunction isUrl(s: string): boolean {\n return URL_RE.test(s);\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction propOrder(p: string): number {\n const i = PROP_ORDER.indexOf(p);\n return i >= 0 ? i : PROP_ORDER.length;\n}\n\nfunction sortProps(props: Record<string, PropertyValue[]>): string[] {\n return Object.keys(props).sort((a, b) => propOrder(a) - propOrder(b));\n}\n\nfunction classes(...parts: (string | undefined)[]): string | undefined {\n const cls = parts.filter(Boolean).join(\" \");\n return cls || undefined;\n}\n\nfunction getRels(url: string, relUrls?: Record<string, RelUrl>): string | undefined {\n const rels = relUrls?.[url]?.rels;\n return rels?.length ? rels.join(\" \") : undefined;\n}\n\nfunction getTag(types: string[]): string {\n for (const t of types) {\n if (t in SEMANTIC_ROOTS) return SEMANTIC_ROOTS[t];\n }\n return \"div\";\n}\n\n// ============================================================================\n// Property Renderers\n// ============================================================================\n\nfunction renderPhoto(prop: string, url: string, cls: string): HTMLImageElement {\n // Don't include alt=\"\" - it changes the parsed output from string to {value, alt}\n return h(\"img\", { class: cls, src: url });\n}\n\nfunction renderVideo(prop: string, url: string, cls: string): HTMLVideoElement {\n return h(\"video\", { class: cls, src: url, controls: \"\" });\n}\n\nfunction renderAudio(prop: string, url: string, cls: string): HTMLAudioElement {\n return h(\"audio\", { class: cls, src: url, controls: \"\" });\n}\n\nfunction renderLink(\n url: string,\n cls: string,\n displayText?: string,\n rel?: string\n): HTMLAnchorElement {\n return h(\"a\", { class: cls, href: url, rel }, [displayText ?? url]);\n}\n\nfunction renderEmail(value: string, cls: string): HTMLAnchorElement {\n const href = value.startsWith(\"mailto:\") ? value : `mailto:${value}`;\n const display = value.replace(/^mailto:/, \"\");\n return h(\"a\", { class: cls, href }, [display]);\n}\n\nfunction renderTel(value: string, cls: string): HTMLAnchorElement {\n const href = value.startsWith(\"tel:\") ? value : `tel:${value}`;\n return h(\"a\", { class: cls, href }, [value]);\n}\n\nfunction renderTime(value: string, cls: string): HTMLTimeElement {\n return h(\"time\", { class: cls, datetime: value }, [value]);\n}\n\nfunction renderText(prop: string, value: string, cls: string): HTMLElement {\n const tag = SEMANTIC_PROPS[`p-${prop}`] ?? \"span\";\n return h(tag, { class: cls }, [value]);\n}\n\nfunction renderUrlObject(prop: string, obj: UrlObject): HTMLImageElement {\n const attrs: Record<string, string | undefined> = {\n class: `u-${prop}`,\n src: obj.value,\n alt: obj.alt,\n };\n\n if (obj.srcset && Object.keys(obj.srcset).length) {\n attrs.srcset = Object.entries(obj.srcset)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([k, v]) => `${v} ${k}`)\n .join(\", \");\n }\n\n return h(\"img\", attrs);\n}\n\nfunction renderEProperty(prop: string, value: EValue): HTMLDivElement {\n const div = h(\"div\", { class: `e-${prop}` });\n if (value.html) {\n div.appendChild(parseHtml(value.html));\n } else if (value.value) {\n div.textContent = value.value;\n }\n return div;\n}\n\nfunction renderRuby(name: string, ipa: string): HTMLElement {\n const ruby = h(\"ruby\", { \"aria-hidden\": \"true\" });\n\n ruby.appendChild(h(\"strong\", { class: \"p-name\" }, [name]));\n ruby.appendChild(h(\"rp\", undefined, [\"(\"]));\n\n const rt = h(\"rt\");\n rt.append(text(\"/ \"), h(\"span\", { class: \"p-ipa\" }, [ipa]), text(\" /\"));\n ruby.appendChild(rt);\n\n ruby.appendChild(h(\"rp\", undefined, [\")\"]));\n\n return ruby;\n}\n\n/** Render a string property value */\nfunction renderStringProp(\n props: string[],\n value: string,\n relUrls?: Record<string, RelUrl>,\n headingLevel?: number\n): HTMLElement {\n const prop = props[0];\n\n // Media elements\n if (prop === \"photo\" || prop === \"logo\") {\n return renderPhoto(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n if (prop === \"video\") {\n return renderVideo(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n if (prop === \"audio\") {\n return renderAudio(prop, value, classes(...props.map(p => `u-${p}`))!);\n }\n\n // URL properties\n if (URL_PROPS.has(prop) && isUrl(value)) {\n return renderLink(\n value,\n classes(...props.map(p => `u-${p}`))!,\n value,\n getRels(value, relUrls)\n );\n }\n\n // Email\n if (EMAIL_PROPS.has(prop)) {\n return renderEmail(value, classes(...props.map(p => `u-${p}`))!);\n }\n\n // Telephone\n if (TEL_PROPS.has(prop)) {\n return renderTel(value, classes(...props.map(p => `p-${p}`))!);\n }\n\n // Datetime\n if (DT_PROPS.has(prop)) {\n return renderTime(value, classes(...props.map(p => `dt-${p}`))!);\n }\n\n // Default text - use heading tag for name property if headingLevel is set\n const cls = classes(...props.map(p => `p-${p}`))!;\n if (prop === \"name\" && headingLevel != null) {\n return h(`h${headingLevel}` as keyof HTMLElementTagNameMap, { class: cls }, [value]);\n }\n return renderText(prop, value, cls);\n}\n\n// ============================================================================\n// Item Renderer\n// ============================================================================\n\ninterface ItemOptions {\n extraClasses?: string[];\n asProperty?: boolean;\n propertyPrefix?: string;\n relUrls?: Record<string, RelUrl>;\n headingLevel?: number;\n}\n\nfunction embeddedPrefix(item: Mf2Item): string {\n if (typeof item.html === \"string\") return \"e\";\n if (typeof item.value === \"object\" && item.value !== null) return \"u\";\n return \"p\";\n}\n\nfunction renderItem(item: Mf2Item, opts: ItemOptions = {}): HTMLElement {\n const { extraClasses = [], asProperty = false, propertyPrefix, relUrls, headingLevel } = opts;\n const props = item.properties;\n const children = item.children ?? [];\n\n // Create root element\n const el = h(getTag(item.type), {\n id: item.id,\n class: classes(...extraClasses, ...item.type),\n });\n\n // VCP data node for p/dt embedded items\n if (asProperty && (propertyPrefix === \"p\" || propertyPrefix === \"dt\")) {\n if (\"value\" in item && typeof item.value !== \"object\") {\n el.appendChild(h(\"data\", { class: \"value\", value: String(item.value) }));\n }\n }\n\n // e-* property with HTML\n if (asProperty && propertyPrefix === \"e\" && typeof item.html === \"string\") {\n el.appendChild(parseHtml(item.html));\n return el;\n }\n\n // Get embedded value for special name handling\n const embeddedValue = asProperty ? item.value : undefined;\n\n // Check for name+ipa ruby rendering\n const consumed = new Set<string>();\n let ruby: [string, string] | null = null;\n\n const names = props.name ?? [];\n const ipas = props.ipa ?? [];\n if (names.length && ipas.length) {\n const name = typeof names[0] === \"string\" ? names[0] : null;\n const ipa = typeof ipas[0] === \"string\" ? ipas[0] : null;\n if (name && ipa) {\n ruby = [name, ipa];\n consumed.add(\"name\");\n consumed.add(\"ipa\");\n }\n }\n\n // Check if name should be rendered as a link (single name + single URL, no ruby)\n // Don't apply when rendering as a property (changes value extraction on re-parse)\n // (name, url, list of url properties to include in class)\n let linkedName: [string, string, string[]] | null = null;\n if (!ruby && !asProperty) {\n const urls = props.url ?? [];\n if (names.length === 1 && urls.length === 1) {\n const nameVal = typeof names[0] === \"string\" ? names[0] : null;\n const urlVal = typeof urls[0] === \"string\" ? urls[0] : null;\n if (nameVal && urlVal && isUrl(urlVal)) {\n // Collect URL properties that share this URL value (like uid)\n const urlProps = [\"url\"];\n const uids = props.uid ?? [];\n if (uids.length === 1 && uids[0] === urlVal) {\n urlProps.push(\"uid\");\n consumed.add(\"uid\");\n }\n consumed.add(\"name\");\n consumed.add(\"url\");\n linkedName = [nameVal, urlVal, urlProps];\n }\n }\n }\n\n // Track rendered (value, category) pairs for grouping\n const rendered = new Set<string>();\n\n for (const prop of sortProps(props)) {\n // Insert ruby at name position\n if (prop === \"name\" && ruby) {\n const rubyEl = renderRuby(...ruby);\n if (headingLevel != null) {\n const heading = h(`h${headingLevel}` as keyof HTMLElementTagNameMap);\n heading.appendChild(rubyEl);\n el.appendChild(heading);\n } else {\n el.appendChild(rubyEl);\n }\n ruby = null;\n }\n\n // Render linked name at the position where \"name\" would appear\n if (prop === \"name\" && linkedName) {\n const [nameVal, urlVal, urlProps] = linkedName;\n const cls = classes(\"p-name\", ...urlProps.map(p => `u-${p}`));\n const rel = getRels(urlVal, relUrls);\n const linkEl = h(\"a\", { class: cls, href: urlVal, rel }, [nameVal]);\n if (headingLevel != null) {\n const heading = h(`h${headingLevel}` as keyof HTMLElementTagNameMap);\n heading.appendChild(linkEl);\n el.appendChild(heading);\n } else {\n el.appendChild(linkEl);\n }\n linkedName = null;\n }\n\n if (consumed.has(prop)) continue;\n\n // Calculate next heading level for embedded items (increment, cap at 6)\n const childHeading = headingLevel != null ? Math.min(headingLevel + 1, 6) : undefined;\n\n for (const v of props[prop]) {\n // Embedded mf2 item\n if (isMf2Item(v)) {\n const prefix = embeddedPrefix(v);\n el.appendChild(renderItem(v, {\n extraClasses: [`${prefix}-${prop}`],\n asProperty: true,\n propertyPrefix: prefix,\n relUrls,\n headingLevel: childHeading,\n }));\n continue;\n }\n\n // e-* HTML content\n if (isEValue(v)) {\n el.appendChild(renderEProperty(prop, v));\n continue;\n }\n\n // URL object (img with alt/srcset)\n if (isUrlObject(v)) {\n el.appendChild(renderUrlObject(prop, v));\n continue;\n }\n\n // If this item is itself embedded as a property, prefer dt-* for `name`\n // when its representative value differs from its `properties.name[0]`.\n if (\n asProperty &&\n propertyPrefix === \"p\" &&\n prop === \"name\" &&\n typeof embeddedValue === \"string\" &&\n typeof v === \"string\" &&\n v !== embeddedValue &&\n !v.startsWith(\"http://\") &&\n !v.startsWith(\"https://\")\n ) {\n // Render as time element with dt-name class (no datetime attribute)\n el.appendChild(h(\"time\", { class: \"dt-name\" }, [v]));\n continue;\n }\n\n // String value - group by value for merged classes\n if (typeof v === \"string\") {\n const cat = URL_PROPS.has(prop) && isUrl(v) ? \"url\"\n : EMAIL_PROPS.has(prop) ? \"email\"\n : TEL_PROPS.has(prop) ? \"tel\"\n : DT_PROPS.has(prop) ? \"datetime\"\n : `text:${prop}`;\n\n const key = `${v}\\0${cat}`;\n if (rendered.has(key)) continue;\n rendered.add(key);\n\n // Collect all props with same value+category\n const group: string[] = [];\n for (const p of sortProps(props)) {\n if (consumed.has(p)) continue;\n for (const pv of props[p]) {\n if (typeof pv !== \"string\" || pv !== v) continue;\n const pCat = URL_PROPS.has(p) && isUrl(pv) ? \"url\"\n : EMAIL_PROPS.has(p) ? \"email\"\n : TEL_PROPS.has(p) ? \"tel\"\n : DT_PROPS.has(p) ? \"datetime\"\n : `text:${p}`;\n if (pCat === cat && !group.includes(p)) {\n group.push(p);\n }\n }\n }\n\n el.appendChild(renderStringProp(group, v, relUrls, headingLevel));\n continue;\n }\n\n // Fallback\n el.appendChild(renderStringProp([prop], String(v), relUrls, headingLevel));\n }\n }\n\n // Render children - calculate next heading level (increment, cap at 6)\n const childrenHeading = headingLevel != null ? Math.min(headingLevel + 1, 6) : undefined;\n for (const child of children) {\n el.appendChild(renderItem(child, { relUrls, headingLevel: childrenHeading }));\n }\n\n return el;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface RenderOptions {\n /** Return HTMLElement instead of string */\n asElement?: boolean;\n /** If set, render name properties as heading elements starting at this level (1-6).\n * Names in nested items use incrementing levels (capped at h6).\n * Default is undefined (render as <strong>). */\n topHeading?: number;\n}\n\n/**\n * Render an mf2 document to HTML.\n */\nexport function render(doc: Mf2Document, opts?: { asElement: true; topHeading?: number }): HTMLElement;\nexport function render(doc: Mf2Document, opts?: { asElement?: false; topHeading?: number }): string;\nexport function render(doc: Mf2Document, opts: RenderOptions = {}): string | HTMLElement {\n const relUrls = doc[\"rel-urls\"];\n const { topHeading } = opts;\n const main = h(\"main\");\n\n // Render items\n for (const item of doc.items) {\n main.appendChild(renderItem(item, { relUrls, headingLevel: topHeading }));\n }\n\n // Render rel-urls as nav\n if (relUrls && Object.keys(relUrls).length) {\n const nav = h(\"nav\");\n for (const url of Object.keys(relUrls).sort()) {\n const info = relUrls[url];\n nav.appendChild(h(\"a\", {\n href: url,\n rel: info.rels?.length ? info.rels.join(\" \") : undefined,\n }, [info.text ?? url]));\n }\n main.appendChild(nav);\n }\n\n return opts.asElement ? main : main.outerHTML;\n}\n\nexport interface RenderItemElementOptions {\n relUrls?: Record<string, RelUrl>;\n topHeading?: number;\n}\n\n/**\n * Render a single mf2 item to an HTMLElement.\n */\nexport function renderItemElement(\n item: Mf2Item,\n options: RenderItemElementOptions = {}\n): HTMLElement {\n const { relUrls, topHeading } = options;\n return renderItem(item, { relUrls, headingLevel: topHeading });\n}\n\nexport interface RenderItemsOptions {\n relUrls?: Record<string, RelUrl>;\n topHeading?: number;\n}\n\n/**\n * Render multiple items efficiently using DocumentFragment.\n */\nexport function renderItems(\n items: Mf2Item[],\n options: RenderItemsOptions = {}\n): DocumentFragment {\n const { relUrls, topHeading } = options;\n const fragment = document.createDocumentFragment();\n for (const item of items) {\n fragment.appendChild(renderItem(item, { relUrls, headingLevel: topHeading }));\n }\n return fragment;\n}\n\nexport { parseHtml as parseHtmlFragment };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["renderer_exports", "__export", "parseHtml", "render", "renderItemElement", "renderItems", "SEMANTIC_ROOTS", "SEMANTIC_PROPS", "URL_PROPS", "EMAIL_PROPS", "TEL_PROPS", "DT_PROPS", "PROP_ORDER", "h", "tag", "attrs", "children", "el", "k", "v", "child", "text", "content", "html", "tpl", "isMf2Item", "isEValue", "isUrlObject", "URL_RE", "isUrl", "s", "propOrder", "p", "i", "sortProps", "props", "a", "b", "classes", "parts", "getRels", "url", "relUrls", "rels", "getTag", "types", "t", "renderPhoto", "prop", "cls", "renderVideo", "renderAudio", "renderLink", "displayText", "rel", "renderEmail", "value", "href", "display", "renderTel", "renderTime", "renderText", "renderUrlObject", "obj", "renderEProperty", "div", "renderRuby", "name", "ipa", "ruby", "rt", "renderStringProp", "headingLevel", "embeddedPrefix", "item", "renderItem", "opts", "extraClasses", "asProperty", "propertyPrefix", "embeddedValue", "consumed", "names", "ipas", "linkedName", "urls", "nameVal", "urlVal", "urlProps", "uids", "rendered", "rubyEl", "heading", "linkEl", "childHeading", "prefix", "cat", "key", "group", "pv", "childrenHeading", "doc", "topHeading", "main", "nav", "info", "options", "items", "fragment"]
|
|
7
7
|
}
|