Usuario:TwinkleUser/wikiwatch.js
Nota: Después de guardar, debes refrescar la caché de tu navegador para ver los cambios. Internet Explorer: mantén presionada Ctrl mientras pulsas Actualizar. Firefox: mientras presionas Mayús pulsas el botón Actualizar, (o presiona Ctrl-Shift-R). Los usuarios de Google Chrome y Safari pueden simplemente pulsar el botón Recargar. Para más detalles e instrucciones acerca de otros exploradores, véase Ayuda:Cómo limpiar la caché.
// <pre><nowiki>
// ==UserScript==
// @name wikiWatch
// @namespace http://en.wikipedia.org/wiki/User:Cacycle/
// @description A MediaWiki watchlist and recent changes tool that sorts into namespaces, adds unwatch links, and auto-expands entries
// @include *
// @exclude
//
// @homepage http://en.wikipedia.org/wiki/User:Cacycle/wikiWatch
// @source http://en.wikipedia.org/wiki/User:Cacycle/wikiWatch.js
// @author Cacycle (http://en.wikipedia.org/wiki/User:Cacycle)
// @license Released into the public domain
// @version 0.9.4
// ==/UserScript==
//
// add wrapped wikiWatch code to body in order to access and use page scripts and variables under Greasemonkey
//
// start of global code wrapper
if (typeof(wwInstalledFlag) == 'undefined') { window.wwInstalledFlag = false; }
window.WWWrapper = function() {
window.wwInstalledFlag = true;
if (typeof(wwSetupFlag) == 'undefined') { window.wwSetupFlag = false; }
var wwOpenPopup;
var wwEditDivs = [];
//
// WWMain: wikiWatch setup
//
window.WWMain = function() {
WWRemoveEventListener(window, 'load', WWMain, false);
// check if this has already been run, either as a wiki gadget, wiki user script, or a Greasemonkey user script
if (wwSetupFlag == true) {
return;
}
wwSetupFlag = true;
// customizable definitions
// number of most recent entries in short display
var wwRecentShort = wwRecentShort || 15;
// texts
var WWText = WWText || {
'WWRecentAll': 'Todos',
'WWRecentAllToggle': '<span class="WWToggle" title="Toggle the display of all entries">(<a style="cursor: pointer;" onclick="javascript:{document.getElementById(\'WWSectionBlock-1-{day}\').style.display=\'block\';document.getElementById(\'WWSectionBlock-2-{day}\').style.display=\'none\';}">mostrar más recientes</a>)</span>',
'WWRecentTop': 'Todos',
'WWRecentTopToggle': '<span class="WWToggle" title="Toggle the display of all entries">(<a style="cursor: pointer;" onclick="document.getElementById(\'WWSectionBlock-2-{day}\').style.display=\'block\';document.getElementById(\'WWSectionBlock-1-{day}\').style.display=\'none\';">mostrar todos</a>)</span>',
'WWUnwatch': 'borrar'
};
// css styles
var WWCss = WWCss ||
'.WWToggle { font-weight: normal; }' +
'.WWSectionFooter { margin-left: 0.5em; }' +
'.WWDayHeading { background-color: #c0c0c0; border: gray solid 1px; margin: 1.25em 0 0.75em 0 !important; padding: 0 2em; }' +
'.WWSectionHeading { margin: 0 0 0.5em 0; padding: 0 0 0.75em 0.5em; }' +
'.WWSectionBlock { margin: 0 0 0.75em 0; }' +
'.WWSection { border: gray solid 1px; padding: 0 0.5em 0.75em 0.5em; }' +
'.WWSection > H5 { padding-top: 0.3em; padding-bottom: 0; }' +
'.WWPopup { display: block; padding: 0 1em 1.5em 2em; position: absolute; left: 17em; right: 1em; border: 1px solid black; border-top: none; border-right: 1px solid gray; }' +
'.WWPopup TT { display: none; }' +
'.WWDebug { display: none; position: static; margin-top: 3em; margin-left: 10em; zIndex: 1000000;}' +
// 'TD': 'text-indent: -2em; padding-left: 2em;',
'.WWSection-1, .WWSection-1 DIV { background-color: #f8fcff; }' +
'.WWSection-2, .WWSection-2 DIV { background-color: #f8fcff; }' +
'.WWSection0, .WWSection0 DIV { background-color: #ffffff; }' +
'.WWSection1, .WWSection1 DIV { background-color: #f2f2f2; }' +
'.WWSection2, .WWSection2 DIV { background-color: #e5e5e5; }' +
'.WWSection3, .WWSection3 DIV { background-color: #d0d0d0; }' +
// colors: HSB 40°-5%-100% (light), 40°-5%-95% (dark), 40° steps
'.WWSection4, .WWSection4 DIV { background-color: #fffbf2; }' +
'.WWSection5, .WWSection5 DIV { background-color: #f2eee6; }' +
'.WWSection6, .WWSection6 DIV { background-color: #fbfff2; }' +
'.WWSection7, .WWSection7 DIV { background-color: #eef2e6; }' +
'.WWSection8, .WWSection8 DIV { background-color: #f2fff2; }' +
'.WWSection9, .WWSection9 DIV { background-color: #e6f2e6; }' +
'.WWSection10, .WWSection10 DIV { background-color: #f2fffb; }' +
'.WWSection11, .WWSection11 DIV { background-color: #e6f2ee; }' +
'.WWSection12, .WWSection12 DIV { background-color: #f2fbff; }' +
'.WWSection13, .WWSection13 DIV { background-color: #e6eef2; }' +
'.WWSection14, .WWSection14 DIV { background-color: #f2f2ff; }' +
'.WWSection15, .WWSection15 DIV { background-color: #e6e6f2; }' +
'.WWSection16, .WWSection16 DIV { background-color: #fbf2ff; }' +
'.WWSection17, .WWSection17 DIV { background-color: #eee6f2; }' +
'.WWSection18, .WWSection18 DIV { background-color: #fff2fb; }' +
'.WWSection19, .WWSection19 DIV { background-color: #f2e6ee; }' +
'.WWSection20, .WWSection20 DIV { background-color: #fff2f2; }' +
'.WWSection21, .WWSection21 DIV { background-color: #f2e6e6; }' +
'.WWSection22, .WWSection22 DIV { background-color: #fff2fb; }' +
'.WWSection23, .WWSection23 DIV { background-color: #f2e6ee; }'
;
// add stylesheet definitions
var styles = new WWStyleSheet();
styles.addRules(WWCss);
var regExpMatch;
// get watchlist block
var sectionBlockIds = [];
var regExpWatchlist = new RegExp('(<select\\b[^>]*?\\bid="?namespace"?[^>]*>(.|\\s)*?)(<h4\\b[^>]*>(.|\\s)*?)(<div\\b[^>]*?\\bclass="?printfooter"?[^>]*>)', 'i');
// get the smallest container to replace for compatibility
var container = document.body;
var watchlistElement = document.getElementById('watchlist-message');
if (watchlistElement != null) {
container = watchlistElement.parentNode;
}
else {
watchlistElement = document.getElementById('recentchangestext');
if (watchlistElement != null) {
container = watchlistElement.parentNode;
}
}
// replace watchlist container
container.innerHTML = container.innerHTML.replace(regExpWatchlist,
function (p, p1, p2, p3, p4, p5) {
var namespaceBlock = p1;
var watchlistBlock = p3;
var pageBottom = p5;
// add unwatch links
if (wgCanonicalSpecialPageName == 'Watchlist') {
// 12 link 2 action3 3 4 41
watchlistBlock = watchlistBlock.replace(/((<a href=\"?[^\"]*?&action=)history(\b[^\" ]*\"?[^>]*>)[^<]+(<\/a>))/gi, '$1, $2unwatch$3' + WWText['WWUnwatch'] + '$4');
}
// get namespaces
var namespaceName = [];
var namespaceNumber = [];
var namespaceHash = [];
var ns = 0;
var regExpNamespace = new RegExp('<option\\b[^>]*?\\bvalue="?(\\d+)"?[^>]*>((.|\\s)*?)</option>', 'gi');
while ( (regExpMatch = regExpNamespace.exec(namespaceBlock)) != null) {
namespaceNumber[ns] = regExpMatch[1];
namespaceName[ns] = regExpMatch[2];
if (namespaceNumber[ns] == 0) {
namespaceName[ns] = namespaceName[ns].substr(0, 1).toUpperCase() + namespaceName[ns].substr(1);
}
namespaceHash[ 'WW' + namespaceName[ns] ] = ns;
ns ++;
}
var namespaceMax = ns;
namespaceName[-1] = WWText['WWRecentTop'];
namespaceName[-2] = WWText['WWRecentAll'];
var namespaceSection = [];
// get day block
var day = 0;
var sorted = '';
var regExpDays = new RegExp('(<h4\\b[^>]*>\\s*((.|\\s)*?)\\s*</h4>)\\s*(<ul\\b[^>]*>)?\\s*((.|\\s)*?)\\s*(</ul>)?\\s*(?=(<h4\\b[^>]*>|$))', 'gi');
while ( (regExpMatch = regExpDays.exec(watchlistBlock)) != null) {
var dayHeading = regExpMatch[1];
var dayContainerTop = regExpMatch[4] || '';
var dayContainer = regExpMatch[5];
var dayContainerBottom = regExpMatch[7] || '';
var mostRecent = 0;
// initialize and clear for +=
for (var ns = -2; ns <= namespaceMax; ns ++) {
namespaceSection[ns] = '';
}
namespaceSection[-2] = dayContainer;
// add day heading
sorted += '<div class="WWDayHeading">' + dayHeading + '</div>';
// define regexps outside the loops
var regExpArticles = new RegExp('((<(table|li)\\b[^>]*?>(.|\\s)*?</\\3>)\\s*(<div\\b[^>]*>(.|\\s)*?</div>)?)', 'gi');
var regExpArticleName = new RegExp('<a\\b[^>]*?\\btitle=(\\"([^\\n\\>"]*)\\"|([^\\s\\">]*))[^>]*>(\\2|\\4)</a>', 'gi');
// get article block
while ( (regExpMatch = regExpArticles.exec(dayContainer)) != null) {
var articleEditsBlock = regExpMatch[1];
var articleBlock = regExpMatch[2];
var editsBlock = regExpMatch[5];
// get article name
while ( (regExpMatch = regExpArticleName.exec(articleBlock)) != null) {
var articleName = regExpMatch[4];
// get article namespace
regExpMatch = /^(.*?):/.exec(articleName);
var namespaceIndex = 0;
if (regExpMatch != null) {
namespaceIndex = namespaceHash[ 'WW' + regExpMatch[1] ];
}
// append article block to section
if (namespaceIndex != null) {
namespaceSection[namespaceIndex] += articleEditsBlock;
// add to all section
// add to most recent section
if (mostRecent < wwRecentShort) {
namespaceSection[-1] += articleEditsBlock;
mostRecent ++;
}
}
}
// finish articles
}
// finish sections
for (var ns = -2; ns <= namespaceMax; ns ++) {
// sort the two main namespaces last
if (ns == 0) {
ns = 2;
}
else if (ns == namespaceMax) {
ns = 0;
}
else if (ns == 2) {
break;
}
// skip empty sections
if (namespaceSection[ns] == '') {
continue;
}
// rename all and top section elements
if ( (ns == -2) || (ns == -1) ) {
namespaceSection[ns] = namespaceSection[ns].replace(/(<[^>]*?\bid=(\"?)RC[IML]\d+)\2/g, '$1.' + ns + '$2');
namespaceSection[ns] = namespaceSection[ns].replace(/(<[^>]*?=\"?javascript:toggleVisibility\(\'RC[IML]\d+)(\',\s*\'RC[IML]\d+)(\',\s*\'RC[IML]\d+)(\')/g, '$1.' + ns + '$2.' + ns + '$3.' + ns + '$4');
}
var sectionStyle = '';
var headerToggle = '';
var footerToggle = '';
if (ns == -1) {
var topToggle = WWText['WWRecentTopToggle'].replace(/\{day\}/g, day)
headerToggle += ' ' + topToggle;
footerToggle = '<div class="WWSectionFooter">' + topToggle + '</div>';
if (wgCanonicalSpecialPageName != 'Watchlist') {
sectionStyle = ' style="display: none;"';
}
}
else if (ns == -2) {
var allToggle = WWText['WWRecentAllToggle'].replace(/\{day\}/g, day)
headerToggle = ' ' + allToggle;
footerToggle = '<div class="WWSectionFooter">' + allToggle + '</div>';
if (wgCanonicalSpecialPageName == 'Watchlist') {
sectionStyle = ' style="display: none;"';
}
}
// add sections to sorted watchlist
sorted += '<div class="WWSectionBlock"' + sectionStyle + ' id="WWSectionBlock' + ns + '-' + day + '"><div class="WWSection' + ns + '"><div class="WWSection"><h5 class="WWSectionHeading">' + namespaceName[ns] + headerToggle + '</h5>' + dayContainerTop + namespaceSection[ns] + dayContainerBottom + footerToggle + '</div></div></div>';
// remember section block names
sectionBlockIds.push('WWSectionBlock' + ns + '-' + day);
}
// finish day
day ++;
}
// return changed document.body
return(namespaceBlock + '<div id="WWSorted" class="WWSorted">' + sorted + '</div>' + pageBottom);
}
);
// ceate list of expandable entries for closing popups
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i ++) {
if (divs[i].id.match(/^RCI[\d\.\-]+/) != null) {
wwEditDivs.push(divs[i]);
}
}
// regexp to identify article links from link href
var regExpStr = '^' + mw.config.get('wgServer') + mw.config.get('wgArticlePath') + '$';
regExpStr = regExpStr.replace(/\$\d/, '[^\\?]*?');
regExpStr = regExpStr.replace(/(file:\/\/)([A-Z]:)(\/)/, '$1(/$2)?$3');
regExpStr = regExpStr.replace(/\/()/g, '\\/');
regExpStr = regExpStr.replace(/\./g, '\\.');
var regExpArticleLink = new RegExp(regExpStr);
// get all page links
var bodyContent = document.getElementById('bodyContent');
if (bodyContent == null) {
return;
}
var links = bodyContent.getElementsByTagName('a');
// cycle through all links
var linkNumber = 0;
for (var i = 0; i < links.length; i ++) {
// check if this is an article link
if (links[i].innerHTML.replace(/\"/g, '') != links[i].title) {
continue;
}
if (links[i].href.match(regExpArticleLink) == null) {
continue;
}
// add mouseover event to link
WWAddEventListener(links[i], 'mouseover', WWOpenPopup, false);
// remove title
links[i].title = '';
// find the container table element
var mainTable = links[i];
while (mainTable != null) {
if (mainTable.nodeName == 'TABLE') {
break;
}
mainTable = mainTable.parentNode;
}
// check if next sibling is an edits div
if (mainTable == null) {
continue;
}
var editsDiv = mainTable.nextSibling;
while (editsDiv != null) {
if (editsDiv.nodeType != 3) {
break;
}
editsDiv = editsDiv.nextSibling;
}
// add link id for easy access of related edits div
if (editsDiv == null) {
continue;
}
if (editsDiv.nodeName != 'DIV') {
continue;
}
var editsDivId = editsDiv.id;
if (editsDivId.match(/^RCI[\d\.\-]+/) != null) {
links[i].id = 'WW' + linkNumber + '-' + editsDivId;
linkNumber ++;
}
}
// close popup when leaving a section
for (var i = 0; i < sectionBlockIds.length; i ++) {
WWAddEventListener( document.getElementById( sectionBlockIds[i] ), 'mouseout', WWClosePopupsHandler, false );
}
return;
}
//
// WWToggleVisibility: replacement for toggleVisibility
//
function WWToggleVisibility(levelId, otherId, linkId) {
var thisLevel = document.getElementById(levelId);
var otherLevel = document.getElementById(otherId);
var linkLevel = document.getElementById(linkId);
if (thisLevel.className == 'WWPopup') {
thisLevel.style.display = 'none';
thisLevel.className = 'WWStandardExpand';
}
if (thisLevel.style.display == 'none') {
thisLevel.style.display = 'block';
otherLevel.style.display = 'none';
linkLevel.style.display = 'inline';
}
else {
thisLevel.style.display = 'none';
otherLevel.style.display = 'inline';
linkLevel.style.display = 'none';
}
WWClosePopups(levelId);
return;
}
var toggleVisibility = WWToggleVisibility;
//
// WWOpenPopup: open detailed edits preview
//
function WWOpenPopup(event) {
// MS IE compatibility fix
event = WWEvent(event);
if (event == null) {
return;
}
// get link id with div RCI id
var lnk = event.target
var levelId;
if (lnk == null) {
return;
}
if (lnk.nodeName != 'A') {
return;
}
// only close popups for single-entry links
if (lnk.id == '') {
WWClosePopups();
}
// popup edits
else {
levelId = lnk.id.replace(/^WW\d+-/, '');
if (levelId != '') {
var thisLevel = document.getElementById(levelId);
// show edits div as popup
thisLevel.className = 'WWPopup';
thisLevel.style.display = 'block';
wwOpenPopup = thisLevel;
// down arrow back to right arrow
var regExpMatch = /^RCI([\d\.\-]+)/.exec(levelId);
if (regExpMatch != null) {
var idNumber = regExpMatch[1];
var otherLevel = document.getElementById('RCM' + idNumber);
var linkLevel = document.getElementById('RCL' + idNumber);
otherLevel.style.display = 'inline';
otherLevel.blur();
linkLevel.style.display = 'none';
}
WWClosePopups(levelId);
}
}
return;
}
//
// WWClosePopups: close all edit popups
//
function WWClosePopups(levelId) {
if (wwOpenPopup != null) {
if (wwOpenPopup.id != levelId) {
wwOpenPopup.className = '';
wwOpenPopup.style.display = 'none';
wwOpenPopup = null;
}
}
for (var i = 0; i < wwEditDivs.length; i ++) {
if (wwEditDivs[i].className == 'WWPopup') {
if (wwEditDivs[i].id != levelId) {
wwEditDivs[i].className = '';
wwEditDivs[i].style.display = 'none';
}
}
}
return;
}
//
// WWClosePopupsHandler: close all edit popups when leaving the section
//
function WWClosePopupsHandler(event) {
// MS IE compatibility fix
event = WWEvent(event);
if (event == null) {
return;
}
event.stopPropagation();
if (event.relatedTarget != null) {
if (event.relatedTarget.id != '') {
if (event.relatedTarget.id.match(/\bRCI\d+\.+/) == null) {
WWClosePopups();
}
}
}
return;
}
//
// WWEvent: MS IE compatibility fix for event object
//
function WWEvent(event) {
var eventAlt;
if (window.event != null) {
eventAlt = window.event;
if (eventAlt != null) {
event = eventAlt;
event.stopPropagation = function() {
event.cancelBubble = true;
};
event.preventDefault = function() {
event.returnValue = false;
};
event.target = event.srcElement;
if (event.type == 'mouseout') {
event.relatedTarget = event.toElement;
}
else if (event.type == 'mouseover') {
event.relatedTarget = event.fromElement;
}
}
}
return(event);
}
//
// WWAddEventListener: wrapper for addEventListener (http://ejohn.org/projects/flexible-javascript-events/)
//
function WWAddEventListener(domElement, eventType, eventHandler, useCapture) {
if (domElement != null) {
if (domElement.attachEvent != null) {
domElement['WW' + eventType + eventHandler] = eventHandler;
domElement[eventType + eventHandler] = function() {
domElement['WW' + eventType + eventHandler](window.event);
}
domElement.attachEvent('on' + eventType, domElement[eventType + eventHandler] );
}
else {
domElement.addEventListener(eventType, eventHandler, useCapture);
}
}
return;
}
//
// WWRemoveEventListener: wrapper for removeEventListener
//
function WWRemoveEventListener(domElement, eventType, eventHandler, useCapture) {
if (domElement.detachEvent != null) {
domElement.detachEvent('on' + eventType, domElement[eventType + eventHandler]);
domElement[eventType + eventHandler] = null;
}
else {
domElement.removeEventListener(eventType, eventHandler, useCapture);
}
return;
}
//
// WWStyleSheet: create a new style sheet object
//
function WWStyleSheet(contextObj) {
if (contextObj == null) {
contextObj = document;
}
this.styleElement = null;
// MS IE compatibility
if (contextObj.createStyleSheet) {
this.styleElement = contextObj.createStyleSheet();
}
// standards compliant browsers
else {
this.styleElement = contextObj.createElement('style');
this.styleElement.from = 'text/css';
var insert = contextObj.getElementsByTagName('head')[0];
if (insert != null) {
this.styleElement.appendChild(contextObj.createTextNode(''));
insert.appendChild(this.styleElement);
}
}
//
// WWStyleSheet.addRules: add all rules at once, much faster
//
this.addRules = function(rules) {
// MS IE compatibility
if (this.styleElement.innerHTML == null) {
this.styleElement.cssText = rules;
}
// via innerHTML
else {
this.styleElement.innerHTML = rules;
}
return;
}
}
//
// WWDebug: print the value of variables, use either a single value or a description followed by a value
//
function WWDebug(objectName, object) {
// create debug textarea and add to debug wrapper
if (window.WWDebugTextarea == null) {
window.WWDebugTextarea = document.createElement('textarea');
WWDebugTextarea.id = 'WWDebug';
WWDebugTextarea.className = 'WWDebug';
WWDebugTextarea.rows = 20;
WWDebugTextarea = document.body.insertBefore(WWDebugTextarea, document.body.firstChild);
}
WWDebugTextarea.style.display = 'block';
if (objectName == null) {
WWDebugTextarea.value = '';
}
else {
if (object == null) {
WWDebugTextarea.value = objectName + '\n' + WWDebugTextarea.value;
}
else {
WWDebugTextarea.value = objectName + ': ' + object + '\n' + WWDebugTextarea.value;
}
}
return;
}
var WWD = WWDebug;
// schedule setup routine
if ( (wgCanonicalNamespace == 'Special') && ( (wgCanonicalSpecialPageName == 'Watchlist') || (wgCanonicalSpecialPageName == 'Recentchanges') ) ) {
WWAddEventListener(window, 'load', WWMain, false);
}
// close global wrapper
return;
}
// append wrapper to head if run under Greasemonkey
if (window.parent == window) {
if (typeof(GM_getValue) == 'function') {
if ( (document.getElementById('WWHeadScript') == null) && (window.wwInstalledFlag == false) ) {
window.wwInstalledFlag = true;
var script = document.createElement('script');
script.id = 'WWHeadScript';
script.type = 'text/javascript';
script.text = 'WWHeadWrapper = ' + WWWrapper.toString() + '; WWHeadWrapper();';
document.getElementsByTagName('head')[0].appendChild(script);
}
}
// otherwise run installation directly
else {
WWWrapper();
}
}
// </nowiki></pre>