MediaWiki:Common.js: difference between revisions

From Wiktionary, the free dictionary
Jump to navigation Jump to search
Content deleted Content added
Conrad.Irwin (talk | contribs)
remove pgcounter that's been broken for years, move page specific things to the page-specific section
Bequw (talk | contribs)
remove importExternalScript(), duplicate, unused function
Line 43: Line 43:
}
}


/*</pre>
===importExternalScript===
<pre>*/

/**
* importExternalScript inserts a javascript page
* from anywhere including your local hard drive: importExternalScript('file:///C:/Documents%20and%20Settings/Andrew/My%20Documents/apitest.js');
*
* based on importScript above 2008-01-21
**/
function importExternalScript(url) {
//Only include scripts once
return importScriptURI(url);
}
/*</pre>
/*</pre>
=== DOM creation ===
=== DOM creation ===

Revision as of 13:18, 5 February 2010

/* Any JavaScript here will be loaded for all users on every page load. */

/*</pre>
==JavaScript standard library==
<pre>*/

/*</pre>
===importScript===
<pre>*/

/**
 * importScript inserts a javascript page either 
 *    from Wiktionary: importScript('User:Connel MacKensie/yetanother.js');
 *    from another Wikimedia wiki: importScript('User:Lupin/insane.js','en.wikipedia.org');
 *
 *    by specifying the third argument, an oldid can be passed to ensure that updates to the script are not included.
 *    by specifying the fourth argument, a specific version of JavaScript can be declared.
 *
 *    based on [[w:MediaWiki:Common.js]] 2007-11-29
**/
function importScript(page, wiki, oldid, jsver) {
    //Default to local
    if(!wiki)
      wiki=wgScript;
    else
      wiki='http://'+escape(wiki)+'/w/index.php';
 
    var url = wiki + '?title='
             + encodeURIComponent(page.replace(/ /g, '_')).replace(/%2F/ig, '/').replace(/%3A/ig, ':')
            + (oldid?'&oldid='+encodeURIComponent( oldid ):'')
            + '&action=raw&ctype=text/javascript';
 
    //Only include scripts once
    if(loadedScripts[url])
        return false;
    loadedScripts[url] = true;
 
    var scriptElem = document.createElement("script");
    scriptElem.setAttribute("src",url);
    scriptElem.setAttribute("type", jsver ? "application/javascript;version=" + jsver : "text/javascript");
    document.getElementsByTagName("head")[0].appendChild(scriptElem);
    return true;
}

/*</pre>
=== DOM creation ===
<pre>*/
/**
 * Create a new DOM node for the current document.
 *    Basic usage:  var mySpan = newNode('span', "Hello World!")
 *    Supports attributes and event handlers*: var mySpan = newNode('span', {style:"color: red", focus: function(){alert(this)}, id:"hello"}, "World, Hello!")
 *    Also allows nesting to create trees: var myPar = newNode('p', newNode('b',{style:"color: blue"},"Hello"), mySpan)
 *
 * *event handlers, there are some issues with IE6 not registering event handlers on some nodes that are not yet attached to the DOM,
 * it may be safer to add event handlers later manually.
**/
function newNode(tagname){

  var node = document.createElement(tagname);
  
  for( var i=1;i<arguments.length;i++ ){
    
    if(typeof arguments[i] == 'string'){ //Text
      node.appendChild( document.createTextNode(arguments[i]) );
      
    }else if(typeof arguments[i] == 'object'){ 
      
      if(arguments[i].nodeName){ //If it is a DOM Node
        node.appendChild(arguments[i]);
        
      }else{ //Attributes (hopefully)
        for(var j in arguments[i]){
          if(j == 'class'){ //Classname different because...
            node.className = arguments[i][j];
            
          }else if(j == 'style'){ //Style is special
            node.style.cssText = arguments[i][j];
            
          }else if(typeof arguments[i][j] == 'function'){ //Basic event handlers
            try{ node.addEventListener(j,arguments[i][j],false); //W3C
            }catch(e){try{ node.attachEvent('on'+j,arguments[i][j],"Language"); //MSIE
            }catch(e){ node['on'+j]=arguments[i][j]; }}; //Legacy
          
          }else{
            node.setAttribute(j,arguments[i][j]); //Normal attributes

          }
        }
      }
    }
  }
  
  return node;
}
/*</pre>
=== CSS ===
<pre>*/

