User:Liangent/Scripts/RDT.js
< User:Liangent | Scripts
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google Chrome、Firefox、Microsoft Edge及Safari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
mw.loader.using( [
'jquery', 'jquery.ui'
], function() {
(function($) { $(function() {
if ($('#rdtui_wrapper').length == 0) return;
$('#rdtui_wrapper').text('正在初始化,请稍候……');
var rdt_config = {
data_page: 'Wikipedia:铁路系统标示/图标列表/机读格式',
help_page: 'Wikipedia:铁路系统标示/编辑器/帮助',
html_unusedvalue: '_unused',
icon_size: 24, // icon size in template: 20px, cannot provide high enough cells for textboxes
max_layers: 6,
max_icons_in_row: 10,
max_undo: -1,
fake_title: '铁路系统标示'
};
var data_prefix = [];
var data_base = [];
var data_reverse = {};
var map = [];
var maprow_blank = { icons: [], text1: '', text2: '', text3: '', text4: '', backgroundColor: '', textWidth: '' };
var icon_blank = { layers: [], link: '' };
var maprow_default = $.extend(true, {}, maprow_blank), icon_default = $.extend(true, {}, icon_blank);
var getcode_icon = function(icon, pos) {
var text = '';
$.each(icon.layers, function(index) {
text += '|';
switch (index) {
case 0:
text += pos;
break;
case 1:
text += 'O' + pos;
break;
default:
text += 'O' + pos + index;
}
text += '=' + this;
});
if (icon.link.length != 0) {
text += '|L' + pos + '=' + icon.link;
}
return text;
};
var getcode_row = function(row) {
var text = '{\{BS';
if (row.icons.length > 1) {
text += row.icons.length;
}
$.each(row.icons, function(index) {
text += getcode_icon(this, index + 1);
});
var textvarindex = row.icons.length;
if (textvarindex == 0) {
textvarindex = 1;
}
if (row.text1.length != 0) {
text += '|' + (textvarindex + 1) + '=' + row.text1;
}
if (row.text2.length != 0) {
text += '|' + (textvarindex + 2) + '=' + row.text2;
}
if (row.text3.length != 0) {
text += '|' + (textvarindex + 3) + '=' + row.text3;
}
if (row.text4.length != 0) {
text += '|' + (textvarindex + 4) + '=' + row.text4;
}
if (row.backgroundColor.length != 0) {
text += '|bg=' + row.backgroundColor;
}
if (row.textWidth.length != 0) {
text += '|tw=' + row.textWidth;
}
text += '}}';
return text;
};
var getcode = function() {
return $.map(map, function(row) {
return getcode_row(row);
}).join($.browser.msie ? '\r\n' : '\n');
};
var geticondesc = function(prefix, base) {
var iconname = prefix + (base === undefined ? '' : base);
var rev = data_reverse[iconname];
return rev === undefined ? iconname : rev;
};
var geticonname_cur = function() {
if ($('#rdtui_iconselect_own').val().length != 0) {
return $('#rdtui_iconselect_own').val();
} else if ($('#rdtui_iconselect_prefix').val() != rdt_config.html_unusedvalue &&
$('#rdtui_iconselect_base').val() != rdt_config.html_unusedvalue) {
return $('#rdtui_iconselect_prefix').val() + $('#rdtui_iconselect_base').val();
} else {
return null;
}
};
var geticon_url = function(prefix, base) {
// thumb.php cannot handle file redirects. we just hope that the user's browser supports svg
return '//zh.wikipedia.org/wiki/Special:FilePath/' +
encodeURIComponent('BSicon_' + prefix + (base === undefined ? '' : base) + '.svg');
};
var geticon_img = function(prefix, base) {
return $('<img />').attr({
'src': geticon_url(prefix, base),
'width': rdt_config.icon_size,
'height': rdt_config.icon_size
});
};
var drawicon = function(icon) {
var div = $('<div />').css('position', 'relative').attr(
'title', (icon.link.length != 0 ? '链接到:' + icon.link + ',' : '') +
icon.layers.length + '层' +
(icon.layers.length > 0 ? ':(从下到上)' +
$.map(icon.layers, function(iconname) {
return geticondesc(iconname) + '(' + iconname + ')'
}).join('、') : '')
);
// we must add something for background? (placeholder) // transparent?
geticon_img('').css('z-index', -1).appendTo(div);
$.each(icon.layers, function(index) {
geticon_img(this).css({
'position': 'absolute',
'left': 0,
'top': 0,
'z-index': index
}).appendTo(div);
});
return div;
};
var drawicon_row = function(icons) {
var table = $('<table />').css({
'margin': '0 auto',
'border-collapse': 'collapse',
'cursor': 'pointer',
'background': 'transparent'
});
var tr = $('<tr />').appendTo(table);
$.each(icons, function() {
var icon = this;
$('<td />').append(drawicon(this)).click(function(event) {
if (event.altKey || event.ctrlKey) {
if (event.shiftKey) {
var newicon = $.extend(true, {}, icon);
var td = this;
var dialog = $('<div title="图标编辑" />');
dialog.html('<div id="rdtui_icon_preview" style="float: right;" />' +
'<p>链接到:<input type="text" id="rdtui_icon_link" />' +
'</p><ul id="rdtui_icon_layers"></ul>'
);
var updpreview = function() {
$('#rdtui_icon_preview').empty().append(drawicon(newicon));
};
$('#rdtui_icon_link').val(newicon.link).change(function() {
newicon.link = $(this).val();
updpreview();
});
var drawlayers = function() {
// avoid using a table -- possible tbody element problems...
var ul = $('#rdtui_icon_layers').empty().css({
'white-space': 'nowrap',
'cursor': 'move', // we are not resizing, so not ns-resize
'margin-left': 0,
'list-style': 'none'
});
var li_idprefix = 'rdtui_icon_layer_';
$.each(newicon.layers, function(index) {
var li = $('<li />');
var iconname = this.toString();
li.append($('<a href="#" />').text('×').click(function() {
newicon.layers.splice(index, 1);
drawlayers(); // or bad index numbers
updpreview();
})).append(' ');
li.append(geticon_img(this)).append(' ');
li.append(geticondesc(this)).append(' ');
li.append(iconname);
li.attr('id', li_idprefix + iconname);
li.appendTo(ul);
});
ul.sortable({
update: function(event, ui) {
newicon.layers = $.map(ul.sortable('toArray'), function(i) {
return i.slice(li_idprefix.length);
});
drawlayers(); // or bad index numbers
updpreview();
},
forcePlaceholderSize: true,
forceHelperSize: true
});
};
drawlayers();
dialog.dialog({
buttons: {
'确定': function() {
icon.layers = newicon.layers;
icon.link = newicon.link;
$(td).empty().append(drawicon(icon));
$(this).dialog('close');
},
'取消': function() {
$(this).dialog('close');
}
},
close: function() {
$(this).remove();
},
modal: true,
width: 'auto',
height: 'auto'
});
updpreview();
return;
} else {
icon.link = '';
icon.layers = [];
}
} else {
var iconname = geticonname_cur();
if (iconname == null) return;
if (event.shiftKey) {
icon.layers = [iconname];
} else {
if (icon.layers.length >= rdt_config.max_layers) {
alert('层数超过限制(这个限制取决于此wiki系统的模板)');
return;
}
icon.layers.push(iconname);
}
}
$(this).empty().append(drawicon(icon));
}).css({'padding': 0, 'border': '1px solid gray'}).appendTo(tr);
});
return table;
};
var drawmap = function() {
$('#rdtui_map').html('<table><tr><th>控制</th><th>图标</th>' +
'<th>文字1</th><th>文字2</th><th>文字3</th><th>文字4</th>' +
'<th>背景</th><th>文字宽度</th></tr></table>'
).css({
'white-space': 'nowrap',
'font-size': '100%'
});
$('#rdtui_map > table').css('border-collapse', 'collapse');
var genrow = function(index) {
var row = this;
var tr = $('<tr />');
$('<td />').append($('<a href="#" />').text('+R').click(function(event) {
event.preventDefault();
map.splice(index, 0, $.extend(true, {}, maprow_default));
// can we avoid this to improve performance?
drawmap(); // must redraw. or index numbers (like above) may become a mess
})).append(' ').append($('<a href="#" />').text('-R').click(function(event) {
event.preventDefault();
map.splice(index, 1);
// can we avoid this to improve performance?
drawmap(); // must redraw. or index numbers (like above) may become a mess
})).append(' ').append($('<a href="#" />').text('I+').click(function(event) {
event.preventDefault();
if (row.icons.length >= rdt_config.max_icons_in_row) {
alert('本行图标数超过限制(这个限制取决于此wiki系统的模板)');
return;
}
row.icons.splice(0, 0, $.extend(true, {}, icon_default));
$('.rdtui_map_icons', tr).empty().append(drawicon_row(row.icons));
})).append(' ').append($('<a href="#" />').text('I-').click(function(event) {
event.preventDefault();
row.icons.splice(0, 1);
$('.rdtui_map_icons', tr).empty().append(drawicon_row(row.icons));
})).append(' ').append($('<a href="#" />').text('+I').click(function(event) {
event.preventDefault();
if (row.icons.length >= rdt_config.max_icons_in_row) {
alert('本行图标数超过限制(这个限制取决于此wiki系统的模板)');
return;
}
row.icons.push($.extend(true, {}, icon_default));
$('.rdtui_map_icons', tr).empty().append(drawicon_row(row.icons));
})).append(' ').append($('<a href="#" />').text('-I').click(function(event) {
event.preventDefault();
row.icons.pop();
$('.rdtui_map_icons', tr).empty().append(drawicon_row(row.icons));
})).append(' ').append($('<a href="#" />').text('DEF').click(function(event) {
event.preventDefault();
maprow_default = $.extend(true, {}, row);
})).appendTo(tr);
$('<td />').addClass('rdtui_map_icons').append(drawicon_row(this.icons))
.css({
'padding': 0,
'background-color': this.backgroundColor
}).appendTo(tr);
// no need to redraw if only text is changed
$('<td />').addClass('rdtui_map_text rdtui_map_text1').append($('<input type="text" />').val(this.text1).change(function() {
row.text1 = $(this).val();
})).appendTo(tr);
$('<td />').addClass('rdtui_map_text rdtui_map_text2').append($('<input type="text" />').val(this.text2).change(function() {
row.text2 = $(this).val();
})).appendTo(tr);
$('<td />').addClass('rdtui_map_text rdtui_map_text3').append($('<input type="text" />').val(this.text3).change(function() {
row.text3 = $(this).val();
})).appendTo(tr);
$('<td />').addClass('rdtui_map_text rdtui_map_text4').append($('<input type="text" />').val(this.text4).change(function() {
row.text4 = $(this).val();
})).appendTo(tr);
$('<td />').addClass('rdtui_map_backgroundcolor').append($('<input type="text" />').val(this.backgroundColor).change(function() {
var color = $(this).val();
row.backgroundColor = color;
$('.rdtui_map_icons', tr).css('background-color', color);
})).appendTo(tr);
$('<td />').addClass('rdtui_map_textwidth').append($('<input type="text" />').val(this.textWidth).change(function() {
row.textWidth = $(this).val();
})).appendTo(tr);
return tr;
};
$.each(map, function(index) {
genrow.call(this, index).appendTo('#rdtui_map > table');
});
$('<tr id="rdtui_map_newrow" />').append($('<td />').append($('<a href="#" />').text('+R').click(function(event) {
event.preventDefault();
var newrow = $.extend(true, {}, maprow_default);
map.push(newrow);
$('#rdtui_map_newrow').before(genrow.call(newrow, map.length - 1)); // avoid redrawing
}))).appendTo('#rdtui_map > table');
};
$.ajax({
type: 'GET',
url: wgScript + '?action=render&title=' + encodeURIComponent(rdt_config.data_page),
dataType: 'html',
success: function(data, status) {
var tmpdiv = $('<div />');
tmpdiv.html(data);
data = tmpdiv;
$('.rdtdata_prefix', data).each(function() {
data_prefix.push({str: $('.rdtdata_prefix_str', this).text(), desc: $('.rdtdata_prefix_desc', this).text()});
});
$('.rdtdata_basesection', data).each(function() { // TODO: support subsections
var basesection = {desc: $('.rdtdata_basesection_desc', this).text(), data: []};
$('.rdtdata_base', this).each(function() {
var base_str = $('.rdtdata_base_str', this).text();
var base_desc = $('.rdtdata_base_desc', this).text();
basesection.data.push({str: base_str, desc: base_desc});
var base = this;
$.each(data_prefix, function() {
// seticondesc
data_reverse[this.str + base_str] =
this.desc + ' - ' + basesection.desc + ' - ' + base_desc;
});
});
data_base.push(basesection);
});
data.remove();
$('#rdtui_wrapper').html('<div id="rdtui_tabs"><ul><li><a href="#rdtui_edit">编辑</a></li>' +
'<li><a href="#rdtui_source">代码</a></li><li><a href="' + wgScript + '?action=render&title=' +
encodeURIComponent(rdt_config.help_page) + '">帮助</a></li></ul>' +
'<div id="rdtui_edit"></div><div id="rdtui_source"></div>'
);
$('#rdtui_edit').html('<div id="rdtui_toolbar" /><div id="rdtui_iconselect" /><div id="rdtui_map" />');
$('#rdtui_iconselect').html(
'选择一个图片:<select id="rdtui_iconselect_prefix"><option value="' +
rdt_config.html_unusedvalue + '">[前缀]</option></select>' +
'<select id="rdtui_iconselect_basesection"><option value="' +
rdt_config.html_unusedvalue + '">[基础节]</option></select>' +
'<select id="rdtui_iconselect_base"><option value="' +
rdt_config.html_unusedvalue + '">[基础]</option></select>' +
'<br />或自己输入一个图片名:<input type="text" id="rdtui_iconselect_own" />' +
'<span id="rdtui_iconselect_preview"></span>'
);
$.each(data_prefix, function() {
$('<option />').attr('value', this.str).text(this.desc).appendTo('#rdtui_iconselect_prefix');
});
$.each(data_base, function() {
var d = this.data;
$('<option />').text(this.desc).each(function() {
$.data(this, 'rdt_base', d);
}).appendTo('#rdtui_iconselect_basesection');
});
$('#rdtui_iconselect_basesection').change(function() {
$('#rdtui_iconselect_base').html('<option value="' + rdt_config.html_unusedvalue + '">[基础]</option>');
if ($(this).val() == rdt_config.html_unusedvalue) return;
$.each($.data(this.options[this.options.selectedIndex], 'rdt_base'), function() {
$('<option />').attr('value', this.str).text(this.desc).appendTo('#rdtui_iconselect_base');
});
});
var update_preview = function() {
$('#rdtui_iconselect_preview').empty();
var iconname = geticonname_cur();
if (iconname != null) {
$('#rdtui_iconselect_preview').append('<br />图片名:').append(iconname);
$('#rdtui_iconselect_preview').append(' 图片:').append(geticondesc(iconname));
$('#rdtui_iconselect_preview').append(' 预览:').append(geticon_img(iconname).attr(
'title', '点击以重叠于现有图片上,Shift-点击以替换现有图片'
).error(function(event) {
$(this).replaceWith('载入失败,图片可能不存在');
})); // cannot use onload to show loading tip. non-exist images will be never onload.
}
};
$('#rdtui_iconselect select').change(function() {
$('#rdtui_iconselect_own').val('');
update_preview();
});
$('#rdtui_iconselect_own').change(update_preview);
drawmap();
$('#rdtui_source').html('Wiki代码:<textarea id="rdtui_wikitext" />');
$('<a href="#" />').click(function(event) {
event.preventDefault();
var dialog = $('<div title="预览" />').text('请稍候').dialog({
close: function() {
$(this).remove();
},
modal: true
});
MediaWiki._request({
action: 'parse',
title: rdt_config.fake_title,
text: '{| {{Railway line header2 (center)}}\n' + $('#rdtui_wikitext').val() + '\n|}',
prop: 'text',
pst: ''
}, function(data) {
dialog.html($('api>parse>text', data).text());
}, function() {
dialog.text('读取失败');
});
}).text('预览').appendTo('#rdtui_source');
$('#rdtui_source').append(
'<hr />以下是路线图的转储格式,可能与将来的版本不兼容,仅供调试和临时保存使用。' +
'如果一个旧版本或格式错误的路线图被载入,可能导致编辑器不能工作:' +
'<textarea id="rdtui_json" />'
);
$('<a href="#" />').click(function(event) {
event.preventDefault();
map = JSON.parse($('#rdtui_json').val());
drawmap();
$('#rdtui_tabs').tabs('select', '#rdtui_edit');
}).text('载入').appendTo('#rdtui_source');
$('#rdtui_tabs').tabs({
select: function(event, ui) {
if ($(ui.panel).attr('id') == 'rdtui_source') {
$('#rdtui_wikitext').attr('rows', map.length + 2).val(getcode());
$('#rdtui_json').val(JSON.stringify(map));
}
}
});
},
error: function() {
$('#rdtui_wrapper').text('初始化失败');
}
});
window.rdt_vars = {
map: map,
redraw: drawmap
};
}); })(jQuery);
});