Greasy Fork镜像 还支持 简体中文。

Feeder - 貼り付けて画像投稿

コピーした画像や画像のアドレスを貼り付けるだけでアップロードできるスクリプトです。

目前為 2021-05-27 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Feeder - 貼り付けて画像投稿
// @namespace    http://tampermonkey.net/
// @version      1.0.0
// @license      MIT
// @description  コピーした画像や画像のアドレスを貼り付けるだけでアップロードできるスクリプトです。
// @author       You
// @match        *.x-feeder.info/*
// @exclude      *.x-feeder.info/*/sp
// @exclude      *.x-feeder.info/*/settings/*
// @icon         https://www1.x-feeder.info/favicon.ico
// @grant        GM.setValue
// @grant        GM.getValue
// @grant        GM.xmlHttpRequest
// ==/UserScript==

'use strict'
const SIZE_SAVE_KEY = 'size',
    PASTE_AREA_LABEL_TEXT = 'ここに貼り付け',
    POST_URL = 'post_picture_xhr.php'

const main = async () => {
    const scrollData = {
        old: [window.pageXOffset, window.pageYOffset],
        cur: [window.pageXOffset, window.pageYOffset]
    }
    window.addEventListener('scroll', () => {
        [scrollData.old[0], scrollData.old[1]] = scrollData.cur
        scrollData.cur[0] = window.pageXOffset
        scrollData.cur[1] = window.pageYOffset
    })

    const h = (() => {
        const e = document.createElement('div')
        e.style.padding = '1em'
        e.style.borderRadius = '5px'
        e.style.backgroundColor = '#C0C0C0'
        const parNode = document.getElementById('main_right')
        parNode.insertBefore(e, parNode.firstChild)
        return e
    })()

    const selectSize = await (async () => {
        const label = document.createElement('label')
        label.textContent = 'サイズ '
        h.appendChild(label)

        const e = document.createElement('select')
        for (const [i, v] of ['縮小しない', '84 x 84', '168 x 168(デフォルト)', '252 x 252', '336 x 336', '420 x 420'].entries()) {
            const opt = document.createElement('option')
            opt.textContent = v
            opt.value = i.toString()
            e.appendChild(opt)
        }
        e.addEventListener('change', e => void GM.setValue(SIZE_SAVE_KEY, e.target.value))
        const val = await GM.getValue(SIZE_SAVE_KEY)
        e.value = val || '2'
        label.appendChild(e)
        return e
    })()

    h.appendChild(document.createElement('hr'))

    const pasteArea = (() => {
        const label = document.createElement('div')
        label.textContent = PASTE_AREA_LABEL_TEXT
        h.appendChild(label)

        const e = document.createElement('div')
        e.contentEditable = true
        e.style.height = '3em'
        e.style.borderRadius = '5px'
        e.style.boxShadow = '0px 0px 2.5px 0px #000000 inset'
        e.style.caretColor = 'transprent'
        e.style.backgroundColor = 'gray'
        label.appendChild(e)
        return e
    })()

    const btnArea = (() => {
        const e = document.createElement('div')
        e.style.display = 'none'
        h.appendChild(e)
        e.appendChild(document.createElement('hr'))
        e.appendChild(document.createTextNode('画像を削除'))
        e.appendChild(document.createElement('br'))
        return e
    })()

    for (const e of h.getElementsByTagName('hr')) e.style.margin = '5px'

    new MutationObserver(([record]) => {
        const e = record.addedNodes[0]
        pasteArea.innerHTML = ''
        window.scrollTo(...scrollData.old)
        if (e === void 0 || (('tagName' in e) && e.tagName !== 'IMG')) return
        GM.xmlHttpRequest({
            method: 'GET',
            responseType: 'blob',
            url: e.src || e.textContent,
            onload: async res => {
                if (res.status >= 200 && res.status < 400) {
                    const fd = new FormData()
                    fd.append('frame_size', selectSize.value)
                    fd.append('picture', res.response)
                    const body = await (await fetch(POST_URL, { method: 'POST', body: fd })).text(),
                        m = body.match(/^([1-9][0-9]*),([0-9a-f]{16})$/)
                    if (m === null) {
                        console.error(body)
                        alert(body)
                        return
                    }
                    const [id, hash] = m.slice(1),
                        inputArea = document.getElementById(unsafeWindow.newActiveForm),
                        pos = inputArea.selectionStart
                    inputArea.value = `${inputArea.value.substr(0, pos)}[P:${id}]${inputArea.value.substr(pos, inputArea.value.length)}`
                    btnArea.style.display = 'block'
                    const btn = document.createElement('button')
                    btn.textContent = id
                    btnArea.appendChild(btn)
                    btn.addEventListener('click', async e => {
                        const fd = new FormData()
                        fd.append('id', id)
                        fd.append('hash', hash)
                        await fetch(POST_URL, { method: 'POST', body: fd })
                        e.target.parentNode.removeChild(e.target)
                        if (btnArea.getElementsByTagName('button').length === 0) btnArea.style.display = 'none'
                    })
                } else {
                    console.error(res)
                    alert('画像を取得できませんでした')
                }
            }
        })
    }).observe(pasteArea, { childList: true })
}

main().catch(console.error)

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址