Greasy Fork

Greasy Fork is available in English.

GoodNote - VSCode 网页笔记助手

在任何网页添加VSCode编辑器功能 ctrl + shift + l

当前为 2025-02-14 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         GoodNote - VSCode 网页笔记助手
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  在任何网页添加VSCode编辑器功能 ctrl + shift + l
// @author       kasusa
// @license MIT
// @match        *://*/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=greasyfork.org
// @grant        GM_setValue
// @grant        GM_getValue
// @requirt      file:///
// ==/UserScript==

(function() {
    'use strict';

    // 创建模糊背景遮罩
    const blurOverlay = document.createElement('div');
    blurOverlay.style.position = 'fixed';
    blurOverlay.style.top = '0';
    blurOverlay.style.left = '0';
    blurOverlay.style.width = '100%';
    blurOverlay.style.height = '100%';
    blurOverlay.style.backgroundColor = 'rgba(0, 0, 0, 0.4)';
    blurOverlay.style.backdropFilter = 'blur(5px)';
    blurOverlay.style.WebkitBackdropFilter = 'blur(5px)'; // Safari 支持
    blurOverlay.style.zIndex = '9998'; // 确保在编辑器下面
    blurOverlay.style.display = 'none';
    blurOverlay.style.transition = 'opacity 0.2s ease';
    blurOverlay.style.opacity = '0';
    document.body.appendChild(blurOverlay);

    const editorContainer = document.createElement('div');
    editorContainer.style.position = 'fixed';
    editorContainer.style.bottom = '-100%'; // 初始位置在屏幕下方
    editorContainer.style.left = '15%';
    editorContainer.style.width = '70%';
    editorContainer.style.height = '80%';
    editorContainer.style.zIndex = '9999';
    editorContainer.style.backgroundColor = '#1e1e1e';
    editorContainer.style.border = '2.5px solid rgb(0, 237, 229)';
    editorContainer.style.borderRadius = '10px';
    editorContainer.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.43)';
    editorContainer.style.display = 'none';
    editorContainer.style.padding = '15px';
    editorContainer.style.transition = 'bottom 0.2s ease'; // 添加过渡效果

    // 创建语言选择下拉菜单
    const languageSelect = document.createElement('select');
    languageSelect.style.position = 'absolute';
    languageSelect.style.top = '10px';
    languageSelect.style.right = '10px';
    languageSelect.style.padding = '5px';
    languageSelect.style.backgroundColor = '#2d2d2d';
    languageSelect.style.color = '#fff';
    languageSelect.style.border = '1px solid #454545';
    languageSelect.style.borderRadius = '4px';
    languageSelect.style.zIndex = '10001';

    // 添加常用语言选项
    const languages = [
        { id: 'javascript', name: 'JavaScript' },
        { id: 'typescript', name: 'TypeScript' },
        { id: 'html', name: 'HTML' },
        { id: 'css', name: 'CSS' },
        { id: 'python', name: 'Python' },
        { id: 'java', name: 'Java' },
        { id: 'cpp', name: 'C++' },
        { id: 'csharp', name: 'C#' },
        { id: 'php', name: 'PHP' },
        { id: 'sql', name: 'SQL' },
        { id: 'markdown', name: 'Markdown' },
        { id: 'json', name: 'JSON' },
        { id: 'plaintext', name: '纯文本' }
    ];

    languages.forEach(lang => {
        const option = document.createElement('option');
        option.value = lang.id;
        option.textContent = lang.name;
        languageSelect.appendChild(option);
    });

    editorContainer.appendChild(languageSelect);
    document.body.appendChild(editorContainer);

    // 添加代码图标
    const codeIcon = document.createElement('div');
    codeIcon.style.position = 'fixed';
    codeIcon.style.bottom = '10px';
    codeIcon.style.right = '10px';
    codeIcon.style.width = '50px';
    codeIcon.style.height = '50px';
    codeIcon.style.backgroundImage = 'url(http://139.196.171.60:88/images/code/code.png)';
    codeIcon.style.backgroundSize = 'cover';
    codeIcon.style.cursor = 'pointer';
    codeIcon.style.zIndex = '10000';
    codeIcon.addEventListener('click', toggleEditor);
    document.body.appendChild(codeIcon);

    // 创建VSCode编辑器实例
    let editor;
    function initializeEditor() {
        require(['vs/editor/editor.main'], function() {
            editor = monaco.editor.create(editorContainer, {
                value: '',
                language: languageSelect.value,
                theme: 'vs-dark',
                automaticLayout: true
            });

            // 监听语言选择变化
            languageSelect.addEventListener('change', () => {
                monaco.editor.setModelLanguage(editor.getModel(), languageSelect.value);
                // 保存当前选择的语言
                GM_setValue('vscode_language', languageSelect.value);
            });

            // 加载保存的笔记和语言设置
            const savedNote = GM_getValue('vscode_note', '');
            const savedLanguage = GM_getValue('vscode_language', 'javascript');
            languageSelect.value = savedLanguage;
            editor.setValue(savedNote);
            monaco.editor.setModelLanguage(editor.getModel(), savedLanguage);

            // 屏蔽其他快捷键
            editorContainer.addEventListener('keydown', (e) => {
                e.stopPropagation();
            });

            // 自动保存功能
            editor.onDidChangeModelContent(() => {
                const content = editor.getValue();
                GM_setValue('vscode_note', content);
            });
        });
        
    }


    // 切换编辑器显示
    function toggleEditor() {
        if (editorContainer.style.display === 'none') {
            // 显示模糊背景
            blurOverlay.style.display = 'block';
            setTimeout(() => {
                blurOverlay.style.opacity = '1';
            }, 0);
            
            editorContainer.style.display = 'block';
            setTimeout(() => {
                editorContainer.style.bottom = '10%'; // 显示时移动到可见位置
            }, 0);
            if (!editor) {
                initializeEditor();
            }
        } else {
            editorContainer.style.bottom = '-100%'; // 隐藏时移动到屏幕下方
            // 隐藏模糊背景
            blurOverlay.style.opacity = '0';
            setTimeout(() => {
                editorContainer.style.display = 'none';
                blurOverlay.style.display = 'none';
            }, 500); // 等待动画结束后隐藏
        }
    }

    // 添加快捷键监听
    document.addEventListener('keydown', (e) => {
        const isMac = /Mac|iPod|iPhone|iPad/.test(navigator.platform);
        if ((isMac && e.metaKey || !isMac && e.ctrlKey) && e.shiftKey && e.key.toLowerCase() === 'l') {
            e.preventDefault();
            toggleEditor();
        }
    });

    // 添加点击外部隐藏功能
    document.addEventListener('click', (e) => {
        if (editorContainer.style.display === 'block' && !editorContainer.contains(e.target) && !codeIcon.contains(e.target)) {
            editorContainer.style.bottom = '-100%'; // 隐藏时移动到屏幕下方
            // 隐藏模糊背景
            blurOverlay.style.opacity = '0';
            setTimeout(() => {
                editorContainer.style.display = 'none';
                blurOverlay.style.display = 'none';
            }, 500); // 等待动画结束后隐藏
        }
    });

    // 加载Monaco Editor
    const script = document.createElement('script');
    script.src = 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.33.0/min/vs/loader.js';
    script.onload = function() {
        require.config({ paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.33.0/min/vs' }});
    };
    document.body.appendChild(script);
})();