// ==UserScript== // @name B-Note-Uni (哔记通用版) // @namespace http://tampermonkey.net/ // @version 0.4 // @description 哔记(B-Note)的"Universal version"(通用版本),可在多个页面实现文本快速插入、图片插入、本地导入导出、快捷键、markdown写作、分屏模式。 // @author XYZ // @match *://*/* // @exclude *://*.bilibili.com/* // @exclude *://github.com/* // @grant none // @require https://code.jquery.com/jquery-3.6.0.min.js // @require https://code.jquery.com/ui/1.12.1/jquery-ui.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.5.0/jszip.min.js // @require https://unpkg.com/axios@1.1.2/dist/axios.min.js // @license MIT License // @icon data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIxLjUiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBhcmlhLWhpZGRlbj0idHJ1ZSI+CiAgPHBhdGggc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNC4yNiAxMC4xNDdhNjAuNDM2IDYwLjQzNiAwIDAwLS40OTEgNi4zNDdBNDguNjI3IDQ4LjYyNyAwIDAxMTIgMjAuOTA0YTQ4LjYyNyA0OC42MjcgMCAwMTguMjMyLTQuNDEgNjAuNDYgNjAuNDYgMCAwMC0uNDkxLTYuMzQ3bS0xNS40ODIgMGE1MC41NyA1MC41NyAwIDAwLTIuNjU4LS44MTNBNTkuOTA1IDU5LjkwNSAwIDAxMTIgMy40OTNhNTkuOTAyIDU5LjkwMiAwIDAxMTAuMzk5IDUuODRjLS44OTYuMjQ4LTEuNzgzLjUyLTIuNjU4LjgxNG0tMTUuNDgyIDBBNTAuNjk3IDUwLjY5NyAwIDAxMTIgMTMuNDg5YTUwLjcwMiA1MC43MDIgMCAwMTcuNzQtMy4zNDJNNi43NSAxNWEuNzUuNzUgMCAxMDAtMS41Ljc1Ljc1IDAgMDAwIDEuNXptMCAwdi0zLjY3NUE1NS4zNzggNTUuMzc4IDAgMDExMiA4LjQ0M20tNy4wMDcgMTEuNTVBNS45ODEgNS45ODEgMCAwMDYuNzUgMTUuNzV2LTEuNSI+PC9wYXRoPgo8L3N2Zz4= // @downloadURL https://update.greasyfork.icu/scripts/477045/B-Note-Uni%20%28%E5%93%94%E8%AE%B0%E9%80%9A%E7%94%A8%E7%89%88%29.user.js // @updateURL https://update.greasyfork.icu/scripts/477045/B-Note-Uni%20%28%E5%93%94%E8%AE%B0%E9%80%9A%E7%94%A8%E7%89%88%29.meta.js // ==/UserScript== (function () { 'use strict'; // 填写你的github的token以及repo(仓库名) let token = ''; let repo = ''; // Add the TOAST UI Editor CSS $('head').append(''); // Add the TOAST UI Editor JS const scriptEditor = document.createElement('script'); scriptEditor.src = 'https://uicdn.toast.com/editor/latest/toastui-editor-all.min.js'; document.body.appendChild(scriptEditor); // Add the JQuery UI $('head').append(''); // Create a switch using SVG. function createSVGIcon(svgContent) { const svgIcon = $(svgContent); svgIcon.css({ width: '24px', height: '24px', verticalAlign: 'middle', marginRight: '5px' }); return svgIcon; } const openEditorIcon = ''; const closeEditorIcon = ''; // Create the button const openEditorButton = $(''); openEditorButton.append(createSVGIcon(openEditorIcon)); $('body').append(openEditorButton); const toggleButton = $(''); const toggleButtonText = $('打开B-Note'); toggleButton.append(createSVGIcon(openEditorIcon)).append(toggleButtonText); $('body').append(toggleButton); const buttonStyles = ` .B-Note-button { position: fixed; bottom: 10px; right: -80px; width: 120px; height: 32px; z-index: 10000; background-color: rgba(255, 255, 255, 0.2); color: black; border: none; border-radius: 4px; padding: 2px 0px; font-size: 13px; cursor: pointer; transition: right 0.3s, background-color 0.3s; } .B-Note-button:hover { background-color: rgba(255, 255, 255, 0.9); right: 0px; } `; const styleElement = $(''); styleElement.text(buttonStyles); $('head').append(styleElement); let saveButton; let helpButton; let editor; let editorDiv; let isEditorOpen = false; let isSplitScreen = false; let originalContainerStyle; // Get the current date, title, and current webpage link. function getPageInfo() { let currentDate = new Date(); let formattedDate = `${currentDate.getFullYear()}年${currentDate.getMonth() + 1}月${currentDate.getDate()}日`; let pageTitle = document.title; let pageLink = window.location.href; return { formattedDate, pageTitle, pageLink }; } let pageInfo = getPageInfo(); // Use IndexedDB to automatically back up notes. const dbName = 'BNoteDB'; const storeName = 'notes'; let db; const openRequest = indexedDB.open(dbName, 1); openRequest.onupgradeneeded = function (e) { const db = e.target.result; if (!db.objectStoreNames.contains(storeName)) { db.createObjectStore(storeName, { keyPath: 'pageTitle' }); } }; openRequest.onsuccess = function (e) { db = e.target.result; }; function saveNoteToDB() { if (isEditorOpen) { let { formattedDate, pageTitle, pageLink } = getPageInfo(); const content = editor.getMarkdown(); const timestamp = Date.now(); const note = { pageTitle, content, timestamp }; const transaction = db.transaction(storeName, 'readwrite'); const store = transaction.objectStore(storeName); store.put(note); } } setInterval(saveNoteToDB, 120000); // Upload to Github async function handleImageInsertion() { const content = editor.getMarkdown(); const regex = /!\[.*?\]\(data:image\/.*?;base64,.*?\)/g; const matches = content.match(regex); if (matches) { for (const match of matches) { const base64 = match.substring(match.indexOf('base64,') + 7, match.lastIndexOf(')')); const blob = base64ToBlob(base64); const imageUrl = await uploadImageToGitHub(blob); const newContent = content.replace(match, ``); editor.setMarkdown(newContent); } } } function base64ToBlob(base64) { const binary = atob(base64); const array = new Uint8Array(binary.length); for (let i = 0; i < binary.length; i++) { array[i] = binary.charCodeAt(i); } return new Blob([array], { type: 'image/png' }); } async function uploadImageToGitHub(blob) { const branch = 'main'; const currentDate = new Date(); currentDate.setMinutes(currentDate.getMinutes() + currentDate.getTimezoneOffset() + 8 * 60); const year = currentDate.getFullYear(); const month = currentDate.getMonth() + 1; const day = currentDate.getDate(); const hours = currentDate.getHours(); const minutes = currentDate.getMinutes(); const seconds = currentDate.getSeconds(); const time = `${hours}-${minutes}-${seconds}`; const pageInfo = getPageInfo(); const invalidChars = /[<>:"/\\|?*]/g; const cleanedPageTitle = pageInfo.pageTitle.replace(invalidChars, ''); const path = `images/B-Note/${year}/${month}/${day}/${cleanedPageTitle}/${time}.png`; const url = `https://api.github.com/repos/${repo}/contents/${path}`; const base64 = await blobToBase64(blob); const payload = { message: 'Upload image', content: base64, branch: branch, }; const response = await axios.put(url, payload, { headers: { 'Authorization': `token ${token}`, 'Content-Type': 'application/json', }, }); return response.data.content.download_url; } function blobToBase64(blob) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result.split(',')[1]); reader.onerror = reject; reader.readAsDataURL(blob); }); } const container = $('
'); // Function to create the editor function createEditor() { container.css({ position: 'fixed', top: '8%', right: '0%', width: '32%', height: '86%', zIndex: 99999, backgroundColor: '#fff', border: '1px solid #ccc', borderRadius: '5px', padding: '0px', overflow: 'hidden', }); $('body').append(container); // Make the container resizable container.resizable({ handles: 'n, e, s, w, ne, se, sw, nw', minWidth: 300, minHeight: 200, resize: function (event, ui) { const newHeight = ui.size.height - 80; editorDiv.height(newHeight + 'px'); } }); const handle = $('