feat: 1.3.0 release, fix export error

This commit is contained in:
binaryify
2026-08-07 12:25:28 +08:00
parent c32890fe09
commit e37d865f70
235 changed files with 2823 additions and 2011 deletions
+99 -144
View File
@@ -1,150 +1,105 @@
<!doctype html>
<html lang="zh-CN">
<html lang="zh-CN" class="light">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="color-scheme" content="light" />
<meta
name="description"
content="一个可打开、编辑并保存本地 PPTD 项目的 neo-ppt 第三方宿主。"
/>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
<meta name="color-scheme" content="light only" />
<title>NeoDeck Local</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<div class="app-shell">
<header class="topbar">
<div class="brand" aria-label="NeoDeck Local">
<span class="brand-mark">N</span>
<span class="brand-copy">
<strong>NeoDeck</strong>
<small>LOCAL</small>
</span>
</div>
<div class="toolbar" aria-label="文件工具栏">
<button class="button button-primary" id="open-folder" type="button">
<span class="button-icon" aria-hidden="true">+</span>
打开 PPTD 文件夹
</button>
<button class="button" id="open-demo" type="button">示例</button>
<button class="icon-button" id="reload-deck" type="button" title="重新载入当前文稿" disabled>
↻
</button>
</div>
<div class="document-meta" aria-live="polite">
<div class="document-title" id="document-title">等待编辑器连接</div>
<div class="document-path" id="document-path">当前使用演示文稿</div>
</div>
<div class="topbar-actions">
<span class="status-pill status-connecting" id="connection-status">
<span class="status-dot"></span>
<span id="connection-label">连接中</span>
</span>
<span class="save-state" id="save-state">未保存到本地</span>
<button class="icon-button" id="toggle-activity" type="button" title="打开活动记录">☰</button>
</div>
</header>
<main class="editor-stage">
<iframe
id="editor"
title="neo-ppt 编辑器"
allow="fullscreen; clipboard-read; clipboard-write"
></iframe>
<section class="loading-card" id="loading-card" aria-live="polite">
<span class="loading-orbit" aria-hidden="true"></span>
<h1 id="loading-title">正在连接 neo-ppt</h1>
<p id="loading-message">编辑器就绪后会自动载入示例文稿。</p>
</section>
<aside class="activity-panel" id="activity-panel" aria-hidden="true">
<div class="activity-header">
<div>
<strong>活动记录</strong>
<small>连接、加载与保存状态</small>
</div>
<button class="icon-button" id="close-activity" type="button" aria-label="关闭活动记录">×</button>
</div>
<ol class="activity-list" id="activity-list"></ol>
<div class="activity-footer">
文件只会在你授权的项目文件夹内读写;远程编辑器不会获得任意磁盘访问权限。
</div>
</aside>
</main>
</div>
<dialog class="open-dialog" id="open-dialog" aria-labelledby="open-dialog-title">
<div class="open-dialog-shell">
<div class="open-dialog-header">
<div class="dialog-heading">
<span class="dialog-mark">P</span>
<div>
<h2 id="open-dialog-title">打开 PPTD 项目文件夹</h2>
<p>请选择或拖入包含完整项目结构的文件夹</p>
</div>
</div>
<button class="icon-button" id="close-open-dialog" type="button" aria-label="关闭打开文稿弹窗">×</button>
</div>
<button class="upload-dropzone" id="upload-dropzone" type="button">
<span class="upload-illustration" aria-hidden="true">
<span class="upload-file">P</span>
<span class="upload-arrow">↑</span>
</span>
<strong>拖动 PPTD 项目文件夹到这里</strong>
<span>仅接受一个完整文件夹,不支持单独的 .pptd 文件</span>
<em>点击上传完整文件夹(只读)</em>
</button>
<div class="open-choice-row">
<button class="open-choice open-choice-primary" id="choose-writable-folder" type="button">
<span class="choice-icon" aria-hidden="true">▣</span>
<span>
<strong>选择项目文件夹</strong>
<small>授权后支持自动保存</small>
</span>
<span aria-hidden="true">›</span>
</button>
<button class="open-choice" id="upload-folder" type="button">
<span class="choice-icon choice-icon-muted" aria-hidden="true">↑</span>
<span>
<strong>上传项目文件夹</strong>
<small>兼容模式,只读打开</small>
</span>
<span aria-hidden="true">›</span>
</button>
</div>
<div class="open-dialog-note">
<span aria-hidden="true">ⓘ</span>
<span>PPTD 项目由 .pptd 清单、pages 页面目录和 media 素材目录组成,必须上传整个文件夹。若提示含系统文件,请移除 .DS_Store。</span>
</div>
<link rel="icon" href="./neo-ppt/favicon-kimi.ico" />
<style>
/* Avoid dark FOUC before Vue theme init (official default is system → OS dark). */
html, body { background: #ffffff; color-scheme: light; }
</style>
<!-- Official neo-ppt assets (local mirror) -->
<script type="module" crossorigin src="./neo-ppt/assets/polyfills-CXLN5T9E.js"></script>
<script>
(function () {
// Official app defaults theme to "system" and may flip to dark on mount.
// Lock light mode before the Vue bundle runs.
try {
localStorage.setItem("CUSTOM_THEME", JSON.stringify("light"));
} catch (_) {}
window.INJECT_ENV = Object.assign({}, window.INJECT_ENV, { theme: "light" });
document.documentElement.classList.remove("dark");
document.documentElement.classList.add("light");
// Completely offline: block cloud APIs early
const blocked = [
/\/apiv2\//,
/www\.kimi\.com/,
/kimi\.ai/,
/slides\.kimi\./,
/gator\.volces\.com/,
/volces\.com/,
/byteimg\.com\/obj\/.*log/,
/\/list$/,
/accounts\.google\.com/,
/googleapis\.com/,
/docs\.google\.com/,
];
const nativeFetch = window.fetch.bind(window);
window.fetch = function (input, init) {
const url = typeof input === "string" ? input : input && input.url;
if (url && blocked.some((re) => re.test(String(url)))) {
return Promise.resolve(
new Response(JSON.stringify({ signature: "offline-bypass", algorithm: "Ed25519", offline: true }), {
status: 200,
headers: { "Content-Type": "application/json" },
}),
);
}
return nativeFetch(input, init);
};
const XO = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function (method, url) {
this.__ndUrl = url;
return XO.apply(this, arguments);
};
const XS = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function () {
if (this.__ndUrl && blocked.some((re) => re.test(String(this.__ndUrl)))) {
Object.defineProperty(this, "status", { value: 200 });
Object.defineProperty(this, "responseText", { value: '{"offline":true}' });
this.onload && this.onload();
return;
}
return XS.apply(this, arguments);
};
})();
</script>
<!-- Local bridge MUST load before official app (defines __NEODECK_CONNECT__) -->
<script type="module" src="./local-bridge.js"></script>
<script type="module" crossorigin src="./neo-ppt/assets/index-jtNAhQeK.js"></script>
<link rel="modulepreload" crossorigin href="./neo-ppt/assets/rolldown-runtime-DWdDZTNf.js" />
<link rel="modulepreload" crossorigin href="./neo-ppt/assets/vue-B11_pI9F.js" />
<link rel="modulepreload" crossorigin href="./neo-ppt/assets/common-utils-G6HD4Ji1.js" />
<link rel="modulepreload" crossorigin href="./neo-ppt/assets/_plugin-vue_export-helper-B67ILkmu.js" />
<link rel="modulepreload" crossorigin href="./neo-ppt/assets/preload-helper-NECkhNH4.js" />
<link rel="modulepreload" crossorigin href="./neo-ppt/assets/kimi-DRwOD7EI.js" />
<link rel="modulepreload" crossorigin href="./neo-ppt/assets/icons-CgDhqj4h.js" />
<link rel="modulepreload" crossorigin href="./neo-ppt/assets/const-BjfH-jZe.js" />
<link rel="stylesheet" crossorigin href="./neo-ppt/assets/index-Bn1xM_xZ.css" />
<link rel="stylesheet" href="./local-shell.css" />
<style id="neodeck-layout-fix">
/* editor-app height fix: avoid 100vh under local topbar */
.editor-app[data-v-ddddc63d] { height: 100% !important; width: 100% !important; }
.editor-app .editor-content[data-v-ddddc63d] { height: calc(100% - var(--topbar-height, 52px)) !important; }
.feedback-snackbar-wrap[data-v-ddddc63d] { z-index: 20000 !important; }
</style>
</head>
<body class="neodeck-local">
<header class="nd-topbar" id="nd-topbar">
<div class="nd-brand"><strong>NeoDeck</strong><small>LOCAL</small></div>
<div class="nd-actions">
<button type="button" class="nd-btn nd-btn-primary" id="nd-open">打开 PPTD 文件夹</button>
</div>
</dialog>
<dialog class="deck-dialog" id="deck-dialog">
<form method="dialog">
<div class="dialog-heading">
<span class="dialog-mark">P</span>
<div>
<h2>选择 PPTD 文稿</h2>
<p>这个文件夹里发现了多个 .pptd 清单,请选择一个。</p>
</div>
</div>
<div class="deck-options" id="deck-options"></div>
<div class="dialog-actions">
<button class="button" value="cancel">取消</button>
</div>
</form>
</dialog>
<input id="folder-fallback" type="file" webkitdirectory multiple hidden />
<div class="toast-region" id="toast-region" aria-live="polite"></div>
<script type="module" src="./app.js"></script>
<div class="nd-meta">
<span id="nd-title">未打开文稿</span>
<span id="nd-status" class="nd-status">初始化中</span>
</div>
<input type="file" id="nd-folder" webkitdirectory directory multiple hidden />
</header>
<div id="app"></div>
<div id="nd-toast" class="nd-toast" hidden></div>
</body>
</html>