コピーした画像や画像のアドレスを貼り付けるだけでアップロードできるスクリプトです。
当前为
// ==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)