卡厄思
梦
境
菜单
首页
回到首页
WIKI工具
全站样式
全站JS
修改导航栏
测试
沙盒
可视化管理器
战斗员管理器
卡牌管理器
伙伴管理器
装备管理器
词典管理器
图鉴
战斗员
伙伴
装备
怪物卡牌
中立卡牌
词典
小工具
配队模拟器
节奏榜生成器
搜索
链入页面
相关更改
特殊页面
页面信息
最近更改
登录
MediaWiki
查看“︁Card.js”︁的源代码
←
MediaWiki:Card.js
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
此页面为本wiki上的软件提供界面文本,并受到保护以防止滥用。 如欲修改所有wiki的翻译,请访问
translatewiki.net
上的MediaWiki本地化项目。
您无权编辑此JavaScript页面,因为编辑此页面可能会影响所有访问者。
您可以查看和复制此页面的源代码。
// MediaWiki:Card.js (function() { 'use strict'; // 加载CSS mw.loader.load('/index.php?title=Template:Card.css&action=raw&ctype=text/css', 'text/css'); // 主管理器对象 const CardManager = { currentFighter: '', cardData: {}, cardList: [], init: function() { this.createInterface(); this.loadFighters(); this.bindEvents(); }, createInterface: function() { const container = $('<div>').attr('id', 'card-manager').addClass('card-manager-container'); // 创建三列布局 const leftPanel = this.createLeftPanel(); const centerPanel = this.createCenterPanel(); const rightPanel = this.createRightPanel(); container.append(leftPanel, centerPanel, rightPanel); $('#mw-content-text').prepend(container); }, createLeftPanel: function() { const panel = $('<div>').addClass('card-panel card-panel-left'); // 战斗员选择 const fighterSection = $('<div>').addClass('card-section'); fighterSection.append( $('<div>').addClass('section-title').text('战斗员选择'), $('<div>').addClass('form-group').append( $('<div>').addClass('form-label').text('当前战斗员:'), $('<div>').attr('id', 'fighter-select').addClass('custom-select').append( $('<div>').addClass('select-display').text('请选择战斗员'), $('<div>').addClass('select-options').hide() ) ) ); // 默认信息区 const defaultInfo = $('<div>').addClass('card-section'); defaultInfo.append( $('<div>').addClass('section-title').text('默认信息'), this.createInput('card-order', '卡牌顺序', '灭,灭,救,虚无残影,消灭烙印,黑洞,虚妄的誓约,无忧的回声'), this.createInput('ego', '属性', '虚无') ); // 卡牌数据输入区 const cardDataSection = $('<div>').addClass('card-section'); cardDataSection.append( $('<div>').addClass('section-title').text('卡牌数据'), this.createInput('card-name', '卡牌名称', '黑洞'), this.createInput('displayname', '显示名称', ''), this.createInput('art', '图片', 'unique_1064_02.png'), this.createDropdown('group', '卡组', ['自我意识技能', '起始卡牌', '独特卡牌', '灵光一闪', '神光一闪']), this.createDropdown('rarity', '稀有度', ['白', '蓝', '橙', '彩']), this.createDropdown('god', '神明', ['circen', 'diallos', 'nihilum', 'secred', 'vitor']), this.createInput('ap', 'AP', '2'), this.createDropdown('type', '卡牌类型', ['攻击', '技能', '强化']), this.createInput('dict', '机制', ''), this.createDescriptionInput(), this.createInput('sub', '衍生卡牌', ''), this.createCheckbox('isinspiration', '是否存在灵光一闪'), this.createCheckbox('god_inspiration', '是否存在神光一闪') ); panel.append(fighterSection, defaultInfo, cardDataSection); return panel; }, createCenterPanel: function() { const panel = $('<div>').addClass('card-panel card-panel-center'); // 卡牌列表 const cardListSection = $('<div>').addClass('card-section'); cardListSection.append( $('<div>').addClass('section-title').text('卡牌列表'), $('<div>').attr('id', 'card-list').addClass('card-list') ); // 灵光一闪列表 const inspirationSection = $('<div>').addClass('card-section'); inspirationSection.append( $('<div>').addClass('section-title').text('灵光一闪列表'), $('<div>').attr('id', 'inspiration-list').addClass('card-list') ); // 神光一闪列表 const godInspirationSection = $('<div>').addClass('card-section'); godInspirationSection.append( $('<div>').addClass('section-title').text('神光一闪列表'), $('<div>').attr('id', 'god-inspiration-list').addClass('card-list') ); // 操作按钮 const buttonSection = $('<div>').addClass('card-section button-group'); buttonSection.append( $('<div>').addClass('card-button button-add').text('添加卡牌'), $('<div>').addClass('card-button button-update').text('更新卡牌'), $('<div>').addClass('card-button button-delete').text('删除卡牌'), $('<div>').addClass('card-button button-save').text('保存到模块') ); panel.append(cardListSection, inspirationSection, godInspirationSection, buttonSection); return panel; }, createRightPanel: function() { const panel = $('<div>').addClass('card-panel card-panel-right'); const previewSection = $('<div>').addClass('card-section'); previewSection.append( $('<div>').addClass('section-title').text('Lua代码预览'), $('<div>').addClass('code-preview-wrapper').append( $('<pre>').attr('id', 'lua-preview').addClass('lua-preview') ) ); panel.append(previewSection); return panel; }, createInput: function(id, label, placeholder) { return $('<div>').addClass('form-group').append( $('<div>').addClass('form-label').text(label + ':'), $('<div>').attr('id', id).addClass('custom-input').attr('contenteditable', 'true') .attr('data-placeholder', placeholder || '') ); }, createDropdown: function(id, label, options) { const dropdown = $('<div>').addClass('form-group').append( $('<div>').addClass('form-label').text(label + ':'), $('<div>').attr('id', id).addClass('custom-select').append( $('<div>').addClass('select-display').text(options[0]), $('<div>').addClass('select-options').hide() ) ); const optionsContainer = dropdown.find('.select-options'); options.forEach(opt => { optionsContainer.append( $('<div>').addClass('select-option').text(opt) ); }); return dropdown; }, createCheckbox: function(id, label) { return $('<div>').addClass('form-group').append( $('<div>').addClass('form-label').text(label + ':'), $('<div>').attr('id', id).addClass('custom-checkbox').append( $('<div>').addClass('checkbox-box'), $('<div>').addClass('checkbox-label').text('否') ).data('checked', false) ); }, createDescriptionInput: function() { const descGroup = $('<div>').addClass('form-group'); // 工具栏 const toolbar = $('<div>').addClass('desc-toolbar').append( $('<div>').addClass('toolbar-btn').text('蓝色文本').data('format', 'blue'), $('<div>').addClass('toolbar-btn').text('绿色文本').data('format', 'green'), $('<div>').addClass('toolbar-btn').text('绿色描边').data('format', 'outline'), $('<div>').addClass('toolbar-btn').text('词典').data('format', 'dict'), $('<div>').addClass('toolbar-btn').text('换行').data('format', 'br') ); descGroup.append( $('<div>').addClass('form-label').text('描述:'), toolbar, $('<div>').attr('id', 'desc_global').addClass('custom-textarea') .attr('contenteditable', 'true') .html('伤害{{文本|蓝|240}}%<br>按照消灭卡牌的数量,伤害量+{{文本|蓝|40}}%<br>(最多{{文本|蓝|10}}次)') ); return descGroup; }, loadFighters: function() { // 通过API加载战斗员分类的页面 new mw.Api().get({ action: 'query', list: 'categorymembers', cmtitle: 'Category:战斗员', cmlimit: 500, format: 'json' }).done(function(data) { const fighterSelect = $('#fighter-select .select-options'); fighterSelect.empty(); data.query.categorymembers.forEach(function(member) { fighterSelect.append( $('<div>').addClass('select-option').text(member.title).data('fighter', member.title) ); }); }); }, bindEvents: function() { const self = this; // 下拉框事件 $(document).on('click', '.custom-select', function(e) { e.stopPropagation(); const options = $(this).find('.select-options'); $('.select-options').not(options).hide(); options.toggle(); }); $(document).on('click', '.select-option', function(e) { e.stopPropagation(); const select = $(this).closest('.custom-select'); const display = select.find('.select-display'); display.text($(this).text()); $(this).parent().hide(); if (select.attr('id') === 'fighter-select') { self.currentFighter = $(this).data('fighter'); self.loadFighterCards(); } }); // 复选框事件 $(document).on('click', '.custom-checkbox', function() { const isChecked = !$(this).data('checked'); $(this).data('checked', isChecked); $(this).find('.checkbox-box').toggleClass('checked'); $(this).find('.checkbox-label').text(isChecked ? '是' : '否'); }); // 描述工具栏事件 $(document).on('click', '.toolbar-btn', function() { const format = $(this).data('format'); const textarea = $('#desc_global')[0]; const selection = window.getSelection(); const selectedText = selection.toString(); let insertText = ''; switch(format) { case 'blue': insertText = selectedText ? `{{文本|蓝|${selectedText}}}` : '{{文本|蓝|}}'; break; case 'green': insertText = selectedText ? `{{文本|绿|${selectedText}}}` : '{{文本|绿|}}'; break; case 'outline': insertText = selectedText ? `{{描边|绿|${selectedText}}}` : '{{描边|绿|}}'; break; case 'dict': insertText = selectedText ? `{{词典|${selectedText}}}` : '{{词典|}}'; break; case 'br': insertText = '<br>'; break; } document.execCommand('insertHTML', false, insertText); }); // 按钮事件 $('.button-add').on('click', function() { self.addCard(); }); $('.button-update').on('click', function() { self.updateCard(); }); $('.button-delete').on('click', function() { self.deleteCard(); }); $('.button-save').on('click', function() { self.saveToModule(); }); // 输入变化时更新预览 $(document).on('input', '.custom-input, .custom-textarea', function() { self.updatePreview(); }); // 点击其他地方关闭下拉框 $(document).on('click', function() { $('.select-options').hide(); }); }, addCard: function() { const cardName = $('#card-name').text(); if (!cardName) { mw.notify('请输入卡牌名称', {type: 'error'}); return; } const cardData = this.getFormData(); this.cardData[cardName] = cardData; this.updateCardList(); this.updatePreview(); mw.notify('卡牌添加成功', {type: 'success'}); }, updateCard: function() { const cardName = $('#card-name').text(); if (!cardName || !this.cardData[cardName]) { mw.notify('请选择要更新的卡牌', {type: 'error'}); return; } const cardData = this.getFormData(); this.cardData[cardName] = cardData; this.updateCardList(); this.updatePreview(); mw.notify('卡牌更新成功', {type: 'success'}); }, deleteCard: function() { const cardName = $('#card-name').text(); if (!cardName || !this.cardData[cardName]) { mw.notify('请选择要删除的卡牌', {type: 'error'}); return; } delete this.cardData[cardName]; this.updateCardList(); this.updatePreview(); this.clearForm(); mw.notify('卡牌删除成功', {type: 'success'}); }, getFormData: function() { const data = { base: { displayname: $('#displayname').text(), art: $('#art').text(), group: $('#group .select-display').text(), rarity: $('#rarity .select-display').text(), ap: $('#ap').text(), type: $('#type .select-display').text(), dict: $('#dict').text(), desc_global: $('#desc_global').html(), sub: $('#sub').text(), isinspiration: $('#isinspiration').data('checked') ? 1 : 0, god_inspiration: $('#god_inspiration').data('checked') ? 1 : 0 }, var: {} }; // 如果有灵光一闪,添加默认数据 if (data.base.isinspiration) { data.var.inspiration = [ { ap: 1 }, { desc_global: data.base.desc_global }, { desc_global: data.base.desc_global }, { ap: 3, desc_global: data.base.desc_global }, { ap: 1, type: '强化', desc_global: data.base.desc_global } ]; } // 如果有神光一闪,添加默认数据 if (data.base.god_inspiration) { data.var.god_inspiration = { circen: [{ ap: 1 }], diallos: [{ ap: 1 }], nihilum: [{ ap: 1 }], secred: [{ ap: 1 }], vitor: [{ ap: 1 }] }; } return data; }, updateCardList: function() { const cardList = $('#card-list'); cardList.empty(); Object.keys(this.cardData).forEach(cardName => { const card = this.cardData[cardName]; const cardItem = $('<div>').addClass('card-item').text(cardName); cardItem.on('click', () => this.loadCard(cardName)); cardList.append(cardItem); // 更新灵光一闪列表 if (card.base.isinspiration) { const inspirationItem = $('<div>').addClass('card-item inspiration-item') .text(cardName + ' - 灵光一闪'); $('#inspiration-list').append(inspirationItem); } // 更新神光一闪列表 if (card.base.god_inspiration) { const godItem = $('<div>').addClass('card-item god-item') .text(cardName + ' - 神光一闪'); $('#god-inspiration-list').append(godItem); } }); }, loadCard: function(cardName) { const card = this.cardData[cardName]; if (!card) return; $('#card-name').text(cardName); $('#displayname').text(card.base.displayname || ''); $('#art').text(card.base.art || ''); $('#group .select-display').text(card.base.group || ''); $('#rarity .select-display').text(card.base.rarity || ''); $('#ap').text(card.base.ap || ''); $('#type .select-display').text(card.base.type || ''); $('#dict').text(card.base.dict || ''); $('#desc_global').html(card.base.desc_global || ''); $('#sub').text(card.base.sub || ''); const inspirationChecked = card.base.isinspiration === 1; $('#isinspiration').data('checked', inspirationChecked); $('#isinspiration .checkbox-box').toggleClass('checked', inspirationChecked); $('#isinspiration .checkbox-label').text(inspirationChecked ? '是' : '否'); const godChecked = card.base.god_inspiration === 1; $('#god_inspiration').data('checked', godChecked); $('#god_inspiration .checkbox-box').toggleClass('checked', godChecked); $('#god_inspiration .checkbox-label').text(godChecked ? '是' : '否'); }, clearForm: function() { $('.custom-input').text(''); $('.custom-textarea').html(''); $('.custom-checkbox').data('checked', false); $('.checkbox-box').removeClass('checked'); $('.checkbox-label').text('否'); }, updatePreview: function() { const cardOrder = $('#card-order').text(); const ego = $('#ego').text(); let luaCode = 'local card = {}\n\n'; luaCode += `card.order = { "${cardOrder}" }\n\n`; luaCode += 'card.info = {\n'; luaCode += ` ego = "${ego}",\n`; luaCode += '}\n\n'; Object.keys(this.cardData).forEach(cardName => { const card = this.cardData[cardName]; luaCode += `card["${cardName}"] = {\n`; luaCode += ' base = {\n'; Object.keys(card.base).forEach(key => { const value = card.base[key]; if (value !== '' && value !== 0) { if (typeof value === 'number') { luaCode += ` ${key} = ${value},\n`; } else { luaCode += ` ${key} = "${value}",\n`; } } }); luaCode += ' },\n'; if (card.var && Object.keys(card.var).length > 0) { luaCode += ' var = {\n'; if (card.var.inspiration) { luaCode += ' inspiration = {\n'; card.var.inspiration.forEach(insp => { luaCode += ' {\n'; Object.keys(insp).forEach(key => { if (typeof insp[key] === 'number') { luaCode += ` ${key} = ${insp[key]},\n`; } else { luaCode += ` ${key} = "${insp[key]}",\n`; } }); luaCode += ' },\n'; }); luaCode += ' },\n'; } if (card.var.god_inspiration) { luaCode += ' god_inspiration = {\n'; Object.keys(card.var.god_inspiration).forEach(god => { luaCode += ` ${god} = {\n`; card.var.god_inspiration[god].forEach(godInsp => { luaCode += ' {\n'; Object.keys(godInsp).forEach(key => { if (typeof godInsp[key] === 'number') { luaCode += ` ${key} = ${godInsp[key]},\n`; } else { luaCode += ` ${key} = "${godInsp[key]}",\n`; } }); luaCode += ' },\n'; }); luaCode += ' },\n'; }); luaCode += ' },\n'; } luaCode += ' },\n'; } luaCode += '}\n\n'; }); luaCode += 'return card'; $('#lua-preview').text(luaCode); }, loadFighterCards: function() { if (!this.currentFighter) return; const moduleName = `模块:卡牌/${this.currentFighter}`; new mw.Api().get({ action: 'query', prop: 'revisions', titles: moduleName, rvprop: 'content', format: 'json' }).done((data) => { const pages = data.query.pages; const pageId = Object.keys(pages)[0]; if (pageId !== '-1') { const content = pages[pageId].revisions[0]['*']; // 这里需要解析Lua内容并加载到界面 this.parseLuaContent(content); } }); }, parseLuaContent: function(content) { // 简化的Lua解析,实际使用可能需要更复杂的解析器 try { // 提取卡牌数据 const cardMatches = content.matchAll(/card\["([^"]+)"\]\s*=\s*{([^}]+})}/gs); this.cardData = {}; for (const match of cardMatches) { const cardName = match[1]; // 这里需要更复杂的解析逻辑 // 暂时使用简化版本 } this.updateCardList(); this.updatePreview(); } catch (e) { console.error('解析Lua内容失败:', e); } }, saveToModule: function() { if (!this.currentFighter) { mw.notify('请先选择战斗员', {type: 'error'}); return; } const moduleName = `模块:卡牌/${this.currentFighter}`; const luaContent = $('#lua-preview').text(); new mw.Api().postWithToken('csrf', { action: 'edit', title: moduleName, text: luaContent, summary: '更新卡牌数据', format: 'json' }).done(function() { mw.notify('保存成功!', {type: 'success'}); }).fail(function(error) { mw.notify('保存失败:' + error, {type: 'error'}); }); } }; // 页面加载完成后初始化 $(document).ready(function() { // 只在特定页面加载 if (mw.config.get('wgPageName') === 'Special:CardManager' || mw.config.get('wgPageName').indexOf('卡牌管理') !== -1) { CardManager.init(); } }); // 添加到全局对象以便调试 window.CardManager = CardManager; })();
该页面使用的模板:
模板:图标
(
查看源代码
)
模板:描边
(
查看源代码
)
模板:描边/颜色
(
查看源代码
)
模板:文本
(
查看源代码
)
模板:词典
(
查看源代码
)
模块:文本
(
查看源代码
)
模块:词典
(
查看源代码
)
模块:词典/data
(
查看源代码
)
返回
MediaWiki:Card.js
。