User:Fl/scripts/secedit.js

///////////////////////////////////////// // By Alek Storm with modifications by Foxy Loxy // Please see talk page for instructions ///////////////////////////////////////// var body; // shortcut for body node var xmlhttp; // XMLHTTPRequest object var startNode; // div that includes section header and edit link var editSec; // edit link var editForm; // spliced edit form var preview; // spliced preview or diff content var oldContent; // original content of section var xmlhttpDone = false; // kludge to prevent multiple calls to callback importScript("User:Supadawg/util.js"); function inc(path) { var lt = String.fromCharCode(60); var gt = String.fromCharCode(62); document.writeln(lt+'script type="text/javascript" src="/w/index.php?title='+path+'&action=raw&ctype=text/javascript&dontcountme=s"'+gt+lt+'/script'+gt); } function initSecEdit { if (wgNamespaceNumber == "0") return; body = document.getElementsByTagName("body")[0]; // apply to all divs of class "editsection" var editSecs = document.getElementsByTagName("span"); var pagetitleRe=/\/w\/index\.php\?title=(.*)\&action=edit\&section=(.*)/; // from [Wikipedia:WikiProject User scripts/Techniques] for ( var i = 0; i < editSecs.length; i++ ) { if ( editSecs[i].getAttribute("class") == "editsection" ) { for ( var k = 0; k < editSecs[i].childNodes.length; k++ ) { if ( editSecs[i].childNodes[k].nodeName == "A" ) { // grab editing uri, escape it, then put it back in         var hrefatt = editSecs[i].childNodes[k].getAttribute("href"); var decodeduri = decodeURI(hrefatt); var regexarr = pagetitleRe.exec(decodeduri); var titlematch = regexarr[1]; var sectionmatch = regexarr[2]; var title = encodeURIComponent2(titlematch).replace(/\"/gi, "%22").replace(/\'/gi, "%27");         var section = encodeURIComponent2(sectionmatch).replace(/\"/gi, "%22").replace(/\'/gi, "%27"); var editURI = "http://en.wikipedia.org/w/index.php?title=" +title+"&action=edit&section="+section; // give it a unique id         editSecs[i].childNodes[k].setAttribute( "id", "editSection"+section ); // swap the href with a function call, passing the original href as the second parameter editSecs[i].childNodes[k].setAttribute( "href", "javascript:editSection( document.getElementById('editSection" + section + "'), '"+editURI+"' );" ); }     }    }  } } // called on click of section edit link function editSection( elem, editURI ) { cancelEdit; // get rid of any other sections being edited editSec = elem; startNode = elem.parentNode.parentNode; // initiate xmlhttprequest for section edit page xmlhttpDone = false; xmlhttp = null // kludge xmlhttp = createXMLHTTP( "GET", editURI, stateChange ); } // put raw input returned from XMLHTTPRequest into a div so we can grab specific elements function makeDiv( rawHTML ) { var div = createNode( body, "div", {style: "visibility: hidden; position: absolute;"} ); div.innerHTML = rawHTML.replace(/]*><\/script>/gi, ""); // if script tags are placed into the DOM, they force reload of files, and nasty things happen return div; } function isHTag( node ) { return node.nodeName.charAt(0) == 'H' && !isNaN( parseInt( node.nodeName.charAt(1) ) ); } // callback for onclick of an edit link function stateChange { if ( xmlhttp && xmlhttp.readyState == 4 ) { if ( xmlhttp.status == 200 ) { if ( xmlhttpDone ) return; xmlhttpDone = true; // store old content of section - loop until we hit header of same spot in hierarchy if ( !oldContent ) { oldContent = makeDiv(""); var curElem = startNode.nextSibling; //var searchRegex = /\[.*<\/a>\]/; while ( curElem ) { var hitSiblingSection = false; if ( isHTag( curElem ) ) { for ( var i = 0; i < curElem.childNodes.length; i++ ) { if ( curElem.childNodes[i].nodeName == "SPAN"		  && curElem.childNodes[i].getAttribute("class") == "editsection"		   && parseInt( curElem.nodeName.charAt(1) ) <= parseInt( startNode.nodeName.charAt(1) ) ) { //var regexarr = searchRegex.exec(curElem.childNodes[i].nodeValue); //var link = regexarr[1]; //var title = regexarr[2]; //alert(link+"<<link   "+title"<<< title    "); hitSiblingSection = true; }         }          else if ( curElem.nodeName == "DIV" && curElem.getAttribute("class") == "printfooter" ) break; if ( hitSiblingSection ) break; var nextElem = curElem.nextSibling; oldC ontent.appendChild( curElem ); curElem = nextElem; }     }      else removeNode( oldContent ); var div = makeDiv( xmlhttp.responseText ); editForm = $("editform"); // change onclick of preview and diff buttons to our function $("wpPreview").setAttribute( "type", "button" ); $("wpPreview").setAttribute( "onclick", "javascript:getEditData( previewChanged, $('wpPreview') );" ); $("wpDiff").setAttribute( "type", "button" ); $("wpDiff").setAttribute( "onclick", "javascript:getEditData( diffChanged, $('wpDiff') );" ); insertAfter( editForm, startNode ); removeNode( div ); editSec.setAttribute( "oldHref", editSec.getAttribute("href") ); editSec.setAttribute( "href", "javascript:cancelEdit;" ); editSec.innerHTML = "cancel"; }   else alert("Problem retrieving data - status: "+xmlhttp.status); } } // firefox hack, not sure if this is a problem in other browsers function encodeURIComponent2( content ) { // from content = content.replace(/\&lt\;/gi, "<"); content = content.replace(/\&gt\;/gi, ">"); content = content.replace(/\&quot\;/gi, "\""); content = content.replace(/\&amp\;/gi, "&");  return encodeURIComponent( content ); } // encode differently based on type of form element function field2Post( node, allowButton ) {  var reqBody = "";  switch ( node.nodeName ) {    case "TEXTAREA":      reqBody += "&"+node.getAttribute("name")+"="+encodeURIComponent2( node.value );      break;    case "INPUT":      var inputType = node.getAttribute("type");      if ( inputType == "checkbox" ) {        if ( node.checked )          reqBody += "&"+node.getAttribute("name")+"=on"      }      else if ( allowButton || (inputType != "submit" && inputType != "button") )        reqBody += "&"+node.getAttribute("name")+"="+encodeURIComponent2( node.value );      break;    case "DIV":      reqBody += form2Post( node, false );      break;  }  return reqBody; } // manually encodes a form element for XMLHTTPRequest function form2Post( node ) { var reqBody = ""; for ( var i = 0; i < node.childNodes.length; i++ ) reqBody += field2Post( node.childNodes[i], false ); return reqBody; } // get preview or diff data function getEditData( callback, clickedBut ) { xmlhttpDone = false; xmlhttp = null; // kludge var action = editForm.getAttribute("action"); xmlhttp = createXMLHTTP( "POST", "http://en.wikipedia.org"+action, callback, {   body: form2Post( editForm ) + field2Post( clickedBut, true ),    headers: {      "Content-Type": "application/x-www-form-urlencoded",      "Referer": "http://en.wikipedia.org" + action.substring( 0, action.indexOf('&') ) + "&action=edit&section="+(parseInt(editSec.getAttribute("id").substring(11))+1)    }  } ); } // callback for preview data function previewChanged { if ( xmlhttp && xmlhttp.readyState == 4 ) { if ( xmlhttp.status == 200 ) { if ( xmlhttpDone ) return; xmlhttpDone = true; var div = makeDiv( xmlhttp.responseText ); if ( preview ) removeNode( preview ); preview = $("wikiPreview"); insertAfter( preview, startNode ); removeNode( div ); }   else alert("Problem retrieving data - status: "+xmlhttp.status); } } // callback for diff data function diffChanged { if ( xmlhttp && xmlhttp.readyState == 4 ) { if ( xmlhttp.status == 200 ) { if ( xmlhttpDone ) return; xmlhttpDone = true; var div = makeDiv( xmlhttp.responseText ); if ( preview ) removeNode( preview ); preview = $("wikiDiff"); insertAfter( preview, startNode ); removeNode( div ); }   else alert("Problem retrieving data - status: "+xmlhttp.status); } } // remove form and preview or diff data function cancelEdit { if ( preview ) removeNode( preview ); preview = null; if ( editForm ) removeNode( editForm ); editForm = null; if ( oldContent ) { oldContent.setAttribute( "style", "position: static; visibility: visible;" ); insertAfter( oldContent, startNode ); } oldContent = null; if ( editSec ) { editSec.setAttribute( "href", editSec.getAttribute("oldHref") ); editSec.innerHTML = "edit"; } } addEventListener( "load", initSecEdit, false );