← Back to Skills Marketplace
nicshliu

Html Ppt Editable

by NICSHLIU · GitHub ↗ · v1.1.0 · MIT-0
cross-platform ✓ Security Clean
70
Downloads
0
Stars
0
Active Installs
2
Versions
Install in OpenClaw
/install html-ppt-editable
Description
为 HTML 演示文稿添加浏览器内联编辑功能——文字修改、字体颜色调整、文字框拖拽。基于 contenteditable + localStorage 实现,零依赖。
README (SKILL.md)

触发关键词

当用户提到以下内容时使用此技能:

  • 可编辑PPT / HTML幻灯片编辑 / inline edit slides
  • html-ppt-editable / HTML可编辑
  • 明确要求在浏览器中修改 HTML 幻灯片文字

html-ppt-editable

在任意 HTML 演示文稿的基础上,追加浏览器内联编辑能力。

核心特性

  • 编辑按钮隐藏式:默认完全隐藏,鼠标移入左上角 90×90px 区域才淡入显现,移开 500ms 后自动淡出
  • 键盘快捷键:按 E 进入/退出编辑,Ctrl+S 下载保存
  • contentEditable:点击文字直接修改,修改后虚线边框提示
  • localStorage:自动保存编辑状态
  • 零依赖:纯原生 JS,无任何外部库

为什么不用 CSS ~ 选择器

.hotzone:hover ~ .toggle 会失效——鼠标从热区移向按钮时,先离开热区,按钮立刻消失,根本点不到。

正确做法:JS 500ms 延迟隐藏

let hideTimer = null;

document.addEventListener('mousemove', (e) => {
  // 热区 → 显示
  if (e.clientX \x3C 90 && e.clientY \x3C 90) {
    clearTimeout(hideTimer);
    btn.classList.add('show');
  } else {
    // 热区外 + 非按钮/非编辑区 → 延迟隐藏
    if (!isEditing && !e.target.closest('.edit-btn')) scheduleHide();
  }
});

function scheduleHide() {
  hideTimer = setTimeout(() => {
    if (!isEditing) btn.classList.remove('show');
  }, 500); // 宽限期,让用户移动到按钮
}

集成步骤

在 HTML 演示文稿的 \x3C/body> 前追加三块代码:

Step 1: HTML(在 \x3C/body> 前插入)

\x3C!-- 编辑按钮(完全隐藏,鼠标移入左上角区域显现) -->
\x3Cbutton class="edit-btn" id="editBtn" title="按 E 进入编辑模式">✏️\x3C/button>
\x3Cspan class="edit-hint">按 E 键进入编辑 · Ctrl+S 保存\x3C/span>

\x3C!-- 保存操作条 -->
\x3Cdiv class="save-banner" id="saveBanner">
  \x3Cspan>编辑模式 · 点击文字直接修改\x3C/span>
  \x3Cbutton id="saveBtn">💾 保存下载\x3C/button>
  \x3Cbutton class="secondary" id="exitBtn">退出\x3C/button>
\x3C/div>

Step 2: CSS(在 \x3Cstyle> 中追加)

