User:Polygnotus/Scripts/WikiEditorToolbarHelperConfigurator.js: Difference between revisions

Content deleted Content added
No edit summary
No edit summary
 
(5 intermediate revisions by the same user not shown)
Line 1:
/**
* WikiEditor Button Configuration ToolConfigurator
* @version 2025-06-07
* PURE JAVASCRIPT CONFIGURATION TOOL - NO BUTTON DEFINITIONS
* @author Your Username
* Usage: Add ?wikieditorconfig=1 to any Wikipedia URL
*
* Usage: Add ?wikieditorconfig=1 to any Wikipedia URL to open the configuration tool
* Or add mw.loader.load('//en.wikipedia.org/w/index.php?title=User:YourUsername/wikieditor-config.js&action=raw&ctype=text/javascript');
* to your common.js
*/
/*jshint browser: true */
/*global jQuery, mediaWiki, OO */
(function ($, mw) {
"'use strict"';
 
// OnlyCheck load if thefor configuration parameter is present
var urlParams = new URLSearchParams(window.___location.search);
if (urlParams.get('wikieditorconfig') !== '1' && !window.forceWikiEditorConfig) {
return;
}
 
var buttons = [];
var editingIndexdefaults = -1;{
section: 'advanced',
group: 'insert',
type: 'ooui'
};
 
// Create interface
function createConfigInterface() {
function init() {
// Create the modal overlay
var// $overlayAdd = $('<div>').css({CSS
var css = position: 'fixed',[
'#wec-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); z-index: 10000; overflow: auto; }',
top: 0,
'#wec-container { max-width: 900px; margin: 20px auto; background: #fff; border-radius: 8px; padding: 20px; }',
left: 0,
'#wec-form { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 20px; }',
width: '100%',
'.wec-panel { background: #f8f9fa; padding: 15px; border-radius: 5px; }',
height: '100%',
backgroundColor: 'rgba(0,0,0,0.8)wec-field { margin-bottom: 10px; }',
'.wec-label { display: block; margin-bottom: 5px; font-weight: bold; }',
zIndex: 10000,
'.wec-input { width: 100%; padding: 5px; border: 1px solid #ccc; border-radius: 3px; }',
overflow: 'auto'
'.wec-btn { background: #0645ad; color: #fff; border: none; padding: 8px 12px; margin: 0 5px 5px 0; border-radius: 3px; cursor: pointer; }',
});
'.wec-btn-danger { background: #d33; }',
'.wec-list { max-height: 300px; overflow-y: auto; border: 1px solid #ccc; padding: 10px; background: #fff; }',
'.wec-item { border: 1px solid #ddd; padding: 8px; margin-bottom: 5px; border-radius: 3px; }',
'#wec-json { width: 100%; height: 200px; font-family: monospace; font-size: 12px; }'
].join(' ');
$('<style>').text(css).appendTo('head');
 
var $container = $createInterface('<div>').css({;
maxWidth: '1200px',loadExistingConfig();
}
margin: '20px auto',
 
backgroundColor: '#fff',
function createInterface() {
borderRadius: '8px',
var $overlay = $('<div id="wec-overlay">');
boxShadow: '0 4px 20px rgba(0,0,0,0.3)',
var $container = $('<div position: 'relativeid="wec-container">');
});
 
// Header
var $header = $('<divh1>').css({
backgroundColortextAlign: '#0645adcenter',
color: '#fff0645ad',
paddingmarginBottom: '20px',
borderRadius: '8px 8px 0 0',
textAlign: 'center'
});
var $title = $('<h1>').css({
margin: '0',
fontSize: '24px'
}).text('WikiEditor Button Configuration Tool');
var $subtitle = $('<p>').css({
margin: '10px 0 0 0',
opacity: '0.9'
}).text('Create custom buttons for your WikiEditor toolbar');
$header.append($title, $subtitle);
 
var $closeBtn = $('<button>').text('×').css({
position: 'absolute',
top: '10px20px',
right: '15px20px',
background: 'none',
border: 'none',
colorfontSize: '#fff20px',
fontSizecursor: '24pxpointer',
cursor: 'pointer',
padding: '5px 10px'
}).click(function() {
$overlay.remove();
});
 
$header.append($closeBtn);// Form
var $form = $('<div id="wec-form">');
 
$form.append(createFormPanel(), createListPanel());
var $content = $('<div>').css({
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gap: '20px',
padding: '20px'
});
 
var $leftPanel = createLeftPanel();
var $rightPanel = createRightPanel();
 
$content.append($leftPanel, $rightPanel);
 
var $jsonSection = $('<div>').css({
padding: '20px',
borderTop: '1px solid #ccc'
});
 
var $jsonTitle = $('<h3>').text('Generated JSON Configuration').css({
marginBottom: '15px'
});
 
var $jsonOutput = $('<textarea>').attr('id', 'json-output').css({
width: '100%',
height: '200px',
fontFamily: 'monospace',
fontSize: '12px',
padding: '10px',
border: '1px solid #ccc',
borderRadius: '4px',
backgroundColor: '#f9f9f9'
}).val('Click "Generate JSON" to see your configuration');
 
var $jsonButtons = $('<div>').css({
marginTop: '10px',
textAlign: 'center'
});
 
var $generateBtn = createButton('Generate JSON', function() {
generateJSON();
});
 
var $copyBtn = createButton('Copy to Clipboard', function() {
copyJSON();
});
 
var $saveBtn = createButton('Save to User Page', function() {
saveToUserPage();
});
 
// JSON section
$jsonButtons.append($generateBtn, ' ', $copyBtn, ' ', $saveBtn);
var $jsonSection.append($jsonTitle, $jsonOutput,= $jsonButtonscreateJsonSection();
 
$container.append($header, $contentcloseBtn, $form, $jsonSection);
$overlay.append($container);
$('body').append($overlay);
 
// Load existing configuration if it exists
loadExistingConfig();
}
 
function createLeftPanelcreateFormPanel() {
var $panel = $('<div class="wec-panel">').css({;
$panel.append($('<h3>').text('Button Configuration'));
backgroundColor: '#f8f9fa',
padding: '20px',
borderRadius: '8px',
border: '1px solid #ddd'
});
 
// Form fields
var $title = $('<h3>').text('Button Configuration').css({
marginBottom: '20px',$panel.append(
color:createField('Button ID*', 'text', '#333wec-id'),
createField('Label*', 'text', 'wec-label'),
});
createField('Tooltip', 'text', 'wec-tooltip'),
 
var $form = $ createSelectField('<div>Type');, 'wec-type', [
{value: 'ooui', text: 'OOUI'},
 
// Basic fields
$form.append(
createFormGroup('Button ID', 'text', 'button-id', 'unique-button-id', true),
createFormGroup('Label', 'text', 'button-label', 'Button Label', true),
createFormGroup('Tooltip', 'text', 'button-tooltip', 'Button tooltip (optional)'),
createSelectGroup('Button Type', 'button-type', [
{value: 'traditional', text: 'Traditional'},
{value: 'ooui', text: 'OOUI'},
{value: 'element', text: 'Element'}
]),
createFormGroupcreateField('Icon', 'text', 'buttonwec-icon'), 'Icon URL or OOUI icon name')
createField('Insert Before', 'textarea', 'wec-before'),
createField('Sample Text', 'text', 'wec-sample'),
createField('Insert After', 'textarea', 'wec-after'),
createCheckField('Has Prompt', 'wec-prompt'),
createField('Prompt Message', 'text', 'wec-promptmsg'),
createCheckField('Auto Summary', 'wec-summary'),
createField('Summary Text', 'text', 'wec-summarytext'),
createField('Namespaces (comma-separated)', 'text', 'wec-ns')
);
 
// Collapsible sectionsButtons
var $buttons = $('<div>').css({marginTop: '15px'});
$form.append(
$buttons.append(
createCollapsibleSection('Text Insertion', [
$('<button class="wec-btn">').text('Add Button').click(addButton),
createFormGroup('Insert Before', 'textarea', 'insert-before', 'Text to insert before cursor'),
$('<button class="wec-btn">').text('Clear Form').click(clearForm)
createFormGroup('Sample Text', 'textarea', 'sample-text', 'Text to select/replace'),
createFormGroup('Insert After', 'textarea', 'insert-after', 'Text to insert after cursor'),
createFormGroup('Placeholder Pattern', 'text', 'placeholder-pattern', '{input}', false, '{input}')
]),
createCollapsibleSection('Prompt Configuration', [
createCheckboxGroup('Enable Prompt', 'has-prompt'),
createSelectGroup('Prompt Type', 'prompt-type', [
{value: 'simple', text: 'Simple (browser prompt)'},
{value: 'ooui', text: 'OOUI Dialog'}
]),
createFormGroup('Prompt Message', 'text', 'prompt-message', 'Enter your input:'),
createFormGroup('Dialog Title', 'text', 'prompt-title', 'Input Required'),
createFormGroup('Default Value', 'text', 'prompt-default', 'Default input value')
]),
createCollapsibleSection('Auto Summary', [
createCheckboxGroup('Enable Auto Summary', 'has-auto-summary'),
createFormGroup('Summary Text', 'text', 'summary-text', 'Edit summary'),
createSelectGroup('Position', 'summary-position', [
{value: 'append', text: 'Append'},
{value: 'prepend', text: 'Prepend'},
{value: 'replace', text: 'Replace'}
]),
createFormGroup('Delimiter', 'text', 'summary-delimiter', '; ', false, '; '),
createCheckboxGroup('Use Placeholder in Summary', 'summary-use-placeholder')
]),
createCollapsibleSection('Filters & Namespaces', [
createNamespaceSelector(),
createFormGroup('Page Filters', 'textarea', 'page-filters', 'CSS selectors, one per line')
])
);
 
var $buttonRow = panel.append($('<div>'buttons).css({;
marginTop: '20px',
textAlign: 'center'
});
 
var $addBtn = createButton('Add Button', function() {
addButton();
}, 'primary');
 
var $clearBtn = createButton('Clear Form', function() {
clearForm();
});
 
var $exampleBtn = createButton('Load Example', function() {
loadExample();
});
 
$buttonRow.append($addBtn, ' ', $clearBtn, ' ', $exampleBtn);
$form.append($buttonRow);
 
$panel.append($title, $form);
return $panel;
}
 
function createRightPanelcreateListPanel() {
var $panel = $('<div class="wec-panel">').css({;
backgroundColor: '#f8f9fa',$panel.append(
padding: $('20px<h3>').text('Button List'),
$('<div class="wec-list" id="wec-list">').text('No buttons added yet'),
borderRadius: '8px',
border$('<div>').css({marginTop: '1px solid #ddd15px'}).append(
$('<button class="wec-btn wec-btn-danger">').text('Clear All').click(clearAll)
});
)
 
var $title = $('<h3>').text('Buttons List').css({
marginBottom: '20px',
color: '#333'
});
 
var $buttonsList = $('<div>').attr('id', 'buttons-list').css({
maxHeight: '300px',
overflowY: 'auto',
border: '1px solid #ddd',
borderRadius: '4px',
padding: '10px',
backgroundColor: '#fff',
marginBottom: '20px'
}).html('<p style="text-align: center; color: #666; font-style: italic;">No buttons added yet</p>');
 
var $defaultsTitle = $('<h3>').text('Global Defaults').css({
marginBottom: '15px',
color: '#333'
});
 
var $defaults = $('<div>').append(
createSelectGroup('Default Section', 'default-section', [
{value: 'main', text: 'Main'},
{value: 'advanced', text: 'Advanced'},
{value: 'format', text: 'Format'},
{value: 'insert', text: 'Insert'}
]),
createSelectGroup('Default Group', 'default-group', [
{value: 'insert', text: 'Insert'},
{value: 'format', text: 'Format'},
{value: 'reference', text: 'Reference'},
{value: 'special', text: 'Special'}
])
);
 
var $clearAllBtn = createButton('Clear All Buttons', function() {
if (confirm('Are you sure you want to clear all buttons?')) {
buttons = [];
updateButtonsList();
}
}, 'danger');
 
$panel.append($title, $buttonsList, $defaultsTitle, $defaults, $('<div>').css({marginTop: '15px'}).append($clearAllBtn));
return $panel;
}
 
function createJsonSection() {
function createFormGroup(label, type, id, placeholder, required, defaultValue) {
var $group = $('<div>').css({marginBottom: '15px'});
var $label = $('<label>').attr('for', id).text(label + (required ? ' *' : '')).css({
display: 'block',
marginBottom: '5px',
fontWeight: 'bold'
});
 
var $input;
if (type === 'textarea') {
$input = $('<textarea>').attr({
id: id,
placeholder: placeholder,
rows: 3
});
} else {
$input = $('<input>').attr({
type: type,
id: id,
placeholder: placeholder
});
}
 
if (defaultValue) {
$input.val(defaultValue);
}
 
$input.css({
width: '100%',
padding: '8px',
border: '1px solid #ccc',
borderRadius: '4px',
fontSize: '14px'
});
 
$group.append($label, $input);
return $group;
}
 
function createSelectGroup(label, id, options) {
var $group = $('<div>').css({marginBottom: '15px'});
var $label = $('<label>').attr('for', id).text(label).css({
display: 'block',
marginBottom: '5px',
fontWeight: 'bold'
});
 
var $select = $('<select>').attr('id', id).css({
width: '100%',
padding: '8px',
border: '1px solid #ccc',
borderRadius: '4px',
fontSize: '14px'
});
 
options.forEach(function(option) {
$select.append($('<option>').val(option.value).text(option.text));
});
 
$group.append($label, $select);
return $group;
}
 
function createCheckboxGroup(label, id) {
var $group = $('<div>').css({marginBottom: '15px'});
var $wrapper = $('<div>').css({
display: 'flex',
alignItems: 'center',
gap: '8px'
});
 
var $checkbox = $('<input>').attr({
type: 'checkbox',
id: id
});
 
var $label = $('<label>').attr('for', id).text(label).css({
fontWeight: 'bold'
});
 
$wrapper.append($checkbox, $label);
$group.append($wrapper);
return $group;
}
 
function createCollapsibleSection(title, content) {
var $section = $('<div>').css({
borderborderTop: '1px solid #dddccc',
borderRadiuspaddingTop: '4px20px',
marginBottom: '15px'
});
 
var $header = $('<div>')section.cssappend({
padding: $('10px<h3>').text('Generated JSON 15pxConfiguration'),
$('<textarea id="wec-json">').val('Configuration will appear here'),
backgroundColor: '#e9ecef',
cursor$('<div>').css({marginTop: 'pointer10px',}).append(
$('<button class="wec-btn">').text('Generate JSON').click(generateJson),
display: 'flex',
$('<button class="wec-btn">').text('Copy').click(copyJson),
justifyContent: 'space-between',
$('<button class="wec-btn">').text('Save to User Page').click(saveToUserPage)
alignItems: 'center'
} ).text(title);
);
 
var $toggle = $('<span>').text('▼').css({
transition: 'transform 0.3s'
});
 
$header.append($toggle);
 
var $content = $('<div>').css({
padding: '15px',
display: 'none'
});
 
content.forEach(function(item) {
$content.append(item);
});
 
$header.click(function() {
$content.toggle();
$toggle.css('transform', $content.is(':visible') ? 'rotate(180deg)' : 'rotate(0deg)');
});
 
$section.append($header, $content);
return $section;
}
 
function createNamespaceSelectorcreateField(label, type, id) {
var $groupfield = $('<div class="wec-field">').css({marginBottom: '15px'});
var $label = $('<label class="wec-label">').text('Namespaces'label).css({;
var $input = type display:=== 'blocktextarea',
? $('<textarea class="wec-input" rows="3">').attr('id', id)
marginBottom: '10px',
: $('<input class="wec-input">').attr({type: type, id: id});
fontWeight: 'bold'
});
$field.append($label, $input);
return $field;
}
 
function createSelectField(label, id, options) {
var $grid = $('<div>').css({
var $field = $('<div display: 'gridclass="wec-field">',);
var $label = $('<label class="wec-label">').text(label);
gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))',
var $select = $('<select gap: class="wec-input">'8px).attr('id', id);
options.forEach(function(opt) {
$select.append($('<option>').val(opt.value).text(opt.text));
});
 
var$field.append($label, namespaces = [$select);
return $field;
{value: 0, text: 'Main (0)'},
{value: 1, text: 'Talk (1)'},
{value: 2, text: 'User (2)'},
{value: 3, text: 'User talk (3)'},
{value: 4, text: 'Project (4)'},
{value: 5, text: 'Project talk (5)'},
{value: 6, text: 'File (6)'},
{value: 100, text: 'Portal (100)'}
];
 
namespaces.forEach(function(ns) {
var $item = $('<div>').css({
display: 'flex',
alignItems: 'center',
gap: '5px',
padding: '5px',
backgroundColor: '#f8f9fa',
borderRadius: '3px'
});
 
var $checkbox = $('<input>').attr({
type: 'checkbox',
id: 'ns-' + ns.value,
value: ns.value
});
 
var $itemLabel = $('<label>').attr('for', 'ns-' + ns.value).text(ns.text).css({
fontSize: '12px'
});
 
$item.append($checkbox, $itemLabel);
$grid.append($item);
});
 
$group.append($label, $grid);
return $group;
}
 
function createButtoncreateCheckField(textlabel, onclick, typeid) {
var colors$field = {$('<div class="wec-field">');
var $wrapper = primary$('<label>').css({display: {bg'flex', alignItems: '#0645adcenter', colorgap: '#fff5px'},);
var $checkbox = danger: $('<input>').attr({bgtype: '#d33checkbox', colorid: '#fff'id},);
$wrapper.append($checkbox, $('<span>').text(label));
default: {bg: '#f8f9fa', color: '#333'}
}$field.append($wrapper);
return $field;
 
var style = colors[type] || colors.default;
 
return $('<button>').text(text).css({
backgroundColor: style.bg,
color: style.color,
border: '1px solid ' + (type === 'default' ? '#ccc' : style.bg),
padding: '8px 16px',
borderRadius: '4px',
cursor: 'pointer',
fontSize: '14px',
margin: '0 5px'
}).click(onclick);
}
 
// Button management functions
function addButton() {
var buttonDatadata = getFormDatacollectFormData();
if (!buttonDatadata.id || !buttonDatadata.label) {
alert('Button ID and Label are required!');
return;
}
 
if (buttons.some(function(b) { return b.id === data.id; })) {
// Check for duplicate IDs
if (editingIndex === -1 && buttons.some(function(b) { return b.id === buttonData.id; })) {
alert('Button ID must be unique!');
return;
}
 
if buttons.push(editingIndex >= 0data) {;
updateButtonList();
buttons[editingIndex] = buttonData;
editingIndex = -1;
} else {
buttons.push(buttonData);
}
 
updateButtonsList();
clearForm();
}
 
function getFormDatacollectFormData() {
var data = {
id: $('#buttonwec-id').val(),
label: $('#buttonwec-label').val(),
type: $('#buttonwec-type').val()
};
 
// Optional fields
var tooltipoptionalFields = $('#button-tooltip').val();{
if (tooltip) data.tooltip = 'wec-tooltip': 'tooltip;',
'wec-icon': 'icon',
'wec-before': 'insertBefore',
'wec-sample': 'sampleText',
'wec-after': 'insertAfter',
'wec-promptmsg': 'promptMessage',
'wec-summarytext': 'summaryText',
'wec-ns': 'namespaces'
};
 
var icon = $Object.keys('#button-icon'optionalFields).valforEach(function(fieldId); {
if (icon) data.icon var value = icon$('#' + fieldId).val();
if (value) {
var key = optionalFields[fieldId];
if (key === 'namespaces') {
data[key] = value.split(',').map(function(n) {
return parseInt(n.trim());
}).filter(function(n) { return !isNaN(n); });
} else {
data[key] = value;
}
}
});
 
// TextHandle insertionprompt
var insertBefore =if ($('#insertwec-beforeprompt').valis(':checked'); && data.promptMessage) {
if (insertBefore) data.insertBefore = insertBefore;
 
var sampleText = $('#sample-text').val();
if (sampleText) data.sampleText = sampleText;
 
var insertAfter = $('#insert-after').val();
if (insertAfter) data.insertAfter = insertAfter;
 
var placeholderPattern = $('#placeholder-pattern').val();
if (placeholderPattern && placeholderPattern !== '{input}') {
data.placeholderPattern = placeholderPattern;
}
 
// Prompt configuration
if ($('#has-prompt').is(':checked')) {
data.prompt = {
type: $('#prompt-typesimple').val(),
message: $('#prompt-message')data.val() || 'Enter your input:'promptMessage
};
delete data.promptMessage;
 
var promptTitle = $('#prompt-title').val();
if (promptTitle) data.prompt.title = promptTitle;
 
var promptDefault = $('#prompt-default').val();
if (promptDefault) data.prompt.defaultValue = promptDefault;
}
 
// AutoHandle auto summary
if ($('#has-autowec-summary').is(':checked') && data.summaryText) {
data.autoSummary = {
summary: $('#summary-text')data.val() || 'Auto summary'summaryText,
position: $('#summary-positionappend').val(),
delimiter: $('#summary-delimiter').val() || '; '
};
delete data.summaryText;
 
if ($('#summary-use-placeholder').is(':checked')) {
data.autoSummary.usePlaceholder = true;
data.autoSummary.placeholderPattern = placeholderPattern || '{input}';
}
}
 
// Namespaces
var namespaces = [];
$('input[id^="ns-"]:checked').each(function() {
namespaces.push(parseInt($(this).val()));
});
if (namespaces.length > 0) data.namespaces = namespaces;
 
// Page filters
var pageFilters = $('#page-filters').val()
.split('\n')
.map(function(f) { return f.trim(); })
.filter(function(f) { return f; });
if (pageFilters.length > 0) data.pageFilters = pageFilters;
 
return data;
}
 
function updateButtonsListupdateButtonList() {
var $list = $('#buttonswec-list');
$list.empty();
 
if (buttons.length === 0) {
$list.htmltext('<p style="text-align: center; color: #666; font-style: italic;">No buttons added yet</p>');
return;
}
 
var html = buttons.mapforEach(function(buttonbtn, indexi) {
var safeLabel$item = $('<div class="wec-item">').text(button.label).html();
var safeId$title = $('<divstrong>').text(buttonbtn.label + ' (' + btn.id + ').html(');
var safeTooltip$type = button.tooltip ? $('<divspan>').text(button' - ' + btn.tooltiptype).htmlcss() :'color', '#666');
var $deleteBtn = $('<button class="wec-btn wec-btn-danger">').text('Delete').click(function() {
if (confirm('Delete this button?')) {
buttons.splice(i, 1);
updateButtonList();
}
});
$item.append($title, $type, $('<br>'), $deleteBtn);
return '<div style="background: #fff; border: 1px solid #ddd; border-radius: 4px; padding: 10px; margin-bottom: 8px;">' +
$list.append($item);
'<h4 style="margin: 0 0 5px 0; color: #333;">' + safeLabel + ' (' + safeId + ')</h4>' +
});
'<p style="margin: 0 0 10px 0; color: #666; font-size: 12px;">Type: ' + button.type + (safeTooltip ? ' • ' + safeTooltip : '') + '</p>' +
'<button onclick="editButton(' + index + ')" style="background: #0645ad; color: #fff; border: none; padding: 4px 8px; border-radius: 3px; margin-right: 5px; cursor: pointer;">Edit</button>' +
'<button onclick="deleteButton(' + index + ')" style="background: #d33; color: #fff; border: none; padding: 4px 8px; border-radius: 3px; cursor: pointer;">Delete</button>' +
'</div>';
}).join('');
 
$list.html(html);
}
 
Line 609 ⟶ 284:
}
});
$('#placeholderwec-patterntype').val('{input}ooui');
$('#summary-delimiter').val('; ');
editingIndex = -1;
}
 
function generateJSONclearAll() {
if (confirm('Clear all buttons?')) {
buttons = [];
updateButtonList();
}
}
 
function generateJson() {
var config = {
defaults: {defaults,
sectionbuttons: $('#default-section')buttons.valmap(function(btn), {
group:// $('#default-group').val(),Escape newlines for JSON storage
type:var "ooui",processed = JSON.parse(JSON.stringify(btn));
autoSummary:['insertBefore', 'insertAfter', 'sampleText'].forEach(function(field) {
position:if "append",(processed[field]) {
delimiter: "; " processed[field] = processed[field].replace(/\n/g, '\\n');
}
},);
buttons: buttons return processed;
})
};
 
var $('#wec-json = ').val(JSON.stringify(config, null, 2));
$('#json-output').val(json);
}
 
function copyJSONcopyJson() {
var $jsonOutputtextarea = $document.getElementById('#jsonwec-outputjson');
textarea.select();
if (navigator.clipboard && navigator.clipboard.writeText) {
try {
navigator.clipboard.writeText($jsonOutput.val()).then(function() {
alert('JSON copied to clipboard!');
}).catch(function() {
// Fallback to older method
$jsonOutput.select();
document.execCommand('copy');
alert('JSON copied to clipboard!');
});
} else {
// Fallback for older browsers
$jsonOutput.select();
document.execCommand('copy');
alert('JSON copiedCopied to clipboard!');
} catch (e) {
alert('Copy failed. Please select and copy manually.');
}
}
Line 654 ⟶ 326:
var username = mw.config.get('wgUserName');
if (!username) {
alert('You must be logged in to save to your user page.');
return;
}
 
var json = $('#jsonwec-outputjson').val();
if (!json || json.indexOf('{') =!== 'Click "Generate JSON" to see your configuration'0) {
alert('Please generate JSON first!');
return;
}
 
var pageName = 'User:' + username + '/Data/WikiEditorButtons.json';
var api = new mw.Api();
 
api.postWithToken('csrf', {
action: 'edit',
title: pageName'User:' + username + '/Data/WikiEditorToolbarConfig.json',
text: json,
summary: 'Updated WikiEditor button configuration',
contentmodel: 'json'
}).done(function() {
alert('Configuration saved to ' + pageName + 'successfully!');
}).fail(function(error) {
alert('ErrorSave savingfailed. configuration:Please try again.' + error);
});
}
Line 684 ⟶ 354:
if (!username) return;
 
var pageName = 'User:' + username + '/Data/WikiEditorButtons.json';
var api = new mw.Api();
 
api.get({
action: 'query',
titles: pageName'User:' + username + '/Data/WikiEditorToolbarConfig.json',
prop: 'revisions',
rvprop: 'content',
Line 700 ⟶ 368:
var config = JSON.parse(content);
if (config.buttons && Array.isArray(config.buttons)) {
buttons// =Unescape config.buttons;newlines for editing
updateButtonsListbuttons = config.buttons.map(function(btn); {
['insertBefore', 'insertAfter', 'sampleText'].forEach(function(field) {
if (btn[field]) {
btn[field] = btn[field].replace(/\\n/g, '\n');
}
});
return btn;
});
updateButtonList();
}
 
if (config.defaults) {
if (config.defaults.section) $('#default-section').val(= config.defaults.section);
if (config.defaults.group) $('#default-group').val(config.defaults.group);
}
} catch (e) {
Line 716 ⟶ 391:
}
 
// Initialize
function loadExample() {
buttons = [
{
"id": "welcome-template",
"label": "Welcome",
"tooltip": "Welcome new user",
"icon": "userAvatar",
"type": "ooui",
"insertBefore": "== Welcome! ==
 
Hi Polygnotus/Scripts! I noticed [[Special:Contributions/Polygnotus/Scripts|your contributions]] and wanted to welcome you to the Wikipedia community. I hope you like it here and decide to stay.
 
As you get started, you may find this short tutorial helpful:
 
{{Clickable button|Help:Introduction|Learn more about editing|class=mw-ui-progressive|style=margin-left: 1.6em;}}
 
Alternatively, the [[Wikipedia:Contributing to Wikipedia|contributing to Wikipedia]] page covers the same topics.
 
If you have any questions, we have a friendly space where experienced editors can help you here:
 
{{Clickable button|Wikipedia:Teahouse|Get help at the Teahouse|style=margin-left: 1.6em;}}
 
If you are not sure where to help out, you can find a task here:
 
{{Clickable button|Wikipedia:Task Center|Volunteer at the Task Center|style=margin-left: 1.6em;}}
 
Happy editing! <!-- Template:Welcome--> [[User:Polygnotus|Polygnotus]] ([[User talk:Polygnotus|talk]]) 06:50, 7 June 2025 (UTC)",
"autoSummary": {
"summary": "Welcome new user",
"position": "replace"
},
"namespaces": [3]
},
{
"id": "wp-policy-ref",
"label": "WP Policy",
"tooltip": "Reference Wikipedia policy",
"icon": "articles",
"type": "ooui",
"prompt": {
"type": "simple",
"message": "Enter policy abbreviation (e.g., NPOV, V, RS):",
"defaultValue": "NPOV"
},
"insertBefore": "== [[WP:{input}]] ==\nPlease read [[WP:{input}]], thanks! [[User:Polygnotus|Polygnotus]] ([[User talk:Polygnotus|talk]]) 06:50, 7 June 2025 (UTC)",
"placeholderPattern": "{input}",
"autoSummary": {
"summary": "Referenced [[WP:{input}]]",
"usePlaceholder": true,
"placeholderPattern": "{input}"
},
"namespaces": [3]
}
];
updateButtonsList();
alert('Example configuration loaded!');
}
 
// Global functions for button actions
window.editButton = function(index) {
var button = buttons[index];
editingIndex = index;
 
// Fill form with button data
$('#button-id').val(button.id || '');
$('#button-label').val(button.label || '');
$('#button-tooltip').val(button.tooltip || '');
$('#button-type').val(button.type || 'traditional');
$('#button-icon').val(button.icon || '');
$('#insert-before').val(button.insertBefore || '');
$('#sample-text').val(button.sampleText || '');
$('#insert-after').val(button.insertAfter || '');
$('#placeholder-pattern').val(button.placeholderPattern || '{input}');
 
// Prompt
$('#has-prompt').prop('checked', !!button.prompt);
if (button.prompt) {
$('#prompt-type').val(button.prompt.type || 'simple');
$('#prompt-message').val(button.prompt.message || '');
$('#prompt-title').val(button.prompt.title || '');
$('#prompt-default').val(button.prompt.defaultValue || '');
}
 
// Auto summary
$('#has-auto-summary').prop('checked', !!button.autoSummary);
if (button.autoSummary) {
$('#summary-text').val(button.autoSummary.summary || '');
$('#summary-position').val(button.autoSummary.position || 'append');
$('#summary-delimiter').val(button.autoSummary.delimiter || '; ');
$('#summary-use-placeholder').prop('checked', !!button.autoSummary.usePlaceholder);
}
 
// Namespaces
$('input[id^="ns-"]').prop('checked', false);
if (button.namespaces) {
button.namespaces.forEach(function(ns) {
$('#ns-' + ns).prop('checked', true);
});
}
 
// Page filters
$('#page-filters').val(button.pageFilters ? button.pageFilters.join('\n') : '');
};
 
window.deleteButton = function(index) {
if (confirm('Are you sure you want to delete this button?')) {
buttons.splice(index, 1);
updateButtonsList();
}
};
 
// Initialize when DOM is ready
$(function() {
createConfigInterfaceinit();
});