(function(){ function getMetaEditBase(){ // 从 Sphinx html_context 注入的值读取 try { var metas = document.getElementsByTagName('meta'); for (var i=0;i= 0){ path = path.substring(idx + marker.length); } // 将 docs 拷贝后的路径映射回真实项目源路径 // 示例:driver/Titan_driver_hyperram/README_zh.html -> project/Titan_driver_hyperram/README_zh.md var projectsDir = (window.versionInfo && window.versionInfo.projectsDir) ? window.versionInfo.projectsDir : ''; var copyFiles = (window.versionInfo && window.versionInfo.copyFiles) ? window.versionInfo.copyFiles : []; var mapped = path; // 剥离 docs 分类前缀(start/basic/driver/component/...)后取剩余相对路径 var firstSlash = mapped.indexOf('/'); if (firstSlash >= 0) { mapped = mapped.substring(firstSlash + 1); } // 去掉 .html 后缀 var htmlName = mapped.split('/').pop(); var baseName = htmlName.replace(/\.html$/i, ''); // 依据 copy_files 中的候选名推断源文件名优先级(README_zh.md、README.md 等) // 回退规则: // 1) 如果 baseName 匹配 README_zh/README 等,按列表顺序尝试; // 2) 否则将 .html 改为 .md var candidates = []; if (/^readme(_zh)?$/i.test(baseName)) { var normalized = copyFiles.map(function(n){ return String(n || '').toLowerCase(); }); // 根据当前页面文件名匹配对应的源文件 var targetFile = ''; if (baseName.toLowerCase() === 'readme_zh') { targetFile = 'README_zh.md'; } else if (baseName.toLowerCase() === 'readme') { targetFile = 'README.md'; } // 如果找到匹配的目标文件且存在于 copyFiles 中,优先使用 if (targetFile && normalized.indexOf(targetFile.toLowerCase()) >= 0) { candidates.push(targetFile); } else { // 回退到原有逻辑:常见文件名优先,保持原始大小写 ['README_zh.md','README.md'].forEach(function(name){ var lowerName = name.toLowerCase(); if (normalized.indexOf(lowerName) >= 0 && candidates.indexOf(name) < 0) candidates.push(name); }); } // 追加其余列表中文件名(保持原始大小写) copyFiles.forEach(function(n){ var fileName = String(n || ''); var ln = fileName.toLowerCase(); if (candidates.map(function(c){return c.toLowerCase();}).indexOf(ln) < 0) candidates.push(fileName); }); } if (candidates.length === 0) { candidates = [baseName + '.md']; } // 组装目录 + 源文件名 var dir = mapped.substring(0, mapped.lastIndexOf('/')); mapped = dir + '/' + candidates[0]; // 拼接为仓库中的项目路径 if (projectsDir) { mapped = projectsDir.replace(/\/+$/,'') + '/' + mapped.replace(/^\//,''); } // 修复:正确构建 GitHub 编辑链接 // 从 base URL 中提取 user 和 repo 信息 // base 格式应该是类似 "https://github.com/user/repo/" 或 "github.com/user/repo/" var match = base.match(/github\.com\/([^\/]+)\/([^\/]+)\/?/i); if (!match) { console.warn('无法从 base URL 中解析 GitHub 用户名和仓库名:', base); return ''; } var user = match[1]; var repo = match[2]; // 构建正确的 GitHub 编辑 URL 格式 // https://github.com/$user/$repo/edit/$branch/$file_path var editUrl = 'https://github.com/' + user + '/' + repo + '/edit/' + branch + '/' + mapped; return editUrl; } function insertButton(){ // 首先检查是否是可编辑的文档页面 if (!isEditablePage()) return; var url = buildEditUrl(); if (!url) return; // 检测当前页面语言 var currentLang = detectCurrentLanguage(); var buttonText = currentLang === 'zh' ? '在GitHub上编辑' : 'Edit on GitHub'; var buttonTitle = currentLang === 'zh' ? '在GitHub上编辑此页面' : 'Edit this page on GitHub'; // 优先插入到面包屑,保持与导航同高;使用带边框+图标样式 var breadcrumbs = document.querySelector('.wy-breadcrumbs'); if (breadcrumbs) { var oldAside = breadcrumbs.querySelector('.wy-breadcrumbs-aside'); if (oldAside && oldAside.parentNode) oldAside.parentNode.removeChild(oldAside); var li = document.createElement('li'); li.className = 'wy-breadcrumbs-aside'; var a = document.createElement('a'); a.href = url; a.target = '_blank'; a.rel = 'noopener'; a.className = 'sdk-edit-on-github__btn'; a.innerHTML = '' + buttonText + ''; a.title = buttonTitle; li.appendChild(a); breadcrumbs.appendChild(li); return; } // 回退:插入到正文容器顶部右侧 var content = document.querySelector('.wy-nav-content'); if (!content) return; if (document.querySelector('.sdk-edit-on-github')) return; var container = document.createElement('div'); container.className = 'sdk-edit-on-github'; var a2 = document.createElement('a'); a2.className = 'sdk-edit-on-github__btn'; a2.target = '_blank'; a2.rel = 'noopener'; a2.href = url; a2.innerHTML = '' + buttonText + ''; a2.title = buttonTitle; container.appendChild(a2); var first = content.firstElementChild; if (first) content.insertBefore(container, first); else content.appendChild(container); } function init(){ injectMetaFromContext(); if (document.readyState === 'loading'){ document.addEventListener('DOMContentLoaded', insertButton); } else { insertButton(); } } init(); })();