Compare commits

...
2 Commits
Author SHA1 Message Date
xiaoqidun 3634a6125c feat(前端界面): 优化WebUI系统字体权限请求
build.yaml / build (push) Successful in 35s
2026-07-07 15:30:18 +08:00
xiaoqidun ebfe7b5d17 feat(前端界面): OFDGo WebUI优化系统字体权限请求 2026-07-07 15:14:25 +08:00
3 changed files with 84 additions and 8 deletions
+1
View File
@@ -101,6 +101,7 @@
<button id="fontAddButton" class="small-button" type="button">添加</button>
</div>
</div>
<div id="fontPermissionHint" class="font-permission-hint" hidden>需授权读取系统字体</div>
<div id="fontList" class="font-list"></div>
</section>
</aside>
+10
View File
@@ -652,6 +652,16 @@ body[data-hide-meta] .meta-panel {
gap: 8px;
}
.font-permission-hint {
margin: 0 0 8px;
padding: 7px 8px;
border: 1px solid var(--line);
background: #ffffff;
color: var(--text-muted);
font-size: 12px;
line-height: 1.35;
}
.font-row {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
+70 -5
View File
@@ -53,6 +53,8 @@ const state = {
localFonts: [],
userFonts: [],
systemFontCatalog: [],
systemFontCatalogLoaded: false,
systemFontPermission: "prompt",
doc: null,
pageIndex: 0,
scale: 1,
@@ -108,11 +110,12 @@ const el = {
docFontList: document.querySelector("#docFontList"),
docFontSummary: document.querySelector("#docFontSummary"),
availableFontSummary: document.querySelector("#availableFontSummary"),
fontPermissionHint: document.querySelector("#fontPermissionHint"),
fontList: document.querySelector("#fontList"),
statusText: document.querySelector("#statusText"),
};
el.ofdButton.addEventListener("click", () => el.ofdInput.click());
el.ofdButton.addEventListener("click", openOFDFile);
el.togglePagesButton.addEventListener("click", () => toggleSidebar("pages"));
el.toggleMetaButton.addEventListener("click", () => toggleSidebar("meta"));
el.fontAddButton.addEventListener("click", () => el.fontInput.click());
@@ -148,11 +151,19 @@ el.viewerPanel.addEventListener("dblclick", openOFDFromViewer);
updateSidebarState();
boot();
function openOFDFromViewer() {
async function openOFDFile() {
if (document.body.hasAttribute("aria-busy")) {
return;
}
await requestLocalFontsBeforeOpen();
el.ofdInput.click();
}
async function openOFDFromViewer() {
if (state.doc || document.body.hasAttribute("aria-busy")) {
return;
}
el.ofdInput.click();
await openOFDFile();
}
function toggleSidebar(side) {
@@ -194,6 +205,7 @@ async function boot() {
renderFontList();
updateControls();
updateLocalFontButton();
await refreshLocalFontPermission();
setStatus(STATUS.ready);
setBusy(false);
} catch (err) {
@@ -394,19 +406,49 @@ async function loadLocalFonts() {
}
}
async function requestLocalFontsBeforeOpen() {
if (!canReadLocalFonts() || state.systemFontCatalogLoaded || state.systemFontPermission === "denied") {
return;
}
setBusy(true, "正在请求授权", 12, "正在请求授权");
try {
const available = await queryLocalFonts();
setStatus(available.length ? `已授权 ${available.length} 个系统字体` : "未读取到系统字体");
} catch (err) {
if (err && err.name === "NotAllowedError") {
setStatus("未授权读取系统字体");
return;
}
setStatus(String(err.message || err));
} finally {
setBusy(false);
}
}
async function queryLocalFonts() {
try {
const available = await window.queryLocalFonts();
state.systemFontCatalog = available;
state.systemFontCatalogLoaded = true;
state.systemFontPermission = "granted";
updateFontPermissionHint();
return available;
} catch (err) {
if (err && err.name === "NotAllowedError") {
state.systemFontPermission = "denied";
updateFontPermissionHint();
}
throw err;
}
}
async function autoLoadDocumentLocalFonts(openSeq) {
if (!externalDocumentFontNames().length || !canReadLocalFonts()) {
if (!externalDocumentFontNames().length || !canReadLocalFonts() || state.systemFontPermission === "denied") {
return false;
}
setProgress("正在匹配字体", 62, STATUS.fonts);
try {
const available = state.systemFontCatalog.length ? state.systemFontCatalog : await queryLocalFonts();
const available = state.systemFontCatalogLoaded ? state.systemFontCatalog : await queryLocalFonts();
if (openSeq !== state.openSeq) {
return false;
}
@@ -765,12 +807,35 @@ function updateLocalFontButton() {
const supported = canReadLocalFonts();
el.localFontButton.disabled = !supported;
el.localFontButton.title = supported ? "授权读取浏览器可访问的系统字体" : "当前浏览器不支持读取系统字体";
updateFontPermissionHint();
}
function updateFontPermissionHint() {
el.fontPermissionHint.hidden = !canReadLocalFonts() || state.systemFontPermission === "granted";
}
function canReadLocalFonts() {
return typeof window.queryLocalFonts === "function";
}
async function refreshLocalFontPermission() {
if (!canReadLocalFonts() || !navigator.permissions?.query) {
updateFontPermissionHint();
return;
}
try {
const permission = await navigator.permissions.query({ name: "local-fonts" });
state.systemFontPermission = permission.state;
permission.onchange = () => {
state.systemFontPermission = permission.state;
updateFontPermissionHint();
};
} catch {
state.systemFontPermission = "prompt";
}
updateFontPermissionHint();
}
async function openDocument(options = {}) {
if (!state.ofdBytes) {
return;