/* Cross browser CSS - yurk */
var p_styleSheet=false;
 
window.addCSSRule = function (selector,cssText){
  if(!p_styleSheet) return setupCSS(selector,cssText);
  if(p_styleSheet.insertRule){
    p_styleSheet.insertRule( selector+' { '+cssText+' }', p_styleSheet.cssRules.length );
  }else if(p_styleSheet.addRule){ //Guess who...
    p_styleSheet.addRule(selector,cssText);
  }
 
  function setupCSS(selector,cssText){
    if(document.styleSheets){
      var i = document.styleSheets.length-1;
      while(i>=0){
        try{ //This loop tries to get around the irritation that some extensions
             //include external, and thus read-only, stylesheets. Bah.
          p_styleSheet = document.styleSheets[i];
          var media = p_styleSheet.media.mediaType?p_styleSheet.media.mediaType:p_styleSheet.media;
          if( media.indexOf('screen') > -1 || media == '' ){
            addCSSRule(selector,cssText);
            return true;
          }
        }catch(e){ i--; }
      }  
    }
    //Ok document.stylesheets isn't an option :(... take this for hacky
    //It might be better to create one <style> element and write into it
    // but it doesn't work :(
    window.addCSSRule = function(sel,css){
      var head = document.getElementsByTagName('head')[0];
      var text = sel + '{' + css + '}';
      try { head.innerHTML += '<style type="text/css">' + text + '</style>'; }
      catch(e) {
        var style = document.createElement('style');
        style.setAttribute('type', 'text/css');
        style.appendChild(document.createTextNode(text));
        head.appendChild(style);
      }
    }
    addCSSRule(selector,cssText);
  }
}
/*</pre>

===Cookies===
<pre>*/

function setCookie(cookieName, cookieValue) {
 var today = new Date();
 var expire = new Date();
 var nDays = 30;
 expire.setTime( today.getTime() + (3600000 * 24 * nDays) );
 document.cookie = cookieName + "=" + escape(cookieValue)
                 + ";path=/w"
                 + ";expires="+expire.toGMTString();
 document.cookie = cookieName + "=" + escape(cookieValue)
                 + ";path=/wiki"
                 + ";expires="+expire.toGMTString();
}

function getCookie(cookieName) {
  var start = document.cookie.indexOf( cookieName + "=" );
  if ( start == -1 ) return "";
  var len = start + cookieName.length + 1;
  if ( ( !start ) &&
    ( cookieName != document.cookie.substring( 0, cookieName.length ) ) )
      {
        return "";
      }
  var end = document.cookie.indexOf( ";", len );
  if ( end == -1 ) end = document.cookie.length;
  return unescape( document.cookie.substring( len, end ) );
}

function deleteCookie(cookieName) {
  if ( getCookie(cookieName) ) {
    document.cookie = cookieName + "=" + ";path=/w" +
    ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
    document.cookie = cookieName + "=" + ";path=/wiki" +
    ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
  }
}

/*</pre>
==Wiktionary Customisation==
===[[MediaWiki:Youhavenewmessages]] to display differently for non-newbies with JS than for others===
<pre>*/
if (wgUserGroups && wgUserGroups.join("").indexOf("autoconfirmed") > -1)
{
    addCSSRule(".msgfornewbies", "display: none");
}
/*</pre>
===WT:PREFS===
<pre>*/

if (wgUserName == "Hippietrail") {
  if (getCookie('WiktPrefs') || wgPageName == "Wiktionary:Preferences") {
     importScript('User:Hippietrail/custom-alpha.js');
  }
} else {
  if (getCookie('WiktPrefs') || wgPageName == "Wiktionary:Preferences") {
     //importScript('User:Connel_MacKenzie/custom.js');
     importScript('User:Hippietrail/custom.js');
  }
}

/*</pre>
===Page specific extensions===
<pre>*/

