User:Remsense/PortletLinks.js

/*** Portlet Link Manager ***/

// Easily add and manage custom portlet linls // Documentation at en:w:User:BrandonXLF/PortletLinks // By en:w:User:BrandonXLF, tweaked by en:w:User:Remsense

$(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 = $(' ').attr('data-row', '') .append($('')					.append($('') .click(function {							$(this).closest('tr').remove;						}) )					.append( '' )				);

for (i = 0; i < vars.length; i++) { var td = $(' ').appendTo(tr), 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(						$(' ' + areas[j] + ' ')							.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, encodeURIComponent(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 = $(' ').prependTo(mw.util.$content);

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; }' +			'#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($(' ').sortable({items: 'tr:not(.nodrag)', handle: '.drag'}).wrap(' '))				.append(' Remember to save your changes! Your common.js. Your common.css. Show portlets. for the current 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  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($(' <td style="border:1px solid #a2a9b1;text-align:center;" colspan="8"> ').find('td').append($('<span style="display:inline-block;font-size:1.2em;border-radius:100%;background:#888;color:white;width:1em;line-height:1em;height:1em;margin:4px;cursor:pointer;" title="Add">+ ').click(row)).parent);

for (i = 0; i < links.length; i++) row(links[i]); });	} });