domma-cms 1.10.0 → 1.10.2
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.10.2] - 2026-10-24
|
|
4
|
+
|
|
5
|
+
- Blocks, Components, Views and Content API now default to the Content menu. Existing menus move these entries from their former default folders once, preserving labels, permissions, settings and later admin rearrangements.
|
|
6
|
+
|
|
7
|
+
## [1.10.1] - 2026-10-24
|
|
8
|
+
|
|
9
|
+
- **Format on save no longer puts a block's CSS into its HTML.** With Format on save on, saving a block formatted its hidden CSS through the browser's insertText, which types into whatever has focus - the HTML editor - so the formatted CSS was saved inside the HTML. Edits now go through insertText only when their own editor has focus (`applyEdit` in `code-format.js`, `replaceRange` in `markdown-toolbar.js`).
|
|
10
|
+
|
|
3
11
|
## [1.10.0] - 2026-10-24
|
|
4
12
|
|
|
5
13
|
- **A new game every day, from a queue (rotation).** The Games library gains rotation, off until a site switches it on: a **Queued** status, a **Rotate** setting (Off, Every day, Every week) in a Rotation card above each Game's list, and the site's midnight opening the next queued game and moving the last one to an archive - still playable, never on a leaderboard. A restart never rotates twice; an empty queue leaves today's game up. `[quiz rotate /]` (and `[crossword rotate]`, `[word-search rotate]`) always shows today's game with the earlier ones below; notices when the queue runs low or empty. Fresh games from Domma arrive as drafts marked **From Domma**, with **Approve all**. `plugins/_lib/games/rotation.js`, `rotation-http.js`, `_lib/public/games/rotation.js`, `_lib/admin/games/rotation.js`; archive plays in `plays.js`. Quiz 1.5.0, Crossword 1.5.0, Word Search 1.2.0 and Daily Word 1.3.0 need this release.
|
|
@@ -4,22 +4,22 @@ let C=" ";export const DEFAULT_CODE_PREFS=Object.freeze({indent:"spaces",size:2
|
|
|
4
4
|
`).filter(o=>/^[ \t]+\S/.test(o)).length;C=n==="md"||n==="html"&&s<3?prefUnit():unitFor(e);try{switch(n){case"json":return{text:formatJson(e)};case"css":return{text:formatCss(e)};case"js":return{text:formatJs(e)};case"html":return{text:formatHtml(e)};case"md":return{text:formatMarkdown(e)};default:return{error:"Nothing to format here."}}}catch(o){return{error:o.message||"Could not format this."}}}export function formatJson(t){if(!t.trim())return t;try{JSON.parse(t)}catch(o){throw new Error(`Not valid JSON: ${o.message}`)}let n="",e=0;const s=()=>`
|
|
5
5
|
`+C.repeat(e);for(let o=0;o<t.length;o++){const l=t[o];if(l==='"'){let a=o+1;for(;t[a]!=='"';)a+=t[a]==="\\"?2:1;n+=t.slice(o,a+1),o=a}else if(l==="{"||l==="["){const a=l==="{"?"}":"]",r=t.slice(o+1).search(/\S/);if(t[o+1+r]===a){n+=l+a,o+=r+1;continue}e++,n+=l+s()}else l==="}"||l==="]"?(e--,n+=s()+l):l===","?n+=","+s():l===":"?n+=": ":/\s/.test(l)||(n+=l)}return n+(t.endsWith(`
|
|
6
6
|
`)?`
|
|
7
|
-
`:"")}export function formatCss(t){if(!t.trim())return t;if(/\{\{\{?\s*[#/^\w]/.test(t))throw new Error("This CSS has {{placeholders}} in it - left as it is.");const n=[];let e=0,s="",o=!1,l="",a=!1,r=0;const i=()=>C.repeat(e),f=
|
|
8
|
-
`);f(i()+c[0]),n.push(...c.slice(1))}
|
|
9
|
-
`;)y+=t[y]==="\\"?2:1;s+=t.slice(
|
|
7
|
+
`:"")}export function formatCss(t){if(!t.trim())return t;if(/\{\{\{?\s*[#/^\w]/.test(t))throw new Error("This CSS has {{placeholders}} in it - left as it is.");const n=[];let e=0,s="",o=!1,l="",a=!1,r=0;const i=()=>C.repeat(e),f=h=>{o&&n.length&&n[n.length-1]!==""&&!n[n.length-1].endsWith("{")&&n.push(""),o=!1,n.push(h)},p=()=>{a&&e===0?(o=!0,a=!1):(l.match(/\n/g)||[]).length>=2&&(o=!0),l=""},d=h=>{const g=h.match(/^(--[\w-]+|[-\w]+)\s*:\s*([\s\S]*)$/);return!g||h.startsWith("@")?h:`${g[1]}: ${g[2]}`},m=h=>{const g=s.trim();if(s="",!!g){if(h==="{"){const y=g.startsWith("@")?[g]:Z(g,",");y.forEach((b,$)=>f(i()+b.trim()+($<y.length-1?",":" {")));return}f(i()+d(g)+";")}};for(let h=0;h<t.length;h++){const g=t[h];if(g==="/"&&t[h+1]==="*"){const y=t.indexOf("*/",h+2),b=y<0?t.length:y+2,$=t.slice(h,b);if(s.trim())s+=$;else{p();const c=$.split(`
|
|
8
|
+
`);f(i()+c[0]),n.push(...c.slice(1))}h=b-1;continue}if(g==='"'||g==="'"){s.trim()||p();let y=h+1;for(;y<t.length&&t[y]!==g&&t[y]!==`
|
|
9
|
+
`;)y+=t[y]==="\\"?2:1;s+=t.slice(h,y+1),h=y;continue}if(/\s/.test(g)){s.trim()?s.endsWith(" ")||(s+=" "):l+=g;continue}if(s.trim()||p(),g==="("?r++:g===")"&&(r=Math.max(0,r-1)),r===0&&g==="{"){m("{"),e++,l="";continue}if(r===0&&g===";"){m(";");continue}if(r===0&&g==="}"){if(m(";"),e--,e<0)throw new Error("There is a } with no { before it.");o=!1,n.push(i()+"}"),l="",e===0&&(a=!0);continue}s+=g}if(s.trim()&&m(";"),e!==0)throw new Error(`${e} { left without a closing }.`);return n.join(`
|
|
10
10
|
`)+`
|
|
11
11
|
`}function Z(t,n){const e=[];let s=0,o=null,l="";for(const a of t){if(o)a===o&&(o=null);else if(a==='"'||a==="'")o=a;else if("([{".includes(a))s++;else if(")]}".includes(a))s--;else if(a===n&&s===0){e.push(l),l="";continue}l+=a}return e.push(l),e}const v=/(^|[(,=:[!&|?{};+\-*%<>~^]|\b(?:return|typeof|case|do|else|in|of|new|delete|void|throw|yield|await))\s*$/;function q(t,n,e){let s=0;if(n.str){let o=0;for(;o<t.length&&t[o]!==n.str;)o+=t[o]==="\\"?2:1;if(o>=t.length){t.endsWith("\\")||(n.str=null);return}n.str=null,s=o+1}for(;s<t.length;){const o=n.stack[n.stack.length-1];if(n.comment){const a=t.indexOf("*/",s);if(a<0)return;n.comment=!1,s=a+2;continue}if(o==="`"){const a=t[s];if(a==="\\"){s+=2;continue}if(a==="`"){n.stack.pop(),s++;continue}if(a==="$"&&t[s+1]==="{"){n.stack.push("${"),s+=2;continue}s++;continue}const l=t[s];if(l==="/"&&t[s+1]==="/")return;if(l==="/"&&t[s+1]==="*"){n.comment=!0,s+=2;continue}if(l==='"'||l==="'"){let a=s+1;for(;a<t.length&&t[a]!==l;)a+=t[a]==="\\"?2:1;if(a>=t.length&&t.endsWith("\\")){n.str=l;return}s=a+1;continue}if(l==="`"){n.stack.push("`"),s++;continue}if(l==="/"&&v.test(t.slice(0,s))){let a=s+1,r=!1;for(;a<t.length;){const i=t[a];if(i==="\\"){a+=2;continue}if(i==="[")r=!0;else if(i==="]")r=!1;else if(i==="/"&&!r)break;a++}s=a+1;continue}if(l==="}"&&o==="${"){n.stack.pop(),s++;continue}l==="{"&&n.stack.length?n.stack.push("{"):l==="}"&&o==="{"&&n.stack.pop(),"{[(".includes(l)?e(l,s,!0):"}])".includes(l)&&e(l,s,!1),s++}}function L(t){return t.replace(/(["'`])(?:\\.|(?!\1).)*\1/g,'""').replace(/\/\*.*?(\*\/|$)/g,"").replace(/\/\/.*$/,"").trimEnd()}export function formatJs(t,n=0){const e=t.split(`
|
|
12
|
-
`),s={comment:!1,str:null,stack:[]},o=[],l=[];let a="";const r=()=>{const i=o[o.length-1];return i?i.at+1+(i.sw&&i.inCase?1:0):0};if(e.forEach((i,f)=>{const p=s.stack[s.stack.length-1]==="`"||!!s.str,d=s.comment,m=i.trim();let
|
|
12
|
+
`),s={comment:!1,str:null,stack:[]},o=[],l=[];let a="";const r=()=>{const i=o[o.length-1];return i?i.at+1+(i.sw&&i.inCase?1:0):0};if(e.forEach((i,f)=>{const p=s.stack[s.stack.length-1]==="`"||!!s.str,d=s.comment,m=i.trim();let h=i;if(p)h=i;else if(!m)h="";else if(d)h=C.repeat(n+r())+(m.startsWith("*")?" ":"")+m;else{const y=Math.min(o.length,(m.match(/^[}\])]+/)||[""])[0].length),b=o[o.length-1],$=/^(case\b.*|default\s*):/.test(m);let c;y?c=o[o.length-y].at:b?.sw&&$?c=b.at+1:c=r();const u=L(m),w=/^(\.(?!\.\.)|\?\.|[+\-*/%]|&&|\|\||\?\?|\?(?!\.)|:(?!:))/.test(u)&&!$||/(=>|[^=!<>]=|[+\-*/%]|&&|\|\||\?\?|\?)$/.test(a)&&!y&&!/^[{[(]/.test(u),x=u.startsWith("/")&&v.test(a);w&&!x&&!/^[}\])]/.test(m)&&c++,h=C.repeat(n+c)+m}l.push(h);const g=Math.round(h.match(/^[ \t]*/)[0].length/C.length)-n;if(p||d||m){const y=o[o.length-1];q(i,s,(b,$,c)=>{if(c){const u=b==="{"&&/\bswitch\s*\(.*\)\s*$/.test(L(i.slice(0,$)));o.push({at:p||d?r():g,sw:u,inCase:!1})}else o.pop()}),y?.sw&&!p&&!d&&/^(case\b.*|default\s*):/.test(m)&&(y.inCase=!0),!p&&!d&&(a=L(m))}}),s.comment||s.str||s.stack.some(i=>i!=="{"))throw new Error("A comment, string or template is left open.");return l.join(`
|
|
13
13
|
`)}const _=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),P=new Set(["pre","textarea","script","style"]),z=new Set(["address","article","aside","blockquote","body","caption","center","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frameset","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","legend","li","main","menu","nav","ol","optgroup","option","p","pre","search","section","summary","table","tbody","td","tfoot","th","thead","tr","ul"]),D=new Set(["base","link","meta","noscript","param","script","source","style","template","title","track"]),H=new Set(["address","article","aside","blockquote","details","dialog","div","dl","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","hr","main","menu","nav","ol","p","pre","search","section","table","ul"]),J=120;export function formatHtml(t,{templates:n=!0}={}){if(!t.trim())return t;const e=[],s=c=>c.includes(`
|
|
14
|
-
`)?`\0${e.push(c)-1}\0`:c,o=c=>C.repeat(c),l=c=>c?.type==="el"&&z.has(c.name)||c?.type==="raw"&&c.name==="pre"||c?.type==="decl",a=c=>{if(c.type!=="el"||!c.open.lineStart||!c.close?.lineEnd)return!1;const
|
|
15
|
-
`).map(O=>O.trim());k=[];let N=0;j.forEach((O,A)=>{const F=(O.match(/^(?:\u0002<\/[^>]*>)+/)||[""])[0].split("").length-1,K=Math.max(0,N-F);N+=O.split("").length-O.split("").length,O=O.replace(/[\u0001\u0002]/g,""),O?S(o(
|
|
16
|
-
`))return[w[0]+S.replace(/[\u0001\u0002]/g,"")+x]}return[...w,...g(c.children,
|
|
17
|
-
`)||!c.close)return[o(
|
|
18
|
-
`),o(
|
|
19
|
-
`).replace(/[\u0001\u0002]/g,"").replace(/\u0000(\d+)\u0000/g,(c,
|
|
14
|
+
`)?`\0${e.push(c)-1}\0`:c,o=c=>C.repeat(c),l=c=>c?.type==="el"&&z.has(c.name)||c?.type==="raw"&&c.name==="pre"||c?.type==="decl",a=c=>{if(c.type!=="el"||!c.open.lineStart||!c.close?.lineEnd)return!1;const u=c.children.map(d).join("");return/^[ \t]*\n/.test(u)&&/\n\s*$/.test(u)},r=(c,u)=>!c||!u||l(c)||l(u)||c.type==="text"&&/\s$/.test(c.text)||u.type==="text"&&/^\s/.test(u.text),i=new WeakSet,f=c=>{c.forEach((u,w)=>{const x=u.type==="el"||u.type==="sec"?u.children:null;if(x&&f(x),l(u)){i.add(u);return}if(!(!(x&&x.some(k=>i.has(k))||a(u)||u.type==="sec"&&u.open.lineStart||u.type==="comment"&&u.lineStart||(u.type==="el"||u.type==="raw"||u.type==="stray")&&(D.has(u.name)||z.has(u.name)))||!r(c[w-1],u)||!r(u,c[w+1]))){if(x&&x.length){const k=(T,j)=>l(T)||T.type==="text"&&j.test(T.text);if(!k(x[0],/^\s/)||!k(x[x.length-1],/\s$/)||x.some((T,j)=>T.type==="else"&&(!r(x[j-1],T)||!r(T,x[j+1]))))return}i.add(u)}})},p=c=>i.has(c),d=c=>{switch(c.type){case"text":return c.text;case"el":return m(c.open.text,-1)[0]+(c.close?""+c.children.map(d).join("")+""+c.close.text:c.children.map(d).join(""));case"sec":return c.open.text+c.children.map(d).join("")+(c.close?.text??"");case"raw":return s(c.open+c.body+c.close);default:return s(c.text)}},m=(c,u)=>{const w=X(c);if(!w)return[s(c)];const x=w.slash?w.attrs.length||w.spaced?" />":"/>":">",S=`<${w.name}${w.attrs.map(k=>" "+k).join("")}${x}`;return u<0||w.attrs.length<2||o(u).length+S.length<=J?[u<0?S:o(u)+S]:[o(u)+"<"+w.name,...w.attrs.map((k,T)=>o(u+1)+k+(T===w.attrs.length-1?x.trim()===">"?">":x:""))]},h=c=>c.type==="text"&&!c.text.trim(),g=(c,u)=>{const w=[];let x=!1;const S=j=>{x&&w.length&&w.push(""),x=!1,w.push(j)};let k=[];const T=()=>{if(!k.length)return;const j=k.map(d).join("").split(`
|
|
15
|
+
`).map(O=>O.trim());k=[];let N=0;j.forEach((O,A)=>{const F=(O.match(/^(?:\u0002<\/[^>]*>)+/)||[""])[0].split("").length-1,K=Math.max(0,N-F);N+=O.split("").length-O.split("").length,O=O.replace(/[\u0001\u0002]/g,""),O?S(o(u+K)+O):A>0&&A<j.length-1&&!j[A-1]&&(x=!0)})};for(const j of c){if(!p(j)){k.push(j);continue}T(),y(j,u).forEach(S)}return T(),w},y=(c,u)=>{if(c.type==="el"){const w=m(c.open.text,u),x=c.close?c.close.text:"";if(c.children.every(h))return w.length===1&&x?[w[0]+x]:x?[...w,o(u)+x]:w;if(w.length===1&&!c.children.some(p)){const S=c.children.map(d).join("").replace(c.close?/$^/:/\s+$/,"");if(!S.includes(`
|
|
16
|
+
`))return[w[0]+S.replace(/[\u0001\u0002]/g,"")+x]}return[...w,...g(c.children,u+1),...x?[o(u)+x]:[]]}if(c.type==="sec"){const w=[o(u)+c.open.text];let x=[];for(const S of c.children){if(S.type!=="else"){x.push(S);continue}w.push(...g(x,u+1),o(u)+S.text),x=[]}return w.push(...g(x,u+1)),c.close&&w.push(o(u)+c.close.text),w}if(c.type==="raw"){if(c.name==="pre"||!c.body.includes(`
|
|
17
|
+
`)||!c.close)return[o(u)+s(c.open+c.body+c.close)];const w=c.body.replace(/^[ \t]*\n/,"").replace(/\n[ \t]*$/,"");let x=null;try{const S=(c.open.match(/\btype\s*=\s*["']?([^"'\s>]*)/i)||[])[1]||"";c.name==="script"&&(!S||/module|javascript|ecmascript/i.test(S))?x=formatJs(w,u+1):c.name==="style"&&(x=Y(formatCss(Q(w)).replace(/\n$/,""),u+1))}catch{x=null}return[o(u)+s(c.open),...(x??s(w)).split(`
|
|
18
|
+
`),o(u)+c.close]}return[o(u)+s(c.text)]},b=V(G(t,n));return f(b),g(b,0).join(`
|
|
19
|
+
`).replace(/[\u0001\u0002]/g,"").replace(/\u0000(\d+)\u0000/g,(c,u)=>e[Number(u)])+(t.endsWith(`
|
|
20
20
|
`)?`
|
|
21
21
|
`:"")}function U(t,n){let e=null;for(let s=n+1;s<t.length;s++){const o=t[s];if(e){o===e&&(e=null);continue}if(o==='"'||o==="'")e=o;else if(o==="{"&&t[s+1]==="{"){const l=t.indexOf("}}",s+2);if(l<0)return-1;s=l+1}else{if(o===">")return s+1;if(o==="<")return-1}}return-1}function G(t,n){const e=[];let s=0,o=0;const l=(a,r)=>{s>o&&e.push({type:"text",text:t.slice(o,s)}),a.lineStart=!t.slice(t.lastIndexOf(`
|
|
22
|
-
`,s-1)+1,s).trim(),a.lineEnd=/^[ \t]*(\n|$)/.test(t.slice(r,r+200)),e.push(a),s=o=r};for(;s<t.length;){const a=t[s],r=t[s+1]||"";if(a==="<"&&t.startsWith("<!--",s)){const i=t.indexOf("-->",s+4);l({type:"comment",text:t.slice(s,i<0?t.length:i+3)},i<0?t.length:i+3);continue}if(a==="<"&&r==="!"){const i=t.indexOf(">",s);if(i>=0){l({type:"decl",text:t.slice(s,i+1)},i+1);continue}}if(a==="<"&&r==="/"){const i=/^<\/([a-zA-Z][\w:.-]*)\s*>/.exec(t.slice(s,s+200));if(i){l({type:"close",name:i[1].toLowerCase(),text:i[0]},s+i[0].length);continue}}if(a==="<"&&/[a-zA-Z]/.test(r)){const i=U(t,s);if(i>0){const f=t.slice(s,i),p=/^<([a-zA-Z][\w:.-]*)/.exec(f)[1].toLowerCase(),d=_.has(p)||B(f);if(P.has(p)&&!d){const m=new RegExp(`</${p}\\s*>`,"i").exec(t.slice(i)),
|
|
22
|
+
`,s-1)+1,s).trim(),a.lineEnd=/^[ \t]*(\n|$)/.test(t.slice(r,r+200)),e.push(a),s=o=r};for(;s<t.length;){const a=t[s],r=t[s+1]||"";if(a==="<"&&t.startsWith("<!--",s)){const i=t.indexOf("-->",s+4);l({type:"comment",text:t.slice(s,i<0?t.length:i+3)},i<0?t.length:i+3);continue}if(a==="<"&&r==="!"){const i=t.indexOf(">",s);if(i>=0){l({type:"decl",text:t.slice(s,i+1)},i+1);continue}}if(a==="<"&&r==="/"){const i=/^<\/([a-zA-Z][\w:.-]*)\s*>/.exec(t.slice(s,s+200));if(i){l({type:"close",name:i[1].toLowerCase(),text:i[0]},s+i[0].length);continue}}if(a==="<"&&/[a-zA-Z]/.test(r)){const i=U(t,s);if(i>0){const f=t.slice(s,i),p=/^<([a-zA-Z][\w:.-]*)/.exec(f)[1].toLowerCase(),d=_.has(p)||B(f);if(P.has(p)&&!d){const m=new RegExp(`</${p}\\s*>`,"i").exec(t.slice(i)),h=m?i+m.index:t.length;l({type:"raw",name:p,open:f,body:t.slice(i,h),close:m?m[0]:""},m?h+m[0].length:h);continue}l({type:"open",name:p,text:f,self:d},i);continue}}if(n&&a==="{"&&r==="{"){if(t.startsWith("{{!--",s)){const f=t.indexOf("--}}",s);s=f<0?t.length:f+4;continue}const i=t.indexOf("}}",s+2);if(i>=0){const f=t.slice(s+2,i).trim();let p,d=null;if((p=/^[#^]\s*([\w.-]+)/.exec(f))?d={type:"hb",kind:"open",name:p[1]}:(p=/^\/\s*([\w.-]+)$/.exec(f))?d={type:"hb",kind:"close",name:p[1]}:/^(else\b|\^$)/.test(f)&&(d={type:"hb",kind:"else"}),d){d.text=t.slice(s,i+2),l(d,i+2);continue}s=i+2;continue}}s++}return s>o&&e.push({type:"text",text:t.slice(o,s)}),e}function V(t){const n={type:"root",children:[]},e=[n],s=()=>e[e.length-1],o=r=>s().children.push(r),l=r=>{for(let i=e.length-1;i>0;i--)if(e[i].type==="sec"&&(!r||e[i].name===r))return i;return-1},a=r=>{const i=s();if(i.type!=="el")return;const f=p=>p==="td"||p==="th";(r==="li"&&i.name==="li"||r==="option"&&i.name==="option"||(r==="dt"||r==="dd")&&(i.name==="dt"||i.name==="dd")||f(r)&&f(i.name)||r==="tr"&&(i.name==="tr"||f(i.name))||i.name==="p"&&H.has(r))&&(e.pop(),r==="tr"&&s().type==="el"&&s().name==="tr"&&e.pop())};for(const r of t)if(r.type==="open"){a(r.name);const i={type:"el",name:r.name,open:r,children:[],close:null};o(i),r.self||e.push(i)}else if(r.type==="close"){let i=e.length-1;for(;i>0&&e[i].type==="el"&&e[i].name!==r.name;)i--;i>0&&e[i].type==="el"?(e[i].close=r,e.length=i):o({type:"stray",name:r.name,text:r.text})}else if(r.type==="hb"){if(r.kind==="open"){const f={type:"sec",name:r.name,open:r,children:[],close:null};o(f),e.push(f);continue}const i=l(r.kind==="close"?r.name:null);if(i<0){o({type:"text",text:r.text});continue}r.kind==="else"?(e.length=i+1,o({type:"else",text:r.text})):(e[i].close=r,e.length=i)}else o(r);return n.children}function B(t){const n=/^<[a-zA-Z][\w:.-]*([\s\S]*?)\/\s*>$/.exec(t);return!!n&&(!n[1].trim()||/[\s"'}]$/.test(n[1])||!/=\s*[^\s"'=]+$/.test(n[1]))}function X(t){const n=/^<([a-zA-Z][\w:.-]*)/.exec(t);if(!n)return null;let e=t.slice(n[0].length,-1);const s=B(t);if(s&&(e=e.replace(/\/\s*$/,"")),e&&!/^\s/.test(e))return null;const o=[];let l="",a=null;for(let r=0;r<e.length;r++){const i=e[r];if(a){if(i===`
|
|
23
23
|
`)return null;l+=i,i===a&&(a=null);continue}if(i==='"'||i==="'"){a=i,l+=i;continue}if(i==="{"&&e[r+1]==="{"){const f=e.indexOf("}}",r+2),p=e.slice(r,f+2);if(p.includes(`
|
|
24
24
|
`))return null;l+=p,r=f+1;continue}if(/\s/.test(i)){const f=e.slice(r).match(/^\s+/)[0];if(l&&(l.endsWith("=")||e[r+f.length]==="=")){r+=f.length-1;continue}l&&o.push(l),l="",r+=f.length-1;continue}l+=i}return a?null:(l&&o.push(l),{name:n[1],attrs:o,slash:s,spaced:/\s\/\s*>$/.test(t)})}function Q(t){const n=t.split(`
|
|
25
25
|
`),e=n.filter(o=>o.trim()).map(o=>o.match(/^[ \t]*/)[0].length),s=e.length?Math.min(...e):0;return n.map(o=>o.slice(Math.min(s,o.match(/^[ \t]*/)[0].length))).join(`
|
|
@@ -27,20 +27,20 @@ let C=" ";export const DEFAULT_CODE_PREFS=Object.freeze({indent:"spaces",size:2
|
|
|
27
27
|
`).map(e=>e&&C.repeat(n)+e).join(`
|
|
28
28
|
`)}export const SHORT_TAG_CONTAINERS=new Set(["grid","row","col","card","box","header","footer","tabs","tab","accordion","item","carousel","slide","timeline","event","hero","banner","slideover","center","listgroup","table","dconfig","reveal","animate","pulse","shake","scramble","ripple","breathe","ambient","twinkle","fireworks","scribe","wait","render","redraw"]);export function shortTagLine(t){const n=String(t).trim().match(/^\[(\/?)([a-z][\w-]*)(?:\s[^\]]*)?\]$/i);return!n||!SHORT_TAG_CONTAINERS.has(n[2].toLowerCase())||!n[1]&&/\/\]$/.test(t.trim())?null:{name:n[2].toLowerCase(),close:!!n[1]}}export function shortTagLayout(t){const n=t.map(()=>({tag:!1,depth:0,block:-1,fence:!1})),e=new Set;let s=null;t.forEach((r,i)=>{if(s){e.add(i);const p=r.match(/^\s*(`{3,}|~{3,})\s*$/);p&&p[1][0]===s[0]&&p[1].length>=s.length&&(s=null);return}const f=r.match(/^\s*(`{3,}|~{3,})/);f&&(s=f[1])});const o=(r,i)=>{let f=0;const p=new RegExp(`\\[(\\/?)${r}(?:[\\s\\]])`,"gi");for(let d=i;d<t.length;d++)if(!e.has(d))for(const m of t[d].matchAll(p))if(!m[1])f++;else{if(f===0)return!0;f--}return!1},l=[];t.forEach((r,i)=>{const f=l[l.length-1];if(n[i].depth=l.length,n[i].block=f?f.at:-1,e.has(i)){n[i].fence=!0;return}const p=shortTagLine(r);if(p)if(p.close){const d=l.map(m=>m.name).lastIndexOf(p.name);if(d<0)return;l.length=d,Object.assign(n[i],{tag:!0,depth:l.length})}else o(p.name,i+1)&&(n[i].tag=!0,l.push({name:p.name,at:i}))});const a=new Map;return t.forEach((r,i)=>{const f=n[i];if(f.tag||f.fence||f.block<0||!r.trim())return;const p=r.match(/^[ \t]*/)[0].length;a.set(f.block,Math.min(a.get(f.block)??1/0,p))}),n.map((r,i)=>{const f=t[i].match(/^[ \t]*/)[0].length,p=r.tag?f:r.block<0?0:Math.min(f,a.get(r.block)??0);return{...r,cut:p}})}function tt(t){const n=shortTagLayout(t);return t.map((e,s)=>n[s].cut?e.slice(n[s].cut):e)}function et(t){const n=shortTagLayout(t);return t.map((e,s)=>{const o=n[s];return o.tag?C.repeat(o.depth)+e.trim():!o.depth||!e.trim()?e:C.repeat(o.depth)+e})}export function formatMarkdown(t){if(!t.trim())return t;const n=E.shortTags?tt(t.split(`
|
|
29
29
|
`)):t.split(`
|
|
30
|
-
`),e=[];let s=null,o=!1;const l=r=>/^( {4}|\t)/.test(r),a=r=>{for(let i=r+1;i<n.length;i++)if(n[i].trim())return n[i];return""};for(let r=0;r<n.length;r++){const i=n[r];if(s){e.push(i);const
|
|
30
|
+
`),e=[];let s=null,o=!1;const l=r=>/^( {4}|\t)/.test(r),a=r=>{for(let i=r+1;i<n.length;i++)if(n[i].trim())return n[i];return""};for(let r=0;r<n.length;r++){const i=n[r];if(s){e.push(i);const h=i.match(/^ {0,3}(`{3,}|~{3,})\s*$/);h&&h[1][0]===s[0]&&h[1].length>=s.length&&(s=null);continue}if(o||/^\s*<pre[\s>]/i.test(i)){e.push(i),o=!/<\/pre\s*>/i.test(i);continue}const f=i.match(/^ {0,3}(`{3,}|~{3,})/);if(f){s=f[1],e.push(i.trimEnd());continue}if(E.html&&nt.test(i)){let h=r;for(;h<n.length&&n[h].trim()&&!shortTagLine(n[h]);)h++;const g=n.slice(r,h);if(!g.some(y=>st.test(y))){const y=i.match(/^ */)[0];e.push(...formatHtml(g.join(`
|
|
31
31
|
`),{templates:!1}).split(`
|
|
32
|
-
`).map(b=>b&&y+b)),r=
|
|
32
|
+
`).map(b=>b&&y+b)),r=h-1;continue}}if(E.tables&&it(n,r)){let h=r+2;for(;h<n.length&&/\|/.test(n[h])&&n[h].trim();)h++;e.push(...rt(n.slice(r,h))),r=h-1;continue}if(!i.trim()){const h=e.length?e[e.length-1]:"",g=[...e].reverse().find(y=>y.trim())||"";if(!h.trim()&&!(l(g)&&l(a(r))))continue;e.push("");continue}if(l(i)){e.push(i);continue}const p=i.match(/[ \t]*$/)[0],d=i.slice(0,i.length-p.length),m=/ {2,}$/.test(p)&&(n[r+1]||"").trim()&&!/^\s*#/.test(d);e.push(m?d+" ":d)}for(;e.length&&!e[0].trim();)e.shift();for(;e.length&&!e[e.length-1].trim();)e.pop();return(E.shortTags?et(e):e).join(`
|
|
33
33
|
`)+`
|
|
34
|
-
`}const nt=/^ {0,3}<(?:address|article|aside|blockquote|body|caption|center|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|h[1-6]|header|html|legend|li|main|menu|nav|ol|p|search|section|summary|table|tbody|td|tfoot|th|thead|tr|ul)(?=[\s/>]|$)/i,st=/<\/?(?:pre|textarea|script|style)\b|^\s*(?:`{3,}|~{3,})/i,ot=/^\s*:?-+:?\s*$/;function W(t){let n=t.trim();n.startsWith("|")&&(n=n.slice(1)),n.endsWith("|")&&!n.endsWith("\\|")&&(n=n.slice(0,-1));const e=[];let s="";for(let o=0;o<n.length;o++){if(n[o]==="\\"&&n[o+1]==="|"){s+="\\|",o++;continue}if(n[o]==="|"){e.push(s.trim()),s="";continue}s+=n[o]}return e.push(s.trim()),e}function it(t,n){const e=t[n],s=t[n+1];if(!e||!s||!e.includes("|")||!s.includes("|")||/^\s{4,}/.test(e))return!1;const o=W(s);if(!(o.length>0&&o.every(l=>ot.test(l))&&W(e).length===o.length))return!1;for(let l=n+2;l<t.length&&t[l].includes("|")&&t[l].trim();l++)if(W(t[l]).length>o.length)return!1;return!0}function rt(t){const n=t[0].match(/^\s*/)[0],e=t.map(W),s=Math.max(...e.map(r=>r.length)),o=e[1].map(r=>r.startsWith(":")&&r.endsWith(":")?"c":r.endsWith(":")?"r":r.startsWith(":")?"l":""),l=r=>[...r].length,a=Array.from({length:s},(r,i)=>Math.max(3,...e.map((f,p)=>p===1?3:l(f[i]??""))));return e.map((r,i)=>{const f=Array.from({length:s},(p,d)=>{const m=a[d];if(i===1){const y=o[d]||"",b="-".repeat(m-(y==="c"?2:y?1:0));return y==="c"?`:${b}:`:y==="r"?`${b}:`:y==="l"?`:${b}`:b}const
|
|
34
|
+
`}const nt=/^ {0,3}<(?:address|article|aside|blockquote|body|caption|center|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|h[1-6]|header|html|legend|li|main|menu|nav|ol|p|search|section|summary|table|tbody|td|tfoot|th|thead|tr|ul)(?=[\s/>]|$)/i,st=/<\/?(?:pre|textarea|script|style)\b|^\s*(?:`{3,}|~{3,})/i,ot=/^\s*:?-+:?\s*$/;function W(t){let n=t.trim();n.startsWith("|")&&(n=n.slice(1)),n.endsWith("|")&&!n.endsWith("\\|")&&(n=n.slice(0,-1));const e=[];let s="";for(let o=0;o<n.length;o++){if(n[o]==="\\"&&n[o+1]==="|"){s+="\\|",o++;continue}if(n[o]==="|"){e.push(s.trim()),s="";continue}s+=n[o]}return e.push(s.trim()),e}function it(t,n){const e=t[n],s=t[n+1];if(!e||!s||!e.includes("|")||!s.includes("|")||/^\s{4,}/.test(e))return!1;const o=W(s);if(!(o.length>0&&o.every(l=>ot.test(l))&&W(e).length===o.length))return!1;for(let l=n+2;l<t.length&&t[l].includes("|")&&t[l].trim();l++)if(W(t[l]).length>o.length)return!1;return!0}function rt(t){const n=t[0].match(/^\s*/)[0],e=t.map(W),s=Math.max(...e.map(r=>r.length)),o=e[1].map(r=>r.startsWith(":")&&r.endsWith(":")?"c":r.endsWith(":")?"r":r.startsWith(":")?"l":""),l=r=>[...r].length,a=Array.from({length:s},(r,i)=>Math.max(3,...e.map((f,p)=>p===1?3:l(f[i]??""))));return e.map((r,i)=>{const f=Array.from({length:s},(p,d)=>{const m=a[d];if(i===1){const y=o[d]||"",b="-".repeat(m-(y==="c"?2:y?1:0));return y==="c"?`:${b}:`:y==="r"?`${b}:`:y==="l"?`:${b}`:b}const h=r[d]??"",g=m-l(h);return o[d]==="r"?" ".repeat(g)+h:o[d]==="c"?" ".repeat(Math.floor(g/2))+h+" ".repeat(Math.ceil(g/2)):h+" ".repeat(g)});return`${n}| ${f.join(" | ")} |`})}const M=(t,n)=>t.lastIndexOf(`
|
|
35
35
|
`,n-1)+1,I=(t,n)=>{const e=t.indexOf(`
|
|
36
36
|
`,n);return e<0?t.length:e};export function enterEdit(t,n,e,s){const o=M(t,n),l=t.slice(o,I(t,n)),a=t.slice(o,n),r=t.slice(e,I(t,e)),i=(a.match(/^[ \t]*/)||[""])[0],f=(b,$=b.length)=>({start:n,end:e,text:b,selStart:n+$,selEnd:n+$});if(s==="md"||!s){const b=shortTagLine(l);if(b&&n===e&&!r.trim()&&!R(t,o))return!E.shortTags||!E.autoIndent?f(`
|
|
37
37
|
`):f(`
|
|
38
38
|
`+i+(b.close?"":prefUnit()));const $=a.match(/<([a-zA-Z][\w-]*)(?:\s[^<>]*)?>\s*$/);if($&&E.autoIndent&&n===e&&(z.has($[1].toLowerCase())||$[1].includes("-"))&&!_.has($[1].toLowerCase())&&!/\/\s*>\s*$/.test(a)&&!R(t,o)){const c=`
|
|
39
|
-
`+i+prefUnit();if(new RegExp(`^\\s*</${$[1]}\\s*>`,"i").test(r)){const
|
|
40
|
-
`+i,selStart:n+c.length,selEnd:n+c.length}}return f(c)}if(E.continueLists&&!R(t,o)){const c=a.match(/^([ \t]*)((?:>[ \t]?)+)?([ \t]*)([-*+]|(\d+)([.)]))?([ \t]+)(\[[ xX]\][ \t]+)?/),
|
|
41
|
-
`+c[1]+
|
|
39
|
+
`+i+prefUnit();if(new RegExp(`^\\s*</${$[1]}\\s*>`,"i").test(r)){const u=(t.slice(e).match(/^[ \t]*/)||[""])[0].length;return{start:n,end:e+u,text:c+`
|
|
40
|
+
`+i,selStart:n+c.length,selEnd:n+c.length}}return f(c)}if(E.continueLists&&!R(t,o)){const c=a.match(/^([ \t]*)((?:>[ \t]?)+)?([ \t]*)([-*+]|(\d+)([.)]))?([ \t]+)(\[[ xX]\][ \t]+)?/),u=c?.[2]||"",w=c?.[4]||"",x=/^\s*([-*_])(\s*\1){2,}\s*$/.test(l);if(c&&(u||w)&&!x&&c[0].length<=a.length){if(!l.slice(c[0].length).trim()&&n===e&&n>=o+c[0].length)return{start:o,end:I(t,n),text:c[1],selStart:o+c[1].length,selEnd:o+c[1].length};if(n>=o+c[0].length-(c[7]?.length||0)){const k=c[5]?`${Number(c[5])+1}${c[6]}`:w,T=`
|
|
41
|
+
`+c[1]+u+(c[3]||"")+(w?k+(c[7]||" ")+(c[8]?"[ ] ":""):c[7]||"");return f(T)}}}return f(`
|
|
42
42
|
`+(E.autoIndent?i:""))}if(!E.autoIndent)return f(`
|
|
43
|
-
`);const p=(s==="html"?a:L(a)).trimEnd().slice(-1),d=r.trimStart()[0]||"",m={"{":"}","[":"]","(":")"};let
|
|
43
|
+
`);const p=(s==="html"?a:L(a)).trimEnd().slice(-1),d=r.trimStart()[0]||"",m={"{":"}","[":"]","(":")"};let h=!!m[p],g=h&&d===m[p];if(s==="html"||s==="css"){const b=a.match(/<([a-zA-Z][\w:-]*)(?:\s[^<>]*)?>\s*$/);b&&!_.has(b[1].toLowerCase())&&!/\/\s*>\s*$/.test(a)&&(h=!0,g=new RegExp(`^\\s*</${b[1]}\\s*>`,"i").test(r)),/\{\{\s*#\w+[^}]*\}\}\s*$/.test(a)&&(h=!0,g=/^\s*\{\{\s*\//.test(r))}if(!h)return f(`
|
|
44
44
|
`+i);const y=`
|
|
45
45
|
`+i+unitFor(t);if(g){const b=(t.slice(e).match(/^[ \t]*/)||[""])[0].length;return{start:n,end:e+b,text:y+`
|
|
46
46
|
`+i,selStart:n+y.length,selEnd:n+y.length}}return f(y)}function R(t,n){let e=null;for(const s of t.slice(0,n).split(`
|
|
@@ -48,7 +48,7 @@ let C=" ";export const DEFAULT_CODE_PREFS=Object.freeze({indent:"spaces",size:2
|
|
|
48
48
|
`?e-1:e,r=I(t,a);if(!t.slice(n,e).includes(`
|
|
49
49
|
`)&&!(s&&n===e))return null;const i=t.slice(l,r),f=i.split(`
|
|
50
50
|
`),p=f.map(m=>s?m.startsWith(o)?m.slice(o.length):m.startsWith(" ")?m.slice(2):m.startsWith(" ")?m.slice(1):m.replace(/^ /,""):m.trim()?o+m:m),d=p.join(`
|
|
51
|
-
`);if(d===i)return null;if(n===e){const m=f[0].length-p[0].length,
|
|
51
|
+
`);if(d===i)return null;if(n===e){const m=f[0].length-p[0].length,h=Math.max(l,n-m);return{start:l,end:r,text:d,selStart:h,selEnd:h}}return{start:l,end:r,text:d,selStart:l,selEnd:l+d.length}}export function closerEdit(t,n,e,s,o=""){if(n!==e)return null;const l=M(t,n);let a=t.slice(l,n),r=s;if(o==="html"&&s==="/"&&/^[ \t]*<$/.test(a))a=a.slice(0,-1),r="</";else if(!"}])".includes(s))return null;if(!E.autoIndent)return null;const i=unitFor(t);if(!a||a.trim()||!a.endsWith(i))return null;const f=a.slice(0,-i.length),p=l+f.length+r.length;return{start:l,end:n,text:f+r,selStart:p,selEnd:p}}export const tabUnit=(t,n)=>n==="md"?prefUnit():unitFor(t);export function changedSpan(t,n){let e=0;const s=Math.min(t.length,n.length);for(;e<s&&t[e]===n[e];)e++;let o=0;for(;o<s-e&&t[t.length-1-o]===n[n.length-1-o];)o++;return{start:e,end:t.length-o,text:n.slice(e,n.length-o)}}export function caretAfterFormat(t,n,e){const s=t.slice(0,e).split(`
|
|
52
52
|
`).length-1,o=t.split(`
|
|
53
53
|
`)[s]??"",l=e-M(t,e),a=Math.max(0,l-o.match(/^[ \t]*/)[0].length),r=n.split(`
|
|
54
|
-
`),i=Math.min(s,r.length-1);let f=0;for(let m=0;m<i;m++)f+=r[m].length+1;const p=r[i],d=p.match(/^[ \t]*/)[0].length;return f+Math.min(p.length,d+a)}export function applyEdit(t,n){const{start:e,end:s,text:o}=n;let l=!1;if(typeof document<"u"&&typeof document.execCommand=="function"
|
|
54
|
+
`),i=Math.min(s,r.length-1);let f=0;for(let m=0;m<i;m++)f+=r[m].length+1;const p=r[i],d=p.match(/^[ \t]*/)[0].length;return f+Math.min(p.length,d+a)}export function applyEdit(t,n){const{start:e,end:s,text:o}=n;let l=!1;if(typeof document<"u"&&typeof document.execCommand=="function"&&(t.focus(),t.setSelectionRange(e,s),document.activeElement===t))try{l=o?document.execCommand("insertText",!1,o):e===s||document.execCommand("delete")}catch{l=!1}l||(t.value=t.value.slice(0,e)+o+t.value.slice(s),t.dispatchEvent(new Event("input",{bubbles:!0}))),t.setSelectionRange(n.selStart,n.selEnd)}export function formatTextarea(t,n){const e=t.value,s=formatCode(e,n);if(s.error)return s;if(s.text===e)return{text:e,unchanged:!0};const o=caretAfterFormat(e,s.text,t.selectionStart),l=changedSpan(e,s.text),a=t.scrollTop;return applyEdit(t,{...l,selStart:o,selEnd:o}),t.scrollTop=a,s}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{pageCommentEdit as b}from"./page-comments.js";import{applyEdit as m,closerEdit as y,enterEdit as M,formatTextarea as C,indentEdit as w,isFormatKey as S,tabUnit as x}from"./code-format.js";function B(){I.register("bold",{viewBox:"0 0 24 24",path:"M7 5H14a3 3 0 0 1 0 6H7V5zM7 11H15a3 3 0 0 1 0 6H7V11z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("italic",{viewBox:"0 0 24 24",path:"M11 5h4M9 19h4M13 5l-2 14",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("strikethrough",{viewBox:"0 0 24 24",path:"M16 4H9a3 3 0 0 0 0 6h6a3 3 0 0 1 0 6H6M3 12h18",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("quote",{viewBox:"0 0 24 24",path:"M3 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1zM15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("eye",{viewBox:"0 0 24 24",path:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("expand",{viewBox:"0 0 24 24",path:"M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("columns",{viewBox:"0 0 24 24",path:"M3 4h18a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1zM12 4v16",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("card",{viewBox:"0 0 24 24",paths:["M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z","M3 9h18"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("help-circle",{viewBox:"0 0 24 24",path:"M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zM12 17h.01M12 13a2 2 0 0 0 2-2 2 2 0 0 0-2-2 2 2 0 0 0-2 2",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("book-open",{viewBox:"0 0 24 24",paths:["M2 4h7a2 2 0 0 1 2 2v14a2 2 0 0 0-2-2H2z","M22 4h-7a2 2 0 0 0-2 2v14a2 2 0 0 1 2-2h7z"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("spacer-insert",{viewBox:"0 0 24 24",paths:["M3 8h18","M3 16h18","M12 8v8"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("icon-pick",{viewBox:"0 0 24 24",paths:["M4 4h6v6H4z","M14 4h6v6h-6z","M4 14h6v6H4z","M14 14h6v6h-6z"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("colour-picker",{viewBox:"0 0 24 24",paths:["M12 2a5 5 0 0 1 5 5c0 3-5 10-5 10S7 10 7 7a5 5 0 0 1 5-5z","M12 7a1 1 0 1 0 0-2 1 1 0 0 0 0 2"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("btn-insert",{viewBox:"0 0 24 24",paths:["M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7z","M8 12h8M12 9v6"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("link-shortcode",{viewBox:"0 0 24 24",paths:["M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71","M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("layout-list",{viewBox:"0 0 24 24",paths:["M3 5h18M3 9h18","M3 14h4v6H3zM9 14h12M9 17h8"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("sparkles",{viewBox:"0 0 24 24",paths:["M12 3L13.5 8.5H19L14.5 11.5L16 17L12 14L8 17L9.5 11.5L5 8.5H10.5L12 3Z","M19 3L19.7 5.3H22L20.2 6.6L20.9 9L19 7.7L17.1 9L17.8 6.6L16 5.3H18.3L19 3Z","M5 13L5.5 14.7H7L5.8 15.5L6.3 17.2L5 16.3L3.7 17.2L4.2 15.5L3 14.7H4.5L5 13Z"],stroke:"currentColor",fill:"none",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("accordion-insert",{viewBox:"0 0 24 24",paths:["M3 4h18","M3 8h18","M8 11l4 4 4-4","M3 16h18","M3 20h18"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("banner-insert",{viewBox:"0 0 24 24",paths:["M3 6h18","M3 10h18","M3 14h12"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("hero",{viewBox:"0 0 24 24",paths:["M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5z","M7 8h10M7 11h6"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("text-style",{viewBox:"0 0 24 24",paths:["M4 7V5h16v2","M9 19h6","M12 5v14","M5 12h14"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("css-code",{viewBox:"0 0 24 24",paths:["M9 9l-6 3 6 3","M15 9l6 3-6 3","M13 5l-2 14"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("scribe-insert",{viewBox:"0 0 24 24",paths:["M4 20h3l10-10-3-3L4 17v3z","M14 7l3 3","M4 4h6"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("carousel-insert",{viewBox:"0 0 24 24",paths:["M7 5h10v14H7z","M3 8h2v8H3z","M19 8h2v8h-2z"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"})}export function replaceRange(e,n,s,t){if(n===s&&!t)return;const r=typeof document<"u"&&typeof e.setSelectionRange=="function"&&typeof document.execCommand=="function";let o=!1;if(r
|
|
1
|
+
import{pageCommentEdit as b}from"./page-comments.js";import{applyEdit as m,closerEdit as y,enterEdit as M,formatTextarea as C,indentEdit as w,isFormatKey as S,tabUnit as x}from"./code-format.js";function B(){I.register("bold",{viewBox:"0 0 24 24",path:"M7 5H14a3 3 0 0 1 0 6H7V5zM7 11H15a3 3 0 0 1 0 6H7V11z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("italic",{viewBox:"0 0 24 24",path:"M11 5h4M9 19h4M13 5l-2 14",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("strikethrough",{viewBox:"0 0 24 24",path:"M16 4H9a3 3 0 0 0 0 6h6a3 3 0 0 1 0 6H6M3 12h18",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("quote",{viewBox:"0 0 24 24",path:"M3 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1zM15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("eye",{viewBox:"0 0 24 24",path:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("expand",{viewBox:"0 0 24 24",path:"M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("columns",{viewBox:"0 0 24 24",path:"M3 4h18a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1zM12 4v16",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("card",{viewBox:"0 0 24 24",paths:["M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z","M3 9h18"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("help-circle",{viewBox:"0 0 24 24",path:"M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zM12 17h.01M12 13a2 2 0 0 0 2-2 2 2 0 0 0-2-2 2 2 0 0 0-2 2",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("book-open",{viewBox:"0 0 24 24",paths:["M2 4h7a2 2 0 0 1 2 2v14a2 2 0 0 0-2-2H2z","M22 4h-7a2 2 0 0 0-2 2v14a2 2 0 0 1 2-2h7z"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("spacer-insert",{viewBox:"0 0 24 24",paths:["M3 8h18","M3 16h18","M12 8v8"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("icon-pick",{viewBox:"0 0 24 24",paths:["M4 4h6v6H4z","M14 4h6v6h-6z","M4 14h6v6H4z","M14 14h6v6h-6z"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("colour-picker",{viewBox:"0 0 24 24",paths:["M12 2a5 5 0 0 1 5 5c0 3-5 10-5 10S7 10 7 7a5 5 0 0 1 5-5z","M12 7a1 1 0 1 0 0-2 1 1 0 0 0 0 2"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("btn-insert",{viewBox:"0 0 24 24",paths:["M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7z","M8 12h8M12 9v6"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("link-shortcode",{viewBox:"0 0 24 24",paths:["M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71","M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("layout-list",{viewBox:"0 0 24 24",paths:["M3 5h18M3 9h18","M3 14h4v6H3zM9 14h12M9 17h8"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("sparkles",{viewBox:"0 0 24 24",paths:["M12 3L13.5 8.5H19L14.5 11.5L16 17L12 14L8 17L9.5 11.5L5 8.5H10.5L12 3Z","M19 3L19.7 5.3H22L20.2 6.6L20.9 9L19 7.7L17.1 9L17.8 6.6L16 5.3H18.3L19 3Z","M5 13L5.5 14.7H7L5.8 15.5L6.3 17.2L5 16.3L3.7 17.2L4.2 15.5L3 14.7H4.5L5 13Z"],stroke:"currentColor",fill:"none",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("accordion-insert",{viewBox:"0 0 24 24",paths:["M3 4h18","M3 8h18","M8 11l4 4 4-4","M3 16h18","M3 20h18"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("banner-insert",{viewBox:"0 0 24 24",paths:["M3 6h18","M3 10h18","M3 14h12"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("hero",{viewBox:"0 0 24 24",paths:["M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5z","M7 8h10M7 11h6"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("text-style",{viewBox:"0 0 24 24",paths:["M4 7V5h16v2","M9 19h6","M12 5v14","M5 12h14"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("css-code",{viewBox:"0 0 24 24",paths:["M9 9l-6 3 6 3","M15 9l6 3-6 3","M13 5l-2 14"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("scribe-insert",{viewBox:"0 0 24 24",paths:["M4 20h3l10-10-3-3L4 17v3z","M14 7l3 3","M4 4h6"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("carousel-insert",{viewBox:"0 0 24 24",paths:["M7 5h10v14H7z","M3 8h2v8H3z","M19 8h2v8h-2z"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"})}export function replaceRange(e,n,s,t){if(n===s&&!t)return;const r=typeof document<"u"&&typeof e.setSelectionRange=="function"&&typeof document.execCommand=="function";let o=!1;if(r&&(e.focus(),e.setSelectionRange(n,s),document.activeElement===e))try{o=t?document.execCommand("insertText",!1,t):document.execCommand("delete")}catch{o=!1}if(!o){const c=e.value;e.value=c.substring(0,n)+t+c.substring(s),e.selectionStart=e.selectionEnd=n+t.length,e.dispatchEvent(new Event("input",{bubbles:!0}))}}export function wrapSelection(e,n,s){const t=e.selectionStart,r=e.selectionEnd,o=e.value.substring(t,r);replaceRange(e,t,r,n+o+s),o?e.setSelectionRange(t+n.length,r+n.length):e.setSelectionRange(t+n.length,t+n.length)}export function insertAtCursor(e,n){const s=e.selectionStart;replaceRange(e,s,s,n),e.setSelectionRange(s+n.length,s+n.length)}export function attachEditorKeybindings(e,{language:n="md",beforeFormat:s=null}={}){e.addEventListener("keydown",t=>{if(t.isComposing)return;if(S(t)){t.preventDefault(),t.stopPropagation(),s?.();const o=C(e,n);o.error?E.toast(o.error,{type:"warning"}):E.toast(o.unchanged?"Already tidy":"Formatted",{type:"info",duration:900});return}if(t.key==="Enter"&&!t.shiftKey&&!t.ctrlKey&&!t.metaKey&&!t.altKey){t.preventDefault(),m(e,M(e.value,e.selectionStart,e.selectionEnd,n));return}if(n==="css"&&t.key.length===1&&!t.ctrlKey&&!t.metaKey&&!t.altKey){const o=y(e.value,e.selectionStart,e.selectionEnd,t.key,n);if(o){t.preventDefault(),m(e,o);return}}if((t.ctrlKey||t.metaKey)&&!t.altKey&&!t.shiftKey&&(t.key==="/"||t.code==="Slash")){t.preventDefault(),t.stopPropagation();const o=b(e.value,e.selectionStart,e.selectionEnd);o&&(replaceRange(e,o.start,o.end,o.text),e.setSelectionRange(o.selectionStart,o.selectionEnd));return}if(t.key==="Tab"&&!t.ctrlKey&&!t.metaKey&&!t.altKey){t.preventDefault();const{selectionStart:o,selectionEnd:c,value:u}=e,d=x(u,n),h=w(u,o,c,t.shiftKey,d)||(t.shiftKey?null:{start:o,end:c,text:d,selStart:o+d.length,selEnd:o+d.length});h&&m(e,h);return}if(!(t.ctrlKey||t.metaKey))return;const r=t.key.toLowerCase();if(r==="z")t.preventDefault(),document.execCommand("undo"),E.toast("Undo",{type:"info",duration:1200});else if(r==="y")t.preventDefault(),document.execCommand("redo"),E.toast("Redo",{type:"info",duration:1200});else if(r==="x"&&e.selectionStart===e.selectionEnd){t.preventDefault();const o=e.value.lastIndexOf(`
|
|
2
2
|
`,e.selectionStart-1)+1,c=e.value.indexOf(`
|
|
3
3
|
`,e.selectionStart),u=c===-1?e.value.length:c+1;e.setSelectionRange(o,u),document.execCommand("cut"),e.dispatchEvent(new Event("input",{bubbles:!0})),E.toast("Line cut",{type:"info",duration:1200})}else if(r==="c"&&e.selectionStart===e.selectionEnd){t.preventDefault();const o=e.selectionStart,c=e.value.lastIndexOf(`
|
|
4
4
|
`,o-1)+1,u=e.value.indexOf(`
|
|
@@ -66,6 +66,30 @@
|
|
|
66
66
|
"url": "#/theme",
|
|
67
67
|
"icon": "droplet",
|
|
68
68
|
"permission": "theme"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"text": "Views",
|
|
72
|
+
"url": "#/views",
|
|
73
|
+
"icon": "eye",
|
|
74
|
+
"permission": "views"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"text": "Blocks",
|
|
78
|
+
"url": "#/blocks",
|
|
79
|
+
"icon": "box",
|
|
80
|
+
"permission": "pages"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"text": "Components",
|
|
84
|
+
"url": "#/components",
|
|
85
|
+
"icon": "component",
|
|
86
|
+
"permission": "components"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"text": "Content API",
|
|
90
|
+
"url": "#/content-api",
|
|
91
|
+
"icon": "file-text",
|
|
92
|
+
"permission": "settings"
|
|
69
93
|
}
|
|
70
94
|
],
|
|
71
95
|
"key": "content"
|
|
@@ -87,30 +111,12 @@
|
|
|
87
111
|
"icon": "layout",
|
|
88
112
|
"permission": "collections"
|
|
89
113
|
},
|
|
90
|
-
{
|
|
91
|
-
"text": "Views",
|
|
92
|
-
"url": "#/views",
|
|
93
|
-
"icon": "eye",
|
|
94
|
-
"permission": "views"
|
|
95
|
-
},
|
|
96
114
|
{
|
|
97
115
|
"text": "Actions",
|
|
98
116
|
"url": "#/actions",
|
|
99
117
|
"icon": "zap",
|
|
100
118
|
"permission": "actions"
|
|
101
119
|
},
|
|
102
|
-
{
|
|
103
|
-
"text": "Blocks",
|
|
104
|
-
"url": "#/blocks",
|
|
105
|
-
"icon": "box",
|
|
106
|
-
"permission": "pages"
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
"text": "Components",
|
|
110
|
-
"url": "#/components",
|
|
111
|
-
"icon": "component",
|
|
112
|
-
"permission": "components"
|
|
113
|
-
},
|
|
114
120
|
{
|
|
115
121
|
"text": "API Builder",
|
|
116
122
|
"url": "#/api-endpoints",
|
package/package.json
CHANGED
package/server/server.js
CHANGED
|
@@ -682,11 +682,11 @@ registerSidebarItem({folder: 'content', item: {source: 'Built in', text: 'Contex
|
|
|
682
682
|
registerSidebarItem({folder: 'content', item: {source: 'Built in', text: 'Theme', url: '#/theme', icon: 'droplet', permission: 'theme', countUrl: '/api/theme/count', inventory: true}});
|
|
683
683
|
registerSidebarItem({folder: 'data', item: {source: 'Built in', text: 'Collections', url: '#/collections', icon: 'database', permission: 'collections', countUrl: '/api/collections/_count', inventory: true}});
|
|
684
684
|
registerSidebarItem({folder: 'data', item: {source: 'Built in', text: 'Forms', url: '#/forms', icon: 'layout', permission: 'collections', countUrl: '/api/forms/_count', inventory: true}});
|
|
685
|
-
registerSidebarItem({folder: '
|
|
685
|
+
registerSidebarItem({folder: 'content', item: {source: 'Built in', text: 'Views', url: '#/views', icon: 'eye', permission: 'views', countUrl: '/api/views/_count', inventory: true}});
|
|
686
686
|
registerSidebarItem({folder: 'data', item: {source: 'Built in', text: 'Actions', url: '#/actions', icon: 'zap', permission: 'actions', countUrl: '/api/actions/_count', inventory: true}});
|
|
687
687
|
registerSidebarItem({folder: 'data', item: {source: 'Built in', text: 'API Builder', url: '#/api-endpoints', icon: 'code', permission: 'api-endpoints', countUrl: '/api/api-endpoints/_count', inventory: true}});
|
|
688
|
-
registerSidebarItem({folder: '
|
|
689
|
-
registerSidebarItem({folder: '
|
|
688
|
+
registerSidebarItem({folder: 'content', item: {source: 'Built in', text: 'Blocks', url: '#/blocks', icon: 'box', permission: 'pages', countUrl: '/api/blocks/_count', inventory: true}});
|
|
689
|
+
registerSidebarItem({folder: 'content', item: {source: 'Built in', text: 'Components', url: '#/components', icon: 'component', permission: 'components', countUrl: '/api/components/_count', inventory: true}});
|
|
690
690
|
// System. Notifications, Site Settings and My Profile are signals (unread, something quietly wrong,
|
|
691
691
|
// details not filled in); Layouts and API Tokens are a count while all is well and a signal when not
|
|
692
692
|
// (pages on a missing layout, tokens expiring - the answer says `inventory` in the calm case); Effects
|
|
@@ -701,7 +701,7 @@ registerSidebarItem({folder: 'system', item: {source: 'Built in', text: 'Layouts
|
|
|
701
701
|
registerSidebarItem({folder: 'system', item: {source: 'Built in', text: 'Plugins', url: '#/plugins', icon: 'package', permission: 'plugins', countUrl: '/api/plugins/_count', inventory: true}});
|
|
702
702
|
registerSidebarItem({folder: 'system', item: {source: 'Built in', text: 'API Tokens', url: '#/api-tokens', icon: 'key', permission: 'api-tokens', countUrl: '/api/api-tokens/_count'}});
|
|
703
703
|
registerSidebarItem({folder: 'system', item: {source: 'Built in', text: 'Search', url: '#/search', icon: 'search', permission: 'settings', countUrl: '/api/search/_count', inventory: true}});
|
|
704
|
-
registerSidebarItem({folder: '
|
|
704
|
+
registerSidebarItem({folder: 'content', item: {source: 'Built in', text: 'Content API', url: '#/content-api', icon: 'file-text', permission: 'settings', countUrl: '/api/content-api/_count', inventory: true}});
|
|
705
705
|
// Documentation pages added after the sidebar menu was seeded (0.93.1). The menu is
|
|
706
706
|
// seeded once, so new pages reach existing sites only by registering here. The two
|
|
707
707
|
// sub-folders have no key in older menus; findFolder() falls back to their name.
|
|
@@ -37,7 +37,11 @@ const SEED_ITEMS = [
|
|
|
37
37
|
items: [
|
|
38
38
|
{text: 'Pages', url: '#/pages', icon: 'file-text', permission: 'pages'},
|
|
39
39
|
{text: 'Media', url: '#/media', icon: 'image', permission: 'media'},
|
|
40
|
-
{text: 'Site menus', url: '#/menus', icon: 'menu', permission: 'menus'}
|
|
40
|
+
{text: 'Site menus', url: '#/menus', icon: 'menu', permission: 'menus'},
|
|
41
|
+
{text: 'Blocks', url: '#/blocks', icon: 'box', permission: 'pages'},
|
|
42
|
+
{text: 'Components', url: '#/components', icon: 'component', permission: 'components'},
|
|
43
|
+
{text: 'Views', url: '#/views', icon: 'eye', permission: 'views'},
|
|
44
|
+
{text: 'Content API', url: '#/content-api', icon: 'file-text', permission: 'settings'}
|
|
41
45
|
]
|
|
42
46
|
},
|
|
43
47
|
{
|
|
@@ -45,11 +49,8 @@ const SEED_ITEMS = [
|
|
|
45
49
|
items: [
|
|
46
50
|
{text: 'Collections', url: '#/collections', icon: 'database', permission: 'collections'},
|
|
47
51
|
{text: 'Forms', url: '#/forms', icon: 'layout', permission: 'collections'},
|
|
48
|
-
{text: 'Views', url: '#/views', icon: 'eye', permission: 'views'},
|
|
49
52
|
{text: 'Actions', url: '#/actions', icon: 'zap', permission: 'actions'},
|
|
50
|
-
{text: 'API Builder', url: '#/api-endpoints', icon: 'code', permission: 'api-endpoints'}
|
|
51
|
-
{text: 'Blocks', url: '#/blocks', icon: 'box', permission: 'pages'},
|
|
52
|
-
{text: 'Components', url: '#/components', icon: 'component', permission: 'components'}
|
|
53
|
+
{text: 'API Builder', url: '#/api-endpoints', icon: 'code', permission: 'api-endpoints'}
|
|
53
54
|
]
|
|
54
55
|
},
|
|
55
56
|
// Enabled Tools are placed here at render time (placeTools in
|
|
@@ -413,6 +414,33 @@ export async function ensureFolderKeys(opts = {}) {
|
|
|
413
414
|
changed = true;
|
|
414
415
|
}
|
|
415
416
|
|
|
417
|
+
// Move content-building entries from their old default folders once. Keep
|
|
418
|
+
// their full saved settings, and respect later admin rearrangements.
|
|
419
|
+
if (!menu.meta?.contentMenuItems && items.length) {
|
|
420
|
+
const oldFolders = {'#/blocks': 'data', '#/components': 'data', '#/views': 'data', '#/content-api': 'system'};
|
|
421
|
+
const moving = [];
|
|
422
|
+
for (const folder of items.filter(n => isFolder(n) && ['data', 'system'].includes(n.key))) {
|
|
423
|
+
const matches = n => oldFolders[n?.url] === folder.key;
|
|
424
|
+
moving.push(...(folder.items || []).filter(matches));
|
|
425
|
+
if (Array.isArray(folder.items)) folder.items = folder.items.filter(n => !matches(n));
|
|
426
|
+
}
|
|
427
|
+
const hasUrl = (nodes, url) => nodes.some(n => n?.url === url
|
|
428
|
+
|| (Array.isArray(n?.items) && hasUrl(n.items, url)));
|
|
429
|
+
let content = items.find(n => isFolder(n) && n.key === 'content');
|
|
430
|
+
for (const item of moving) {
|
|
431
|
+
if (hasUrl(items, item.url)) continue;
|
|
432
|
+
if (!content) {
|
|
433
|
+
content = {text: 'Content', key: 'content', icon: 'edit', items: []};
|
|
434
|
+
const idx = items.findIndex(n => isFolder(n) && ['data', 'system'].includes(n.key));
|
|
435
|
+
items.splice(idx === -1 ? items.length : idx, 0, content);
|
|
436
|
+
}
|
|
437
|
+
if (!Array.isArray(content.items)) content.items = [];
|
|
438
|
+
content.items.push(item);
|
|
439
|
+
}
|
|
440
|
+
menu.meta = {...(menu.meta || {}), contentMenuItems: true};
|
|
441
|
+
changed = true;
|
|
442
|
+
}
|
|
443
|
+
|
|
416
444
|
// An empty menu is left empty: the renderer's minimal fallback (Dashboard,
|
|
417
445
|
// Menus) is what an admin needs to repair it, and a lone Tools folder would
|
|
418
446
|
// stop that fallback from applying.
|