TOOLS为非官方社区,欢迎一起建设,答疑群:717421103
全站通知:
油猴工具/图片粘贴上传BWIKI
刷
历
编
阅读
2026-04-27更新
最新编辑:WIKI不易猫猫叹气
阅读:
更新日期:2026-04-27
最新编辑:WIKI不易猫猫叹气
< 油猴工具
跳到导航
跳到搜索
油猴工具/图片粘贴上传BWIKI
小工具稳定
自动上传你在bwiki原生编辑器里粘贴的图片,并直接插入[[File:文件名]]代码。
- 支持:PNG、JPEG、GIF和WebP
- 有单文件最大限制(可配置)
- 获取API令牌并生成时间戳文件名
// ==UserScript==
// @name MediaWiki图片粘贴上传工具
// @namespace http://tampermonkey.net/
// @version 1.0.2
// @description 自动上传粘贴到MediaWiki编辑器的图片
// @author You
// @match *://wiki.biligame.com/*
// @match *://*.biligame.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 轮询检查mw变量是否存在
const timer = setInterval(() => {
if (window.mw && typeof window.mw === 'object') {
clearInterval(timer);
console.log('✅ MediaWiki已加载,开始初始化图片上传脚本');
initImageUploader();
}
}, 300);
// 配置
const CONFIG = {
SUPPORTED_TYPES: ['image/png', 'image/jpeg', 'image/gif', 'image/webp'],
MAX_SIZE: 10 * 1024 * 1024, // 10MB
NAMING_PREFIX: 'Paste_'
};
// 工具函数
const Utils = {
// 获取编辑器元素
getEditorElement() {
// 优先查找CodeMirror编辑器
const codeMirrorEditable = document.querySelector('.CodeMirror-code[contenteditable="true"]');
if (codeMirrorEditable) return codeMirrorEditable;
// 查找标准textarea
const textarea = document.querySelector('#wpTextbox1');
if (textarea) return textarea;
// 查找其他可能的编辑器
const codeMirror = document.querySelector('.CodeMirror-code');
if (codeMirror) return codeMirror;
return null;
},
// 获取API URL
getApiUrl() {
const server = mw.config.get('wgServer');
const scriptPath = mw.config.get('wgScriptPath');
return server + scriptPath + '/api.php';
},
// 生成文件名
generateFileName(originalName) {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const extension = originalName.split('.').pop() || 'png';
return `${CONFIG.NAMING_PREFIX}${timestamp}.${extension}`;
},
// 检查文件类型
isValidImageType(type) {
return CONFIG.SUPPORTED_TYPES.includes(type);
},
// 检查文件大小
isValidSize(size) {
return size <= CONFIG.MAX_SIZE;
}
};
// 图片上传器
const ImageUploader = {
// 获取CSRF令牌
async getCsrfToken() {
const response = await fetch(Utils.getApiUrl(), {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
action: 'query',
meta: 'tokens',
type: 'csrf',
format: 'json'
})
});
const data = await response.json();
return data.query.tokens.csrftoken;
},
// 上传图片
async uploadImage(file) {
const token = await this.getCsrfToken();
const fileName = Utils.generateFileName(file.name);
const formData = new FormData();
formData.append('action', 'upload');
formData.append('filename', fileName);
formData.append('file', file);
formData.append('token', token);
formData.append('format', 'json');
formData.append('ignorewarnings', '1');
const response = await fetch(Utils.getApiUrl(), {
method: 'POST',
body: formData
});
const data = await response.json();
if (data.upload && data.upload.result === 'Success') {
return {
success: true,
filename: data.upload.filename,
url: data.upload.imageinfo.url
};
} else {
const errorMsg = data.error ? data.error.info : '未知错误';
throw new Error('上传失败: ' + errorMsg);
}
}
};
// 粘贴处理器
const PasteHandler = {
// 处理粘贴事件
async handlePaste(event) {
const clipboardData = event.clipboardData;
if (!clipboardData) return;
const items = Array.from(clipboardData.items);
for (const item of items) {
if (item.kind === 'file' && item.type.startsWith('image/')) {
const file = item.getAsFile();
if (!file) continue;
// 验证文件
if (!Utils.isValidImageType(file.type) || !Utils.isValidSize(file.size)) {
continue;
}
// 阻止默认粘贴行为
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
try {
const result = await ImageUploader.uploadImage(file);
if (result.success) {
this.insertImageCode(result.filename);
}
} catch (error) {
console.error('图片上传失败:', error);
alert('图片上传失败: ' + error.message);
}
}
}
},
// 插入图片代码
insertImageCode(filename) {
const editor = Utils.getEditorElement();
if (!editor) return;
const imageCode = `[[File:${filename}]]`;
if (editor.tagName === 'TEXTAREA') {
// 标准textarea
const start = editor.selectionStart;
const end = editor.selectionEnd;
const text = editor.value;
editor.value = text.substring(0, start) + imageCode + text.substring(end);
editor.selectionStart = editor.selectionEnd = start + imageCode.length;
} else {
// CodeMirror或其他编辑器
const selection = window.getSelection();
if (selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
range.deleteContents();
range.insertNode(document.createTextNode(imageCode));
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
}
}
// 触发input事件
editor.dispatchEvent(new Event('input', { bubbles: true }));
},
// 初始化
init() {
const editor = Utils.getEditorElement();
if (!editor) return;
// 绑定粘贴事件(使用capture模式)
const boundHandler = this.handlePaste.bind(this);
editor.removeEventListener('paste', boundHandler);
editor.addEventListener('paste', boundHandler, true);
// 同时在document上监听作为备用
document.removeEventListener('paste', boundHandler);
document.addEventListener('paste', boundHandler, true);
}
};
// 初始化图片上传器
function initImageUploader() {
console.log('开始初始化图片上传器...');
PasteHandler.init();
console.log('✅ 图片上传器初始化完成');
}
})();

沪公网安备 31011002002714 号