User:Tyrok1/monobook.js: Difference between revisions
Content added Content deleted
(Fixing long lines and escaping problem) |
(Trying out "link directly to language example" script) |
||
Line 1: | Line 1: | ||
/*======================================== |
/*======================================== |
||
This comparison script was written by |
This comparison script was written by |
||
Tyrok1, and has been tested on |
Tyrok1, and has been tested on IE 5.5, |
||
IE 6, IE 7, IE 8, Fx 3.6.2, and |
|||
Cr 5.0.375.99, Epiphany 2.30.2, |
|||
Fe 4.0.280. |
|||
========================================*/ |
========================================*/ |
||
function SectionLinkCreateLoadClosure(request) |
|||
var gadgetsAvailable = [ |
|||
{ |
|||
return function() { |
|||
if(request.readyState == 4) |
|||
{ |
|||
//done loading |
|||
//initialize the "languages with link information" array |
|||
if(typeof localStorage == "undefined") |
|||
{ |
{ |
||
window.localStorage = new Array(); |
|||
id: "LanguageComparison", |
|||
} |
|||
name: "Language comparison", |
|||
if(typeof localStorage.languageLinks = "undefined") |
|||
url: "http://rosettacode.org/mw/index.php" + |
|||
"?title=Rosetta_Code:Language_comparison_script" + |
|||
"&action=raw&ctype=text/javascript", |
|||
prefix: "Compare" |
|||
}, |
|||
{ |
{ |
||
localStorage.languageLinks = new Array(); |
|||
id: "UtilityButtonBar", |
|||
} |
|||
name: "Utility button bar", |
|||
url: "http://rosettacode.org/mw/index.php" + |
|||
//skip the toc |
|||
"?title=Rosetta_Code:Per-Code_Example_Buttonbar" + |
|||
var text = request.responseText; |
|||
"&action=raw&ctype=text/javascript", |
|||
var curPos = text.indexOf(" id=\"toctitle\""); |
|||
prefix: "ButtonBar" |
|||
var catLinksStart = text.indexOf("catlinks"); |
|||
curPos = text.indexOf("</table>", curPos); |
|||
//start looking for anchor tags with name attributes |
|||
while((curPos = text.indexOf("a name=\"", curPos)) >= 0) |
|||
{ |
|||
//isolate the name attribute |
|||
curPos += ("a name=\"").length; |
|||
var endPos = text.indexOf("\"", curPos); |
|||
var curAName = text.substring(curPos, endPos); |
|||
//find the next anchor with a name attribute so we know where the next section is |
|||
var nextA = text.indexOf("a name=\"", endPos); |
|||
//look for a language header |
|||
var headlinePos = text.indexOf("mw-headline", endPos); |
|||
if(nextA < headlinePos || text.substring(endPos, headlinePos).indexOf("h3") >= 0) |
|||
{ |
|||
//no <h2> header |
|||
//not a full language section |
|||
continue; |
|||
} |
|||
//look for the end of the header and isolate the content of the header |
|||
var headlineEnd = text.indexOf("</h2>", headlinePos); |
|||
var headline = text.substring(headlinePos, headlineEnd); |
|||
//isolate the language category page it links to |
|||
var hrefStart = headline.indexOf(" href=\"") + (" href=\"").length; |
|||
var hrefEnd = headline.indexOf("\"", hrefStart); |
|||
var curHREF = headline.substring(hrefStart, hrefEnd); |
|||
//isolate the displayed text name of the language |
|||
var titleStart = headline.indexOf(" title=\"Category:") + (" title=\"Category:").length; |
|||
var titleEnd = headline.indexOf("\"", titleStart); |
|||
var curTitle = headline.substring(titleStart, titleEnd); |
|||
//check to make sure we have all the information we need about this language |
|||
if(curAName == "" || curHREF == "" || curTitle == "") |
|||
{ |
|||
//something's missing |
|||
continue; |
|||
} |
|||
//add the language to our array for later use |
|||
localStorage.languageLinks[curTitle] = { aName: curAName, href: curHREF, title: curTitle }; |
|||
} |
|||
//and if we've got a function to call when we're done, call it |
|||
if(request.callback) |
|||
{ |
|||
request.callback(); |
|||
} |
} |
||
]; |
|||
function GadgetsAddHandler(el, handlerType, func) |
|||
{ |
|||
//add an event handler in a more cross-browser way |
|||
if(el.addEventListener) |
|||
{ |
|||
el.addEventListener(handlerType, func, false); |
|||
} |
|||
else if(el.attachEvent) |
|||
{ |
|||
el.attachEvent("on" + handlerType, func); |
|||
} |
|||
else |
|||
{ |
|||
eval("el.on" + handlerType + " = func;"); |
|||
} |
|||
} |
|||
function GadgetsScriptLoad(g) |
|||
{ |
|||
//see if we need to load it |
|||
//if we don't, there's not much point in loading it again |
|||
if(!document.getElementById("GadgetScript" + g)) |
|||
{ |
|||
var scriptEl = document.createElement("script"); |
|||
scriptEl.setAttribute("id", "GadgetScript" + g); |
|||
scriptEl.setAttribute("type", "text/javascript"); |
|||
scriptEl.setAttribute("src", gadgetsAvailable[g].url); |
|||
document.documentElement.appendChild(scriptEl); |
|||
} |
|||
} |
|||
function GadgetsScriptActivate(g) |
|||
{ |
|||
//check to see if the script's finished loading |
|||
if(eval("typeof " + gadgetsAvailable[g].prefix + "Activate") == "undefined") |
|||
{ |
|||
//not finished yet - try reactivating in another 0.5s |
|||
setTimeout(function() { GadgetsScriptActivate(g); }, 500); |
|||
} |
|||
else |
|||
{ |
|||
//run the activation function |
|||
eval(gadgetsAvailable[g].prefix + "Activate();"); |
|||
} |
|||
} |
|||
function GadgetsScriptDeactivate(g) |
|||
{ |
|||
//check to see if the specified script has a deactivation function |
|||
if(eval("typeof " + gadgetsAvailable[g].prefix + "Deactivate") != "undefined") |
|||
{ |
|||
//it does - run it |
|||
eval(gadgetsAvailable[g].prefix + "Deactivate();"); |
|||
} |
|||
else |
|||
{ |
|||
//pop up a warning to the user to let them know |
|||
//the plugin will be disabled when they reload |
|||
alert("This script will be disabled on next page load"); |
|||
} |
|||
} |
|||
function GadgetsCreateCheckboxClosure(el) |
|||
{ |
|||
//create an onclick handler for the script checkboxes |
|||
return function() { |
|||
//save the checkboxes to the cookie for next page load |
|||
GadgetsSaveCheckboxes(); |
|||
//check to see if we need to activate or deactivate |
|||
if(el.checked) |
|||
{ |
|||
//load and activate the script |
|||
GadgetsScriptLoad(el.value); |
|||
GadgetsScriptActivate(el.value); |
|||
} |
|||
else |
|||
{ |
|||
//deactivate the script |
|||
GadgetsScriptDeactivate(el.value); |
|||
} |
} |
||
}; |
}; |
||
} |
} |
||
function |
function SectionLinkFetchFrom(url, callback) |
||
{ |
{ |
||
//fetch the given page and store all <a name>/language pairs on the page to the cookie for later |
|||
//show the scripts dropdown |
|||
var request = new XMLHttpRequest(); |
|||
document.getElementById("pt-jsgadgets-list").style.display = "block"; |
|||
request.onreadystatechange = SectionLinkCreateLoadClosure(request); |
|||
request.callback = callback; |
|||
request.open("GET", url, true); |
|||
request.send(""); |
|||
} |
} |
||
function |
function SectionLinkActivate() |
||
{ |
{ |
||
//check to see if we're looking at a language page |
|||
//hide the scripts dropdown |
|||
document.getElementById(" |
var catLinksEl = document.getElementById("catlinks"); |
||
var isLanguage = false; |
|||
} |
|||
if(catLinksEl) |
|||
function GadgetsSaveCheckboxes() |
|||
{ |
|||
var checkedBoxes = "", checkboxEl = null; |
|||
//build a string representation of all of the checked boxes to save to the cookie |
|||
for(var c = 0; checkboxEl = document.getElementById("pt-jsgadgets-gadget" + c); ++c) |
|||
{ |
{ |
||
var aEls = catLinksEl.getElementsByTagName("a"); |
|||
if(checkboxEl.checked) |
|||
for(var a = 0; a < aEls.length; ++a) |
|||
{ |
{ |
||
if(aEls[a].getAttribute("title") == "Category:Programming Languages") |
|||
if(checkedBoxes != "") |
|||
{ |
{ |
||
//it's a language |
|||
isLanguage = true; |
|||
break; |
|||
} |
} |
||
checkedBoxes += gadgetsAvailable[c].id; |
|||
} |
} |
||
} |
} |
||
if(!isLanguage) |
|||
//set an expiry date 1000 years into the future |
|||
var expireDate = new Date(); |
|||
expireDate.setFullYear(expireDate.getFullYear() + 1000); |
|||
//store the cookie |
|||
document.cookie = "jsGadgets=" + escape(checkedBoxes) + |
|||
"; expires=" + expireDate.toUTCString(); |
|||
} |
|||
function GadgetsGetCheckboxes() |
|||
{ |
|||
//pull in the cookie and look for the jsGadgets key |
|||
var fullCookie = document.cookie; |
|||
var gadgetsPos = fullCookie.indexOf("jsGadgets="); |
|||
if(gadgetsPos < 0) |
|||
{ |
{ |
||
// |
//we're not on a language page |
||
//this script does not apply |
|||
return new Array(); |
|||
return; |
|||
} |
} |
||
var endPos = fullCookie.indexOf(";", gadgetsPos); |
|||
//check this page's "firstHeading" ID content for a category name |
|||
//split the gadget IDs by comma |
|||
var firstHeadingEl = document.getElementById("firstHeading"); |
|||
var jsGadgets = fullCookie.substring(gadgetsPos + ("jsGadgets=").length, |
|||
var langName = (firstHeadingEl.textContent ? firstHeadingEl.textContent : firstHeadingEl.innerText); |
|||
(endPos > 0 ? endPos : fullCookie.length)); |
|||
langName = langName.substring(("Category:").length, langName.length); |
|||
var checkIDs = unescape(jsGadgets).split(","); |
|||
// |
//get a list of all task pages on this page for later use |
||
var tasksEl = document.getElementById("mw-pages"); |
|||
//in keeping with the way the rest of this module works |
|||
var |
var aEls = tasksEl.getElementsByTagName("a"); |
||
for(var g = 0; g < gadgetsAvailable.length; ++g) |
|||
//check to see if we already have link information about the current language |
|||
if(localStorage.languageLinks && localStorage.languageLinks[langName]) |
|||
{ |
{ |
||
//we do |
|||
for(var c = 0; c < checkIDs.length; ++c) |
|||
//modify all of the links on the page to link directly to the current language's section |
|||
for(var i = 0; i < aEls.length; ++i) |
|||
{ |
{ |
||
if( |
if(aEls[i].href.indexOf("#") < 0) |
||
{ |
{ |
||
aEls[i].href += "#" + encodeURIComponent(localStorage.languageLinks[langName].aName); |
|||
checkIndices[checkIndices.length] = g; |
|||
break; |
|||
} |
} |
||
} |
} |
||
} |
} |
||
else |
|||
return checkIndices; |
|||
} |
|||
function GadgetsActivate() |
|||
{ |
|||
//find the user preferences button and add a new list item to the right of it |
|||
var prefsEl = document.getElementById("pt-preferences"); |
|||
if(!prefsEl) |
|||
{ |
{ |
||
//we do not have link information on the current language |
|||
var personalEl = document.getElementById("p-personal"); |
|||
//start fetching task pages and searching through them, starting with the first task link on the page |
|||
if(!personalEl) |
|||
if(typeof SectionLinkActivate.linkNum == "undefined") |
|||
{ |
{ |
||
SectionLinkActivate.linkNum = 0; |
|||
return; |
|||
} |
} |
||
var liEls = personalEl.getElementsByTagName("li"); |
|||
//only check the first five task links |
|||
if(!liEls || liEls.length < 2) |
|||
if(SectionLinkActivate.linkNum >= 5) |
|||
{ |
{ |
||
return; |
return; |
||
} |
} |
||
prefsEl = liEls[liEls.length - 2]; |
|||
} |
|||
var jsMenuEl = prefsEl.parentNode.insertBefore( |
|||
document.createElement("li"), prefsEl.nextSibling); |
|||
jsMenuEl.setAttribute("id", "pt-jsgadgets"); |
|||
//add a new link named "My scripts" in the new list item |
|||
//from a semantics point of view, this is not great, |
|||
//but this way the styling kicks in to keep it consistent with its siblings |
|||
var jsLinkEl = jsMenuEl.appendChild(document.createElement("a")); |
|||
jsLinkEl.appendChild(document.createTextNode("My scripts")); |
|||
jsLinkEl.setAttribute("href", "javascript: void(0);"); |
|||
jsLinkEl.style.position = "relative"; |
|||
//add handlers for showing on mouseover and hiding on mouseout |
|||
GadgetsAddHandler(jsLinkEl, "mouseover", GadgetsMouseOver); |
|||
GadgetsAddHandler(jsLinkEl, "mouseout", GadgetsMouseOut); |
|||
//build a list for showing available JS gadgets |
|||
var modulesListEl = jsLinkEl.appendChild(document.createElement("ol")); |
|||
modulesListEl.setAttribute("id", "pt-jsgadgets-list"); |
|||
modulesListEl.style.listStyle = "none"; |
|||
modulesListEl.style.margin = 0; |
|||
modulesListEl.style.padding = 0; |
|||
modulesListEl.style.position = "absolute"; |
|||
modulesListEl.style.top = "100%"; |
|||
modulesListEl.style.left = 0; |
|||
modulesListEl.style.backgroundColor = "#fff"; |
|||
modulesListEl.style.border = "1px solid #69c"; |
|||
modulesListEl.style.padding = "0.5em"; |
|||
modulesListEl.style.display = "none"; |
|||
//raise the zIndex of the new button (as well as |
|||
//a few parents) so the menu overlaps the page |
|||
var zEl = modulesListEl; |
|||
for(var z = 0; z < 6 && zEl && zEl.style; ++z, zEl = zEl.parentNode) |
|||
{ |
|||
zEl.style.zIndex = 100; |
|||
} |
|||
//add each of the gadgets to the list |
|||
for(var m = 0; m < gadgetsAvailable.length; ++m) |
|||
{ |
|||
//add the list item element |
|||
var liEl = modulesListEl.appendChild(document.createElement("li")); |
|||
liEl.style.display = "block"; |
|||
liEl.style.cssFloat = "none"; |
|||
liEl.style.right = "auto"; |
|||
liEl.style.left = 0; |
|||
liEl.style.textAlign = "left"; |
|||
liEl.style.margin = 0; |
|||
liEl.style.padding = 0; |
|||
//fetch and process the task, and rerun this activation function when done |
|||
//add the checkbox |
|||
SectionLinkFetchFrom(aEls[SectionLinkActivate.linkNum].href, SectionLinkActivate); |
|||
var inputEl = document.createElement("input"); |
|||
var checkboxId = "pt-jsgadgets-gadget" + m; |
|||
inputEl.setAttribute("type", "checkbox"); |
|||
inputEl.setAttribute("id", checkboxId); |
|||
inputEl.setAttribute("value", m); |
|||
GadgetsAddHandler(inputEl, "click", GadgetsCreateCheckboxClosure(inputEl)); |
|||
liEl.appendChild(inputEl); |
|||
//update the link number so we move on to the next link if the current one doesn't have this language |
|||
//add the label |
|||
++SectionLinkActivate.linkNum; |
|||
var labelEl = document.createElement("label"); |
|||
labelEl.setAttribute("for", checkboxId); |
|||
labelEl.appendChild(document.createTextNode(gadgetsAvailable[m].name)); |
|||
labelEl.style.paddingLeft = "1em"; |
|||
liEl.appendChild(labelEl); |
|||
} |
|||
//fetch the saved checkboxes from the cookie |
|||
var checks = GadgetsGetCheckboxes(); |
|||
for(var c = 0; c < checks.length; ++c) |
|||
{ |
|||
//for each one that should be checked on page load, |
|||
//check the box, load, and activate it |
|||
document.getElementById("pt-jsgadgets-gadget" + checks[c]).checked = true; |
|||
GadgetsScriptLoad(checks[c]); |
|||
GadgetsScriptActivate(checks[c]); |
|||
} |
} |
||
} |
} |
||
//register the |
//register the link correcting script with the window's load event |
||
if(window.addEventListener) |
|||
GadgetsAddHandler(window, "load", GadgetsActivate); |
|||
{ |
|||
window.addEventListener("load", SectionLinkActivate, false); |
|||
} |
|||
else if(window.attachEvent) |
|||
{ |
|||
window.attachEvent("onload", SectionLinkActivate); |
|||
} |
|||
else if(document.addEventListener) |
|||
{ |
|||
document.addEventListener("load", SectionLinkActivate, false); |
|||
} |
|||
else |
|||
{ |
|||
window.onload = SectionLinkActivate; |
|||
} |
Revision as of 23:54, 6 October 2010
/*========================================
This comparison script was written by
Tyrok1, and has been tested on IE 5.5,
IE 6, IE 7, IE 8, Fx 3.6.2, and
Fe 4.0.280.
========================================*/
function SectionLinkCreateLoadClosure(request)
{
return function() {
if(request.readyState == 4)
{
//done loading
//initialize the "languages with link information" array
if(typeof localStorage == "undefined")
{
window.localStorage = new Array();
}
if(typeof localStorage.languageLinks = "undefined")
{
localStorage.languageLinks = new Array();
}
//skip the toc
var text = request.responseText;
var curPos = text.indexOf(" id=\"toctitle\"");
var catLinksStart = text.indexOf("catlinks");
curPos = text.indexOf("</table>", curPos);
//start looking for anchor tags with name attributes
while((curPos = text.indexOf("a name=\"", curPos)) >= 0)
{
//isolate the name attribute
curPos += ("a name=\"").length;
var endPos = text.indexOf("\"", curPos);
var curAName = text.substring(curPos, endPos);
//find the next anchor with a name attribute so we know where the next section is
var nextA = text.indexOf("a name=\"", endPos);
//look for a language header
var headlinePos = text.indexOf("mw-headline", endPos);
if(nextA < headlinePos || text.substring(endPos, headlinePos).indexOf("h3") >= 0)
{
//no <h2> header
//not a full language section
continue;
}
//look for the end of the header and isolate the content of the header
var headlineEnd = text.indexOf("</h2>", headlinePos);
var headline = text.substring(headlinePos, headlineEnd);
//isolate the language category page it links to
var hrefStart = headline.indexOf(" href=\"") + (" href=\"").length;
var hrefEnd = headline.indexOf("\"", hrefStart);
var curHREF = headline.substring(hrefStart, hrefEnd);
//isolate the displayed text name of the language
var titleStart = headline.indexOf(" title=\"Category:") + (" title=\"Category:").length;
var titleEnd = headline.indexOf("\"", titleStart);
var curTitle = headline.substring(titleStart, titleEnd);
//check to make sure we have all the information we need about this language
if(curAName == "" || curHREF == "" || curTitle == "")
{
//something's missing
continue;
}
//add the language to our array for later use
localStorage.languageLinks[curTitle] = { aName: curAName, href: curHREF, title: curTitle };
}
//and if we've got a function to call when we're done, call it
if(request.callback)
{
request.callback();
}
}
};
}
function SectionLinkFetchFrom(url, callback)
{
//fetch the given page and store all <a name>/language pairs on the page to the cookie for later
var request = new XMLHttpRequest();
request.onreadystatechange = SectionLinkCreateLoadClosure(request);
request.callback = callback;
request.open("GET", url, true);
request.send("");
}
function SectionLinkActivate()
{
//check to see if we're looking at a language page
var catLinksEl = document.getElementById("catlinks");
var isLanguage = false;
if(catLinksEl)
{
var aEls = catLinksEl.getElementsByTagName("a");
for(var a = 0; a < aEls.length; ++a)
{
if(aEls[a].getAttribute("title") == "Category:Programming Languages")
{
//it's a language
isLanguage = true;
break;
}
}
}
if(!isLanguage)
{
//we're not on a language page
//this script does not apply
return;
}
//check this page's "firstHeading" ID content for a category name
var firstHeadingEl = document.getElementById("firstHeading");
var langName = (firstHeadingEl.textContent ? firstHeadingEl.textContent : firstHeadingEl.innerText);
langName = langName.substring(("Category:").length, langName.length);
//get a list of all task pages on this page for later use
var tasksEl = document.getElementById("mw-pages");
var aEls = tasksEl.getElementsByTagName("a");
//check to see if we already have link information about the current language
if(localStorage.languageLinks && localStorage.languageLinks[langName])
{
//we do
//modify all of the links on the page to link directly to the current language's section
for(var i = 0; i < aEls.length; ++i)
{
if(aEls[i].href.indexOf("#") < 0)
{
aEls[i].href += "#" + encodeURIComponent(localStorage.languageLinks[langName].aName);
}
}
}
else
{
//we do not have link information on the current language
//start fetching task pages and searching through them, starting with the first task link on the page
if(typeof SectionLinkActivate.linkNum == "undefined")
{
SectionLinkActivate.linkNum = 0;
}
//only check the first five task links
if(SectionLinkActivate.linkNum >= 5)
{
return;
}
//fetch and process the task, and rerun this activation function when done
SectionLinkFetchFrom(aEls[SectionLinkActivate.linkNum].href, SectionLinkActivate);
//update the link number so we move on to the next link if the current one doesn't have this language
++SectionLinkActivate.linkNum;
}
}
//register the link correcting script with the window's load event
if(window.addEventListener)
{
window.addEventListener("load", SectionLinkActivate, false);
}
else if(window.attachEvent)
{
window.attachEvent("onload", SectionLinkActivate);
}
else if(document.addEventListener)
{
document.addEventListener("load", SectionLinkActivate, false);
}
else
{
window.onload = SectionLinkActivate;
}