利用者:Whym/editsectionenhanced.js

/*
 * modifyEditsection
 * (1) 冒頭部編集用のセクション編集リンクをつける
 * (2) トランスクルードされたセクションのセクション編集リンクを拡張する
 *
 *   dbenzhuser (de:Benutzer:Dbenzhuser)
 *   Alex Smotrov (en:User:Alex Smotrov)
 *   TheDJ (en:User:TheDJ)
 *   mizusumashi (ja:User:Mizusumashi)
 */
 
function modifyEditsection(){
    // メッセージのセットアップ
    var messages = {};
 
    messages['en'] = {  'edit'          : 'edit',
                        'topEditDescription'  : 'Edit lead section',
                        'openTitle'          : 'open',
                        'openDescription'     : 'Open "$1#$2"',
                        'historyTitle'       : 'history',
                        'historyDescription'  : 'Past version of "$1"',
                        'watchTitle'         : 'watch',
                        'watchDescription'    : 'Add "$1" to your watchlist',
                        'unwatchDescription'  : 'Remove "$1" from your watchlist',
                        'purgeTitle'         : 'purge',
                        'purgeDescription'    : 'Clear the cache of "$1" and view the last version of "$2"' }
 
    messages['ja'] = {  'editTitle'          : '編集',
                        'topEditDescription'  : '導入部を編集',
                        'openTitle'          : '閲覧',
                        'openDescription'     : '「$1#$2」を閲覧"',
                        'historyTitle'       : '履歴',
                        'historyDescription'  : '「$1」の履歴',
                        'watchTitle'         : 'ウォッチ',
                        'watchDescription'    : '「$1」をウォッチリストに追加',
                        'unwatchDescription'  : '「$1」をウォッチリストから削除',
                        'purgeTitle'         : '更新',
                        'purgeDescription'    : '「$1」を更新し、「$2」の最新版を反映' }
 
    messages['fr'] = {  'topEditDescription'  : 'Modifier le résumé introductif' }
 
    messages['it'] = {  'topEditDescription'  : 'Modifica della sezione iniziale' }
 
 
    // コード全体を通して使う値の設定
    var pageUri = encodeURIComponent(mw.config.get('wgPageName'));
 
    var heading = document.getElementById('firstHeading')      // simple, chick, vector, myskin, modern, monobook
                    || getElementsByClassName(document, 'h1', 'pagetitle')[0];
                                                                // standard, cologneblue, nostalgia
                    /* || document.getElementsByTagName('h1')[0] */;   // others - フェールセーフ用
 
    var edits = getElementsByClassName(document, 'span', 'mw-editsection');
 
    // editsection が存在しなければ何もしない。
    // 冒頭編集リンクもつけないのは、過去版閲覧時などに付与してしまうことを避けるため。
    if(!edits.length){
        return;
    }
 
    // 動作条件の設定
 
    // 冒頭編集リンクの設置を行うか
    // topEditsectionEnable = true を設定していれば、機能を有効化できる
    var top = typeof topEditsectionEnable != 'undefined' && topEditsectionEnable;
 
    // セクション編集リンクの拡張を行うか
    // expandEditsectionDisable = true を設定していれば、機能を無効化できる
    var expand = (typeof expandEditsectionDisable == 'undefined' || ! expandEditsectionDisable)
                    && (wgNamespaceNumber == 4 || wgNamespaceNumber % 2 == 1);
 
 
    // デバック・モード
    // expandEditsectionDebug = true をユーザースクリプトで設定していれば、機能を有効化できる
    var debug = typeof modifyEditsectionDebug != 'undefined' && modifyEditsectionDebug;
 
 
    // すべての機能が無効にされていれば、ここで脱出
    if(!top && !expand){
        return;
    }
 
 
    // メッセージのセットアップ(承前)
    if(! messages[wgUserLanguage]){
        messages[wgUserLanguage] = {};
    }
 
    if(! messages[wgUserLanguage]['editTitle'] && edits.length){
        messages[wgUserLanguage]['editTitle'] = edits[0].getElementsByTagName('a')[0].innerHTML;
    }
 
    var ca = function(key){
        var span = document.getElementById('ca-' + key);
        if(span){
            var aTags = span.getElementsByTagName('a');
            if(aTags.length){
                var spanTags = span.getElementsByTagName('span');
                if(spanTags.length){
                    return spanTags[0].innerHTML.toLowerCase();
                } else {
                    return aTags[0].innerHTML.toLowerCase();
                }
            }
        }
        return null;
    }
 
    if(! messages[wgUserLanguage]['editTitle']){
        messages[wgUserLanguage]['editTitle'] = ca('edit');
    }
 
    if(! messages[wgUserLanguage]['historyTitle']){
        messages[wgUserLanguage]['historyTitle'] = ca('history');
    }
 
    var message = function(key){
        return messages[wgUserLanguage][key] || messages['en'][key];
    }
 
 
    // ここから本体の動作
 
 
    // 冒頭編集リンクの設置
    if( top ){
        var topEdit = document.createElement('span');
        var topEditA = document.createElement('a');
        topEditA.appendChild(document.createTextNode(message('editTitle')));
        topEditA.href = wgScript + '?title=' + pageUri + '&action=edit&section=0';
        topEditA.title = message('topEditDescription');
 
        topEdit.appendChild(document.createTextNode('['));
        topEdit.appendChild(topEditA);
        topEdit.appendChild(document.createTextNode(']'));
 
        topEdit.className = 'mw-editsection';
        heading.appendChild(document.createTextNode(' '));
        heading.appendChild(topEdit);
    }

    // 以下、セクション編集リンクの拡張
    // セクション編集リンクの拡張が無効にされていれば、ここで脱出
    if(!expand){
        return;
    }
 
    // セクション編集リンクを処理していくループ
    var expanded = {};
    for (var i = 0; i < edits.length; i++) {
        var parent = edits[i].parentNode;
        var debugMsg = '';
 
 
        // セクション・リンクの拡張が無効にされていれば、ここでループ折り返し
        if(! expand){
            continue;
        }
 
 
        // 以下の処理は、セクション・リンクの拡張
        var a = edits[i].getElementsByTagName('a')[0];
 
        // トランスクードされたのではないセクションは拡張しない
        if(! a.href.match('&section=T')){
            expanded = {};
            continue;
        }
 
        a.href.match(/\?title=([^&]+).+/);
        var transUri = RegExp.$1;
        var level = Number(parent.tagName.replace(/h/i, ''));
 
 
        // 以前に同じページからのトランスクルードがあり、かつセクション・レベルが下がっていれば、拡張しない
        if(expanded[transUri] && level > expanded[transUri]){
            continue;
        }
 
        expanded[transUri] = level;
 
        var section = getElementsByClassName(parent, 'span', 'mw-headline')[0].innerHTML
                        .replace(/^(\s|(&nbsp;))*/, '').replace(/(\s|(&nbsp;))*$/, '');
        var transTitle = a.title;
 
        // セクションID(http//...#*** の *** の部分)を取得
        // MediaWiki のバージョンにけっこう依存。1.16alpha-wmf (r56620) では、このコードで取得できる
        // 失敗した場合は、セクションタイトルから自力で生成した transId を使う
        var sectionId = null;
 
        var headline = getElementsByClassName(parent, 'span', 'mw-headline');
        if(headline){
            headline = headline[0];
            if(headline.id){
                sectionId = headline.id;
            }
        }
 
        if(! sectionId){
            debugMsg += 'sectionId が取得できませんでした。';
        }
 
 
        // セクションタイトルから自力でIDを生成
        // これは、セクションタイトルが重複した場合に区別するための末尾の「_2」がない
        // (1) [閲覧]リンクのリンク先につかう
        //          リンク先(読み込み元)でセクションタイトルが重複しているのか、
        //          重複しているのであれば何番目なのかはわからないから、
        //          重複していないと仮定してこちらを使う
        // (2) sectionId の取得に失敗した場合に使う
        //          フェールセーフ
        var transId
                = encodeURIComponent
                        (section
                            .replace(/ /g, '_')
                            .replace(/&amp;/g, '&')
                            .replace(/&lt;/g, '<')
                            .replace(/&gt;/g, '>'))
                    .replace(/%/g, '.')
                    .replace(/!/g, '.21')
                    .replace(/'/g, '.27')
                    .replace(/\(/g, '.28')
                    .replace(/\)/g, '.29')
                    .replace(/\*/g, '.2A')
                    .replace(/\.3A/g, ':');
 
 
        var extensions = document.createElement('span');
        extensions.className = 'editsection-extensions';
 
        var open = document.createElement('a');
        open.appendChild(document.createTextNode(message('openTitle')));
        open.href = wgScript + '?title=' + transUri + '&action=view#' + transId;
        open.title = message('openDescription').replace('$1', transTitle).replace('$2', section);
 
        extensions.appendChild(document.createTextNode('['));
        extensions.appendChild(open);
        extensions.appendChild(document.createTextNode(']'));
 
        var history = document.createElement('a');
        history.appendChild(document.createTextNode(message('historyTitle')));
        history.href = wgScript + '?title=' + transUri + '&action=history';
        history.title = message('historyDescription').replace('$1', transTitle);
 
        extensions.appendChild(document.createTextNode('['));
        extensions.appendChild(history);
        extensions.appendChild(document.createTextNode(']'));
 
        if(wgUserName != null){
            var watch = document.createElement('a');
            watch.appendChild(document.createTextNode(message('watchTitle')));
            watch.href = wgScript + '?title=' + transUri + '&action=watch';
            watch.title = message('watchDescription').replace('$1', transTitle);
 
            var unwatch = document.createElement('a');
            unwatch.appendChild(document.createTextNode('-'));
            unwatch.href = wgScript + '?title=' + transUri + '&action=unwatch';
            unwatch.title = message('unwatchDescription').replace('$1', transTitle);
 
            extensions.appendChild(document.createTextNode('['));
            extensions.appendChild(watch);
            extensions.appendChild(document.createTextNode('('));
            extensions.appendChild(unwatch);
            extensions.appendChild(document.createTextNode(')]'));
 
            if(wgAction != 'purge'){
                var purge = document.createElement('a');
                purge.appendChild(document.createTextNode(message('purgeTitle')));
                purge.href = wgScript + '?title=' + pageUri + '&action=purge#' + (sectionId || transId);
                purge.title = message('purgeDescription').replace('$1', wgPageName).replace('$2', transTitle);
 
                extensions.appendChild(document.createTextNode('['));
                extensions.appendChild(purge);
                extensions.appendChild(document.createTextNode(']'));
            }
 
            if(debug && debugMsg){
                debugSignal = document.createElement('span');
                debugSignal.appendChild(document.createTextNode('*'));
                debugSignal.title = debugMsg;
                extensions.appendChild(debugSignal);
            }
        }
 
        edits[i].appendChild(extensions);
    }
}
 
if( (wgAction == 'view' || wgAction == 'purge') && wgNamespaceNumber >= 0 ){
    $(modifyEditsection);
}