Jump to content

User:Cacycle/wikiWatch.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Cacycle (talk | contribs) at 05:26, 25 February 2008 (0.0.2). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// <pre><nowiki>

// ==UserScript==
// @name        watchlistSorter
// @namespace   http://en.wikipedia.org/wiki/User:Cacycle/
// @description A universally compatible watchlist sorter for Wikipedia and other MediaWikis
// @include     *
// @exclude
//
// @homepage    http://en.wikipedia.org/wiki/User:Cacycle/watchlistSorter
// @source      http://en.wikipedia.org/wiki/User:Cacycle/watchlistSorter.js
// @author      Cacycle (http://en.wikipedia.org/wiki/User:Cacycle)
// @license     Released into the public domain
// @version     0.0.2
// ==/UserScript==


// watchlist sorter main program
window.WLSMain = function() {

    WLSRemoveEventListener(window, 'load', WLSMain, false);

// check if this has already been run, either as a wiki gadget, wiki user script, or a Greasemonkey user script
    if (document.getElementById('WLSSetupFlag') != null) {
        return;
    }

// set already run flag
    var flag = document.createElement('span');
    flag.id = 'WLSSetupFlag';
    flag.style.display = 'none';
    flag.style.visibility = 'hidden';
    document.body.appendChild(flag);

// check if this runs under Greasemonkey
    window.WLSGreasemonkey = false;
    if (typeof(GM_getValue) == 'function') {
        WLSGreasemonkey = true;
    }

// get MediaWiki globals in a Greasemonkey compatible way
    window.WLSGetGlobalNode = window.WLSGetGlobalNode || null;
    var wgCanonicalNamespace = WLSGetGlobal('wgCanonicalNamespace');
    var wgCanonicalSpecialPageName = WLSGetGlobal('wgCanonicalSpecialPageName');
    var wgArticlePath = WLSGetGlobal('wgArticlePath');

// check if this is a MediaWiki watchlist
    if ( (wgCanonicalNamespace != 'Special') || (wgCanonicalSpecialPageName != 'Watchlist') ) {
        return;
    }

// text translation
    window.WLSText = window.WLSText || {
        'recentAll':       'Most recent',
        'recentAllToggle': '<span class="WLSToggle" title="Toggle the display of all entries">(<a onclick="javascript:{document.getElementById(\'WLSMostRecentHidden\').style.display=\'block\';document.getElementById(\'WLSMostRecentAll\').style.display=\'none\';}">short</a>)</span>',
        'recentTop':       'Most recent',
        'recentTopToggle': '<span class="WLSToggle" title="Toggle the display of all entries">(<a onclick="document.getElementById(\'WLSMostRecentAll\').style.display=\'block\';document.getElementById(\'WLSMostRecentHidden\').style.display=\'none\';">show all</a>)</span>'
    };

// css styles
    window.WLSCss = window.WLSCss || {
        '.WLSToggle':      'font-weight: normal;',
        '.WLSToggle A':    'cursor: pointer;',
        '.WLSToggleDiv':   'margin-left: 4em;',
        '.WLSToggleUi':    '',

        '.WLSDate':        'background-color: #c0c0c0; border: grey solid 1px; margin: 1em 0 0.5em 0 !important; padding: 0.4em 2em;',

        '.WLSHeadingDiv':  'margin: 0; padding: 0.4em 0 0 4em;',
        '.WLSHeadingUl':   'margin: 0; padding: 0.4em 0 0 0;',

        '.WLDDayDiv':      '',
        '.WLDDayUl':       '',
        '.WLDDayDiv> DIV': 'border: grey solid 1px; margin: 0 0 0.5em 0; padding: 0 0 0.75em 0.5em;',
        '.WLDDayUl > DIV': 'border: grey solid 1px; margin: 0 0 0.5em 0; padding: 0 0 0.75em 0.5em;',
        '.WLDDayUl LI': 'list-style: none;',

        '.WLSSection-1':   '',
        '.WLSSection-2':   '',

        '.WLSSection0':    'background-color: #ffffff;',
        '.WLSSection1':    'background-color: #f2f2f2;',

        '.WLSSection2':    'background-color: #e5e5e5;',
        '.WLSSection3':    'background-color: #d0d0d0;',

// colors: HSB 40°-5%-100% (light), 40°-5%-95% (dark), 40° steps
        '.WLSSection4':    'background-color: #fffbf2;',
        '.WLSSection5':    'background-color: #f2eee6;',

        '.WLSSection6':    'background-color: #fbfff2;',
        '.WLSSection7':    'background-color: #eef2e6;',

        '.WLSSection8':    'background-color: #f2fff2;',
        '.WLSSection9':    'background-color: #e6f2e6;',

        '.WLSSection10':   'background-color: #f2fffb;',
        '.WLSSection11':   'background-color: #e6f2ee;',

        '.WLSSection12':   'background-color: #f2fbff;',
        '.WLSSection13':   'background-color: #e6eef2;',

        '.WLSSection14':   'background-color: #f2f2ff;',
        '.WLSSection15':   'background-color: #e6e6f2;',

        '.WLSSection16':   'background-color: #fbf2ff;',
        '.WLSSection17':   'background-color: #eee6f2;',

        '.WLSSection18':   'background-color: #fff2fb;',
        '.WLSSection19':   'background-color: #f2e6ee;',

        '.WLSSection20':   'background-color: #fff2f2;',
        '.WLSSection21':   'background-color: #f2e6e6;',

        '.WLSSection100':  'background-color: #fff2fb;',
        '.WLSSection101':  'background-color: #f2e6ee;',
    };

// number of most recent entries in short display
    window.WLSRecentShort = window.WLSRecentShort || 15;

// add stylesheet definitions
    var styles = new WLSStyleSheet();
    var rules = '';
    for (var ruleName in WLSCss) {
        var ruleStyle = WLSCss[ruleName];
        if (typeof(ruleStyle) != 'string') {
            continue;
        }
        rules += ruleName + ' {' + ruleStyle + '}\n';
    }
    styles.addRules(rules);

// read namespaces
    var namespace = {};
    var namespaceText = [];
    var namespaceSelect = document.getElementById('namespace');
    if (namespaceSelect == null) {
        return;
    }
    var namespaceOptions = namespaceSelect.getElementsByTagName('option');
    for (var i = 0; i < namespaceOptions.length; i ++) {
        var optionNumber = namespaceOptions[i].value;
        var optionText = namespaceOptions[i].innerHTML;
        if (/^\d+$/.test(optionNumber) == true) {
            if (optionNumber == 0) {
                optionText = optionText.replace(/^\W*|\W*$/, '');
                optionText = optionText.substr(0, 1).toUpperCase() + optionText.substr(1);
            }
            namespace[optionText] = optionNumber;
            namespaceText[optionNumber] = optionText;
        }
    }

// cycle through days
    var days = namespaceSelect.parentNode.parentNode.parentNode.getElementsByTagName('h4');
  for (var day = 0; day < days.length; day ++) {

// get first container after date
        var dayList;
        var node = days[day];
        while (node != null) {
            if (node.tagName != null) {
                if ( (node.tagName == 'DIV') || (node.tagName == 'UL') ) {
                    dayList = node;
                    break;
                }
            }
            node = node.nextSibling;
        }
        if (dayList == null) {
            break;
        }
        var dayListClone = node.cloneNode(true);

// detect watchlist style: either <br> separated <div> container or <li> entries in an <ul> container
        var watchlistStyle;
        if (dayList.tagName == 'DIV') {
            watchlistStyle = 'div';
        }
        else {
            watchlistStyle = 'ul';
        }

// split day entries
        var entries = [];

// <br> separated entries
        if (watchlistStyle == 'div') {
            var i = 0;
            entries[0] = document.createElement('span');
            node = dayListClone.firstChild;
            while (node != null) {
                var newNode = node.nextSibling;
                entries[i].appendChild(node);
                if (node.tagName != null) {
                    if (node.tagName == 'BR') {
                        entries[++ i] = document.createElement('span');
                    }
                }
                node = newNode;
            }
        }

// <li> entries
        else {
            entries = dayListClone.getElementsByTagName('li');
        }

// create new day container
        var newList;
        if (watchlistStyle == 'div') {
            newList = document.createElement('DIV');
            newList.className = 'WLDDayDiv';
        }
        else {
            newList = document.createElement('UL');
            newList.className = 'WLDDayUl';
        }

// cycle through day entries
      var sections = [];
      for (var i = 0; i < entries.length; i ++) {
            var links = entries[i].getElementsByTagName('a');
            if (links.length == 0) {
                continue;
            }
            var article = links[0].title;
            var articleNamespace;
            var articleNamespaceNumber;
            var result = /^(.*?):/.exec(article);
            if (result == null) {
                articleNamespace = namespaceText[0];
                articleNamespaceNumber = 0;
            }
            else {
                articleNamespace = result[1];
                articleNamespaceNumber = namespace[ articleNamespace ];
            }

// create new section
            if (sections[articleNamespaceNumber] == null) {
                sections[articleNamespaceNumber] = WLSCreateNewSection(articleNamespace, watchlistStyle);
            }

// add entries to sections
            sections[ articleNamespaceNumber ].appendChild( entries[i].cloneNode(true) );
        }

// create most recent sections
        if (day == 0) {

// create all todays
            namespace['Most recent (all)'] = -2;
            namespaceText[-2] = WLSText['recentAll'] + ' ' + WLSText['recentAllToggle'];
            sections[-2] = WLSCreateNewSection(namespaceText[-2], watchlistStyle, 'WLSMostRecentAll');
          for (var i = 0; i < entries.length; i ++) {
                sections[-2].appendChild( entries[i].cloneNode(true) );
            }
            var span = document.createElement('span');
            span.innerHTML = WLSText['recentAllToggle'];
            if (watchlistStyle == 'div') {
                span.className = 'WLSToggleDiv';
            }
            else {
                span.className = 'WLSToggleUl';
            }
            sections[-2].appendChild(span);
            sections[-2].style.display = 'none';

// create short todays
            namespace['Most recent (hidden)'] = -1;
            namespaceText[-1] = WLSText['recentTop'] + ' ' + WLSText['recentTopToggle'];
            sections[-1] = WLSCreateNewSection(namespaceText[-1], watchlistStyle, 'WLSMostRecentHidden');
          for (var i = 0; i < entries.length; i ++) {
                if (i > WLSRecentShort) {
                    var span = document.createElement('span');
                    span.innerHTML = WLSText['recentTopToggle'];
                    if (watchlistStyle == 'div') {
                        span.className = 'WLSToggleDiv';
                    }
                    else {
                        span.className = 'WLSToggleUl';
                    }
                    sections[-1].appendChild(span);
                    break;
                }
                sections[-1].appendChild( entries[i].cloneNode(true) );
            }
        }

// add sections to new list, cycle through all namespaces
        var classNumber = 0;
        for (i = -2; i <= namespaceText.length; i ++) {

// sort the two main namespaces last
            if (i == 0) {
                i = 2;
            }
            else if (i == namespaceText.length) {
                i = 0;
            }
            else if (i == 2) {
                break;
            }

// skip empty ranges
            if (namespaceText[i] == null) {
                continue;
            }

// append section to new list
            if (sections[i] != null) {
                sections[i].className = 'WLSSection' + i;
                newList.appendChild(sections[i]);
                classNumber ++;
            }
        }
        days[day].className = 'WLSDate';

// insert new list into page
        dayList.parentNode.insertBefore(newList, dayList.previousSibling);

// hide old list
        dayList.style.display = 'none';

    }

    return;
}


