function encodePickedPath(p) { if (p === '/' || p === '') return '/'; return '/' + p.replace(/^\/+/, '').split('/').map(encodeURIComponent).join('/'); } function promptPageName(title, initial, confirmLabel, onName) { var input = document.createElement('input'); input.type = 'text'; input.className = 'input'; input.placeholder = 'Page name'; if (initial) input.value = initial; openModal({ title: title, body: input, confirm: { label: confirmLabel, onConfirm: function () { var name = input.value.trim(); if (!name) return; onName(name); } } }); } function newPage() { var current = decodeURIComponent(window.location.pathname).replace(/\/+$/, '') || '/'; openTreePicker({ title: 'New page — where?', mode: 'folder', initialPath: current, preselect: current, hideFiles: true, confirmLabel: 'NEXT', onSelect: function (parentPath) { promptPageName('New page — name?', '', 'CREATE', function (name) { var base = parentPath === '/' ? '/' : encodePickedPath(parentPath) + '/'; window.location.href = base + encodeURIComponent(name) + '/?edit'; }); } }); } function movePage() { var current = decodeURIComponent(window.location.pathname).replace(/\/+$/, ''); if (!current) return; var parent = '/' + current.split('/').filter(Boolean).slice(0, -1).join('/'); openTreePicker({ title: 'Move — new parent?', mode: 'folder', initialPath: parent, preselect: parent, hideFiles: true, confirmLabel: 'NEXT', onSelect: function (newParent) { // The server renders the name step and handles what follows // (merge confirmation, errors, redirect). closeModal(); htmx.ajax('GET', window.location.pathname + '?dialog=move', { target: '#modal-host', values: { parent: newParent } }); } }); }