/* ====== 编辑按钮 ====== */
.edit-btn {
  position: fixed;
  top: 16px; left: 16px;
  width: 44px; height: 44px;
  background: rgba(245,244,237,0.95);
  border: 1.5pt solid var(--brand, #1B365D);
  border-radius: 8px;
  color: var(--brand, #1B365D);
  font-size: 20px;
  cursor: pointer;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
  font-family: sans-serif;
  /* 隐藏式核心 */
  opacity: 0;
  pointer-events: none;
  transform: scale(0.9);
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.edit-btn.show {
  opacity: 0.88;
  pointer-events: auto;
  transform: scale(1);
}
.edit-btn.show:hover {
  opacity: 1;
  transform: scale(1.06);
}
.edit-hint {
  position: fixed;
  top: 16px; left: 70px;
  background: rgba(245,244,237,0.95);
  border: 1pt solid var(--brand, #1B365D);
  border-radius: 6px;
  padding: 6px 12px;
  font-size: 9pt;
  color: var(--brand, #1B365D);
  z-index: 9999;
  pointer-events: none;
  font-family: sans-serif;
  opacity: 0;
  transition: opacity 0.25s ease;
  white-space: nowrap;
}
.edit-btn.show:hover ~ .edit-hint {
  opacity: 1;
}

/* 编辑模式下:文字悬停虚线提示 */
body.edit-mode [contenteditable]:hover {
  outline: 1.5px dashed rgba(27,54,93,0.4);
  cursor: text;
}
[contenteditable] { outline: none; }

/* ====== 保存操作条 ====== */
.save-banner {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%) translateY(80px);
  background: rgba(245,244,237,0.97);
  border: 1.5pt solid var(--brand, #1B365D);
  border-radius: 8px;
  padding: 8px 16px;
  display: flex;
  gap: 10px;
  align-items: center;
  z-index: 9999;
  font-family: sans-serif;
  font-size: 9pt;
  color: var(--olive, #504e49);
  box-shadow: 0 4px 16px rgba(0,0,0,0.15);
  transition: transform 0.3s ease;
}
.save-banner.show { transform: translateX(-50%) translateY(0); }
.save-banner button {
  background: var(--brand, #1B365D);
  border: none;
  border-radius: 4px;
  color: white;
  padding: 5px 12px;
  font-size: 9pt;
  cursor: pointer;
  font-family: sans-serif;
}
.save-banner button.secondary {
  background: transparent;
  color: var(--brand, #1B365D);
  border: 1pt solid var(--brand, #1B365D);
}

/* 打印时隐藏 */
@media print {
  .edit-btn, .edit-hint, .save-banner { display: none !important; }
}

Step 3: JavaScript(在 \x3C/body> 前插入)

\x3Cscript>
(function() {
  var btn = document.getElementById('editBtn');
  var banner = document.getElementById('saveBanner');
  var saveBtn = document.getElementById('saveBtn');
  var exitBtn = document.getElementById('exitBtn');
  var isEditing = false;
  var hideTimer = null;

  // 可编辑元素(根据实际结构调整选择器)
  var editables = document.querySelectorAll(
    'h1, h2, h3, h4, p, li, td, th, .metric-value, .metric-label,' +
    '.lead, .callout, .footer span, .eyebrow, .subtitle, .meta,' +
    '.tl-year, .tl-head, .tl-body'
  );

  /* ---- 隐藏式按钮核心逻辑 ---- */
  function showBtn() {
    clearTimeout(hideTimer);
    btn.classList.add('show');
  }

  function scheduleHide() {
    hideTimer = setTimeout(function() {
      if (!isEditing) btn.classList.remove('show');
    }, 500);
  }

  // 鼠标移动:左上角热区显示,其他区域延迟隐藏
  document.addEventListener('mousemove', function(e) {
    if (e.clientX \x3C 90 && e.clientY \x3C 90) {
      showBtn();
    } else if (
      !isEditing &&
      !e.target.closest('.edit-btn') &&
      !e.target.closest('.save-banner')
    ) {
      scheduleHide();
    }
  });

  // 按钮悬停保持显示
  btn.addEventListener('mouseenter', function() {
    clearTimeout(hideTimer);
    showBtn();
  });
  btn.addEventListener('mouseleave', scheduleHide);

  /* ---- 编辑模式 ---- */
  function enterEdit() {
    isEditing = true;
    document.body.classList.add('edit-mode');
    btn.classList.add('show', 'active');
    btn.textContent = '✓';
    banner.classList.add('show');
    editables.forEach(function(el) {
      el.setAttribute('contenteditable', 'true');
    });
  }

  function exitEdit() {
    isEditing = false;
    document.body.classList.remove('edit-mode');
    btn.classList.remove('active');
    btn.textContent = '✏️';
    banner.classList.remove('show');
    editables.forEach(function(el) {
      el.removeAttribute('contenteditable');
    });
  }

  /* ---- 保存下载 ---- */
  function saveFile() {
    editables.forEach(function(el) { el.removeAttribute('contenteditable'); });
    document.body.classList.remove('edit-mode');
    banner.classList.remove('show');
    var html = '\x3C!DOCTYPE html>\
' + document.documentElement.outerHTML;
    editables.forEach(function(el) { el.setAttribute('contenteditable', 'true'); });
    document.body.classList.add('edit-mode');
    banner.classList.add('show');
    var blob = new Blob([html], { type: 'text/html' });
    var a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = 'edited.html';
    a.click();
    URL.revokeObjectURL(a.href);
  }

  /* ---- 事件绑定 ---- */
  btn.addEventListener('click', function() {
    isEditing ? exitEdit() : enterEdit();
  });
  exitBtn.addEventListener('click', exitEdit);
  saveBtn.addEventListener('click', saveFile);

  document.addEventListener('keydown', function(e) {
    // E 键切换编辑模式(非输入框内)
    if ((e.key === 'e' || e.key === 'E') && !e.target.getAttribute('contenteditable')) {
      isEditing ? exitEdit() : enterEdit();
    }
    // Ctrl+S 保存
    if ((e.ctrlKey || e.metaKey) && e.key === 's') {
      e.preventDefault();
      if (isEditing) saveFile();
    }
  });
})();
\x3C/script>

使用方式

  1. 在 HTML 文件的 \x3C/body> 前插入上述三段代码
  2. 浏览器打开
  3. 鼠标移到左上角 → 编辑按钮 ✏️ 淡入
  4. 按 E 或点 ✏️ → 进入编辑模式,按钮变成 ✓
  5. 点击文字直接修改(虚线边框提示)
  6. Ctrl+S 或点"💾 保存下载" → 下载 HTML 文件
  7. 按 E 或点"退出" → 退出编辑模式

局限性

  • contentEditable 不支持表格行的动态增删
  • localStorage 有 5MB 上限
  • 拖拽功能需额外实现

触发条件

  • "可编辑PPT" / "HTML幻灯片编辑" / "inline edit slides"
  • "html-ppt-editable" / "HTML可编辑"
  • 明确要求在浏览器中修改 HTML 幻灯片文字
Usage Guidance
This skill is coherent for adding inline editing to HTML slides. Before installing or pasting the snippet into important pages: (1) review the full JavaScript to ensure there are no external network calls or unexpected behavior, (2) test on a copy or non-sensitive content because the script runs in-page and uses localStorage, and (3) note a minor bug in references/draggable.js (the e.target.closest(...) === 'true' check is incorrect and may affect drag behavior) — you may want to fix or review that code. If you need automatic remote saving or cross-device sync, this skill does not provide it (it uses localStorage and client-side download by design).
Capability Analysis
Type: OpenClaw Skill Name: html-ppt-editable Version: 1.1.0 The skill bundle provides legitimate functionality for adding inline editing and drag-and-drop capabilities to HTML-based presentations. It uses standard browser APIs like contenteditable for text modification and Blob objects for saving the edited content locally. There is no evidence of data exfiltration, malicious network activity, or prompt injection; the 'hidden' UI elements are documented as a design choice for a clean presentation interface (SKILL.md).
Capability Assessment
Purpose & Capability
The name/description (inline editing for HTML slides) matches the provided artifacts: SKILL.md describes inserting HTML/CSS/JS into a page, the code is client-side JavaScript, and no cloud credentials or system binaries are requested.
Instruction Scope
SKILL.md instructs embedding JS/CSS/HTML into the target page and using contentEditable + localStorage and a save/download feature — all expected for this purpose. The instructions do not reference external network endpoints or request system secrets. The JS is truncated in the listing but surrounding context indicates localStorage and client-side download are used. Be aware that any script you insert runs in-page and can access DOM and localStorage (expected for this feature), so inspect it before use.
Install Mechanism
No install spec or external packages — instruction-only with a small referenced JS file. This is the lowest-risk install profile and appropriate for a zero-dependency browser snippet.
Credentials
The skill requests no environment variables, no credentials, and no config paths — proportional to its stated client-side editing purpose.
Persistence & Privilege
always is false and the skill is user-invocable; it does not request persistent platform privileges. Autonomous invocation is allowed by default but is not combined with other red flags here.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install html-ppt-editable
  3. After installation, invoke the skill by name or use /html-ppt-editable
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v1.1.0
编辑按钮改为隐藏式,鼠标触碰左上角区域才显现;更新SKILL.md文档;修复CSS hover ~选择器失效问题
v1.0.0
Initial release: inline editing for HTML presentations
Metadata
Slug html-ppt-editable
Version 1.1.0
License MIT-0
All-time Installs 0
Active Installs 0
Total Versions 2
Frequently Asked Questions

What is Html Ppt Editable?

为 HTML 演示文稿添加浏览器内联编辑功能——文字修改、字体颜色调整、文字框拖拽。基于 contenteditable + localStorage 实现,零依赖。 It is an AI Agent Skill for Claude Code / OpenClaw, with 70 downloads so far.

How do I install Html Ppt Editable?

Run "/install html-ppt-editable" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is Html Ppt Editable free?

Yes, Html Ppt Editable is completely free, licensed under MIT-0. You can download, install and use it at no cost.

Which platforms does Html Ppt Editable support?

Html Ppt Editable is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created Html Ppt Editable?

It is built and maintained by NICSHLIU (@nicshliu); the current version is v1.1.0.

💬 Comments