您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Write Markdown and HTML in the notes
当前为
// ==UserScript== // @name WaniKani Markdown Editor Notes (2023) // @namespace wanikani // @description Write Markdown and HTML in the notes // @version 2.0.0 // @require https://uicdn.toast.com/editor/latest/toastui-editor-all.min.js // @require https://unpkg.com/dexie@3/dist/dexie.js // @require https://greasyfork.org/scripts/430565-wanikani-item-info-injector/code/WaniKani%20Item%20Info%20Injector.user.js?version=1173815 // @icon https://www.google.com/s2/favicons?sz=64&domain=markdownguide.org // @match *://www.wanikani.com/* // @match *://preview.wanikani.com/* // @license MIT // @source https://github.com/patarapolw/wanikani-userscript/blob/master/userscripts/markdown-notes.user.js // @supportURL https://community.wanikani.com/t/userscript-markdown-editor-notes-2023/62246 // @grant none // ==/UserScript== // @ts-check /// <reference path="./types/item-info.d.ts" /> (function () { 'use strict'; const entryClazz = 'wk-markdown-notes'; // @ts-ignore const _Dexie = /** @type {typeof import('dexie').default} */ (Dexie); /** * @typedef {{ id: number; state: any; markdown: string }} EntryMarkdown */ class Database extends _Dexie { /** @type {import('dexie').Table<EntryMarkdown, number>} */ markdown; constructor() { super(entryClazz); this.version(1).stores({ markdown: 'id', }); } } const db = new Database(); /** @type {HTMLElement} */ let elEditor; /** @type {import('@toast-ui/editor').Editor} */ let editor; /** @type {WKItemInfoState} */ let state; const injector = wkItemInfo .under('meaning,reading') .spoiling('nothing') .append('Markdown Notes', (o) => { if (editor) { save(); } state = o; const onElLoaded = () => { db.markdown.get(state.id).then((entry) => { if (editor) { editor.setMarkdown(entry?.markdown || ''); setTimeout(() => { editor.blur(); }); } else { /** @type {import('@toast-ui/editor').EditorOptions} */ const opts = { el: elEditor, initialEditType: 'markdown', previewStyle: 'vertical', hideModeSwitch: true, linkAttributes: { target: '_blank', }, previewHighlight: false, customHTMLSanitizer: (s) => { return s; }, autofocus: false, initialValue: entry?.markdown, }; // @ts-ignore editor = new toastui.Editor(opts); const elSave = document.createElement('button'); elSave.type = 'button'; elSave.className = 'fa fa-save save-button'; elSave.onclick = () => { elSave.classList.add(isClickedClass); save(); setTimeout(() => { elSave.classList.remove(isClickedClass); }, 100); }; editor.insertToolbarItem( { groupIndex: -1, itemIndex: -1 }, { name: 'Save', el: elSave, }, ); editor.on('blur', () => { save(); }); } }); }; if (!elEditor) { elEditor = document.createElement('div'); elEditor.id = 'wk-markdown-editor'; elEditor.lang = 'ja'; elEditor.onkeydown = (ev) => { ev.stopImmediatePropagation(); ev.stopPropagation(); }; } onElLoaded(); return elEditor; }); window.addEventListener('willShowNextQuestion', () => { injector.renew(); }); function save() { if (editor) { db.markdown.put( { id: state.id, state, markdown: editor.getMarkdown() }, state.id, ); if (!elEditor) { editor.destroy(); } } } const isClickedClass = 'is-clicked'; add_css(/* css */ ` @import url("https://uicdn.toast.com/editor/latest/toastui-editor.min.css"); .toastui-editor-defaultUI { background-color: #fff; } .toastui-editor-defaultUI button.save-button { position: relative; background: transparent; font-size: 1em; bottom: 0.5em; } .toastui-editor-defaultUI button.save-button.${isClickedClass} { background-color: gray; } `); function add_css(css) { const style = document.createElement('style'); style.append(document.createTextNode(css)); document.head.append(style); } })();