Feeder - 貼り付けて画像投稿

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

Verze ze dne 27. 05. 2021. Zobrazit nejnovější verzi.

K instalaci tototo skriptu si budete muset nainstalovat rozšíření jako Tampermonkey, Greasemonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Userscripts.

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

K instalaci tohoto skriptu si budete muset nainstalovat manažer uživatelských skriptů.

(Už mám manažer uživatelských skriptů, nechte mě ho nainstalovat!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Už mám manažer uživatelských stylů, nechte mě ho nainstalovat!)

// ==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)