Changes

Jump to: navigation, search

User:Corey/common.js

13,429 bytes added, 6 years ago
Created page with "* * Main JS function.: (function(window, $, mw, console, delay) { "use strict"; * * Global objects.: const LAST_LOG = '14:22, 8 March 2018 (UTC)'; const c..."
/**
* Main JS function.
*/
(function(window, $, mw, console, delay) {
"use strict";

/**
* Global objects.
*/

const LAST_LOG = '14:22, 8 March 2018 (UTC)';

const conf = mw.config.get([
'wgNamespaceNumber',
'wgPageName'
]);
$.extend(conf, {
action: mw.util.getParamValue('action'),
api: function(query, callbacks, method) {
return new mw.Api()[method || 'get'](query)
.done(callbacks.done)
.fail(callbacks.fail)
.always(callbacks.always);
}
});

const page = {
hasContent: $('#ca-history').length && conf.wgNamespaceNumber !== -1,
$content: $('#content'),
$mwHead: $('#mw-head'),
$userBar: $('#p-personal').children('ul'),
$leftNav: $('#left-navigation').find('#p-namespaces').children('ul'),
$rightNav: $('#right-navigation').find('#p-views').children('ul'),
$rightMenu: $('#right-navigation').find('#p-cactions').find('ul'),
$star: $('#ca-watch').length ? $('#ca-watch') : $('#ca-unwatch')
};

/** End. */


/**
* Constructors and prototypes.
*/

// ------
// String:
String.prototype.strip = function(c) {
return String(this).replace(new RegExp(c || ' ', 'g'), '');
};

// ------
// Query:
function Query(endpoint, query) {
// query | url | full | endpoint
if($.isPlainObject(endpoint)) {
query = endpoint;
endpoint = undefined;
}
this.query = query || {};
this.url = this.fetch();
this.full = this.extend();
this.endpoint = String(endpoint || '').trim().toLowerCase().strip('.php');
}
// Extend prototype:
$.extend(Query.prototype, {
// "Private" methods:
extend: function() {
return $.extend({}, this.url, this.query);
},
fetch: function(parameters) {
const query = {};
const getValue = function(parameter) {
return query[parameter];
};
const getValues = function(parameters) {
return (Array.isArray(parameters)
? parameters.map(function(v) {
return getValue(v);
})
: getValue(parameters)
);
};
window.location.search.slice(1).split('&').forEach(function(component) {
if(!component.trim()) return;
const parts = component.split('=');
query[window.decodeURIComponent(parts[0])] = window.decodeURIComponent(parts[1] || '');
});
return parameters ? getValues(parameters) : query;
},

// "Getters":
getEndpoint: function() {
return this.endpoint;
},
getQuery: function(type) {
switch((type+'').trim().toLowerCase()) {
case 'full': return this.full;
case 'url': return this.url;
default: return this.query;
}
},

// Other:
print: function(full) {
const query = this.getQuery(full && 'full');
return [
mw.util.wikiScript(this.getEndpoint()),
Object.keys(query).map(function(key) {
return [
window.encodeURIComponent(key),
window.encodeURIComponent(query[key])
].join('=');
}).join('&')
].join('?');
},
});

// Static method:
Query.fetch = Query.prototype.fetch;

// ------
// State:
function State(message) {
this.message = message || 'Pending...';
this.status = 'pending';
}
$.extend(State.prototype, {
getMessage: function() {
return this.message;
},
setMessage: function(m) {
this.message = m || '';
return this;
},
getStatus: function() {
return this.status;
},
setStatus: function(s) { // Private.
this.status = s || '';
return this;
},
pending: function() {
return this.setStatus('pending');
},
done: function() {
return this.setStatus('done');
},
failed: function() {
return this.setStatus('failed');
},
clear: function() {
this.setMessage();
this.setStatus();
return this;
},
reset: function() { // TODO: .assign or something
this.setMessage('Pending...');
this.setStatus('pending');
return this;
},
show: function() {
items.$specialMessages.removeClass('hide')
.children()
.removeClass().addClass(this.getStatus())
.text(this.getMessage());
return this;
}
});

/** End. */


/**
* Utility functions.
*/


/** End. */


/**
* Buttons.
*/

const items = {
$searchBar: $('<li>', {
id: 'pt-search',
html: $('#p-search')
}),
$specialMessages: $('<li>', {
id: 'pt-special-messages',
html: $('<span>', {
id: 'special-messages',
class: 'hide'
})
}),
$userBarBottom: $('<div>', {
id: 'p-bottom'
}),

$diff: $('<li>', {
id: 'ca-diff',
class: 'collapsible',
html: $('<span>', {
html: $('<a>', {
title: 'Last diff for this page.',
text: 'Diff'
})
})
}),
$nullEdit: $('<li>', {
id: 'ca-null',
class: 'collapsible',
html: $('<span>', {
html: $('<a>', {
href: '#',
title: 'Null edit this page.',
text: 'Null'
})
})
}),

$raw: $('<li>', {
id: 'ca-raw',
html: $('<a>', {
href: new Query({
title: conf.wgPageName,
action: 'raw'
}).print(),
title: 'View the raw content.',
text: 'Raw'
})
}),
$safe: $('<li>', {
id: 'ca-safe',
html: $('<a>', {
href: new Query({
title: conf.wgPageName,
safemode: true
}).print(true),
title: 'View the page in safemode.',
text: 'Safe'
})
}),
$debug: $('<li>', {
id: 'ca-debug',
html: $('<a>', {
href: new Query({
title: conf.wgPageName,
debug: true
}).print(true),
title: 'View page in debug mode.',
text: 'Debug'
})
}),
$toggle: $('<li>', {
id: 'ca-toggle',
html: $('<a>', {
href: '#',
title: 'Toggle hidden content.',
text: 'Toggle'
})
})
};

// Change "View history" button label to simply "History".
$('#ca-history').find('a').text('History');

// Move the search bar and add container for special messages to the user bar:
page.$userBar
.prepend(items.$searchBar)
.append(items.$specialMessages);

// Place the buttons for the page inside a container in the user bar:
page.$mwHead.append(
items.$userBarBottom.append(
$('#left-navigation')
).append(
$('#right-navigation')
)
);

// Add user contributions button to the top of the page:
page.$leftNav.append(
$('#t-contributions').attr('id', 'ca-contribs')
.find('a')
.wrap('<span>')
.text('Contributions')
.end()
);

// Extract the buttons from the right "More" menu and place them next to the other ones:
page.$rightMenu.children().each(function() {
const $this = $(this);
page.$rightNav.append(
$this.addClass('collapsible').html(function() {
return $('<span>', {
html: $this.html()
});
})
);
});

// Add null edit button (only when reading the page):
if($('#ca-view.selected').length) {
page.$rightNav.append(items.$nullEdit);
}

// Add button to display raw content and last diff (only if the page has content):
if(page.hasContent) {
page.$rightMenu.append(items.$raw);
$('#ca-history').after(items.$diff);
}

// Add a safemode button and a toggel button to the right "More" menu:
page.$rightMenu
.append(items.$safe)
.append(items.$debug)
.append(items.$toggle);

// Place the (un)watch star in the last spot.
page.$rightNav.append(page.$star);

/** End. */


/**
* Procedures.
*/

// Adapt the top buttons to the diff pages: ("prettyfy")
$(function selectDiffButton() {
if(Query.fetch('diff')) {
$('#ca-diff').addClass('selected');
$('#ca-view').removeClass('selected');
}
});

// Get lastest diff link:
$(function getLatestDiffLink() {
const mainFunctionName = 'getLatestDiffLink'; //arguments.callee.name;
const query = {
action: 'query',
prop: 'revisions',
titles: conf.wgPageName,
rvprop: 'ids|user|timestamp|size|parsedcomment|flags',
rvlimit: 2,
formatversion: 2,
format: 'json'
};
const callbacks = {
done: function(data) {
try {
const currentRevision = data.query.pages[0].revisions[0];
items.$diff.off('click')
.find('a')
.attr('href', new Query({
diff: currentRevision.revid
}).print());
} catch(e) {
console.log('%c«' + mainFunctionName + '()» error!', 'color: red;');
if(e instanceof TypeError) {
console.log("%cCan't get diff!", 'color: red;', '(known)');
} else {
console.error(e);
}
console.log(new Query('api', query).print(), data);
return;
}
},
fail: console.log,
always: function() {
console.log('%cDiff getter loaded!', 'color: blue;');
}
};
return conf.api(query, callbacks);
});

// Toggle stuff I've hidden:
$(function toggleWhatIHaveHidden() {
[ // Add toggle class to all selectors:
'#siteNotice', '#editpage-copywarn',
'.mw-editTools', '.smw-editpage-help',
'#n-Twitter', '#n-Facebook', '#p-random'
].forEach(function(selector) {
$(selector).addClass('toggle');
});
});

// Automatically fill Special:Upload page for card images:
$(function makeUploadingCardImagesEasier() {

// Get the card name on the galleries and place it on upload links:
(function getName(MutationObserver, encode) {

// Only for "Card Gallery" and "Set Card Galleries" namespaces:
if(![3004, 3024].includes(conf.wgNamespaceNumber)) {
return;
}

// Function to guess the card name
// and append it to the empty galleries' links:
const guessCardName = function() {
$('.gallerybox').each(function() {
const $this = $(this);
const cardName = (function() {
var brFlag = false;
if(conf.wgNamespaceNumber === 3004) {
// Card galleries:
const $navBoxHeader = $('.navbox-title').children('div');
return $navBoxHeader.text() + $navBoxHeader.find('a').attr('title').replace(/.+?( \(.*\))?/g, function(_, $1) {
return $1 || '';
});
} else {
// Set galleries:
return $this.find('.gallerytext').find('p').contents().filter(function() {
const isBR = this.nodeName === 'BR';
brFlag = isBR ? !brFlag : brFlag;
return brFlag && !isBR;
}).filter('a').first().text();
}
})();

// Append the name to the url, in the form of «_name=cardName»:
$this.find('.noFile').attr('href', function(_, href) {
return [
href,
[
'_name',
encode(cardName)
].join('=')
].join('&');
});
});
};

// Execute guessing the card name:
guessCardName();

// Check if there were changes in the DOM
// to keep the links with the card name in there (when previewing edits, etc.):
if(MutationObserver && ['edit', 'submit'].includes(conf.action)) {

// Wait for the editor to load:
mw.loader.using('jquery.wikiEditor').then(function() {

// (jQuery) Node to observe:
const $targetNode = $('.wikiEditor-ui-view-preview').find('.wikiEditor-preview-contents');

// Options for the observer (which mutations to observe).
// We only want to see when content is loaded from the backend
// and then appended.
// Therefore, observe when new child nodes are placed or removed:
const options = {
childList: true
};

// Create an observer instance and observe:
new MutationObserver(function(mutationsList) {
// No need to iterate over mutationList,
// since we just want to execute the following function once.
delay(function() {
guessCardName();
});
}).observe($targetNode[0], options);

});

}

})(window.MutationObserver, window.encodeURIComponent);

// Populate Special:Upload descrption with the name from the url:
(function populate(name) {

// Fill in the upload description box at Special:Upload:
$('#wpUploadDescription').val(
name ? '{{OCG-TCG card image\n| name = ' + name + '\n}}' : null
);

})(Query.fetch('_name'));

});

/** End. */


/**
* Events.
*/

// Diff:
items.$diff.click(function(e) {
// Prevent default event:
e.preventDefault();
// Display state as failed: (if successfull, the Api request done() will "off" this event.)
new State('Failed to get diff!').failed().show();
});

// Null edit:
items.$nullEdit.click(function(e) {
// Prevent default event:
e.preventDefault();
// Request state:
const state = new State('Null editing...').show();
// Request:
const query = {
action: 'edit',
title: conf.wgPageName,
token: mw.user.tokens.get('editToken'),
summary: 'Something bad happened!',
prependtext: ''
};
const callbacks = {
done: function() {
state.done().setMessage('Null edited!');
page.$content.load(window.location.href + ' #content > *');
},
fail: function(message, errorObject) {
console.log('%cNull edit error!', 'color: red;', '(message, errorObject)');
console.log(message, errorObject);
state.failed().setMessage('Null edit failed! (' + (message === 'http'
? errorObject.textStatus
: message
) + ')');
},
always: function() {
state.show();
}
};
const method = 'post';
return conf.api(query, callbacks, method);
});

// Toggle:
items.$toggle.click(function(e) {
e.preventDefault();
$('.toggle').toggle();
});

/** End. */


/**
* Return.
*/

console.log(
'%cUser Common.js loaded! Last version from ' + LAST_LOG + '.',
'color: blue;'
);

return true;

/** End. */

})(window, window.jQuery, window.mediaWiki, window.console, (function(window, $) {
"use strict";
return function(t, fn) {
if(!fn && $.isFunction(t)) {
fn = t;
t = undefined;
}
return window.setTimeout(fn, t);
};
})(window, window.jQuery));
/** End. */
autopatrol, Check users, System administrator, Administrators
59
edits

Navigation menu