卡厄思
梦
境
菜单
首页
回到首页
WIKI工具
全站样式
全站JS
修改导航栏
测试
沙盒
可视化管理器
战斗员管理器
卡牌管理器
伙伴管理器
装备管理器
词典管理器
图鉴
战斗员
伙伴
装备
怪物卡牌
中立卡牌
词典
小工具
配队模拟器
节奏榜生成器
搜索
链入页面
相关更改
特殊页面
页面信息
最近更改
登录
MediaWiki
查看“︁Gadget-CopyTextTool.js”︁的源代码
←
MediaWiki:Gadget-CopyTextTool.js
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
此页面为本wiki上的软件提供界面文本,并受到保护以防止滥用。 如欲修改所有wiki的翻译,请访问
translatewiki.net
上的MediaWiki本地化项目。
您无权编辑此JavaScript页面,因为编辑此页面可能会影响所有访问者。
您可以查看和复制此页面的源代码。
/** * 文本复制工具 - 修复版 * 支持 MediaWiki 各种编辑器 */ (function($, mw) { 'use strict'; // ===== 自定义配置 ===== var config = { '蓝色': { template: '{{文本|蓝|{text}}}', fallback: '{{文本|蓝|' }, '绿色': { template: '{{文本|绿|{text}}}', fallback: '{{文本|绿|' }, '蓝色下划线': { template: '{{文本|蓝|下划线|{text}}}', fallback: '{{文本|蓝|下划线|' }, '绿色描边': { template: '{{描边|绿|{text}}}', fallback: '{{描边|绿|' }, '词典': { template: '{{词典|{text}}}', fallback: '{{词典|' }, '红色': { template: '{{文本|红|{text}}}', fallback: '{{文本|红|' } }; var defaultPosition = { top: '100px', right: '20px' }; // ==================== var toolPanel = null; var floatButton = null; var isVisible = false; var isMinimized = false; var currentMode = 'auto'; $(function() { var savedState = localStorage.getItem('copyTextTool_visible'); isVisible = savedState === 'true'; createFloatButton(); createToolPanel(); if (isVisible) { showTool(); } }); function createFloatButton() { floatButton = $('<div>') .attr('id', 'copy-tool-fab') .attr('title', '文本复制工具') .html('📋') .css({ position: 'fixed', bottom: '30px', right: '30px', width: '56px', height: '56px', borderRadius: '50%', background: 'linear-gradient(135deg, #2196F3 0%, #1976D2 100%)', color: 'white', fontSize: '24px', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', boxShadow: '0 4px 12px rgba(33, 150, 243, 0.4)', zIndex: 9998, transition: 'all 0.3s ease', userSelect: 'none' }) .on('click', toggleTool) .hover( function() { $(this).css({ transform: 'scale(1.1)', boxShadow: '0 6px 16px rgba(33, 150, 243, 0.6)' }); }, function() { $(this).css({ transform: 'scale(1)', boxShadow: '0 4px 12px rgba(33, 150, 243, 0.4)' }); } ) .appendTo('body'); } function createToolPanel() { var savedPos = localStorage.getItem('copyTextTool_position'); var position = savedPos ? JSON.parse(savedPos) : defaultPosition; toolPanel = $('<div>') .attr('id', 'copy-text-tool') .css({ position: 'fixed', top: position.top, right: position.right, left: position.left || 'auto', width: '340px', background: 'white', border: '2px solid #2196F3', borderRadius: '12px', boxShadow: '0 8px 24px rgba(0,0,0,0.15)', zIndex: 9999, display: 'none', fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif' }); var header = $('<div>') .attr('id', 'tool-header') .css({ background: 'linear-gradient(135deg, #2196F3 0%, #1976D2 100%)', color: 'white', padding: '12px 15px', borderRadius: '10px 10px 0 0', cursor: 'move', display: 'flex', justifyContent: 'space-between', alignItems: 'center', userSelect: 'none' }) .appendTo(toolPanel); $('<div>') .css({ fontWeight: 'bold', fontSize: '15px', display: 'flex', alignItems: 'center', gap: '8px' }) .html('<span style="font-size: 18px">📋</span> 文本工具') .appendTo(header); var controls = $('<div>') .css({ display: 'flex', gap: '8px' }) .appendTo(header); $('<button>') .attr('title', '最小化') .html('−') .css({ background: 'rgba(255,255,255,0.2)', border: 'none', color: 'white', width: '24px', height: '24px', borderRadius: '4px', cursor: 'pointer', fontSize: '16px' }) .on('click', minimizeTool) .hover( function() { $(this).css('background', 'rgba(255,255,255,0.3)'); }, function() { $(this).css('background', 'rgba(255,255,255,0.2)'); } ) .appendTo(controls); $('<button>') .attr('title', '关闭') .html('×') .css({ background: 'rgba(255,255,255,0.2)', border: 'none', color: 'white', width: '24px', height: '24px', borderRadius: '4px', cursor: 'pointer', fontSize: '20px' }) .on('click', hideTool) .hover( function() { $(this).css('background', 'rgba(255,255,255,0.3)'); }, function() { $(this).css('background', 'rgba(255,255,255,0.2)'); } ) .appendTo(controls); var body = $('<div>') .attr('id', 'tool-body') .css({ padding: '15px' }) .appendTo(toolPanel); // 模式选择 var modeSelector = $('<div>') .css({ display: 'flex', gap: '8px', marginBottom: '12px', padding: '8px', background: '#f5f5f5', borderRadius: '6px' }) .appendTo(body); $('<div>') .text('模式:') .css({ fontSize: '13px', color: '#666', lineHeight: '28px', fontWeight: '500' }) .appendTo(modeSelector); var modes = [ { id: 'auto', name: '智能', title: '自动检测' }, { id: 'insert', name: '插入', title: '插入到编辑器' }, { id: 'copy', name: '复制', title: '复制到剪贴板' } ]; var modeButtons = $('<div>') .css({ display: 'flex', gap: '4px', flex: '1' }) .appendTo(modeSelector); modes.forEach(function(mode) { $('<button>') .attr({ 'data-mode': mode.id, 'title': mode.title }) .text(mode.name) .css({ flex: '1', padding: '6px 8px', background: mode.id === 'auto' ? '#2196F3' : 'white', color: mode.id === 'auto' ? 'white' : '#666', border: '1px solid #ddd', borderRadius: '4px', cursor: 'pointer', fontSize: '12px', transition: 'all 0.2s' }) .on('click', function() { currentMode = mode.id; modeButtons.find('button').css({ background: 'white', color: '#666' }); $(this).css({ background: '#2196F3', color: 'white' }); updateStatus('✓ 切换到' + mode.name + '模式', true); }) .appendTo(modeButtons); }); // 按钮容器 var buttonContainer = $('<div>') .css({ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '8px', marginBottom: '10px' }) .appendTo(body); $.each(config, function(name, conf) { $('<button>') .text(name) .css({ padding: '12px 8px', background: '#2196F3', color: 'white', border: 'none', borderRadius: '6px', cursor: 'pointer', fontSize: '13px', fontWeight: '500', transition: 'all 0.2s ease' }) .on('click', function() { handleButtonClick(name, conf); }) .hover( function() { $(this).css({ background: '#1976D2', transform: 'translateY(-1px)', boxShadow: '0 2px 8px rgba(33, 150, 243, 0.3)' }); }, function() { $(this).css({ background: '#2196F3', transform: 'translateY(0)', boxShadow: 'none' }); } ) .appendTo(buttonContainer); }); $('<div>') .attr('id', 'copy-status') .css({ textAlign: 'center', color: '#666', padding: '10px', fontSize: '12px', minHeight: '20px', background: '#f9f9f9', borderRadius: '6px' }) .html('💡 先选中文字,再点击按钮') .appendTo(body); toolPanel.appendTo('body'); makeDraggable(toolPanel[0], header[0]); } // ===== 核心功能:处理按钮点击 ===== function handleButtonClick(name, conf) { console.log('[文本工具] 按钮点击:', name); // 获取选中文字 var selectedText = getSelectedText(); console.log('[文本工具] 选中文字:', selectedText); // 决定使用什么文本 var finalText = selectedText ? conf.template.replace('{text}', selectedText) : conf.fallback; console.log('[文本工具] 最终文本:', finalText); // 根据模式决定操作 if (currentMode === 'copy') { // 强制复制模式 copyToClipboard(finalText); updateStatus('✓ 已复制: ' + name, true); return; } // 尝试插入 var editor = findEditor(); console.log('[文本工具] 找到的编辑器:', editor); if (editor && currentMode !== 'copy') { // 找到编辑器,执行插入 var success = insertToEditor(editor, finalText, selectedText ? true : false); if (success) { updateStatus('✓ 已插入: ' + name, true); } else { // 插入失败,回退到复制 copyToClipboard(finalText); updateStatus('⚠ 插入失败,已复制', false); } } else { // 未找到编辑器或处于复制模式 copyToClipboard(finalText); updateStatus('✓ 已复制: ' + name, true); } } // ===== 查找编辑器 ===== function findEditor() { // 1. 检查 wpTextbox1 (MediaWiki 标准编辑器) var wpTextbox = document.getElementById('wpTextbox1'); if (wpTextbox) { console.log('[文本工具] 找到 wpTextbox1'); return { type: 'textarea', element: wpTextbox }; } // 2. 检查 CodeMirror if (typeof $ !== 'undefined' && $('.CodeMirror').length > 0) { var cm = $('.CodeMirror')[0]; if (cm.CodeMirror) { console.log('[文本工具] 找到 CodeMirror'); return { type: 'codemirror', element: cm.CodeMirror }; } } // 3. 检查当前焦点元素 var activeEl = document.activeElement; if (activeEl && (activeEl.tagName === 'TEXTAREA' || (activeEl.tagName === 'INPUT' && activeEl.type === 'text'))) { console.log('[文本工具] 找到活动输入框:', activeEl.tagName); return { type: 'textarea', element: activeEl }; } // 4. 检查可编辑元素 if (activeEl && activeEl.contentEditable === 'true') { console.log('[文本工具] 找到可编辑元素'); return { type: 'contenteditable', element: activeEl }; } console.log('[文本工具] 未找到编辑器'); return null; } // ===== 获取选中文字 ===== function getSelectedText() { // 1. 先检查编辑器内的选中 var editor = findEditor(); if (editor) { if (editor.type === 'textarea') { var el = editor.element; var start = el.selectionStart; var end = el.selectionEnd; if (start !== end) { return el.value.substring(start, end); } } else if (editor.type === 'codemirror') { var selection = editor.element.getSelection(); if (selection) { return selection; } } } // 2. 检查页面上的选中文字 var selection = window.getSelection(); if (selection && selection.toString().trim()) { return selection.toString().trim(); } return ''; } // ===== 插入到编辑器 ===== function insertToEditor(editor, text, replaceSelection) { console.log('[文本工具] 执行插入:', editor.type, text, replaceSelection); try { if (editor.type === 'textarea') { var el = editor.element; var start = el.selectionStart; var end = el.selectionEnd; var value = el.value; if (replaceSelection && start !== end) { // 替换选中的文本 el.value = value.substring(0, start) + text + value.substring(end); var newPos = start + text.length; el.selectionStart = el.selectionEnd = newPos; } else { // 在光标位置插入 el.value = value.substring(0, start) + text + value.substring(start); var newPos = start + text.length; el.selectionStart = el.selectionEnd = newPos; } // 触发事件 var event = new Event('input', { bubbles: true }); el.dispatchEvent(event); // 聚焦 el.focus(); console.log('[文本工具] 插入成功 (textarea)'); return true; } else if (editor.type === 'codemirror') { var cm = editor.element; if (replaceSelection) { cm.replaceSelection(text); } else { var cursor = cm.getCursor(); cm.replaceRange(text, cursor); } cm.focus(); console.log('[文本工具] 插入成功 (codemirror)'); return true; } else if (editor.type === 'contenteditable') { document.execCommand('insertText', false, text); console.log('[文本工具] 插入成功 (contenteditable)'); return true; } } catch (e) { console.error('[文本工具] 插入失败:', e); return false; } return false; } // ===== 复制到剪贴板 ===== function copyToClipboard(text) { console.log('[文本工具] 复制到剪贴板:', text); if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).then(function() { console.log('[文本工具] 复制成功 (现代API)'); }).catch(function(err) { console.log('[文本工具] 现代API失败,使用备用方法'); fallbackCopy(text); }); } else { fallbackCopy(text); } } function fallbackCopy(text) { var $temp = $('<textarea>') .val(text) .css({ position: 'fixed', opacity: 0, top: '-9999px', left: '-9999px' }) .appendTo('body'); $temp[0].select(); $temp[0].setSelectionRange(0, 99999); try { var success = document.execCommand('copy'); console.log('[文本工具] 复制', success ? '成功' : '失败', '(备用方法)'); } catch(err) { console.error('[文本工具] 复制失败:', err); } $temp.remove(); } // ===== 状态更新 ===== function updateStatus(message, success) { console.log('[文本工具] 状态:', message); var icon = success ? '✓' : '⚠'; var color = success ? '#2196F3' : '#ff9800'; $('#copy-status') .html('<b>' + icon + '</b> ' + message) .css({ color: color, fontWeight: 'bold' }); setTimeout(function() { $('#copy-status') .html('💡 先选中文字,再点击按钮') .css({ color: '#666', fontWeight: 'normal' }); }, 3000); } // ===== UI 控制 ===== function toggleTool() { if (isVisible) { hideTool(); } else { showTool(); } } function showTool() { if (isMinimized) { isMinimized = false; $('#tool-body').show(); toolPanel.css('width', '340px'); } toolPanel.fadeIn(200); isVisible = true; localStorage.setItem('copyTextTool_visible', 'true'); } function hideTool() { toolPanel.fadeOut(200); isVisible = false; localStorage.setItem('copyTextTool_visible', 'false'); } function minimizeTool() { if (isMinimized) { $('#tool-body').slideDown(200); toolPanel.css('width', '340px'); isMinimized = false; } else { $('#tool-body').slideUp(200); toolPanel.css('width', 'auto'); isMinimized = true; } } // ===== 拖动功能 ===== function makeDraggable(element, handle) { var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; handle.onmousedown = dragMouseDown; function dragMouseDown(e) { e = e || window.event; e.preventDefault(); pos3 = e.clientX; pos4 = e.clientY; document.onmouseup = closeDragElement; document.onmousemove = elementDrag; } function elementDrag(e) { e = e || window.event; e.preventDefault(); pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; var newTop = (element.offsetTop - pos2); var newLeft = (element.offsetLeft - pos1); element.style.top = newTop + "px"; element.style.left = newLeft + "px"; element.style.right = "auto"; } function closeDragElement() { document.onmouseup = null; document.onmousemove = null; var position = { top: element.style.top, left: element.style.left }; localStorage.setItem('copyTextTool_position', JSON.stringify(position)); } } })(jQuery, mediaWiki);
该页面使用的模板:
模板:描边
(
查看源代码
)
模板:描边/颜色
(
查看源代码
)
模板:文本
(
查看源代码
)
模板:词典
(
查看源代码
)
模块:文本
(
查看源代码
)
模块:词典
(
查看源代码
)
模块:词典/data
(
查看源代码
)
返回
MediaWiki:Gadget-CopyTextTool.js
。