From 82384e2d2fe203dd492424723e55eca925f359a4 Mon Sep 17 00:00:00 2001 From: vyctorbrzezowski Date: Mon, 1 Jun 2026 01:52:44 -0300 Subject: [PATCH] fix(docs): make page feedback actionable --- scripts/docs-site/assets.mjs | 16 ++++++++++++++-- scripts/docs-site/build.mjs | 12 ++++++++++-- scripts/docs-site/smoke.mjs | 7 +++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/scripts/docs-site/assets.mjs b/scripts/docs-site/assets.mjs index 002726325..3d75b90a7 100644 --- a/scripts/docs-site/assets.mjs +++ b/scripts/docs-site/assets.mjs @@ -24,6 +24,8 @@ export function siteCss() { .docs-chat{top:auto;right:18px;bottom:18px;width:min(420px,calc(100vw - 36px));height:min(680px,calc(100vh - 36px));transition:width .24s cubic-bezier(.23,1,.32,1),height .24s cubic-bezier(.23,1,.32,1)}.docs-chat-launcher{right:0;bottom:0}.docs-chat.expanded{width:min(760px,calc(100vw - 36px));height:min(860px,calc(100vh - 36px))}.docs-chat.open{pointer-events:auto}.docs-chat:not(.open):not(.closing){right:18px!important}.docs-chat.open .docs-chat-launcher,.docs-chat.closing .docs-chat-launcher{display:flex;opacity:0;visibility:hidden;pointer-events:none}.docs-chat-panel{display:grid;opacity:0;transform:translateY(10px) scale(.985);transform-origin:bottom right;pointer-events:none;transition:transform .2s cubic-bezier(.23,1,.32,1),opacity .16s ease}.docs-chat.open .docs-chat-panel{display:grid;opacity:1;transform:none;pointer-events:auto}.docs-chat-maximize[aria-pressed="true"]{border-color:color-mix(in srgb,var(--brand) 44%,var(--line-strong));background:color-mix(in srgb,var(--soft) 68%,transparent);color:var(--ink)}.docs-chat-maximize .icon{transition:none}@media(prefers-reduced-motion:reduce){.docs-chat,.docs-chat-panel{transition:none}} .docs-chat-panel{grid-template-rows:auto auto minmax(0,1fr) auto;inline-size:100%;min-width:0;max-width:100%;background:var(--bg);border:1px solid var(--line-strong);border-radius:16px;box-shadow:0 22px 70px rgba(0,0,0,.42);overflow:hidden}.docs-chat-panel>*{min-width:0;max-width:100%}.docs-chat-head{grid-row:1;min-height:58px;overflow:hidden;padding:10px 14px;background:var(--bg);border-bottom:1px solid var(--line);cursor:grab;touch-action:none;user-select:none}.docs-chat.dragging .docs-chat-head{cursor:grabbing}.docs-chat-title{display:flex;align-items:center;gap:10px;flex:1 1 auto;min-width:0}.docs-chat-mark{display:grid;place-items:center;flex:0 0 28px;width:28px;height:28px;color:var(--brand);filter:drop-shadow(0 0 12px color-mix(in srgb,var(--brand) 35%,transparent))}.docs-chat-mark .icon{width:25px;height:25px;stroke-width:1.8}.docs-chat-head h2{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:500 17px/1.05 ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;letter-spacing:.04em}.docs-chat-actions{flex:0 0 auto;min-width:0;gap:6px}.docs-chat-icon{width:29px;height:29px;border-radius:10px;color:color-mix(in srgb,var(--muted) 82%,transparent)}.docs-chat-icon[hidden]{display:none}.docs-chat-icon .icon{width:17px;height:17px}.docs-chat-copy[data-copy-state] .icon{display:none}.docs-chat-copy[data-copy-state]:before{font:900 15px/1 ui-sans-serif,system-ui,sans-serif}.docs-chat-copy[data-copy-state="copied"]:before{content:"✓"}.docs-chat-copy[data-copy-state="failed"]:before{content:"!"}.docs-chat-minimize{font-size:27px;font-weight:320}.docs-chat-log{grid-row:3;min-width:0;overflow-x:hidden;padding:24px 22px 18px;gap:12px}.docs-chat-message{max-width:min(86%,calc(100% - 28px));min-width:0;overflow-wrap:anywhere;word-break:break-word}.docs-chat-message.user{margin-right:0}.docs-chat-code{max-width:100%}.docs-chat-empty{max-width:300px;margin:0 auto;color:color-mix(in srgb,var(--muted) 72%,transparent);text-align:center;font:500 15px/1.45 ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;letter-spacing:.03em}.docs-chat-form{grid-row:4;position:relative;display:block;width:100%;min-width:0;max-width:100%;overflow:hidden;padding:16px 22px 22px;border-top:0;background:linear-gradient(180deg,transparent,color-mix(in srgb,var(--bg) 96%,#000 4%) 22%)}.docs-chat:not([data-chat-auth-state="ready"]) .docs-chat-form{display:none}.docs-chat-form textarea{display:block;inline-size:100%;max-width:100%;min-width:0;min-height:118px;max-height:158px;border-radius:22px;padding:20px 66px 42px 20px;background:var(--bg);font-size:16px;line-height:1.5;overflow:hidden;box-shadow:inset 0 1px 0 rgba(255,255,255,.02)}.docs-chat-form textarea:focus{outline:0;border-color:var(--brand);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--brand) 48%,transparent),inset 0 0 0 4px color-mix(in srgb,var(--brand) 12%,transparent),inset 0 1px 0 rgba(255,255,255,.03)}.docs-chat-attach{position:absolute;left:40px;bottom:38px;display:grid;place-items:center;width:28px;height:28px;color:var(--muted);pointer-events:none}.docs-chat-attach .icon{width:17px;height:17px}.docs-chat-form button{position:absolute;right:34px;bottom:34px;width:38px;height:38px;border-radius:999px}.docs-chat-auth{grid-row:4;align-self:end;border-top:1px solid var(--line);border-bottom:0;background:var(--bg);padding:16px 22px 22px}.docs-chat-auth-card{border-radius:16px} .oc-chart-mark,.oc-chart-donut-key{position:relative}.oc-chart-mark:focus-visible,.oc-chart-line-svg circle:focus-visible,.oc-chart-donut-segment:focus-visible,.oc-chart-donut-key:focus-visible{outline:2px solid color-mix(in srgb,var(--brand) 58%,transparent);outline-offset:3px}.oc-chart-mark[data-tip]:hover:after,.oc-chart-mark[data-tip]:focus:after,.oc-chart-donut-key[data-tip]:hover:after,.oc-chart-donut-key[data-tip]:focus:after{content:attr(data-tip);position:absolute;left:50%;bottom:calc(100% + 9px);transform:translateX(-50%);z-index:30;width:max-content;max-width:min(260px,calc(100vw - 40px));padding:7px 9px;border:1px solid var(--tooltip-border);border-radius:7px;background:var(--tooltip-bg);color:var(--tooltip-text);font:760 12px/1.25 ui-sans-serif,system-ui,sans-serif;box-shadow:var(--shadow);pointer-events:none}.oc-chart-mark[data-tip]:hover:before,.oc-chart-mark[data-tip]:focus:before,.oc-chart-donut-key[data-tip]:hover:before,.oc-chart-donut-key[data-tip]:focus:before{content:"";position:absolute;left:50%;bottom:calc(100% + 4px);transform:translateX(-50%) rotate(45deg);z-index:31;width:8px;height:8px;background:var(--tooltip-bg);pointer-events:none}.oc-chart-area-fill{fill:color-mix(in srgb,var(--brand) 18%,transparent)}.oc-chart-donut-wrap{display:grid;grid-template-columns:minmax(170px,220px) minmax(0,1fr);gap:18px;align-items:center}.oc-chart-donut-svg{display:block;width:100%;height:auto}.oc-chart-donut-bg{fill:none;stroke:color-mix(in srgb,var(--line-strong) 72%,transparent);stroke-width:28}.oc-chart-donut-segment{fill:none;stroke:var(--oc-chart-tone);stroke-width:28;stroke-linecap:butt;stroke-dasharray:var(--oc-chart-share) 100;stroke-dashoffset:calc(var(--oc-chart-offset) * -1);transition:stroke-width .16s ease,opacity .16s ease}.oc-chart-donut-segment:hover,.oc-chart-donut-segment:focus{stroke-width:32;opacity:.92}.oc-chart-donut-svg text:first-of-type{fill:var(--ink);font:780 24px/1 ui-sans-serif,system-ui,sans-serif}.oc-chart-donut-svg text:last-of-type{fill:var(--muted);font:760 11px/1 ui-sans-serif,system-ui,sans-serif;text-transform:uppercase}.oc-chart-donut-legend{display:grid;gap:8px}.oc-chart-donut-key{display:grid;grid-template-columns:10px minmax(0,1fr) auto;gap:8px;align-items:center;color:var(--text);font-size:12px}.oc-chart-donut-key i{width:10px;height:10px;border-radius:2px;background:var(--oc-chart-tone)}.oc-chart-donut-key span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.oc-chart-donut-key strong{color:var(--ink);font:760 12px/1 ui-sans-serif,system-ui,sans-serif}.oc-callout{--callout-surface:var(--paper);background:var(--callout-surface);border-color:var(--line-strong);border-left-color:var(--callout-accent);box-shadow:none}.oc-callout strong:before{background:var(--paper)}:root[data-theme="light"] .oc-callout{background:var(--paper);border-color:var(--line-strong);border-left-color:var(--callout-accent)}:root[data-theme="light"] .oc-callout strong:before{background:var(--paper);box-shadow:0 0 0 3px var(--paper)} +.page-feedback{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:18px 22px;border-top:1px solid var(--line);margin-top:42px;padding-top:18px}.page-feedback-prompt{display:flex;align-items:center;gap:9px;min-width:0;flex-wrap:wrap}.page-feedback-prompt>span{display:inline-flex;align-items:center;color:var(--text)}.page-feedback-composer{grid-column:1/-1;display:grid;gap:11px}.page-feedback-composer[hidden]{display:none}.page-feedback-composer textarea{width:100%;min-height:110px;resize:vertical;border:1px solid var(--line-strong);border-radius:10px;background:color-mix(in srgb,var(--bg) 80%,var(--paper) 20%);color:var(--ink);padding:13px 14px}.page-feedback-composer textarea:focus{outline:0;border-color:var(--brand);box-shadow:0 0 0 3px color-mix(in srgb,var(--brand) 18%,transparent)}.page-feedback-submit{display:inline-flex;align-items:center;justify-content:center;gap:8px;justify-self:end;min-height:38px;border:1px solid color-mix(in srgb,var(--brand) 46%,var(--line-strong));border-radius:8px;background:color-mix(in srgb,var(--paper) 76%,transparent);color:var(--brand);padding:0 13px;font:800 12px/1 ui-sans-serif,system-ui,sans-serif;white-space:nowrap}.page-feedback-submit .icon{width:15px;height:15px}.page-feedback-submit:hover{border-color:var(--brand);color:var(--ink);background:color-mix(in srgb,var(--soft) 52%,transparent)} +@media(max-width:620px){.page-feedback{grid-template-columns:1fr;padding:16px}.page-feedback-links{margin-left:0}.page-feedback-composer{max-width:none}.page-feedback-submit{width:max-content}} @media(max-width:1120px){html{scroll-padding-top:calc(var(--sticky-header-h) + 54px)}.header-row{grid-template-columns:auto 1fr auto;padding:0 24px}.tabs{padding:0 24px}.header-links a{display:none}.oc-card-grid.oc-card-cols-4{grid-template-columns:repeat(2,minmax(0,1fr))}.doc-shell{grid-template-columns:220px minmax(0,1fr);gap:34px;padding-left:24px;padding-right:24px}.sidebar{top:148px;max-height:calc(100vh - 172px);padding-right:4px}.nav-section{margin-bottom:26px}.nav-link{padding:6px 10px;font-size:13px}.main{grid-template-columns:minmax(0,1fr)}.toc{position:fixed;left:calc(24px + 220px + 34px);top:calc(var(--sticky-header-h) + 8px);z-index:60;width:max-content;max-width:calc(100vw - 302px);max-height:none;margin:0;padding:0;overflow:visible;background:transparent;color:var(--muted);font-size:13px;opacity:0;visibility:hidden;pointer-events:none;transform:translateY(-4px);transition:opacity .16s ease,transform .16s ease,visibility .16s ease}.toc.is-visible,.toc[open]{opacity:1;visibility:visible;pointer-events:auto;transform:none}.toc h2{display:none}.toc summary{display:flex;align-items:center;gap:8px;min-height:34px;padding:0 11px;border:1px solid var(--line-strong);border-radius:8px;background:color-mix(in srgb,var(--paper) 90%,transparent);color:var(--ink);font:760 12px/1 ui-sans-serif,system-ui,sans-serif;cursor:pointer;list-style:none;box-shadow:0 10px 30px rgba(0,0,0,.18)}.toc summary::-webkit-details-marker{display:none}.toc summary:after{content:"";width:6px;height:6px;border-right:1.25px solid color-mix(in srgb,currentColor 72%,transparent);border-bottom:1.25px solid color-mix(in srgb,currentColor 72%,transparent);transform:rotate(45deg);margin-top:-3px}.toc[open] summary{border-color:color-mix(in srgb,var(--brand) 38%,var(--line-strong));background:color-mix(in srgb,var(--soft) 62%,var(--paper) 38%)}.toc[open] summary:after{transform:rotate(225deg);margin-top:3px}.toc nav{position:absolute;left:0;top:calc(100% + 8px);display:none;width:min(340px,calc(100vw - 302px));max-height:min(58vh,520px);overflow:auto;overscroll-behavior:contain;scrollbar-gutter:stable;padding:8px 11px 8px 8px;border:1px solid color-mix(in srgb,var(--line-strong) 82%,var(--brand) 18%);border-radius:10px;background:color-mix(in srgb,var(--paper) 92%,var(--soft) 8%);box-shadow:var(--shadow)}.toc[open] nav{display:grid;gap:2px}.toc a{display:block;max-width:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:7px;padding:8px 9px;color:var(--text)}.toc a:hover,.toc a.active{background:var(--soft);color:var(--ink)}.toc-l3{padding-left:18px!important}}@media(max-width:820px){html{scroll-padding-top:calc(var(--sticky-header-h) + 50px)}.site-header{position:sticky}.header-row{height:auto;min-height:0;grid-template-columns:auto minmax(0,1fr) auto;grid-template-areas:"menu brand actions" "search search search";align-items:center;padding:10px 14px 12px;gap:10px 12px}.header-left{grid-area:brand;justify-self:center;gap:10px;min-width:0}.brand img{width:22px;height:22px}.language-trigger{max-width:48vw;height:34px}.language-current{font-size:13px}.language-menu{left:50%;transform:translateX(-50%);width:min(390px,calc(100vw - 28px));max-height:min(72vh,620px)}.search-button{grid-area:search;width:100%;height:40px}.header-links{grid-area:actions;justify-self:end;gap:0}.theme-toggle{width:40px;height:40px;border:1px solid var(--line-strong)!important;border-radius:10px;background:var(--paper)!important}.nav-toggle{grid-area:menu;display:inline-flex;align-items:center;justify-content:center;justify-self:start;min-width:72px;height:40px;padding:0 12px}.tabs{display:none}.doc-shell{display:block;padding:26px 20px 86px}.toc{left:20px;top:calc(var(--sticky-header-h) + 8px);max-width:calc(100vw - 40px)}.toc nav{width:min(340px,calc(100vw - 40px));max-height:min(62vh,560px)}.toc summary{min-height:36px}body.nav-open{overflow:hidden}body.nav-open:before{content:"";position:fixed;inset:0;z-index:75;background:rgba(0,0,0,.58);backdrop-filter:blur(2px)}.sidebar{position:fixed;inset:0 auto 0 0;width:min(360px,calc(100vw - 28px));z-index:90;transform:translateX(calc(-100% - 1px));transition:transform .2s ease;background:var(--bg);border-right:1px solid var(--line);padding:18px 18px 28px;max-height:none;box-shadow:24px 0 80px rgba(0,0,0,.42);mask-image:none;-webkit-mask-image:none}.sidebar.open{transform:translateX(0)}.sidebar-close{display:flex;align-items:center;justify-content:center;width:100%;height:40px;margin:0 0 18px;border:1px solid var(--line-strong);border-radius:8px;background:var(--paper);color:var(--ink);font:760 13px/1 ui-sans-serif,system-ui,sans-serif}.breadcrumbs{white-space:normal}.article-meta-row .page-tools{flex:0 0 auto}.breadcrumbs .breadcrumb-group{display:none}.page-tools,.page-feedback{flex-wrap:wrap}.article h1{font-size:28px}.oc-card-grid,.oc-card-group,.oc-card-grid.oc-card-cols-3,.oc-card-grid.oc-card-cols-4,.oc-tile-group,.oc-cta-grid,.oc-stat-grid{grid-template-columns:1fr}.oc-steps{margin-left:18px}.oc-step{padding-left:30px}.oc-tabs,.oc-code-group{margin-left:0;margin-right:0}.oc-tab{padding:18px}.doc pre{white-space:pre-wrap;overflow-wrap:anywhere}.doc pre code{white-space:pre-wrap;min-width:0}.doc .code-line{white-space:pre-wrap;overflow-wrap:anywhere}.oc-code-tabs{overflow-x:auto}.oc-code-tab{flex:0 0 auto}.next{text-align:left}.page-nav{grid-template-columns:1fr}.oc-chart-donut-wrap{grid-template-columns:1fr}.docs-chat,.docs-chat.expanded{right:14px;bottom:14px;width:min(390px,calc(100vw - 28px));height:min(680px,calc(100vh - 28px))}.docs-chat:not(.open):not(.closing){right:14px!important}.docs-chat-launcher{right:0;bottom:0;height:44px;padding:0 14px}.docs-chat-head{min-height:58px;padding:12px}.docs-chat-panel{box-shadow:0 18px 54px rgba(0,0,0,.42)}} @media(max-width:1120px){.oc-card-grid.oc-card-cols-4,.oc-card-group.oc-card-cols-4{--oc-card-columns:2;grid-template-columns:repeat(var(--oc-card-columns),minmax(0,1fr))}}@media(max-width:820px){.oc-card-grid,.oc-card-group,.oc-card-grid.oc-card-cols-1,.oc-card-group.oc-card-cols-1,.oc-card-grid.oc-card-cols-2,.oc-card-group.oc-card-cols-2,.oc-card-grid.oc-card-cols-3,.oc-card-group.oc-card-cols-3,.oc-card-grid.oc-card-cols-4,.oc-card-group.oc-card-cols-4{--oc-card-columns:1;grid-template-columns:1fr}} `; @@ -58,14 +60,23 @@ function codeTextForCopy(block){const lines=[...block?.querySelectorAll(".code-l function pageMarkdownForCopy(control){const source=control.closest(".article")?.querySelector("[data-page-markdown]");if(!source)return"";try{return JSON.parse(source.textContent||'""')}catch{return source.textContent||""}} function copyPageMarkdown(control){return copyText(pageMarkdownForCopy(control),control)} function toggleCodeExpand(control){const block=control.closest(".oc-code");if(!block)return;const expanded=!block.classList.contains("is-expanded");block.classList.toggle("is-expanded",expanded);control.setAttribute("aria-expanded",String(expanded));control.textContent=expanded?"Show less":"Show more"} -function handleDocsControlClick(e){const copyCode=e.target.closest("[data-code-copy]");if(copyCode){copyText(codeTextForCopy(copyCode.closest(".oc-code")),copyCode);return true}const expandCode=e.target.closest("[data-code-expand]");if(expandCode){toggleCodeExpand(expandCode);return true}const copyPrompt=e.target.closest("[data-prompt-copy]");if(copyPrompt){const prompt=copyPrompt.closest(".oc-prompt")?.textContent?.replace(/Copy\\s*$/,"").trim()||"";copyText(prompt,copyPrompt);return true}const copyPage=e.target.closest("[data-copy-page]");if(copyPage){copyPageMarkdown(copyPage);return true}const headingAnchor=e.target.closest("[data-heading-anchor]");if(headingAnchor){const url=new URL(location.href);url.hash=headingAnchor.dataset.headingAnchor||"";copyText(url.href,headingAnchor);return true}const feedback=e.target.closest("[data-feedback-value]");if(feedback){const result=feedback.closest(".page-feedback")?.querySelector("[data-feedback-result]");if(result)result.value=feedback.dataset.feedbackValue==="yes"?"Thanks.":"Noted.";return true}return false} +const feedbackStoragePrefix="openclaw.docs.feedback:"; +function feedbackPath(section){return section?.dataset.feedbackPath||new URL(location.href).pathname||"/"} +function feedbackStorageKey(section){return feedbackStoragePrefix+feedbackPath(section)} +function feedbackRepo(section){const repo=section?.dataset.feedbackRepo||"openclaw/openclaw";return /^[^/\\s]+\\/[^/\\s]+$/.test(repo)?repo:"openclaw/openclaw"} +function feedbackPageUrl(section){return section?.dataset.feedbackUrl||location.href} +function feedbackIssueUrl(section){const path=feedbackPath(section);const url=new URL("https://github.com/"+feedbackRepo(section)+"/issues/new");const detail=section?.querySelector("[data-feedback-detail]")?.value.trim();const body=["Page: "+path,"URL: "+feedbackPageUrl(section),"",detail?"Missing or confusing:":"","",detail||""].filter((part,i)=>part||i<3).join("\\n");url.searchParams.set("title","Docs feedback: "+path);url.searchParams.set("body",body);return url.href} +function updateFeedbackIssueLink(section){const link=section?.querySelector("[data-feedback-issue-link]");if(link)link.href=feedbackIssueUrl(section)} +function setFeedbackState(section,value,{persist=false}={}){if(!section)return;const result=section.querySelector("[data-feedback-result]");const composer=section.querySelector("[data-feedback-composer]");section.querySelectorAll("[data-feedback-value]").forEach(button=>button.setAttribute("aria-pressed",String(button.dataset.feedbackValue===value)));if(result)result.value=value==="yes"?"Thanks.":"";if(composer)composer.hidden=value!=="no";if(value==="no")updateFeedbackIssueLink(section);if(persist)try{localStorage.setItem(feedbackStorageKey(section),value)}catch{}} +function initPageFeedback(){document.querySelectorAll(".page-feedback").forEach(section=>{if(section.dataset.feedbackReady)return;section.dataset.feedbackReady="true";const detail=section.querySelector("[data-feedback-detail]");detail?.addEventListener("input",()=>updateFeedbackIssueLink(section));updateFeedbackIssueLink(section);try{const saved=localStorage.getItem(feedbackStorageKey(section));if(saved==="yes"||saved==="no")setFeedbackState(section,saved)}catch{}})} +function handleDocsControlClick(e){const copyCode=e.target.closest("[data-code-copy]");if(copyCode){copyText(codeTextForCopy(copyCode.closest(".oc-code")),copyCode);return true}const expandCode=e.target.closest("[data-code-expand]");if(expandCode){toggleCodeExpand(expandCode);return true}const copyPrompt=e.target.closest("[data-prompt-copy]");if(copyPrompt){const prompt=copyPrompt.closest(".oc-prompt")?.textContent?.replace(/Copy\\s*$/,"").trim()||"";copyText(prompt,copyPrompt);return true}const copyPage=e.target.closest("[data-copy-page]");if(copyPage){copyPageMarkdown(copyPage);return true}const headingAnchor=e.target.closest("[data-heading-anchor]");if(headingAnchor){const url=new URL(location.href);url.hash=headingAnchor.dataset.headingAnchor||"";copyText(url.href,headingAnchor);return true}const feedback=e.target.closest("[data-feedback-value]");if(feedback){setFeedbackState(feedback.closest(".page-feedback"),feedback.dataset.feedbackValue,{persist:true});return true}return false} function scrollTarget(hash){if(hash){document.getElementById(decodeURIComponent(hash.slice(1)))?.scrollIntoView()}else{scrollTo(0,0)}} let tocObserver=null;let tocScrollHandler=null; function tocLinkId(link){try{return decodeURIComponent(link.hash.slice(1))}catch{return link.hash.slice(1)}} function setActiveTocLink(id){const toc=document.querySelector(".toc");if(!toc)return;let active=null;toc.querySelectorAll('a[href^="#"]').forEach(link=>{const on=Boolean(id&&tocLinkId(link)===id);link.classList.toggle("active",on);if(on)active=link});active?.scrollIntoView({block:"nearest"})} function currentTocHeadingId(headings){const top=parseFloat(getComputedStyle(document.documentElement).scrollPaddingTop)||120;const scroller=document.scrollingElement||document.documentElement;if(scroller.scrollTop+innerHeight>=scroller.scrollHeight-2)return headings.at(-1)?.id||"";let current=headings[0];for(const heading of headings){if(heading.getBoundingClientRect().top<=top+1)current=heading;else break}return current?.id||""} function initTocScrollspy(){tocObserver?.disconnect();tocObserver=null;if(tocScrollHandler){removeEventListener("scroll",tocScrollHandler);tocScrollHandler=null;}const toc=document.querySelector(".toc");if(!toc)return;const links=[...toc.querySelectorAll('a[href^="#"]')];const headings=[...document.querySelectorAll(".doc h2[id],.doc h3[id]")].filter(heading=>links.some(link=>tocLinkId(link)===heading.id));links.forEach(link=>link.classList.remove("active"));if(!headings.length)return;const sync=()=>setActiveTocLink(currentTocHeadingId(headings));let tocScrollRaf=0;tocScrollHandler=()=>{cancelAnimationFrame(tocScrollRaf);tocScrollRaf=requestAnimationFrame(sync)};addEventListener("scroll",tocScrollHandler,{passive:true});requestAnimationFrame(sync);if(!("IntersectionObserver" in window)){sync();return}tocObserver=new IntersectionObserver(sync,{rootMargin:"-120px 0px -70% 0px",threshold:[0,1]});headings.forEach(heading=>tocObserver.observe(heading))} -async function navigateTo(url,replace=false){if(navigating)return false;navigating=true;closeLanguage();try{const res=await fetch(url.href,{credentials:"same-origin"});if(!res.ok||!res.headers.get("content-type")?.includes("text/html"))return false;const nextDoc=new DOMParser().parseFromString(await res.text(),"text/html");if(!nextDoc.querySelector(".main"))return false;syncSidebar(nextDoc);swap(".header-left",nextDoc);swapTabs(nextDoc);swap(".main",nextDoc);syncStickyHeaderOffset();syncTocDisclosure();initCodeGroups();initMermaid();document.title=nextDoc.title;history[replace?"replaceState":"pushState"]({docs:true},"",url.href);setNavOpen(false);scrollTarget(url.hash);initTocScrollspy();return true}catch{return false}finally{navigating=false}} +async function navigateTo(url,replace=false){if(navigating)return false;navigating=true;closeLanguage();try{const res=await fetch(url.href,{credentials:"same-origin"});if(!res.ok||!res.headers.get("content-type")?.includes("text/html"))return false;const nextDoc=new DOMParser().parseFromString(await res.text(),"text/html");if(!nextDoc.querySelector(".main"))return false;syncSidebar(nextDoc);swap(".header-left",nextDoc);swapTabs(nextDoc);swap(".main",nextDoc);syncStickyHeaderOffset();syncTocDisclosure();initCodeGroups();initPageFeedback();initMermaid();document.title=nextDoc.title;history[replace?"replaceState":"pushState"]({docs:true},"",url.href);setNavOpen(false);scrollTarget(url.hash);initTocScrollspy();return true}catch{return false}finally{navigating=false}} function openSearch(){modal?.classList.add("open");setTimeout(()=>input?.focus(),0);pagefindReady ||= import(withBase("/pagefind/pagefind.js")).then(m=>m.init?.().then?.(()=>m)??m)} function escapeHtml(text){return String(text).replace(/[&<>"']/g,ch=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[ch]))} function trimTrailingPunctuation(value){return value.replace(/[.,;!?]+$/,"")} @@ -119,6 +130,7 @@ syncStickyHeaderOffset(); syncTocDisclosure(); initChat(); initCodeGroups(); +initPageFeedback(); initMermaid(); scrollActiveNavLink(); initTocScrollspy(); diff --git a/scripts/docs-site/build.mjs b/scripts/docs-site/build.mjs index 4f1c31613..6cc3c3c7b 100644 --- a/scripts/docs-site/build.mjs +++ b/scripts/docs-site/build.mjs @@ -24,6 +24,7 @@ const legacyBasePath = normalizeBasePath(process.env.DOCS_SITE_LEGACY_BASE_PATH const canonicalOrigin = (process.env.DOCS_SITE_CANONICAL_ORIGIN ?? (process.env.DOCS_SITE_CNAME ? `https://${process.env.DOCS_SITE_CNAME}` : "https://docs.openclaw.ai")) .replace(/\/$/, ""); +const feedbackIssueRepository = normalizeRepository(process.env.DOCS_FEEDBACK_ISSUE_REPO ?? "openclaw/openclaw"); const llmsFullAvailable = process.env.DOCS_SITE_LLMS_FULL_AVAILABLE === "1"; const ogImagePath = "/og-card.png"; const renderedPageOgCards = new Set(); @@ -529,13 +530,15 @@ function pager(prev, next) { function pageFeedback(page) { const editUrl = editSourceUrlForPage(page, sourceMetadata); const editLink = editUrl ? `Edit source` : ""; - return `
Was this useful?
`; + const pagePath = pageRoute(page); + const canonicalUrl = `${docsOrigin()}${pagePath}`; + return `
Was this useful?
`; } function raiseIssueUrl(page) { const title = encodeURIComponent("Issue on docs"); const body = encodeURIComponent(`Path: ${pageRoute(page)}`); - return `https://github.com/openclaw/openclaw/issues/new?title=${title}&body=${body}`; + return `https://github.com/${feedbackIssueRepository}/issues/new?title=${title}&body=${body}`; } function searchModal() { @@ -929,6 +932,11 @@ function normalizeBasePath(value) { return `/${value.replace(/^\/+|\/+$/g, "")}`; } +function normalizeRepository(value) { + const repo = String(value).trim(); + return /^[^/\s]+\/[^/\s]+$/.test(repo) ? repo : "openclaw/openclaw"; +} + function htmlLang(locale) { return locale === "zh-CN" ? "zh-CN" : locale === "zh-TW" ? "zh-TW" : locale; } diff --git a/scripts/docs-site/smoke.mjs b/scripts/docs-site/smoke.mjs index 556f4bde9..527ccf175 100644 --- a/scripts/docs-site/smoke.mjs +++ b/scripts/docs-site/smoke.mjs @@ -509,6 +509,13 @@ if (!/function initCodeGroups/.test(siteJs) || !/className="oc-code-tab"/.test(s if (!/function handleDocsControlClick/.test(siteJs) || !/async function copyText/.test(siteJs)) { throw new Error("assets: copy and feedback controls are missing"); } +if (!/data-feedback-repo="openclaw\/openclaw"/.test(index) + || !/data-feedback-issue-link/.test(index) + || !/function initPageFeedback/.test(siteJs) + || !/openclaw\.docs\.feedback/.test(siteJs) + || !/github\.com\/"\+feedbackRepo/.test(siteJs)) { + throw new Error("assets: useful feedback composer is missing"); +} if (!/function toggleCodeExpand/.test(siteJs) || !/data-code-expand/.test(siteJs) || !/is-expanded/.test(siteJs)