//
// WLSCreateNewSection: create new section of entries
//

window.WLSCreateNewSection = function(headingText, watchlistStyle, divId) {

    var div = document.createElement('div');
    if (divId != null) {
        div.id = divId;
    }
    var heading = document.createElement('h5');
    if (watchlistStyle == 'div') {
        heading.className = 'WLSHeadingDiv';
    }
    else {
        heading.className = 'WLSHeadingUl';
    }
    heading.innerHTML = headingText;
    div.appendChild(heading);

    return(div);
}


//
// WLSGetGlobal: access values of global variables from Greasemonkey scripts using the 'location hack'
//

window.WLSGetGlobal = function(globalName) {
    var globalValue;
    if (WLSGreasemonkey == true) {
        if (WLSGetGlobalNode == null) {
            window.WLSGetGlobalNode = document.getElementById('WLSGetGlobalNode');
        }
        if (WLSGetGlobalNode == null) {
            WLSGetGlobalNode = document.createElement('textarea');
            WLSGetGlobalNode.id = 'WLSGetGlobalNode';
            WLSGetGlobalNode.style.display = 'none';
            WLSGetGlobalNode.style.visibility = 'hidden';
            document.body.appendChild(WLSGetGlobalNode);
        }
        location.href = 'javascript:void(typeof(' + globalName + ')!=\'undefined\'?(' + globalName + '!=null?(document.getElementById(\'WLSGetGlobalNode\').value=' + globalName + '.toString()):null):null)';
        globalValue = WLSGetGlobalNode.value;
    }
    else {
        try {
            globalValue = eval(globalName + '.toString();');
        }
        catch(err) { }
    }
    return(globalValue);
}


//
// WLSAddEventListener: wrapper for addEventListener (http://ejohn.org/projects/flexible-javascript-events/)
//

window.WLSAddEventListener = function(domElement, eventType, eventHandler, useCapture) {

    if (domElement != null) {
        if (domElement.attachEvent != null) {
            domElement['WLS' + eventType + eventHandler] = eventHandler;
            domElement[eventType + eventHandler] = function() {
                domElement['WLS' + eventType + eventHandler](window.event);
            }
            domElement.attachEvent('on' + eventType, domElement[eventType + eventHandler] );
        }
        else {
            domElement.addEventListener(eventType, eventHandler, useCapture);
        }
    }
    return;
}


//
// WLSRemoveEventListener: wrapper for removeEventListener
//

window.WLSRemoveEventListener = function(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;
}


//
// WLSStyleSheet: create a new style sheet object
//

window.WLSStyleSheet = function(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('')); // Safari 3 fix
            insert.appendChild(this.styleElement);
        }
    }

//
// WLSStyleSheet.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;
    }
}


// schedule the main routine
WLSAddEventListener(window, 'load', WLSMain, false);


// </nowiki></pre>