New user account creation has been disabled temporarily. Contact membership at wikimedia.in (via e-mail) if you need one.

MediaWiki:Gadget-HotCat.js

From Wikimedia India Chapter
Revision as of 04:16, 20 October 2014 by Viswaprabha (talk | contribs) (Checking & Testing HotCat Script)

Jump to: navigation, search

Note: After saving, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
<!--  importScript("User:TheDJ/Gadget-HotCat.js") -->/* Script:  [[User:TheDJ/Gadget-HotCat.js]]  * HotCat: Adds an easy way to add, modify and remove categories   * Documentation: [[User:TheDJ/HotCat]]  * Originally written by: Magnus Manske  *   * This version was forked from http://commons.wikimedia.org/w/index.php?title=MediaWiki:Gadget-HotCat.js&oldid=10204404  * In sync with version: http://commons.wikimedia.org/w/index.php?title=MediaWiki:Gadget-HotCat.js&oldid=19600669  * Major changes:  *   - all code for the uploadForm has been removed  *   - autocommit is disabled  *   - will be enabled on pages without categories so that you can easily add them  *   - uses javascript:void() as a dummy value for href in order to avoid a conflict with popups.  *   - checks for {{Uncategorized}} and removes it if a category is added  *   - does not use JSconfig for configuration options like its Commons original  *   - tries to detect other categories and if possible, add to the end of them.  *   - fixes a bug in the suggestion list with titles containing : character  *   - Uses opensearch API to look for categories. Allows for case insensitive search.  *   - Postfix blacklisting in addition to prefix blacklisting.  * [[User:TheDJ]] 2009-04-18  <source lang="javascript"><nowiki> */var hotcat_running = 0 ;var hotcat_last_v = "" ;var hotcat_exists_yes = "http://upload.wikimedia.org/wikipedia/commons/thumb/b/be/P_yes.svg/20px-P_yes.svg.png" ;var hotcat_exists_no = "http://upload.wikimedia.org/wikipedia/commons/thumb/4/42/P_no.svg/20px-P_no.svg.png" ;var hotcat_no_autocommit = 0;// In Commons hotcat_suggestion_delay is configurable trough JSconfigvar hotcat_suggestion_delay = 100;var hotcat_old_onsubmit = null;var hotcat_nosuggestions = false;// hotcat_nosuggestions is set to true if we don't have XMLHttp! (On IE6, XMLHttp uses// ActiveX, and the user may deny execution.) If true, no suggestions will ever be// displayed, and there won't be any checking whether the category  exists.// Lupo, 2008-01-20var hotcat_modify_blacklist = new Array (" stubs") ;var hotcat_cnames=["[Cc]ategory"]; // namespaces and alias of category                                   // in chinese: categoryNames=["[Cc]ategory","分类","分類"];addOnloadHook ( hotcat ) ;function hotcat () {  if ( hotcat_check_action() ) return ; // Edited page, reloading anyway  // Do not add interface to protected pages, if user has no edit permission  // Also disable it on preview pages: on a preview, we *are* already editing,  // and HotCat must not open the page for editing a second time. Lupo, 2008-02-27  if( wgAction != "view" || document.getElementById('ca-viewsource' ) != null ||      wgNamespaceNumber == -1 || wgNamespaceNumber == 10 )    return;  // If we have no Categories div, then add one  // TheDJ, 2008-02-28    var visible_catlinks = document.getElementById ('mw-normal-catlinks') || getElementsByClassName ( document , "p" , "catlinks" ) [0];  var hidden_catlinks = document.getElementById ('mw-hidden-catlinks');  if ( visible_catlinks == null || typeof( visible_catlinks ) == 'undefined' ) {    d3 = document.createElement ( "div" );    d3.id = "mw-normal-catlinks";    d3.innerHTML = '<a href="/wiki/Special:Categories" title="Special:Categories">Categories</a>: ';    visible_catlinks = d3;    if ( hidden_catlinks ) {      // There are hidden categories.      hidden_catlinks.parentNode.insertBefore( d3, hidden_catlinks );      hidden_catlinks.parentNode.className = "catlinks";    } else {      // This page has no categories at all, lets create a section where we can add them.      var footer = getElementsByClassName ( document , "div" , "printfooter" ) [0];      if( !footer ) return; // We have no idea where we should add this.      d1 = document.createElement ( "div" );      d1.id = "catlinks";      d1.className = "catlinks";      d1.appendChild ( d3 );      footer.parentNode.insertBefore( d1, footer.nextSibling );    }   }  hotcat_modify_existing ( visible_catlinks ) ;  hotcat_append_add_span ( visible_catlinks ) ;}function hotcat_append_add_span ( catline ) {  var span_add = document.createElement ( "span" ) ;  var span_sep = document.createTextNode ( " | " ) ;  if ( catline.getElementsByTagName("span")[0] ) catline.appendChild ( span_sep ) ;  catline.appendChild ( span_add ) ;  hotcat_create_span ( span_add ) ;}String.prototype.ucFirst = function () {   return this.substr(0,1).toUpperCase() + this.substr(1,this.length);}function hotcat_is_on_blacklist ( cat_title ) {  if ( !cat_title ) return 0 ;  for ( var i = 0 ; i < hotcat_modify_blacklist.length ; i++ ) {      /* prefix */    if ( cat_title.substr ( 0 , hotcat_modify_blacklist[i].length )            == hotcat_modify_blacklist[i] ) return 1 ;    /* postfix */    var postfix_len = cat_title.length - hotcat_modify_blacklist[i].length;    if ( postfix_len >= 0 && cat_title.substr ( postfix_len, hotcat_modify_blacklist[i].length )            == hotcat_modify_blacklist[i] ) return 1 ;  }  return 0 ;}function hotcat_modify_span ( span , i ) {  //var cat_title = span.firstChild.getAttribute ( "title" ) ;  // This fails with MW 1.13alpha if the category is a redlink, because MW 1.13alpha appends  // [[MediaWiki:Red-link-title]] to the category name... it also fails if the category name  // contains "&" (because that is represented by &amp; in the XHTML both in the title and in  // the link's content (innerHTML). Extract the category name from the href instead:  var cat_title = null;  var classes   = span.firstChild.getAttribute ('class');  if (classes && classes.search (/\bnew\b/) >= 0) {  // href="/w/index.php?title=...&action=edit"    cat_title = hotcatGetParamValue ('title', span.firstChild.href);  } else { // href="/wiki/..."    var re = new RegExp (wgArticlePath.replace (/\$1/, '(.*)'));    var matches = re.exec (span.firstChild.href);    if (matches && matches.length > 1)      cat_title = decodeURIComponent (matches[1]);    else      return;  }  // Strip namespace, replace _ by blank  cat_title = cat_title.substring (cat_title.indexOf (':') + 1).replace (/_/g, ' ');  var sep1 = document.createTextNode ( " " ) ;  var a1 = document.createTextNode ( "(-)" ) ;  var remove_link = document.createElement ( "a" ) ;  // Set the href to a dummy value to make sure we don't move if somehow the onclick handler  // is bypassed.  remove_link.className = "noprint";  remove_link.href = "#catlinks";  remove_link.onclick = hotcat_remove;  remove_link.appendChild ( a1 ) ;  span.appendChild ( sep1 ) ;  span.appendChild ( remove_link ) ;  if ( hotcat_is_on_blacklist ( cat_title ) ) return ;  var mod_id = "hotcat_modify_" + i ;  var sep2 = document.createTextNode ( " " ) ;  var a2 = document.createTextNode ( "(±)" ) ;  var modify_link = document.createElement ( "a" ) ;  modify_link.id = mod_id ;  modify_link.className = "noprint";  modify_link.href = "javascript:hotcat_modify(\"" + mod_id + "\");" ;  modify_link.appendChild ( a2 ) ;  span.appendChild ( sep2 ) ;  span.appendChild ( modify_link ) ;  span.hotcat_name = cat_title; //Store the extracted category name in our own new property of the span DOM node}function hotcat_modify_existing ( catline ) {  var spans = catline.getElementsByTagName ( "span" ) ;  for ( var i = 0 ; i < spans.length ; i++ ) {    hotcat_modify_span ( spans[i] , i ) ;  }}function hotcat_getEvt (evt) {  return evt || window.event || window.Event; // Gecko, IE, Netscape}  function hotcat_evt2node (evt) {  var node = null;  try {    var e = hotcat_getEvt (evt);    node = e.target;    if (!node) node = e.srcElement;  } catch (ex) {    node = null;  }  return node;}function hotcat_evtkeys (evt) {  var code = 0;  try {    var e = hotcat_getEvt (evt);    if (typeof(e.ctrlKey) != 'undefined') { // All modern browsers      if (e.ctrlKey)  code |= 1;      if (e.shiftKey) code |= 2;      if (e.altKey) code |= 4;    } else if (typeof (e.modifiers) != 'undefined') { // Netscape...      if (e.modifiers & Event.CONTROL_MASK) code |= 1;      if (e.modifiers & Event.SHIFT_MASK)   code |= 2;      if (e.modifiers & Event.ALT_MASK)   code |= 4;    }  } catch (ex) {  }  return code;}function hotcat_killEvt (evt){  try {    var e = hotcat_getEvt (evt);    if (typeof (e.preventDefault) != 'undefined') {      e.preventDefault();      e.stopPropagation()    } else      e.cancelBubble = true;  } catch (ex) {  }}  function hotcat_remove (evt) {  var node = hotcat_evt2node (evt);  if (!node) return false;  // Get the category name from the original link to the category  var cat_title = node.parentNode.hotcat_name;    var editlk = wgServer + wgScript + '?title=' + encodeURIComponent (wgPageName) + '&action=edit';  if ((hotcat_evtkeys (evt) & 1) || (hotcat_evtkeys (evt) & 4 )) // CTRL or ALT pressed?    editlk = editlk + '&hotcat_nocommit=1';  hotcat_killEvt (evt);  document.location = editlk + '&hotcat_removecat=' + encodeURIComponent(cat_title) ;  return false;}function hotcatGetParamValue(paramName, h) {  if (typeof h == 'undefined' ) { h = document.location.href; }  var cmdRe=RegExp('[&?]'+paramName+'=([^&]*)');  var m=cmdRe.exec(h);  if (m) {    try {      return decodeURIComponent(m[1]);    } catch (someError) {}  }  return null;}// New. Code by Lupo & Superm401, added by Lupo, 2008-02-2007function hotcat_find_category (wikitext, category){  var cat_name  = category.replace(/([\\\^\$\.\?\*\+\(\)])/g, "\\$1");  var initial   = cat_name.substr (0, 1);  var cat_regex = new RegExp ("\\[\\[\\s*(?:" + hotcat_cnames.join("|") + ")\\s*:\\s*"                              + (initial == "\\"                                 ? initial                                 : "[" + initial.toUpperCase() + initial.toLowerCase() + "]")                              + cat_name.substring (1).replace (/[ _]/g, "[ _]")                              + "\\s*(\\|.*?)?\\]\\]", "g"                             );  var result = new Array ();  var curr_match  = null;  while ((curr_match = cat_regex.exec (wikitext)) != null) {    result [result.length] = {match : curr_match};  }  return result; // An array containing all matches, with positions, in result[i].match}// New. Code by TheDJ, 2008-03-12function hotcat_find_ins ( wikitext ){  var re = new RegExp("\\[\\[\\s*(?:" + hotcat_cnames.join("|") + ")\\s*:\[^\\]\]+\\]\\]", "ig" );  var index = -1;  while( re.exec(wikitext) != null ) index = re.lastIndex;    if( index > -1) return index;  //we should try to find interwiki links here, but that's for later.  return -1;}// Rewritten (nearly) from scratch. Lupo, 2008-02-27function hotcat_check_action () {  var ret = 0;  if (wgAction != 'edit' || typeof(document.editform) == "undefined" ) return ret; // Not an edit page, so not our business...  var summary = new Array () ;  var t = document.editform.wpTextbox1.value ;  var prevent_autocommit = 0;  if (   (typeof (hotcat_no_autocommit) != "undefined" && hotcat_no_autocommit)      || hotcatGetParamValue ('hotcat_nocommit') == '1')    prevent_autocommit = 1;  var cat_rm  = hotcatGetParamValue ('hotcat_removecat');  var cat_add = hotcatGetParamValue ('hotcat_newcat');  var comment = hotcatGetParamValue ('hotcat_comment') || "";  var cat_key = hotcatGetParamValue ('hotcat_sortkey');  if (cat_key != null) cat_key = '|' + cat_key;  if (cat_rm != null && cat_rm.length > 0) {    var matches = hotcat_find_category (t, cat_rm);    if (!matches || matches.length == 0) {      alert ('Category "' + cat_rm + '" not found; maybe it is in a template?');      prevent_autocommit = 1;    } else if (matches.length > 1) {      alert ('Category "' + cat_rm             + "\" found several times; don't know which occurrence to remove.");      prevent_autocommit = 1;    } else {      if (cat_add != null && cat_add.length > 0 && matches[0].match.length > 1)        cat_key = matches[0].match[1]; // Remember the category key, if any.      var t1 = t.substring (0, matches[0].match.index);      var t2 = t.substring (matches[0].match.index + matches[0].match[0].length);      // Remove whitespace (properly): strip whitespace, but only up to the next line feed.      // If we then have two linefeeds in a row, remove one. Otherwise, if we have two non-      // whitespace characters, insert a blank.      var i = t1.length - 1;      while (i >= 0 && t1.charAt (i) != '\n' && t1.substr (i, 1).search (/\s/) >= 0) i--;      var j = 0;      while (j < t2.length && t2.charAt (j) != '\n' && t1.substr (j, 1).search (/\s/) >= 0) j++;      if (i >= 0 && t1.charAt (i) == '\n' && j < t2.length && t2.charAt (j) == '\n')        i--;      if (i >= 0) t1 = t1.substring (0, i+1); else t1 = "";      if (j < t2.length) t2 = t2.substring (j); else t2 = "";      if (t1.length > 0 && t1.substring (t1.length - 1).search (/\S/) >= 0          && t2.length > 0 && t2.substr (0, 1).search (/\S/) >= 0)        t1 = t1 + ' ';      t = t1 + t2;      summary.push ( "Removed category \[\[:Category:" + cat_rm + "|" + cat_rm + "\]\]" ) ;      ret = 1;    }  }  if (cat_add != null && cat_add.length > 0) {    var matches = hotcat_find_category (t, cat_add);    if (matches && matches.length > 0) {      alert ('Category "' + cat_add + '" already exists; not added.');      prevent_autocommit = 1;    } else {      var insertionpoint = hotcat_find_ins( t );      var newcatstring = '\n\[\[Category:' + cat_add + (cat_key != null ? cat_key : "") + '\]\]';      if( insertionpoint > -1 ) {        t = t.substring(0, insertionpoint ) + newcatstring + t.substring( insertionpoint );      } else {        t = t + newcatstring;      }      summary.push ("Adding category \[\[:Category:" + cat_add + "|" + cat_add + "\]\]" + comment);      var t2 = t.replace(/\{\{[Uu]ncategorized[^}]*\}\}/g, ""); // Remove "uncategorized" template      if (t2.length != t.length) {        t = t2;        summary.push ( "removed {{uncategorized}}" ) ;      }      ret = 1;    }  }  if (ret) {    document.editform.wpTextbox1.value = t ;    document.editform.wpSummary.value = summary.join( "; " )                                      + " ( using HotCat)" ;    document.editform.wpMinoredit.checked = true ;    if (!prevent_autocommit) {      // Hide the entire edit section so as not to tempt the user into editing...      var bodyContentId = document.getElementById("bodyContent") //monobook skin          || document.getElementById("mw_contentholder")   // modern skin          || document.getElementById ("article");          // classic skin      bodyContentId.style.display = "none";      document.editform.submit();    }  }  return ret;}function hotcat_clear_span ( span_add ) {  while ( span_add.firstChild ) span_add.removeChild ( span_add.firstChild ) ;}function hotcat_create_span ( span_add ) {  hotcat_clear_span ( span_add ) ;  var a_add = document.createElement ( "a" ) ;  var a_text = document.createTextNode ( "(+)" ) ;  span_add.id = "hotcat_add" ;  a_add.className = "noprint";  a_add.href = "javascript:hotcat_add_new()" ;  a_add.appendChild ( a_text ) ;  span_add.appendChild ( a_add ) ;}function hotcat_modify ( link_id ) {  var link = document.getElementById ( link_id ) ;  var span = link.parentNode ;  var catname = span.hotcat_name;  while ( span.firstChild.nextSibling ) span.removeChild ( span.firstChild.nextSibling ) ;  span.firstChild.style.display = "none" ;  hotcat_create_new_span ( span , catname ) ;  hotcat_last_v = "" ;  hotcat_text_changed () ; // Update icon}function hotcat_add_new () {  var span_add = document.getElementById ( "hotcat_add" ) ;  hotcat_clear_span ( span_add ) ;  hotcat_last_v = "" ;  hotcat_create_new_span ( span_add , "" ) ;}function hotcat_create_new_span ( thespan , init_text ) {  var form = document.createElement ( "form" ) ;  form.method = "post" ;  form.onsubmit = function () { hotcat_ok(); return false; } ;   form.id = "hotcat_form" ;  form.style.display = "inline" ;  var list = null;    if (!hotcat_nosuggestions) {    // Only do this if we may actually use XMLHttp...    list = document.createElement ( "select" ) ;    list.id = "hotcat_list" ;    list.onclick = function ()      {        var l = document.getElementById("hotcat_list");        if (l != null)          document.getElementById("hotcat_text").value = l.options[l.selectedIndex].text;        hotcat_text_changed();      };    list.ondblclick = function (evt)      {        var l = document.getElementById("hotcat_list");        if (l != null)          document.getElementById("hotcat_text").value = l.options[l.selectedIndex].text;        // Don't call text_changed here if on upload form: hotcat_ok will remove the list        // anyway, so we must not ask for new suggestions since show_suggestions might        // raise an exception if it tried to show a no longer existing list.        // Lupo, 2008-01-20        hotcat_text_changed();        hotcat_ok((hotcat_evtkeys (evt) & 1) || (hotcat_evtkeys (evt) & 4)); // CTRL or ALT pressed?      };    list.style.display = "none" ;  }    var text = document.createElement ( "input" ) ;  text.size = 40 ;  text.id = "hotcat_text" ;  text.type = "text" ;  text.value = init_text ;  text.onkeyup = function () { window.setTimeout("hotcat_text_changed();", hotcat_suggestion_delay ); } ;  var exists = null;  if (!hotcat_nosuggestions) {    exists = document.createElement ( "img" ) ;    exists.id = "hotcat_exists" ;    exists.src = hotcat_exists_no ;  }  var OK = document.createElement ( "input" ) ;  OK.type = "button" ;  OK.value = "OK" ;  OK.onclick = function (evt) { hotcat_ok ((hotcat_evtkeys (evt) & 1) || (hotcat_evtkeys (evt) & 4)); }; // CTRL or ALT pressed?  var cancel = document.createElement ( "input" ) ;  cancel.type = "button" ;  cancel.value = "Cancel" ;  cancel.onclick = hotcat_cancel ;  if (list != null) form.appendChild ( list ) ;  form.appendChild ( text ) ;  if (exists != null) form.appendChild ( exists ) ;  form.appendChild ( OK ) ;  form.appendChild ( cancel ) ;  thespan.appendChild ( form ) ;  text.focus () ;}function hotcat_ok (nocommit) {  var text = document.getElementById ( "hotcat_text" ) ;  var v = text.value || "";   v = v.replace(/_/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); // Trim leading and trailing blanks    // Empty category ?  if (!v) {    hotcat_cancel() ;    return ;  } else if ( hotcat_is_on_blacklist(v) ) {      alert( 'This type of category needs to be added using a template' );      return;  }  // Get the links and the categories of the chosen category page  var url = wgServer + wgScriptPath + '/api.php?action=query&titles='          + encodeURIComponent ('Category:' + v)          + '&prop=info|links|categories&plnamespace=14&format=json&callback=hotcat_json_resolve';  var request = sajax_init_object() ;  if (request == null) {    //Oops! We don't have XMLHttp...    hotcat_nosuggestions = true;    hotcat_closeform (nocommit);    hotcat_running = 0;    return;  }  request.open ('GET', url, true);  request.onreadystatechange =    function () {      if (request.readyState != 4) return;      if (request.status != 200) {        hotcat_closeform (nocommit);      } else {        var do_submit = eval (request.responseText);        var txt = document.getElementById ('hotcat_text');        if (do_submit) {          hotcat_closeform (             nocommit            ,(txt && txt.value != v) ? " (redirect \[\[:Category:" + v + "|" + v + "\]\] resolved)" : null          );        }      }    };  request.setRequestHeader ('Pragma', 'cache=yes');  request.setRequestHeader ('Cache-Control', 'no-transform');  request.send (null);}function hotcat_json_resolve (params){  function resolve (page)  {    var cats     = page.categories;    var is_dab   = false;    var is_redir = typeof (page.redirect) == 'string'; // Hard redirect?    if (!is_redir && cats) {      for (var c = 0; c < cats.length; c++) {        var cat = cats[c]["title"];        if (cat) cat = cat.substring (cat.indexOf (':') + 1); // Strip namespace prefix        if (cat == 'Disambiguation') {          is_dab = true; break;        } else if (cat == 'Category_redirects' || cat == 'Category redirects') {          is_redir = true; break;        }      }    }    if (!is_redir && !is_dab) return true;    var lks = page.links;    var titles = new Array ();    for (i = 0; i < lks.length; i++) {      if (   lks[i]["ns"] == 14                               // Category namespace          && lks[i]["title"] && lks[i]["title"].length > 0) { // Name not empty        // Internal link to existing thingy. Extract the page name.        var match = lks[i]["title"];        // Remove the category prefix        match = match.substring (match.indexOf (':') + 1);        titles.push (match);        if (is_redir) break;      }    }    if (titles.length > 1) {      // Disambiguation page      hotcat_show_suggestions (titles);      return false;    } else if (titles.length == 1) {      var text = document.getElementById ("hotcat_text");      if (text) text.value = titles[0];    }    return true;  } // end local function resolve  // We should have at most one page here  for (var page in params.query.pages) return resolve (params.query.pages[page]);  return true; // In case we have none.}function hotcat_closeform (nocommit, comment){  var text = document.getElementById ( "hotcat_text" ) ;  var v = text.value || "";   v = v.replace(/_/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); // Trim leading and trailing blanks  if (!v                                                 // Empty      || wgNamespaceNumber == 14 && v == wgTitle         // Self-reference      || text.parentNode.parentNode.id != 'hotcat_add'   // Modifying, but         && text.parentNode.parentNode.hotcat_name == v) //   name unchanged  {    hotcat_cancel ();    return;  }    var editlk = wgServer + wgScript + '?title=' + encodeURIComponent (wgPageName) + '&action=edit';  var url = editlk + '&hotcat_newcat=' + encodeURIComponent( v ) ;  // Editing existing?  var span = text.parentNode.parentNode ; // span.form.text  if ( span.id != "hotcat_add" ) { // Not plain "addition"       url += '&hotcat_removecat=' + encodeURIComponent (span.hotcat_name);  }  if (nocommit) url = url + '&hotcat_nocommit=1';  if (comment) url = url + '&hotcat_comment=' + encodeURIComponent (comment);  // Make the list disappear:  var list = document.getElementById ( "hotcat_list" ) ;  if (list) list.style.display = 'none';      document.location = url ;}function hotcat_just_add ( text ) {  var span = document.getElementById("hotcat_form") ;  while ( span.tagName != "SPAN" ) span = span.parentNode ;  var add = 0 ;  if ( span.id == "hotcat_add" ) add = 1 ;  span.id = "" ;  while ( span.firstChild ) span.removeChild ( span.firstChild ) ;  var na = document.createElement ( "a" ) ;  na.href = wgArticlePath.split("$1").join("Category:" + encodeURI (text)) ;  na.appendChild ( document.createTextNode ( text ) ) ;  na.setAttribute ( "title" , "Category:" + text ) ;  span.appendChild ( na ) ;  var catline = getElementsByClassName ( document , "p" , "catlinks" ) [0] ;  if ( add ) hotcat_append_add_span ( catline ) ;  for ( var i = 0 ; i < span.parentNode.childNodes.length ; i++ ) {    if ( span.parentNode.childNodes[i] != span ) continue ;    hotcat_modify_span ( span , i ) ;    break ;  }}function hotcat_cancel () {  var span = document.getElementById("hotcat_form").parentNode ;  if ( span.id == "hotcat_add" ) {    hotcat_create_span ( span ) ;  } else {    while ( span.firstChild.nextSibling ) span.removeChild ( span.firstChild.nextSibling ) ;    span.firstChild.style.display = "" ;    for ( var i = 0 ; i < span.parentNode.childNodes.length ; i++ ) {      if ( span.parentNode.childNodes[i] != span ) continue ;      hotcat_modify_span ( span , i ) ;      break ;    }  }}function hotcat_text_changed () {  if ( hotcat_running ) return ;  var text = document.getElementById ( "hotcat_text" ) ;  var v = text.value.ucFirst() ;  if ( hotcat_last_v == v ) return ; // Nothing's changed...  if (hotcat_nosuggestions) {    // On IE, XMLHttp uses ActiveX, and the user may deny execution... just make sure    // the list is not displayed.    var list = document.getElementById ('hotcat_list');    if (list != null) list.style.display = "none" ;    var exists = document.getElementById ('hotcat_exists');    if (exists != null) exists.style.display = "none" ;    return;  }    hotcat_running = 1 ;  hotcat_last_v = v ;  if ( v != "" ) {    var url = wgMWSuggestTemplate.replace("{namespaces}","14")                                    .replace("{dbname}",wgDBname)                                    .replace("{searchTerms}",encodeURIComponent(v));    var request = sajax_init_object() ;    if (request == null) {      //Oops! We don't have XMLHttp...      hotcat_nosuggestions = true;      var list = document.getElementById ('hotcat_list');      if (list != null) list.style.display = "none" ;      var exists = document.getElementById ('hotcat_exists');      if (exists != null) exists.style.display = "none" ;      hotcat_running = 0;      return;    }     request.open('GET', url, true);    request.onreadystatechange =      function () {        if (request.readyState == 4) {          try {            eval( "var queryResult="+ request.responseText );          } catch (someError ) {            if( console && console.log )              console.log( "Oh dear, our JSON query went down the drain?\nError: " +someError );            return;          }          var pages = queryResult[1]; // results are *with* namespace here          var titles = new Array();          for ( var i = 0 ; pages && i < pages.length ; i++ ) {            // Remove the namespace. No hardcoding of 'Category:', please, other Wikis may have            // local names ("Kategorie:" on de-WP, for instance). Also don't break on category            // names containing a colon            var s = pages[i].substring (pages[i].indexOf (':') + 1);            if ( s.substr ( 0 , hotcat_last_v.length ).toLowerCase() != hotcat_last_v.toLowerCase() ) break ;            titles.push ( s ) ;          }          hotcat_show_suggestions ( titles ) ;        }      };    request.setRequestHeader ('Pragma', 'cache=yes');    request.setRequestHeader ('Cache-Control', 'no-transform');    request.send(null);  } else {    hotcat_show_suggestions ( new Array () ) ;  }  hotcat_running = 0 ;}function hotcat_show_suggestions ( titles ) {  var text = document.getElementById ( "hotcat_text" ) ;  var list = document.getElementById ( "hotcat_list" ) ;  var icon = document.getElementById ( "hotcat_exists" ) ;  // Somehow, after a double click on the selection list, we still get here in IE, but  // the list may no longer exist... Lupo, 2008-01-20  if (list == null) return;  if (hotcat_nosuggestions) {    list.style.display = "none" ;    if (icon != null) icon.style.display = "none";    return;  }  if ( titles.length == 0 ) {    list.style.display = "none" ;    icon.src = hotcat_exists_no ;    return ;  }    // Set list size to minimum of 5 and actual number of titles. Formerly was just 5.  // Lupo, 2008-01-20  list.size = (titles.length > 5 ? 5 : titles.length) ;  // Avoid list height 1: double-click doesn't work in FF. Lupo, 2008-02-27  if (list.size == 1) list.size = 2;  list.style.align = "left" ;  list.style.zIndex = 5 ;  list.style.position = "absolute" ;  // Was listh = titles.length * 20: that makes no sense if titles.length > list.size  // Lupo, 2008-01-20  var listh = list.size * 20;  var nl = parseInt (text.offsetLeft) - 1 ;  var nt = parseInt (text.offsetTop) - listh ;  if (skin == 'nostalgia' || skin == 'cologneblue' || skin == 'standard') {    // These three skins have the category line at the top of the page. Make the suggestions    // appear *below* out input field.    nt = parseInt (text.offsetTop) + parseInt (text.offsetHeight) + 3;  }  list.style.top = nt + "px" ;  list.style.width = text.offsetWidth + "px" ;  list.style.height = listh + "px" ;  list.style.left = nl + "px" ;  while ( list.firstChild ) list.removeChild ( list.firstChild ) ;  for ( var i = 0 ; i < titles.length ; i++ ) {    var opt = document.createElement ( "option" ) ;    var ot = document.createTextNode ( titles[i] ) ;    opt.appendChild ( ot ) ;    //opt.value = titles[i] ;    list.appendChild ( opt ) ;  }    icon.src = hotcat_exists_yes ;  var nof_titles = titles.length;  var first_title = titles.shift ();  var v = text.value.ucFirst();  text.focus();  if ( first_title == v ) {    if( nof_titles == 1 ) {      // Only one result, and it's the same as whatever is in the input box: makes no sense      // to show the list.      list.style.display = "none";    }    return;  }  list.style.display = "block" ;  // Put the first entry of the title list into the text field, and select the  // new suffix such that it'll be overwritten if the user keeps typing.  // ONLY do this if we have a way to select parts of the content of a text  // field, otherwise, this is very annoying for the user. Note: IE does it  // again differently from the two versions previously implemented.  // Lupo, 2008-01-20  // Only put first entry into the list if the user hasn't typed something   // conflicting yet Dschwen 2008-02-18  if ( ( text.setSelectionRange ||         text.createTextRange ||         typeof (text.selectionStart) != 'undefined' &&         typeof (text.selectionEnd) != 'undefined' ) &&         v == first_title.substr(0,v.length) )  {    // taking hotcat_last_v was a major annoyance,     // since it constantly killed text that was typed in    // _since_ the last AJAX request was fired! Dschwen 2008-02-18    var nosel = v.length ;      text.value = first_title ;        if (text.setSelectionRange)      // e.g. khtml      text.setSelectionRange (nosel, first_title.length);    else if (text.createTextRange) { // IE      var new_selection = text.createTextRange();      new_selection.move ("character", nosel);      new_selection.moveEnd ("character", first_title.length - nosel);      new_selection.select();    } else {      text.selectionStart = nosel;      text.selectionEnd   = first_title.length;    }  }}/* </nowiki></source> */