/*</pre>
====Wiktionary:Main Page====
<pre>*/
// Hide the title and "Redirected from" (maybe we should keep the redirected from so's people update their bookmarks ;)
// Broken in IE!
if ( wgPageName == 'Wiktionary:Main_Page' && !( wgAction == 'view' || wgAction == 'submit' ) ){
  addCSSRule('.firstHeading','display: block !important;');
  addCSSRule('#contentSub','display: inline !important;');

} else if (wgPageName == 'Wiktionary:Main_Page' || wgPageName == 'Wiktionary_talk:Main_Page') 
    addOnloadHook(function () {
        addPortletLink('p-lang', 'http://meta.wikimedia.org/wiki/Wiktionary#List_of_Wiktionaries',
                 'Complete list', 'interwiki-completelist', 'Complete list of Wiktionaries')
        var nstab = document.getElementById('ca-nstab-project')
        if (nstab && wgUserLanguage=='en') {
            while (nstab.firstChild) nstab = nstab.firstChild
            nstab.nodeValue = 'Main Page'
        }
    }
)

/*</pre>
====Special:Search====
<pre>*/

else if ( wgPageName == 'Special:Search') {
    importScript('MediaWiki:SpecialSearch.js');
}

/*</pre>
====WT:CUSTOM====
<pre>*/

else if( wgPageName=='Help:Customizing_your_monobook' ){
    importScript('MediaWiki:CustomSearch.js');
}

/*</pre>
====Turn headings in comments into real headings on JavaScript source pages====
<pre>*/

else if ((wgNamespaceNumber == 2 || wgNamespaceNumber == 8) && wgTitle.lastIndexOf('.js') != -1 && wgAction == 'view') {
    importScript('MediaWiki:JavascriptHeadings.js');
}

/*</pre>
====Geonotice====
<pre>*/

else if (wgPageName == "Special:Watchlist") //watchlist scripts
{
    importScriptURI('http://toolserver.org/~para/geoip.fcgi');
    addOnloadHook(function() { importScriptURI('http://en.wiktionary.org/w/index.php?title=MediaWiki:Geonotice.js&action=raw&ctype=text/javascript&maxage=3600'); });
}

/*</pre>
===Add editor.js for editing translations===
<pre>*/

/** Trial run 2009-04-14. Please disable if causing problems. **/
importScript('User:Conrad.Irwin/editor.js');

/*</pre>
===Make Citations: tabs ===
<pre>*/
function citations_tab(){
  
  var mt_caption = 'Entry';
  var mt_title = 'View the content page [alt-c]';
  var ct_caption = 'Citations';
  var ct_title = 'View the citations page';

  var lookup = new Object();
  var ct_class = '';
  var safeTitle = encodeURIComponent(wgTitle.replace(/ /g,"_"));

  //Where to put Citations tab
  var insbef = document.getElementById('ca-edit');
  if(! insbef) insbef = document.getElementById('ca-viewsource');
  if(! insbef) return false;
  
  if( wgCanonicalNamespace == 'Citations' ){  
 
    //Remove accesskeys etc from Citations tab
    var ct = document.getElementById('ca-nstab-citations');
    ct.removeAttribute('accesskey');
    ct.setAttribute('title',ct_title);
    
    //Reset discussion tab to point to Talk:
    var dt = document.getElementById('ca-talk');
    
    for(var i=0;i<dt.childNodes.length;i++){
      var anc = dt.childNodes[i];
      if(anc.nodeName.toUpperCase()=='A'){
        anc.setAttribute('href',wgArticlePath.replace("$1","Talk:"+safeTitle));
        lookup['Talk:'+wgTitle] = dt;
      }
    }
    if(dt.className) dt.className = dt.className.replace('new','');
    
    //Create main tab before citations tab
    addPortletLink('p-cactions',wgArticlePath.replace("$1",safeTitle),mt_caption,'ca-nstab-main',mt_title,null,ct)
    lookup[wgTitle] = document.getElementById('ca-nstab-main');
    
    //Move Citations tab to correct position
    var tabbar = ct.parentNode;
    tabbar.removeChild(ct);
    tabbar.insertBefore(ct,insbef);
    
  }else if( wgCanonicalNamespace == '' || wgCanonicalNamespace == 'Talk' ){
  
    addPortletLink('p-cactions',wgArticlePath.replace("$1",'Citations:'+safeTitle),ct_caption,'ca-nstab-citations',ct_title,null,insbef); 
    lookup['Citations:'+wgTitle]=document.getElementById('ca-nstab-citations');

  }else{ //Nothing to see here...
  
    return false;
  
  }
  
  //Now check for red pages
  var ajaxer = sajax_init_object();
  if(! ajaxer) return false;
  
  var url = wgScriptPath+ '/api.php?format=txt&action=query&prop=info&titles=';
  var spl = '';
  for(var page in lookup){
    url+=spl+encodeURIComponent(page);
    spl='|';
  }
  
  ajaxer.onreadystatechange = function(){
    if( ajaxer.readyState == 4 ){
      if( ajaxer.status == 200 ){
        var resps = ajaxer.responseText.split("Array\n");
        for(var i in resps){
          if(resps[i].indexOf('[missing]')>0 ){
            var start = resps[i].indexOf("[title] => ")+11;
            var end = resps[i].indexOf("\n",start);
            make_tab_red(lookup[resps[i].substr(start,end-start)]);
          }
        }
      }
    }
  }

  ajaxer.open("GET", url);
  ajaxer.send('');

  function make_tab_red(tab){

    tab.className = tab.className?'new':tab.className+' new';

    for( var i=0;i<tab.childNodes.length;i++ ){
      var lnk = tab.childNodes[i];    
      if(lnk.nodeName.toUpperCase() == 'A' ){
        var href = lnk.getAttribute('href');
        lnk.setAttribute('href',href+(href.indexOf('?')>0?'&':'?')+'action=edit');
      }
    }
  }
}

