User:Saftzie/ui.wikimarks.js
ShoutWiki — express yourself and be heard!
Jump to navigation
Jump to search
Note: After saving, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
/**
* Implement a bookmark menu
* Attach it to the portlet bar
* Add and delete menu items through the module interface
*
* Version 0.4: 28 Sep 2016
* Development version for ShoutWiki
*/
((window.user = window.user || {}).ui = user.ui || {}).wikimarks =
user.ui.wikimarks || (function (mw, $) {
'use strict';
var
self = {
add: add,
message: new Date().toISOString() + ' Initializing',
version: '0.4.2, 25 Nov 2019'
},
has = Object.prototype.hasOwnProperty,
wgArticlePath = mw.config.get('wgArticlePath'),
wgPageName = mw.config.get('wgPageName').replace(/_/g, ' '),
urlAPI = mw.config.get('wgScriptPath') + '/api.php',
wikiDomain, config, ul;
// make a scriptlet mark
// closures should work
// text: string
// js: function
function makeMarklet(o) {
var
t = $('<li><a>' + o.text + '</a></li>');
$('a', t).click(o.js);
return t;
}
// make an article mark
// text: string (optional, default: article value)
// article: string (optional, default: current article) =
// [u:wiki:][namespace:]title
// query: object (optional, default: none) =
// {name: value, name: value, ...}
// fragment: string (optional, default: none)
function makeMark(o) {
var
h, i, t;
if (typeof o.article === 'string') {
// parse article
t = o.article.split(':');
if (t[0] === 'u') {
h = '//' + t[1] + wikiDomain;
t = t.splice(2).join(':');
} else {
h = '';
t = o.article;
}
h += wgArticlePath.replace('$1', encodeURI(t.replace(/\s/g, '_')));
} else {
// article defaults to current
o.article = mw.config.get('wgPageName').replace(/_/g, ' ');
h = location.pathname;
}
if (typeof o.query === 'object') {
// parse query
t = '';
for ( i in o.query ) {
if (has.call(o.query, i) &&
((typeof o.query[i] === 'number') ||
(typeof o.query[i] === 'string'))) {
t += (t.length ? '&' : '?') + encodeURIComponent(i) + '=';
if (typeof o.query[i] === 'number') {
t += o.query[i].toString();
} else {
t += encodeURIComponent(o.query[i].replace(/\s/g, '+'));
}
}
}
h += t;
}
if ((typeof o.fragment === 'string') && o.fragment.length) {
// parse fragment
h += '#' + encodeURIComponent(o.fragment.replace(/\s/g, '_'));
}
return $(
'<li><a href="' + h + '">' +
(o.text ? o.text : o.article) +
'</a></li>'
);
}
// add wikimarks
// m = array of objects (or one object)
// each object is one wikimark config
function add(m) {
var
li = $(),
i, t;
if (!$.isArray(m)) {
m = [m];
}
li = $();
for ( i = 0; i < m.length; ++i ) {
t = typeof m[i];
if (t === 'object') {
if (typeof m[i].script === 'string') {
// mw script
// text: string
// script: string = api|index|...
// query: object (optional) = {name: value, name: value, ...}
// TODO: implement
} else if (typeof m[i].url === 'string') {
// url
// text: string
// url: string
// TODO: implement
} else if ((typeof m[i].js === 'function') &&
(typeof m[i].text === 'string') && m[i].text.length) {
// JavaScript
li = li.add(makeMarklet(m[i]));
} else {
// article
li = li.add(makeMark(m[i]));
}
} else {
self.message += '\n' + new Date().toISOString() +
' add :: unsupported type : ' + i + ' is ' + t;
}
}
if (li.length && !config) {
config = true;
ul.empty();
}
ul.append(li);
self.message += '\n' + new Date().toISOString() +
' add :: added wikimarks : ' + li.length;
}
// purge and refresh the page
function onPurge() {
$.post(urlAPI, {
format: 'none',
action: 'purge',
titles: wgPageName
}, function () {
location.reload();
});
}
// null edit the page
function onNullEdit() {
$.post(urlAPI, {
format: 'json',
action: 'query',
prop: 'revisions',
rvprop: 'content|timestamp',
titles: wgPageName
}, function (data) {
var
id, content;
if ((data = data.query) && (data = data.pages)) {
for (id in data) {
if (data.hasOwnProperty(id)) {
if ((content = data[id].revisions) && (content = content[0])) {
$.post(urlAPI, {
format: 'none',
action: 'edit',
pageid: id,
text: content['*'],
basetimestamp: content.timestamp,
token: mw.user.tokens.get('csrfToken')
});
}
}
}
}
});
}
// init wikimarks
function init() {
ul.empty();
// Special: doesn't get purge or null edit
if (mw.config.get('wgNamespaceNumber') < 0) {
config = false;
ul.append(
'<li><a class="js-wikimarks-a">' +
'No wikimarks configured' +
'</a></li>'
);
} else {
config = true;
ul.append(makeMarklet({
text: 'Purge',
js: onPurge
}));
ul.append(makeMarklet({
text: 'Null edit',
js: onNullEdit
}));
}
}
// main
(function () {
var
wgSkin = mw.config.get('skin'),
pt =
'<a class="js-wikimarks-a">Wikimarks</a>' +
'<div id="js-wikimarks-list"><ul></ul></div>';
// support generic MediaWiki skins only
switch (wgSkin) {
case 'cologneblue':
pt = $(String.prototype.concat(
'<span id="pt-wikimarks">',
pt,
'</span>'
)).add(document.createTextNode(' | '));
break;
case 'modern':
case 'monobook':
case 'vector':
pt = $(String.prototype.concat(
'<li id="pt-wikimarks">',
pt,
'</li>'
));
break;
default:
self.message += '\n' + new Date().toISOString() +
' main :: unsupported skin : ' + wgSkin;
delete self.add;
return;
}
// insert the menu into the DOM
ul = pt.find('ul');
init();
$(function () {
$('#pt-logout').before(pt);
});
// reduce the server name to just the domain
wikiDomain = mw.config.get('wgServerName').split('.');
while (wikiDomain.length > 2) {
wikiDomain.shift();
}
wikiDomain = '.' + wikiDomain.join('.');
}());
return self;
}(mediaWiki, jQuery));