User:BrandonXLF/PortletLinks.js
/*** Portlet Link Manager ***/
// Easily add and manage custom portlet linls
// Documentation at en:w:User:BrandonXLF/PortletLinks
// By en:w:User:BrandonXLF
$(function() {
var vars = ['area', 'url', 'text', 'title', 'id', 'nnode', 'key'],
areas = [
'p-cactions',
'p-personal',
'p-personal-sticky-header',
'p-views',
'p-tb',
'left-navigation',
'p-navigation',
'p-interaction',
'footer',
'footer-places'
],
i = 0,
links = JSON.parse(mw.user.options.get('userjs-portletmanager') || '[]');
function randHex() {
return Math.floor(Math.random() * 256).toString(16).padStart(2, '0');
}
function randColor() {
return '#' + randHex() + randHex() + randHex();
}
function startedit(e) {
e.stopPropagation();
$('.plm .focused').removeClass('focused');
var el = $(this);
$('#largeeditor').val(el.val()).off('input keypress paste click').attr('placeholder', '');
$('#largeeditor').on('input keypress paste', function() {
el.addClass('focused');
el.val(this.value);
});
$('#largeeditor').on('click', function(e) {
e.stopPropagation();
el.addClass('focused');
});
}
function syncedit() {
if ($(this).is(':focus')) {
$('#largeeditor').val(this.value);
}
}
function row(link) {
var i = 0,
j = 0,
tr = $('
.append($('
.append($('')
.click(function() {
$(this).closest('tr').remove();
})
)
.append(
''
)
);
for (i = 0; i < vars.length; i++) {
var td = $('
input = vars[i] === 'area'
? $('
: $('')
.val(link ? link[vars[i]] : '')
.css('width', '100%')
.click(startedit);
input
.on('input keypress paste', syncedit)
.attr('data-name', vars[i])
.appendTo(td);
if (vars[i] === 'area') {
for (j = 0; j < areas.length; j++)
td.children().append(
$('')
.attr('selected', areas[j] == link.area ? '' : null)
);
}
if (vars[i] == 'key')
td.children().css('width', '3em');
}
$('#editor tr:last').before(tr);
}
function addLinks() {
var link;
$('.plm-portletitem').remove();
for (i = 0; i < links.length; i++) {
link = links[i];
try {
var linkEl = mw.util.addPortletLink(
link.area,
/^(https|http|):?\/\/.*/.exec(link.url)
? link.url.replace(/\$PAGENAME\$/g, encodeURIComponent(mw.config.get('wgPageName')))
: mw.util.getUrl(link.url.replace(/\$PAGENAME\$/g, mw.config.get('wgPageName'))),
link.text,
link.id || 'plm-portletitem-' + (i + 1),
link.title,
link.key,
link.nnode
);
linkEl.className += ' plm-portletitem';
} catch (e) {
console.error('PortletLinks.js: Unable to add portlet link to #' + link.area + ' for ' + link.url);
}
}
link = mw.util.addPortletLink('p-navigation', mw.util.getUrl('Special:BlankPage/PortletManager'), '(edit portlet links)');
if (link) link.className += ' plm-portletitem';
}
function save() {
var el = this;
links = [];
$('#editor').find('[data-row]').each(function() {
var item = {};
$(this).find('[data-name]').each(function() {
item[this.getAttribute('data-name')] = this.value;
});
links.push(item);
});
el.src = 'https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif';
el.title = 'Saving...';
el.style.cursor = 'initial';
mw.user.options.set('userjs-portletmanager', JSON.stringify(links));
new mw.Api()
.saveOption('userjs-portletmanager', JSON.stringify(links))
.done(function(r) {
addLinks();
el.src = 'https://upload.wikimedia.org/wikipedia/commons/9/97/PICOL_icon_Floppy_disk.svg';
el.title = 'Save';
el.style.cursor = 'Pointer';
mw.notify(
r.options == 'success'
? 'Saved portlet links successfully!'
: 'An error occurred while saving.',
{
tag: 'portletlinks',
type: r.options == 'success' ? 'notice' : 'error'
}
);
})
.fail(function() {
el.src = 'https://upload.wikimedia.org/wikipedia/commons/9/97/PICOL_icon_Floppy_disk.svg';
el.title = 'Save';
el.style.cursor = 'Pointer';
mw.notify(
'An error occurred while saving.',
{
tag: 'portletlinks',
type: 'error'
}
);
});
}
addLinks();
if (window.location.search.includes('showportlets=true')) {
var el = $('
for (i = 0; i < areas.length; i ++) {
var color = randColor();
$('#' + areas[i]).css({outline: '2px solid ' + color, outlineOffset: Math.round(Math.random() * 2) - 4 + 'px'});
el.append($('
.css({
border: '1px solid #000',
display: 'inline-block',
width: '1em',
height: '1em',
background: color,
marginRight: '5px',
verticalAlign: 'middle',
marginBottom: '5px'
}))
.append($('
.text(areas[i])
.css({
marginRight: '5px',
verticalAlign: 'middle',
marginBottom: '5px',
display: 'inline-block'
})
);
mw.util.addPortletLink(areas[i], '#', areas[i].toUpperCase());
}
}
if (mw.config.get('wgPageName') === 'Special:BlankPage/PortletManager') {
document.title = 'Manage custom portlet links - ' + mw.config.get('wgSiteName');
mw.util.addCSS(
'.plm input:focus, .plm select:focus, .plm textarea:focus, .plm .focused { outline:0; border-color: #36c; box-shadow: inset 0 0 0 1px #36c; }' +
'.plm button, .plm input, .plm select { border: 1px solid #888; padding: 4px; box-sizing: border-box; }' +
'.plm select { padding: 3px 4px; max-width: 10em; }' +
'#editor th { border: 1px solid #888; padding: 2px; }'
);
$(document).click(function() {
$('.plm .focused').removeClass('focused');
$('#largeeditor').off('input keypress paste click').val('').attr('placeholder', 'Select a cell to edit it.');
});
mw.loader.getScript('https://code.jquery.com/ui/1.12.1/jquery-ui.min.js').then(function() {
mw.util.$content.find('.mw-body-content').empty()
.addClass('plm')
.append('
Manage custom portlet links
').append($('
Area | URL | Text | Tooltip | ID | Next node | Key |
---|
.append('
Remember to save your changes! Your common.js. Your common.css. Show portlets.
Area | The portlet link region to add the link. |
---|---|
URL | The target URL of the link. Use $PAGENAME$ for the current URL-friendly full page name. Use // to link to a full URL. |
Text | The text to show as the link. There is no default. |
ID | The ID of the link HTML element. |
Tooltip | Tooltip (title) to show for the link. |
Next node | CSS selector for the node that comes after the link. Use selector + * to have the selector be the previous node. |
Key | The access key for the link. See the article on access keys for more information. |
$('#savecell').click(save);
$('#editor').append($('
for (i = 0; i < links.length; i++) row(links[i]);
});
}
});