您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
为 InPageEdit 的预览添加缺少的样式,以及各种快捷键
// ==UserScript== // @name IPE添加预览样式和快捷键 (on THBWiki) // @namespace https://greasyfork.org/users/551710 // @version 1.0 // @description 为 InPageEdit 的预览添加缺少的样式,以及各种快捷键 // @author Gzz // @match *://thwiki.cc/* // @icon https://static.thbwiki.cc/favicon.ico // @license MIT // @grant none // ==/UserScript== (function() { // 去掉 IPE 预览窗口的内边距 const style = document.createElement('style'); style.innerHTML = ` .in-page-edit.previewbox .ssi-modalContent { padding: 0; } .in-page-edit.previewbox .ssi-overflow::before, .in-page-edit.previewbox .ssi-overflow::after { height: 0; } `; document.head.appendChild(style); function addAccessKeys(editor) { // 给编辑区添加快捷键 Alt+, const progress = editor.querySelector('.ipe-progress'); if (!progress.style.display) { // 等待编辑器加载完毕 const observer = new MutationObserver((mutations, observer) => { if (progress.style.display !== 'none') return; setTimeout(() => { // 判断编辑器类型: CodeMirror 6, Monaco, CodeMirror 5, default let types = ['.cm-content', '.inputarea', '.CodeMirror textarea', '.editArea']; editorType = types.find(type => editor.querySelector(type)); const editArea = editor.querySelector(editorType); editArea?.setAttribute('accesskey', ','); editArea?.focus(); }, 300); observer.disconnect(); }); observer.observe(progress, { attributes: true }); } else { editor.querySelector(editorType)?.setAttribute('accesskey', ','); } // 预览: Alt+P, 差异: Alt+V const buttons = editor.querySelectorAll('#ssi-leftButtons > button'); if (buttons.length > 2) { buttons[0].title = 'Ctrl+S'; buttons[1].accessKey = 'p'; buttons[1].title = 'Alt+P'; buttons[2].accessKey = 'v'; buttons[2].title = 'Alt+V'; // 已存在差异窗口时按下按钮则关闭窗口 buttons[2].addEventListener('click', () => { if (!diff) return; setTimeout(() => { document.querySelector('.in-page-edit.quick-diff .ssi-closeIcon')?.click(); }, 0); }, { capture: true }); } // 摘要: Alt+B const summary = editor.querySelector('.editSummary'); if (summary) { summary.accessKey = 'b'; summary.title = 'Alt+B'; } // 小编辑: Alt+I const minor = editor.querySelector('.editMinor')?.closest('label'); if (minor) { minor.accessKey = 'i'; minor.title = 'Alt+I'; } // 监视: Alt+W const watch = editor.querySelector('.watchList'); const label = watch?.closest('label'); const span = label?.querySelector('span'); if (!label) return; // label 无法被 accesskey 直接激活, 加在 span 上 span.accessKey = 'w'; if (label.dataset.processed) return; label.title += ' [Alt+W]'; label.addEventListener('click', () => { label.title = 'Alt+W'; }, { once: true }); label.dataset.processed = true; } function removeAccessKeys(editor) { editor.querySelectorAll('[accesskey]').forEach(el => {el.accessKey = ''}); } // 等待编辑按钮出现, 添加快捷键 Alt+O const observerEdit = new MutationObserver((mutations, observer) => { const btn = document.getElementById('edit-btn'); if (!btn) return; btn.accessKey = 'o'; btn.title = 'Alt+O'; // 先打开再关闭一次, 解决当前版本 CodeMirror 6 加载不及时的问题 btn.click(); document.querySelector('.in-page-edit.ipe-editor .ssi-closeIcon')?.click(); document.querySelectorAll('.in-page-edit.notify').forEach(notify => notify.remove()); observer.disconnect(); }); observerEdit.observe(document.body, { childList: true }); // 监听 <body> 直接子元素变化 let numModals = 0, numEditors = 0; let editorType, diff; const observer = new MutationObserver(() => { const modals = Array.from(document.querySelectorAll('body > .in-page-edit')); const lastModal = modals.at(-1); if (modals.length === numModals) return; const editors = modals.filter(el => el.matches('.ipe-editor')); const lastEditor = editors.at(-1); numModals = modals.length; // 聚焦最上层的窗口 if (lastModal && lastModal === lastEditor) { if (editorType) lastEditor.querySelector(editorType)?.focus(); } else { const el = ['.ssi-overflow', '.ssi-modalContent'].map(type => lastModal?.querySelector(type)).find(Boolean); if (el) { // 使上下键可以滚动 el.tabIndex = '0'; el.style.outline = 'none'; el.focus(); } } if (!lastEditor) { if (numEditors) { document.querySelectorAll('[data-accesskey]').forEach(el => {el.accessKey = el.dataset.accesskey}); numEditors = 0; } return; } // 快捷键只加在最上层的编辑器里 if (editors.length > numEditors) { if (numEditors) { removeAccessKeys(editors.at(-2)); } else { // 去掉页面里已有的快捷键 document.querySelectorAll('[accesskey]').forEach(el => { el.dataset.accesskey = el.accessKey; el.accessKey = ''; }); } addAccessKeys(lastEditor); } else if (editors.length < numEditors) { addAccessKeys(lastEditor); } numEditors = editors.length; // 如果存在两个以上的预览窗口则全部关闭 const previews = document.querySelectorAll('.in-page-edit.previewbox'); if (previews.length > 1) { previews.forEach(preview => preview.querySelector('.ssi-closeIcon')?.click()); } else if (previews.length) { // 给预览内容添加 class const preview = previews[0].querySelector('.InPageEditPreview'); preview.classList.add('mw-body', 'mw-body-content', 'mw-content-ltr'); preview.style.marginLeft = 0; } diff = document.querySelector('.in-page-edit.quick-diff'); }); observer.observe(document.body, { childList: true }); })();