您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Import prompts into NovelAI from other editor
当前为
// ==UserScript== // @name NAI Prompt Linker // @namespace https://github.com/cpuopt/NAI-Prompt-Linker // @version 1.0.4 // @description Import prompts into NovelAI from other editor // @author cpufan // @license GPL-3.0 License // @include *://*:7860/* // @include *://*:17860/* // @match https://novelai.net/image // @icon https://www.google.com/s2/favicons?sz=64&domain=novelai.net // @grant GM_setValue // @grant GM_addValueChangeListener // @run-at document-end // @supportURL https://github.com/cpuopt/NAI-Prompt-Linker/issues // ==/UserScript== (function () { 'use strict'; if (window.location.href.startsWith("https://novelai.net/image")) { console.debug("NAI端加载成功") var opInterval = 200 var insertText = (area, text) => { area.focus() document.execCommand('selectAll'); document.execCommand('delete'); document.execCommand('insertText', false, text); area.blur() } var click_generate = () => { return new Promise(resolve => { setTimeout(() => { document.evaluate("//span[contains(text(),'Generate ') and contains(text(),' Image')]/..", document.body, null, 9, null).singleNodeValue.click(); resolve(); }, opInterval); }); } var insertPrompt = (prompt) => { return new Promise(resolve => { setTimeout(() => { document.evaluate("//button[text()='Prompt']", document.body, null, 9, null).singleNodeValue.click(); setTimeout(() => { insertText(document.querySelector("textarea[placeholder='Write your prompt here. Use tags to sculpt your outputs.']"), prompt) }, opInterval); resolve(); }, opInterval); }); } var insertUndesiredContent = (uprompt) => { return new Promise(resolve => { setTimeout(() => { document.evaluate("//button[text()='Undesired Content']", document.body, null, 9, null).singleNodeValue.click(); setTimeout(() => { insertText(document.querySelector("textarea[placeholder='Write what you want removed from the generation.']"), uprompt) }, opInterval); resolve(); }, opInterval); }); } async function generate(prompt, uprompt, generate) { await insertUndesiredContent(uprompt) await insertPrompt(prompt) if (generate == true) { await click_generate() } } let NAI_save = GM_addValueChangeListener("->NAI", function (key, oldValue, newValue, remote) { console.debug(key + ":\n" + oldValue + "=>" + newValue); if (newValue != null) { console.debug(newValue.msg, newValue.time, newValue.prompt.prompt, newValue.prompt.uprompt) generate(newValue.prompt.prompt, newValue.prompt.uprompt, newValue.generate) GM_setValue("NAI->", { time: newValue.time }) } }); } else if (/^(http)|(https):\/\/(localhost)|(127.0.0.1):(7860)|(17860)\*+/.test(window.location.href)) { var pluginCanvas var sendPrompt window.onload = function () { //菜单初始化 pluginCanvas = new Canvas() sendPrompt = new SendPrompt() } class SendPrompt { button; last_time; constructor() { this.button = document.createElement('button') this.button.className = 'plugin-button-blue' this.button.id = 'SendPromptButton' this.button.innerText = '发送Prompt到NAI' this.button.setAttribute('onclick', `window.sendPrompt2NAI()`) const canvas = document.querySelector('#plugin-canvas') canvas.appendChild(this.button) let NAI_send = GM_addValueChangeListener("NAI->", function (key, oldValue, newValue, remote) { console.debug(newValue); if (newValue.time == sendPrompt.last_time) { sendPrompt.button.className = 'plugin-button-white' sendPrompt.button.innerText = '发送成功' setTimeout(() => { sendPrompt.button.className = 'plugin-button-blue' sendPrompt.button.innerText = '发送Prompt到NAI' }, 2000) } }); } /** * 发送Prompt到NAI */ send() { let prompt = document.querySelector("#txt2img_prompt > label > textarea").value let uprompt = document.querySelector("#txt2img_neg_prompt > label > textarea").value this.last_time = Number(Date.now()) console.debug("setValue", prompt, uprompt, this.last_time) GM_setValue("->NAI", { msg: "", prompt: { prompt: prompt, uprompt: uprompt }, generate: false, time: this.last_time }) } } /** * 插件菜单类 */ class Canvas { constructor() { var styles = document.createElement('style'); document.head.appendChild(styles); styles.innerHTML = ` #plugin-canvas {transition: right 0.6s;position: fixed;background-color: #ffffff;right: 0;top: 5px;height: 75px;border-radius: 10px;border-left: solid 2px rgb(162, 218, 255)} .plugin-button-blue {display: block;color: rgb(255, 255, 255);background-color: rgb(0, 150, 250);font-size: 14px;font-weight: bold;margin: 16px;padding-left: 20px;padding-right: 20px;height: 42px;border: none;border-radius: 100000px;transition: background-color 0.6s;} .plugin-button-white {display: block;color: rgb(71,71,71);background-color: rgb(245,245,245);font-size: 14px;font-weight: bold;margin: 16px;padding-left: 20px;padding-right: 20px;height: 42px;border: none;border-radius: 100000px;transition: background-color 0.6s;} .plugin-button-blue:hover {background-color: rgb(0,114,240);cursor: pointer;} .plugin-button-white:hover {background-color: rgb(235,235,235);cursor: pointer;} .hideCanvas {padding: 0;height: 60px;width: 15px;position: absolute;left: -15px;top: 6px;border: solid 2px rgb(162, 218, 255);background-color: rgb(255, 255, 255);border-radius: 10px 0px 0px 10px;transition: background-color 0.6s;cursor: pointer;} .hideCanvas:hover{background-color: rgb(162, 218, 255);} .showCanvas {padding: 0;height: 60px;width: 15px;position: absolute;left: -15px;top: 6px;border: solid 2px rgb(162, 218, 255);background-color: rgb(255, 255, 255);border-radius: 10px 0px 0px 10px;transition: background-color 0.6s;cursor: pointer;} .showCanvas:hover{background-color: rgb(162, 218, 255);} ` let canvas = document.createElement('div') canvas.id = 'plugin-canvas' let canvasButton = document.createElement('button') canvas.appendChild(canvasButton) canvasButton.id = 'canvasButton' canvasButton.setAttribute('onclick', `window.hideCanvas()`) canvasButton.className = 'hideCanvas' canvasButton.innerHTML = '<svg style="margin-left:-2px" width="16" height="16" fill="rgb(0,150,250)" class="bi bi-caret-right-fill" viewBox="0 0 16 16"><path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/></svg>' document.body.appendChild(canvas) } /** * 显示插件菜单 */ show() { document.querySelector('#plugin-canvas').style.right = '0px' document.querySelector('#canvasButton').className = 'hideCanvas' document.querySelector('#canvasButton').innerHTML = `<svg style="margin-left:-2px" width="16" height="16" fill="rgb(0,150,250)" class="bi bi-caret-right-fill" viewBox="0 0 16 16"> <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/> </svg>` document.querySelector('#canvasButton').setAttribute('onclick', `window.hideCanvas()`) } /** * 隐藏插件菜单 */ hide() { document.querySelector('#plugin-canvas').style.right = '-171.6px' document.querySelector('#canvasButton').className = 'showCanvas' document.querySelector('#canvasButton').innerHTML = `<svg style="margin-left:-2px" width="16" height="16" fill="rgb(0,150,250)" class="bi bi-caret-left-fill" viewBox="0 0 16 16"> <path d="m3.86 8.753 5.482 4.796c.646.566 1.658.106 1.658-.753V3.204a1 1 0 0 0-1.659-.753l-5.48 4.796a1 1 0 0 0 0 1.506z"/> </svg>` document.querySelector('#canvasButton').setAttribute('onclick', `window.showCanvas()`) } } // 显示插件菜单 unsafeWindow.showCanvas = function () { pluginCanvas.show() GM_setValue('CanvasState', 'S') } // 隐藏插件菜单 unsafeWindow.hideCanvas = function () { pluginCanvas.hide() GM_setValue('CanvasState', 'H') } // 发送Prompt到NAI unsafeWindow.sendPrompt2NAI = function () { sendPrompt.send() } } })();