fix: Codex 自动压缩不触发 —— 接管时链接模型目录(绝对路径)进 config.toml (hot 1.5.83)
This commit is contained in:
@@ -15,14 +15,14 @@
|
||||
|
||||
const TOKEN_INJECT_SCRIPT = `
|
||||
(() => {
|
||||
const VER = "td-token-v17";
|
||||
const VER = "td-token-v18";
|
||||
if (window.__tdTokenInstalled === VER) return;
|
||||
if (window.__tdTokenObserver) { try { window.__tdTokenObserver.disconnect(); } catch {} }
|
||||
const oldBar = document.getElementById("td-token-bar");
|
||||
if (oldBar) oldBar.remove();
|
||||
const oldRow = document.getElementById("td-token-center-row");
|
||||
if (oldRow) oldRow.remove();
|
||||
["td-token-style-v4", "td-token-style-v5", "td-token-style-v6", "td-token-style-v7", "td-token-style-v8", "td-token-style-v9", "td-token-style-v10", "td-token-style-v11", "td-token-style-v12", "td-token-style-v13", "td-token-style-v14", "td-token-style-v15", "td-token-style-v16", "td-token-style-v17"].forEach((id) => {
|
||||
["td-token-style-v4", "td-token-style-v5", "td-token-style-v6", "td-token-style-v7", "td-token-style-v8", "td-token-style-v9", "td-token-style-v10", "td-token-style-v11", "td-token-style-v12", "td-token-style-v13", "td-token-style-v14", "td-token-style-v15", "td-token-style-v16", "td-token-style-v17", "td-token-style-v18"].forEach((id) => {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.remove();
|
||||
});
|
||||
@@ -78,7 +78,7 @@ const TOKEN_INJECT_SCRIPT = `
|
||||
// 2. 创建 UI
|
||||
// ============================================================================
|
||||
const BAR_ID = "td-token-bar";
|
||||
const STYLE_ID = "td-token-style-v17";
|
||||
const STYLE_ID = "td-token-style-v18";
|
||||
const TOKEN_CAP = 5000000000;
|
||||
|
||||
if (!document.getElementById(STYLE_ID)) {
|
||||
@@ -537,18 +537,57 @@ const TOKEN_INJECT_SCRIPT = `
|
||||
}, 700);
|
||||
}
|
||||
|
||||
function findToolbar() {
|
||||
const rich = document.querySelector("DIV.ProseMirror, [contenteditable], textarea");
|
||||
if (!rich) return null;
|
||||
let p = rich;
|
||||
for (let i = 0; i < 7 && p; i++) {
|
||||
const foot = p.querySelector("[class*='_footer_'], [class*='composer-footer'], footer.composer, [class*='footer'][class*='composer']");
|
||||
if (foot && foot.querySelectorAll("button, [role='button']").length >= 2) return foot;
|
||||
p = p.parentElement;
|
||||
const EDITOR_SELECTOR = "DIV.ProseMirror, [contenteditable='true'], [contenteditable=''], textarea";
|
||||
const TOOLBAR_SELECTOR = "[class*='_footer_'], [class*='composer-footer'], footer.composer, [class*='footer'][class*='composer']";
|
||||
|
||||
function isVisible(el) {
|
||||
if (!el || !el.isConnected) return false;
|
||||
const rect = el.getBoundingClientRect();
|
||||
if (!rect.width || !rect.height) return false;
|
||||
const style = window.getComputedStyle(el);
|
||||
return style.display !== "none" && style.visibility !== "hidden" && Number(style.opacity || 1) > 0;
|
||||
}
|
||||
|
||||
function toolbarForEditor(editor) {
|
||||
let parent = editor;
|
||||
for (let i = 0; i < 8 && parent && parent !== document.body && parent !== document.documentElement; i++) {
|
||||
const toolbars = Array.from(parent.querySelectorAll(TOOLBAR_SELECTOR)).filter((toolbar) => (
|
||||
isVisible(toolbar) && toolbar.querySelectorAll("button, [role='button']").length >= 2
|
||||
));
|
||||
if (toolbars.length) {
|
||||
const editorRect = editor.getBoundingClientRect();
|
||||
toolbars.sort((a, b) => {
|
||||
const aRect = a.getBoundingClientRect();
|
||||
const bRect = b.getBoundingClientRect();
|
||||
return Math.abs(aRect.top - editorRect.bottom) - Math.abs(bRect.top - editorRect.bottom);
|
||||
});
|
||||
return toolbars[0];
|
||||
}
|
||||
parent = parent.parentElement;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function toolbarScore(editor, toolbar) {
|
||||
const editorRect = editor.getBoundingClientRect();
|
||||
const toolbarRect = toolbar.getBoundingClientRect();
|
||||
const model = findModelControl(toolbar);
|
||||
// 主会话 composer 通常位于可视区更靠下的位置,并且具备模型选择控件。
|
||||
return (model ? 1000000 : 0) + Math.round(toolbarRect.bottom * 1000) + Math.round(editorRect.bottom);
|
||||
}
|
||||
|
||||
function findToolbar() {
|
||||
const candidates = [];
|
||||
for (const editor of document.querySelectorAll(EDITOR_SELECTOR)) {
|
||||
if (!isVisible(editor)) continue;
|
||||
const toolbar = toolbarForEditor(editor);
|
||||
if (toolbar) candidates.push({ editor, toolbar });
|
||||
}
|
||||
if (!candidates.length) return null;
|
||||
candidates.sort((a, b) => toolbarScore(b.editor, b.toolbar) - toolbarScore(a.editor, a.toolbar));
|
||||
return candidates[0].toolbar;
|
||||
}
|
||||
|
||||
function visibleText(el) {
|
||||
return String((el && (el.getAttribute("aria-label") || el.title || el.textContent)) || "").trim();
|
||||
}
|
||||
@@ -561,25 +600,8 @@ const TOKEN_INJECT_SCRIPT = `
|
||||
return buttons.length > 1 ? buttons[buttons.length - 2] : buttons[0] || null;
|
||||
}
|
||||
|
||||
function centerUnderEditor(bar) {
|
||||
const rich = document.querySelector("DIV.ProseMirror, [contenteditable], textarea");
|
||||
if (!rich || !rich.parentElement) return false;
|
||||
const row = document.createElement("div");
|
||||
row.id = "td-token-center-row";
|
||||
row.style.cssText = "display:flex;justify-content:center;align-items:center;width:100%;padding:2px 0 0;pointer-events:none;";
|
||||
row.appendChild(bar);
|
||||
const anchor = rich.parentElement;
|
||||
anchor.insertAdjacentElement("afterend", row);
|
||||
return true;
|
||||
}
|
||||
|
||||
function cleanupCenterRow() {
|
||||
const row = document.getElementById("td-token-center-row");
|
||||
if (row && !row.querySelector("#" + BAR_ID)) row.remove();
|
||||
}
|
||||
|
||||
function placeInToolbar(bar) {
|
||||
const toolbar = findToolbar();
|
||||
function placeInToolbar(bar, toolbar) {
|
||||
toolbar = toolbar || findToolbar();
|
||||
if (!toolbar) return false;
|
||||
const model = findModelControl(toolbar);
|
||||
if (model && model.parentElement && toolbar.contains(model.parentElement)) {
|
||||
@@ -589,44 +611,53 @@ const TOKEN_INJECT_SCRIPT = `
|
||||
} else {
|
||||
toolbar.appendChild(bar);
|
||||
}
|
||||
cleanupCenterRow();
|
||||
return true;
|
||||
}
|
||||
|
||||
function mountBar() {
|
||||
const existing = document.getElementById(BAR_ID);
|
||||
if (existing) return;
|
||||
const bar = buildBar();
|
||||
if (!placeInToolbar(bar) && !centerUnderEditor(bar)) {
|
||||
(document.body || document.documentElement).appendChild(bar);
|
||||
}
|
||||
const toolbar = findToolbar();
|
||||
if (!toolbar) return false;
|
||||
const bar = document.getElementById(BAR_ID) || buildBar();
|
||||
placeInToolbar(bar, toolbar);
|
||||
render();
|
||||
return true;
|
||||
}
|
||||
|
||||
function maybeRelocate() {
|
||||
const bar = document.getElementById(BAR_ID);
|
||||
if (!bar) return false;
|
||||
const row = document.getElementById("td-token-center-row");
|
||||
if (row && row.contains(bar)) return placeInToolbar(bar);
|
||||
if (bar.parentElement === document.body || bar.parentElement === document.documentElement) return placeInToolbar(bar);
|
||||
return false;
|
||||
const toolbar = findToolbar();
|
||||
if (!toolbar) return false;
|
||||
if (!bar) return mountBar();
|
||||
if (!toolbar.contains(bar)) return placeInToolbar(bar, toolbar);
|
||||
const model = findModelControl(toolbar);
|
||||
const expectedParent = model && model.parentElement && toolbar.contains(model.parentElement) ? model.parentElement : toolbar;
|
||||
if (bar.parentElement !== expectedParent || (model && bar.nextElementSibling !== model)) {
|
||||
return placeInToolbar(bar, toolbar);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 5. MutationObserver:页面重绘后补回悬浮条
|
||||
// ============================================================================
|
||||
function tryMount() {
|
||||
if (document.getElementById(BAR_ID)) return;
|
||||
mountBar();
|
||||
maybeRelocate();
|
||||
}
|
||||
|
||||
let mo = null;
|
||||
let relocateTimer = null;
|
||||
function scheduleRelocate() {
|
||||
if (relocateTimer) return;
|
||||
relocateTimer = setTimeout(() => {
|
||||
relocateTimer = null;
|
||||
tryMount();
|
||||
}, 40);
|
||||
}
|
||||
function startObserver() {
|
||||
if (mo) return;
|
||||
installNetworkFallback();
|
||||
mo = new MutationObserver((mutations) => {
|
||||
maybeRelocate();
|
||||
if (!document.getElementById(BAR_ID)) tryMount();
|
||||
scheduleRelocate();
|
||||
scheduleDomScan();
|
||||
});
|
||||
window.__tdTokenObserver = mo;
|
||||
|
||||
Reference in New Issue
Block a user