addOnloadHook( citations_tab );

/*</pre>

==URL Fixes==
<pre>*/

/**
 * doRedirect will redirect if a did you mean box is found, and create a 
 * "redirected from X" if a rdfrom is passed in the get parameters
 * The first half is an ugly workaround for Bugzilla:3339, :(
 * The second half is an ugly workaround for not having serverware support :(
**/

/*</pre>
===Did you mean ____ redirects===
<pre>*/

function doRedirect() {
  var dym = document.getElementById('did-you-mean')
  var wiktDYMfrom= window.location.href.replace(/^(.+[&\?]rdfrom=([^&]+).*|.*)?$/,"$2");

// REDIRECTED FROM
  if( window.location.href.indexOf('rdfrom=')!=-1 ) {
    var insertPosition= document.getElementById("siteSub");
    var div=document.createElement("div");
    if(insertPosition){
      div.setAttribute("id","contentSub");
      var tt=document.createElement('tt');
      var lnk =document.createElement('a');
      lnk.setAttribute("href",wgArticlePath.replace("$1",wiktDYMfrom)+ '?redirect=no');
      lnk.className="new"; //As they are redlinks
      lnk.appendChild(document.createTextNode(decodeURIComponent(wiktDYMfrom)));
      tt.appendChild(lnk);
      div.appendChild(document.createTextNode("(Auto-redirected from "));
      div.appendChild(tt);
      div.appendChild(document.createTextNode(")"));
      insertPosition.parentNode.insertBefore(div,insertPosition.nextSibling);
      } else {
        alert('No insertposition');
      }

// DID YOU MEAN
    }else{
      if( dym 
          && !window.location.href.match(/[&\?]redirect=no/)
          && (getCookie('WiktionaryDisableAutoRedirect') != 'true')
        ) {
      var target = dym.firstChild.title;
      var pagetitle = document.getElementsByTagName('h1')[0].firstChild.nodeValue;

      if( pagetitle != target 
          && wgArticleId == 0
          && pagetitle.search(/Editing /g) == -1
          && !(document.getElementById('contentSub') && document.getElementById('contentSub').innerHTML.indexOf("Redirected from")>=0) // does contentSub always exist
        ) {
        document.location = wgArticlePath.replace("$1",encodeURIComponent(target.replace(/\ /g, "_")))
                          + '?rdfrom=' + encodeURIComponent(pagetitle.replace(/ /g,"_"));
      }
    }
  }

// Random page in a given language
  document.location.toString().replace(/[?&]rndlang=([^&#]+)[^#]*(?:#(.+))?/, function (m, lang, headlang) {
    var script = 'http://toolserver.org/~hippietrail/randompage.fcgi';

    var insert = document.getElementById('contentSub');
    if (headlang) {
      var heading = document.getElementById(headlang);
      if (heading) heading = heading.parentNode;
      if (heading) {
        insert = newNode('div', {style: 'font-size: 84%; line-height: 1.2em;'});
        heading.parentNode.insertBefore(insert, heading.nextSibling)
      }
    }

    if (!insert || insert.innerHTML != "") return;

    insert.appendChild(newNode('span', {style: 'color: #888;'}, "Another ",
      newNode('a', {href: script + '?langs=1'}, "Random"), " word in ",
      newNode('a', {href: script + '?langname=' + lang}, decodeURIComponent(lang))
    ));
  });
}

addOnloadHook(doRedirect);

/*</pre>

===Fix Wikified section titles===
<pre>*/
addOnloadHook(function () {
  // {temp|template}
  if (/\.7B\.7Btemp\.7C(.*?)\.7D\.7D/.test(window.location.href)) {
    var url=window.location.href.replace(/\.7B\.7Btemp.7C/g, ".7B.7B");
    window.location = url;
  }
});

addOnloadHook(function () {
  if(wgAction != 'edit')
    return;
  if(! /[?&]section=\d/.test(window.location.href))
    return;
  var wpSummary = document.getElementById('wpSummary');
  if(! wpSummary)
    return;
  if(wpSummary.value.substr(0, 3) != '/* ')
    return;
  if(wpSummary.value.substr(wpSummary.value.length - 4) != ' */ ')
    return;
  wpSummary.value = wpSummary.value.replace(/\{\{temp(late)?\|/g, '{{');
});

/*</pre>
==Dynamic Navigation Bars (experimental)==
<pre>*/

 // ============================================================
 // BEGIN Dynamic Navigation Bars (experimental)
 // FIXME: currently only works for one nav bar on a page at a time
 
 // set up the words in your language
 var NavigationBarHide = 'hide ▲';
 var NavigationBarShow = 'show ▼';
 
 // set up max count of Navigation Bars on page,
 // if there are more, all will be hidden
 // NavigationBarShowDefault = 0; // all bars will be hidden
 // NavigationBarShowDefault = 1; // on pages with more than 1 bar all bars will be hidden
 var NavigationBarShowDefault = 1;
 //Honor the User Preferences
 if ( getCookie('WiktionaryPreferencesShowNav') != 'true' ) {
         NavigationBarShowDefault = 0;
    } else {
      if ( wgNamespaceNumber == 0 ) NavigationBarShowDefault = 999 ;
    }
  
/*</pre>
===toggleNavigationBar===
<pre>*/

 // shows and hides content and picture (if available) of navigation bars
 // Parameters:
 //     indexNavigationBar: the index of navigation bar to be toggled
 function toggleNavigationBar(indexNavigationBar)
 {
    var NavToggle = document.getElementById("NavToggle" + indexNavigationBar);
    var NavFrame = document.getElementById("NavFrame" + indexNavigationBar);
 
    if (!NavFrame || !NavToggle) {
        return false;
    }
 
    // if shown now
    if (NavToggle.isHidden == false) {
        for (
                var NavChild = NavFrame.firstChild;
                NavChild;
                NavChild = NavChild.nextSibling
            ) {
            if (NavChild.className == 'NavPic') {
                NavChild.style.display = 'none';
            }
            if (NavChild.className == 'NavContent') {
                NavChild.style.display = 'none';
            }
        }
    NavToggle.childNodes[1].firstChild.nodeValue = NavigationBarShow;
    NavToggle.isHidden = true;
 
    // if hidden now
    } else if (NavToggle.isHidden == true) {
        for (
                var NavChild = NavFrame.firstChild;
                NavChild;
                NavChild = NavChild.nextSibling
            ) {
            if (NavChild.className == 'NavPic') {
                NavChild.style.display = 'block';
            }
            if (NavChild.className == 'NavContent') {
                NavChild.style.display = 'block';
            }
        }
    NavToggle.childNodes[1].firstChild.nodeValue = NavigationBarHide;
    NavToggle.isHidden = false;
    }
 }
 
/*</pre>
===createNavigationBarToggleButton===
<pre>*/

 var wgNavBarArray = new Array();

 // adds show/hide-button to navigation bars
 function createNavigationBarToggleButton()
 {
    // Are we previewing an translation section?
    var preview = document.getElementById('wikiPreview');

    if (preview != null) {
      var p = preview.getElementsByTagName('p');
      if (p != null && p.length >= 2 && p[1].firstChild.id == 'Translations') {
        NavigationBarShowDefault = 999;
      }
    }

    var indexNavigationBar = 0;
    // iterate over all < div >-elements
    for(
            var i=0; 
            NavFrame = document.getElementsByTagName("div")[i]; 
            i++
        ) {
        // if found a navigation bar
        // (Note that a navigation bar is a div whose *sole* class is
        // "NavFrame". That might not be the best approach, but currently
        // {{trans-see}} exploits it, so be cautious in changing that.)
        if (NavFrame.className == "NavFrame") {
 
            indexNavigationBar++;
            var NavToggle = document.createElement("span");
            NavToggle.className = 'NavToggle';
            NavToggle.setAttribute('id', 'NavToggle' + indexNavigationBar);
            
            NavToggle.appendChild(document.createTextNode('['));
            NavToggle.appendChild(document.createElement("a"));
            var NavToggleText = document.createTextNode(NavigationBarHide);
            // These need an href, but must do nothing
            NavToggle.childNodes[1].setAttribute('href', 'javascript:(function(){})()');
            NavToggle.childNodes[1].appendChild(NavToggleText);
            NavToggle.appendChild(document.createTextNode(']'));
            NavToggle.isHidden = false;

            wgNavBarArray[indexNavigationBar - 1] = NavToggle;

            // Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked)
            for(
              var j=0; 
              j < NavFrame.childNodes.length; 
              j++
            ) {
              if (NavFrame.childNodes[j].className == "NavHead") {
                var NavHead = NavFrame.childNodes[j];
                for (var k=0; k < NavHead.childNodes.length; k++) {
                  if (NavHead.childNodes[k].nodeType == 1) { 
                    NavHead.childNodes[k].onclick = function (e) {
                      if (e) {
                        e.stopPropagation ()
                      } else {
                        window.event.cancelBubble = true;
                      }
                    }
                  }
                }
                NavHead.style.cursor = "pointer";
                NavHead.onclick = (function (i) { return function () { toggleNavigationBar(i); } })(indexNavigationBar)
                if( NavHead.childNodes[0] ){
                  NavHead.insertBefore(NavToggle,NavHead.childNodes[0]);
                }else{
                  NavHead.appendChild(NavToggle);
                }
              }
            }
            NavFrame.setAttribute('id', 'NavFrame' + indexNavigationBar);
        }
    }
    // if more Navigation Bars found than Default: hide all
    if (NavigationBarShowDefault < indexNavigationBar) {
        for(
                var i=1; 
                i<=indexNavigationBar; 
                i++
        ) {
            toggleNavigationBar(i);
        }
    }
 
 }
 
 addOnloadHook(createNavigationBarToggleButton);
 
 // END Dynamic Navigation Bars
 // ============================================================

/*

</pre>

==[[MediaWiki:Edittools]]==
<pre>*/

/*</pre>
===applyCharinserts===
<pre>*/

/* handle <span class="charinsert"> like <charinsert> */
function applyCharinserts()
{
  function patchUpInsertTagsArg(arg)
  {
    return(
      arg.replace(/\x22/g,'&quot;').replace(/\x27/g,"\\'").replace(/\x26nbsp;/g,' '));
  }
 
  function charinsertify(s)
  {
    if(s.indexOf('<') > -1)
      return s;
    s = s.replace(/\xA0/g, '\x26nbsp;');
    var strings = s.split(/\s/);
    for(var i = 0; i < strings.length; ++i)
    {
      if(strings[i] == '')
        continue;
      var left, right, index;
      index = strings[i].indexOf('+');
      if(index == -1)
        index = strings[i].length;
      left = strings[i].substring(0, index);
      right = strings[i].substring(index + 1);
      strings[i] = left + right;
      left = patchUpInsertTagsArg(left);
      right = patchUpInsertTagsArg(right);
      strings[i] = "<a onclick=\"insertTags('" + left + "','" + right +
                   "','');return false\" href='#'>" + strings[i] + '</a>';
    }
    return strings.join(' ');
  }
 
  var edittools = document.getElementById('editpage-specialchars');
  if(! edittools)
    return;
  var spans = edittools.getElementsByTagName('span');
  if(! spans)
    return;
  for(var i = 0; i < spans.length; ++i)
  {
    if((' ' + spans[i].className + ' ').indexOf(' charinsert ') == -1)
      continue;
    spans[i].className = spans[i].className.replace(/\bcharinsert\b/, '');
    spans[i].innerHTML = charinsertify(spans[i].innerHTML);
  }
}

/*</pre>

===addCharSubsetMenu===
<pre>*/

/* add menu for selecting subsets of secial characters */
function addCharSubsetMenu() {
  var edittools = document.getElementById('editpage-specialchars');

  if(! edittools)
    return;

  var menu = "<select id='charSubsetControl' style='display:inline' onChange='chooseCharSubset(selectedIndex)'>";

  var pp = edittools.getElementsByTagName('p');
  if(!pp)
    return;
  for(var i = 0; i < pp.length; ++i)
    menu +=
      '<option>' +
      decodeURIComponent
      (
        (''+pp[i].id).replace(/^edittools-/, '')
                     .replace(/\.([0-9A-F][0-9A-F])/g, '%$1')
                     .replace(/_/g, '%20')
      ) +
      '</option>';

  menu += "</select>";
  edittools.innerHTML = menu + edittools.innerHTML;

  /* default subset from cookie */
  var s = parseInt( getCookie('edittoolscharsubset') );
  if ( isNaN(s) ) s = 0;

  /* update dropdown control to value of cookie */
  document.getElementById('charSubsetControl').selectedIndex = s; 

  /* display the subset indicated by the cookie */
  chooseCharSubset( s );
}


/*</pre>
===chooseCharSubsetMenu===
<pre>*/

/* select subsection of special characters */
function chooseCharSubset(s) {
  var l = document.getElementById('editpage-specialchars').getElementsByTagName('p');
  for (var i = 0; i < l.length ; i++) {
    l[i].style.display = i == s ? 'inline' : 'none';
    l[i].style.visibility = i == s ? 'visible' : 'hidden';
  }
  setCookie('edittoolscharsubset', s);
}

/*

</pre>

==Drop-down language preload menu for [[MediaWiki:Noexactmatch]] and [[Wiktionary:Project-Newarticletext]]==
<pre>*/

 function addNogoPreloadMenu() {
  var preloadGuide = document.getElementById('preloadGuide');
  if (preloadGuide) {
   preloadGuide.style.display = 'inline-block';
   var menu = "<select style=\"float: left; display: inline-block; margin: 0 0 0.4em 0.5em;\" onChange=\"showPreloads(selectedIndex)\">";
   menu += "<option>English</option>";
   menu += "<option>American Sign Language</option>";
   menu += "<option>Spanish</option>";
   menu += "<option>Swedish</option>";
   menu += "</select>";
   var menuDiv = document.getElementById('entryTemplateMenu');
   menuDiv.innerHTML = menu;
   showPreloads(0);
  }
 }
 addOnloadHook(addNogoPreloadMenu);

 function showPreloads(selectedIndex) {
  var languageOptions = document.getElementById('preloadGuide').getElementsByTagName('table');
  for (var i = 0; i < languageOptions.length ; i++) {
    if (languageOptions[i].className == "language") {
      languageOptions[i].style.display = i == selectedIndex ? 'block' : 'none';
    }
  }
 }

/*</pre>
==feedback==
<pre>*/

// Solicit feedback from anons

if (wgUserName==null) importScript('User:Conrad.Irwin/feedback.js');

/*</pre>
==customizeWiktionary==
<pre>*/

/* do any Wiktionary-specific customizations */

function customizeWiktionary() {
  addCharSubsetMenu();
  applyCharinserts();
}

addOnloadHook(customizeWiktionary);

/*

</pre>

== Interproject links ==
<pre>*/

/*
#########
### ProjectLinks
###  by [[user:Pathoschild]] (idea from an older, uncredited script)
###    * generates a sidebar list of links to other projects from {{projectlinks}}
#########
*/
function Projectlinks() {
        var elements = new Array();
        var spans = document.getElementsByTagName('span');
        
        // filter for projectlinks
        for (var i=0, j=0; i<spans.length; i++) {
                if (spans[i].className == 'interProject') {
                        elements[j] = spans[i].getElementsByTagName('a')[0];
                        j++;
                }
        }
        
        // sort alphabetically
        function sortbylabel(a,b) {
                // get labels
                a = a.innerHTML.replace(/^.*<a[^>]*>(.*)<\/a>.*$/i,'$1');
                b = b.innerHTML.replace(/^.*<a[^>]*>(.*)<\/a>.*$/i,'$1');

                // return sort order
                if (a < b) return -1;
                if (a > b) return 1;
                return 0;
        }
        elements.sort(sortbylabel);
        
        if (j) {
                // create navbox
                var plheader = document.createElement('h5');
                plheader.appendChild(document.createTextNode('In other projects'));
                var plbox = document.createElement('div');
                plbox.setAttribute('class','pBody');
                plbox.setAttribute('style','margin-top:0.7em;');
                var pllist = document.createElement('ul');

                // append
                for (var i=0; i<elements.length; i++) {
                        var plitem = document.createElement('li');
                        plitem.appendChild(elements[i]);
                        pllist.appendChild(plitem);
                }
                plbox.appendChild(pllist);
                var ptb = document.getElementById("p-tb");
                if(!ptb) return;
                ptb.appendChild(plheader);
                ptb.appendChild(plbox);
        }
}

addOnloadHook(Projectlinks);

/*
</pre>
==Alt shortcuts for namespaces==
<pre>*/

//Added back in until they are otherwise resolved
var ta={};
ta['ca-nstab-project'] = new Array('c','View the project page');
ta['ca-nstab-main'] = new Array('c','View the content page');
ta['ca-nstab-user'] = new Array('c','View the user page');
ta['ca-nstab-media'] = new Array('c','View the media page');
ta['ca-nstab-special'] = new Array('','This is a special page, you can’t edit the page itself.');
ta['ca-nstab-wp'] = new Array('a','View the project page');
ta['ca-nstab-image'] = new Array('c','View the image page');
ta['ca-nstab-mediawiki'] = new Array('c','View the system message');
ta['ca-nstab-template'] = new Array('c','View the template');
ta['ca-nstab-help'] = new Array('c','View the help page');
ta['ca-nstab-category'] = new Array('c','View the category page');
ta['ca-nstab-appendix'] = new Array('c','View the appendix page');
ta['ca-nstab-concordance'] = new Array('c','View the concordance page');
ta['ca-nstab-index'] = new Array('c','View the index page');
ta['ca-nstab-rhymes'] = new Array('c','View the rhymes page');
ta['ca-nstab-transwiki'] = new Array('c','View the imported page');
ta['ca-nstab-wikisaurus'] = new Array('c','View the thesaurus page');
ta['ca-nstab-wt'] = new Array('c','View the shortcut target page');
ta['ca-nstab-citations'] = new Array('c','View the citations page');
ta['ca-nstab-quotations'] = new Array('c','View the quotations page');

/*

[[bs:MediaWiki:Monobook.js]]
[[he:MediaWiki:Monobook.js]]
[[fr:MediaWiki:Monobook.js]]
[[de:MediaWiki:Monobook.js]]
[[ja:MediaWiki:Monobook.js]]
[[vi:MediaWiki:Monobook.js]]
[[zh:MediaWiki:Monobook.js]]

*/