var HOST = '<$MTBlogHost$>'; // Copyright (c) 1996-1997 Athenia Associates. // http://www.webreference.com/js/ // License is granted if and only if this entire // copyright notice is included. By Tomer Shiran. //Adapted by J. Distler for XHTML compatibility, Mar 2003. function setCookie (name, value, expires, path, domain, secure) { var curCookie = name + "=" + escape(value) + ((expires) ? "; expires=" + expires.toGMTString() : "") + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : ""); document.cookie = curCookie; } function getCookie (name) { var prefix = name + '='; var c = document.cookie; if (!c) return ''; var nullstring = ''; var cookieStartIndex = c.indexOf(prefix); if (cookieStartIndex == -1) return nullstring; var cookieEndIndex = c.indexOf(";", cookieStartIndex + prefix.length); if (cookieEndIndex == -1) cookieEndIndex = c.length; return unescape(c.substring(cookieStartIndex + prefix.length, cookieEndIndex)); } function deleteCookie (name, path, domain) { if (getCookie(name)) document.cookie = name + "=" + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + "; expires=Thu, 01-Jan-70 00:00:01 GMT"; } function fixDate (date) { var base = new Date(0); var skew = base.getTime(); if (skew > 0) date.setTime(date.getTime() - skew); } function rememberMe () { var now = new Date(); fixDate(now); now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); setCookie('mtcmtauth', document.getElementById('author').value, now, '/', HOST, ''); setCookie('mtcmtmail', document.getElementById('email').value, now, '/', HOST, ''); setCookie('mtcmthome', document.getElementById('url').value, now, '/', HOST, ''); } function forgetMe () { deleteCookie('mtcmtmail', '/', HOST); deleteCookie('mtcmthome', '/', HOST); deleteCookie('mtcmtauth', '/', HOST); document.getElementById('email').value = ''; document.getElementById('author').value = ''; document.getElementById('url').value = ''; } function setIEcookie () { var now = new Date(); fixDate(now); now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); setCookie('ieLuser', 'luser', now, '/', HOST, ''); } function warnIE() { var havemp = false; var temp, version; if ( (navigator.appName == "Microsoft Internet Explorer" ) && !(navigator.userAgent.indexOf("Opera") > -1) ) { if ( !getCookie('ieLuser') ) { setIEcookie (); window.open('ie.html', 'InternetExploder', 'width=460,height=246,scrollbars=no,resizable=yes,status=no'); } else { if ( navigator.userAgent.indexOf("MathPlayer") > -1) { havemp = true; } temp=navigator.appVersion.split("MSIE"); version=parseFloat(temp[1]); if ( (version >= 6.0) && !havemp && !getCookie('hateMP') ) { window.open('mp.html', 'MathPlayer', 'width=460,height=146,scrollbars=no,resizable=yes,status=no'); } } } } function OpenComments (c) { window.open(c, Math.round(Math.random()*10000), 'width=600,height=480,scrollbars=yes,resizable=yes,status=yes'); } function OpenRSS () { window.open('<$MTBlogURL relative_url="1">rss.html', 'RSS', 'width=305,height=190,scrollbars=no,resizable=yes,status=no'); } function styleAbbr() { var oldBodyText, newBodyText, reg if ( (navigator.appName == "Microsoft Internet Explorer" ) && !(navigator.userAgent.indexOf("Opera") > -1) ) { oldBodyText = document.body.innerHTML; reg = /<(ABBR|ACRONYM)([^>]+)>([^<]+)<\/(ABBR|ACRONYM)>/g; newBodyText = oldBodyText.replace(reg, '<$1 $2>$3'); document.body.innerHTML = newBodyText; } } /* * Based on Simon Willison's blockquotes.js * http://simon.incutio.com/archive/2002/12/20/#blockquoteCitations */ function extractBlockquoteCitations() { var quotes = document.getElementsByTagName('blockquote'); for (i = 0; i < quotes.length; i++) { var cite = quotes[i].getAttribute('cite'); if (cite && cite != '') { var newlink = createElement('a'); newlink.setAttribute('href', cite); newlink.setAttribute('title', cite); newlink.appendChild(document.createTextNode('#')); var newspan = createElement('span'); newspan.setAttribute('class','blockquotesource'); newspan.appendChild(newlink); var foo = quotes[i].lastChild; if (foo.nodeType == 1) { foo.appendChild(newspan); } else { foo.previousSibling.appendChild(newspan); } } } } /* * Editable AccessKeys 0.13.4 * Copyright, 2006 Jacques Distler. All rights reserved. * This software is released under LGPL. * * See https://golem.ph.utexas.edu/~distler/blog/archives/000723.html * for explanations. * * version 0.13.4 Workaround for broken DOM Event support in IE6. * version 0.12 Fixed a bug reported by Rich Pedley. * version 0.11 Revised to disable Gez's updated script. * version 0.10.2 Disable Gez Lemon's Greasemonkey script, which does * the same thing. * version 0.9 Eliminate need for wrapper DIV. Accesskey definition-list * is assumed to have id="AccessKeyList" * version 0.8, Keyboard navigation fix for Opera * version 0.7, Separator character changed to TAB. * version 0.6, Added onkeypress event handler for Safari-compatibility * version 0.5, Initial release. */ /* * Global variables: */ accesskeylistid="AccessKeyList"; /* Id of the accesskey definition-list */ accesskeystarttabindex = 1; /* Tabindex values assigned to edit fields start with this value*/ defaultaccesskeys = new Array(); /* Array to hold the default values */ originalaccesskeys = new Array(); /* Array to hold the original values */ myaccesskeys = new Array(); /* Array to hold the user-edited values */ accesskeyelements = new Array(); /* Associative array to contain all elements with an accesskey attribute */ function initializeAccessKeys() { /* * This is meant to run onload. * Initialize the defaultaccesskeys and myaccesskeys arrays. * These are either taken from a cookie or from the document. * Extract all the elements on the current page with an accesskey attribute * into the associative array "accesskeyelements". * If necessary, rewrite the values of the accesskey attributes on * the current page . * Add an "edit" button. * Disable Gez Lemon's Greasemonkey script, which does the same thing. */ var dl = document.getElementById(accesskeylistid); var keylist = dl.getElementsByTagName('dt'); for (i = 0; i < keylist.length; i++){ defaultaccesskeys[i] = keylist[i].firstChild.data; myaccesskeys[i] = defaultaccesskeys[i]; originalaccesskeys[i] = defaultaccesskeys[i]; } var taglist = ['a','label','area','button','input','legend','textarea']; for (i=0; i < taglist.length; i++) { var mytags=document.getElementsByTagName(taglist[i]); for (j=0; j < mytags.length; j++){ var myaccesskeyval = mytags[j].getAttribute('accesskey'); if (myaccesskeyval != '') { accesskeyelements[myaccesskeyval]=mytags[j]; } } } var savedaccesskeystring = getCookie('accessKeys'); if (savedaccesskeystring != '') { var savedacceskeys= new Array(); savedaccesskeys = savedaccesskeystring.split('\t'); if (savedaccesskeys.length == defaultaccesskeys.length) { for (i = 0; i < defaultaccesskeys.length; i++){ if (accesskeyelements[originalaccesskeys[i]] ) { if (accesskeyelements[originalaccesskeys[i]].accessKey) { accesskeyelements[originalaccesskeys[i]].accessKey = myaccesskeys[i]; } else { accesskeyelements[originalaccesskeys[i]].setAttribute( 'accesskey', myaccesskeys[i]); } } if (accesskeyelements[originalaccesskeys[i]] ) { if (accesskeyelements[originalaccesskeys[i]].accessKey) { accesskeyelements[originalaccesskeys[i]].accessKey = savedaccesskeys[i]; } else { accesskeyelements[originalaccesskeys[i]].setAttribute( 'accesskey', savedaccesskeys[i]); } } defaultaccesskeys[i] = savedaccesskeys[i]; myaccesskeys[i] = savedaccesskeys[i]; keylist[i].replaceChild(document.createTextNode(myaccesskeys[i]), keylist[i].firstChild); } } } var edit = createElement('input'); edit.setAttribute('id', 'editAccessKeys'); edit.setAttribute('type', 'button'); edit.setAttribute('value', 'edit'); edit.onclick = editAccessKeys; edit.onkeypress = function() { if(window.event.keyCode == 13) {editAccessKeys();return false;} }; if (edit.tabindex) { edit.tabindex = defaultaccesskeys.length+accesskeystarttabindex; } else { edit.setAttribute('tabindex', defaultaccesskeys.length+accesskeystarttabindex); } var dlparent = dl.parentNode; dlparent.insertBefore(edit,dl.nextSibling); var greasy = document.getElementById('jsgmAccessKeyContainer'); if(greasy) { greasy.replaceChild(dlparent,greasy.firstChild); var toremove = ['jsgmEdit','jsgmRestore','jsgmToggle']; for (i=0; i < toremove.length; i++ ) greasy.removeChild( document.getElementById(toremove[i])); document.getElementsByTagName('head')[0].removeChild( document.getElementById('jsgmAccessKeyStyles')); document.getElementsByTagName('body')[0].setAttribute('style','padding-bottom:4em'); var keystyle= 'background:#CCC;color:#000;border:outset 2px; padding:1px 2px;'; var key1 = createElement('span'); key1.appendChild(document.createTextNode('Shift')); key1.setAttribute('style',keystyle + 'margin-left:48px;'); dlparent.appendChild(key1); dlparent.appendChild(document.createTextNode('+')); var key2 = createElement('span'); key2.appendChild(document.createTextNode('Esc')); key2.setAttribute('style',keystyle); dlparent.appendChild(key2); dlparent.appendChild(document.createTextNode(' to toggle menu')); greasy.setAttribute('style', 'position:fixed;bottom:0;left:0;margin:0;width:100%;border-top:2px solid #666'); } } function saveAccessKeys() { /* * Replace the default values of the accesskeys by the ones * from the myaccesskeys array. * Change the accesskey attribute values in the current document. * Store these values in a cookie. * Remove the editing fields. * Replace the "reset" and "save" buttons by the 'edit" button. */ var dl = document.getElementById(accesskeylistid); var keylist = dl.getElementsByTagName('dt'); for (i = 0; i < keylist.length; i++){ keylist[i].replaceChild(document.createTextNode(myaccesskeys[i]), keylist[i].firstChild); if (accesskeyelements[originalaccesskeys[i]]) { if (accesskeyelements[originalaccesskeys[i]].accessKey) { accesskeyelements[originalaccesskeys[i]].accessKey = myaccesskeys[i]; } else { accesskeyelements[originalaccesskeys[i]].setAttribute('accesskey', myaccesskeys[i]); } } defaultaccesskeys[i] = myaccesskeys[i]; } var expires = new Date(); var base = new Date(0); var offset = base.getTime(); if (offset > 0) { expires.setTime(expires.getTime()-offset); } expires.setTime(expires.getTime() + 365 * 24 * 60 * 60 * 1000); document.cookie = 'accessKeys=' + escape(myaccesskeys.join('\t')) + "; expires=" + expires.toGMTString() + "; path=/; domain=" + HOST; var editbutton = document.getElementById('editAccessKeys'); editbutton.setAttribute('value','edit'); editbutton.onclick = editAccessKeys; editbutton.onkeypress = function() { if(window.event.keyCode == 13) {editAccessKeys();return false} }; var savebutton = document.getElementById('saveAccessKeys'); dl.parentNode.removeChild(savebutton); } function resetAccessKeys() { /* * Revert the myaccesskeys array to the default values. * Remove the editing fields. * Replace the "revert" and "save" buttons by the "edit" button. */ var dl = document.getElementById(accesskeylistid); var keylist = dl.getElementsByTagName('dt'); for (i = 0; i < keylist.length; i++){ keylist[i].replaceChild(document.createTextNode(defaultaccesskeys[i]), keylist[i].firstChild); myaccesskeys[i] = defaultaccesskeys[i]; } var editbutton = document.getElementById('editAccessKeys'); editbutton.setAttribute('value','edit'); editbutton.onclick = editAccessKeys; editbutton.onkeypress = function() { if(window.event.keyCode == 13) {editAccessKeys();return false} }; var savebutton = document.getElementById('saveAccessKeys'); dl.parentNode.removeChild(savebutton); } function editAccessKeys() { /* * Load the current accesskeys into editable fields. * Replace the "edit" button by "reset" and "save" * buttons. */ var dl = document.getElementById(accesskeylistid); var keylist = dl.getElementsByTagName('dt'); for (i = 0; i < keylist.length; i++){ var input = createElement('input'); var keyvalue = defaultaccesskeys[i]; input.setAttribute('size', '1'); input.setAttribute('type', 'text'); input.setAttribute('id', accesskeylistid + i ); input.setAttribute('maxlength', '1'); input.setAttribute('value', keyvalue); if (input.tabindex) { input.tabindex = i+accesskeystarttabindex; } else { input.setAttribute('tabindex', i+accesskeystarttabindex); } if (input.apppendChild) { input.appendChild(document.createTextNode(keyvalue)); } input.onchange = function() { if (this.tabindex) { myaccesskeys[this.tabindex - accesskeystarttabindex] = this.value; } else { myaccesskeys[this.getAttribute('tabindex') - accesskeystarttabindex] = this.value; } } keylist[i].replaceChild(input, keylist[i].firstChild); } var editbutton = document.getElementById('editAccessKeys'); editbutton.setAttribute('value','reset'); editbutton.onclick = resetAccessKeys; editbutton.onkeypress = function() { if(window.event.keyCode == 13) {resetAccessKeys();return false} }; if (editbutton.tabindex) { editbutton.tabindex = i+accesskeystarttabindex; } else { editbutton.setAttribute('tabindex',i+accesskeystarttabindex); } var savebutton = createElement('input'); savebutton.setAttribute('id', 'saveAccessKeys'); savebutton.setAttribute('type', 'button'); savebutton.setAttribute('value', 'save'); savebutton.onclick = saveAccessKeys; savebutton.onkeypress = function() { if(window.event.keyCode == 13) {saveAccessKeys();return false;} }; if (savebutton.tabindex) { savebutton.tabindex = i+accesskeystarttabindex+1; } else { savebutton.setAttribute('tabindex',i+accesskeystarttabindex+1); } dl.parentNode.insertBefore(savebutton,editbutton.nextSibling); } /* Written by Jonathan Snook, http://www.snook.ca/jonathan Add-ons by Robert Nyman, http://www.robertnyman.com */ function getElementsByClassName(oElm, strTagName, strClassName){ var arrElements = (strTagName == "*" && document.all)? document.all : oElm.getElementsByTagName(strTagName); var arrReturnElements = new Array(); strClassName = strClassName.replace(/\-/g, "\\-"); var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)"); var oElement; for(var i=0; i 2) { var dethread = createElement('input'); dethread.setAttribute('id', 'dethread'); dethread.setAttribute('type', 'button'); dethread.setAttribute('value', 'view chronologically'); dethread.onclick = viewchronological; dethread.onkeypress = function() { if(window.event.keyCode == 13) {viewchronological;return false;} }; var dethread2 = dethread.cloneNode(false); dethread2.setAttribute('id', 'dethread2'); dethread2.onclick = viewchronological; dethread2.onkeypress = function() { if(window.event.keyCode == 13) {viewchronological;return false;} }; document.getElementById('comments').appendChild(dethread); getElementsByClassName(document, 'p', 'newpost')[0].appendChild(dethread2); } } function createElement(element) { if (typeof document.createElementNS != 'undefined') { return document.createElementNS('http://www.w3.org/1999/xhtml', element); } else { return document.createElement(element); } } function mactionWorkarounds() { $$('maction[actiontype="tooltip"]').each( function(mtool){ Element.writeAttribute(mtool, 'title', Element.firstDescendant(mtool).nextSibling.firstChild.data); }); $$('maction[actiontype="statusline"]').each( function(mstatus){ var v = Element.firstDescendant(mstatus).nextSibling.firstChild.data; Event.observe(mstatus, 'mouseover', function(){window.status = v;}); Event.observe(mstatus, 'mouseout', function(){window.status = '';}); }); $$('maction[actiontype="highlight"]').each( function(mhighlight){ var elt = Element.firstDescendant(mhighlight); var a = mhighlight.getAttribute('other').split(/\s*=\s*/); var pp = /^.(#?\w+).$/.exec(a[1]); if (pp) var colspec = pp[1]; switch (a[0]) { case 'color' : var oldColspec = window.getComputedStyle(elt, null).color; break; case 'background' : var oldColspec = window.getComputedStyle(elt, null).backgroundColor; } if (colspec && oldColspec) { Event.observe(mhighlight, 'mouseover', function(){elt.setAttribute('style', a[0]+':'+colspec);}); Event.observe(mhighlight, 'mouseout', function(){elt.setAttribute('style', a[0]+':'+oldColspec);}); } }); } function updateSize(elt, w, h) { // adjust to the size of the user's browser area. var parentheight = document.viewport.getHeight() - 78; var parentwidth = Math.min( document.viewport.getWidth(), $$('div.blogbody')[0].getWidth()); var newcols = Math.floor(parentwidth/w); var newrows = Math.floor(parentheight/h - 3); elt.writeAttribute({'cols': newcols, 'rows': newrows }); elt.setStyle({Width: parentwidth, Height: parentheight}); } function resizeableTextarea() { //make the textarea resize to fit available space $$('textarea#text').each( function(textarea) { var w = textarea.getWidth()/textarea.getAttribute('cols'); var h = textarea.getStyle('lineHeight').replace(/(\d*)px/, "$1"); Event.observe(window, 'resize', function(){ updateSize(textarea, w, h) }); updateSize(textarea, w, h); }); } function setupSVGedit(path){ var t = $('text'); var selected; var before; var after; // create a control button if (t) { var SVGeditButton = new Element('input', {id:'SVGeditButton', type:'button', value: ' '}); t.insert({before: SVGeditButton}); SVGeditButton.disabled = true; Event.observe(SVGeditButton, 'click', function(){ var editor = window.open(path + "?initStroke[width]=2", 'Edit SVG graphic', 'status=1,resizable=1,scrollbars=1'); editor.addEventListener("load", function() { editor.svgEditor.setCustomHandlers({ 'save': function(window,svg){ editor.svgEditor.setConfig({no_save_warning: true}); window.opener.postMessage(svg, window.location.protocol + '//' + window.location.host); window.close(); } }); editor.svgEditor.randomizeIds(); if (selected) editor.svgEditor.loadFromString(selected); }, true); SVGeditButton.value = ' '; SVGeditButton.disabled = true; editor.focus(); }); } var callback = function(){ // This is triggered by 'onmouseup' events var sel = window.getSelection(); var a = sel.anchorOffset; var f = sel.focusOffset; // A bit of ugliness, because Gecko-based browsers // don't support getSelection in textareas if (t.selectionStart ) { var begin = t.selectionStart; var end = t.selectionEnd; } else { if( a < f) { begin = a; end = f; } else { begin = f; end = a; } } // finally, slice up the textarea content into before, selected, & after pieces before = t.value.slice(0, begin); selected = t.value.slice(begin, end); after = t.value.slice(end, t.value.length); if (selected && selected != '') { if ( selected.match(/^$/) && !selected.match(/<\/svg>(.|\n)/)) { SVGeditButton.disabled = false; SVGeditButton.value = 'Edit existing SVG graphic'; } else { SVGeditButton.value = ' '; SVGeditButton.disabled = true; } } else { SVGeditButton.disabled = false; SVGeditButton.value = 'Create SVG graphic'; } } Event.observe(t, 'mouseup', callback ); Event.observe(SVGeditButton, 'click', callback); var my_loc = window.location.protocol + '//' + window.location.host; Event.observe(window, "message", function(event){ if(event.origin !== my_loc) { return;} t.value = before + event.data + after; t.focus(); selectRange(t, before.length, before.length+event.data.length); callback(); }); } function selectRange(elt, start, end) { if (elt.setSelectionRange) { elt.focus(); elt.setSelectionRange(start, end); } else if (elt.createTextRange) { var range = elt.createTextRange(); range.collapse(true); range.moveEnd('character', end); range.moveStart('character', start); range.select(); } } function resizeFormElts() { var mq = window.matchMedia('screen and (max-device-width: 480px)'); if (mq.matches) { document.getElementById('url').setAttribute('size', '35'); document.getElementById('text').setAttribute('cols', '25'); } } function moveSidebar() { var mq = window.matchMedia('screen and (max-device-width: 480px)'); if (mq.matches) { var sidebar = document.getElementById('links'); if (sidebar) { document.getElementById('content').appendChild(sidebar); } } } function retrieveTexSource() { $$('math').each( function(math){Event.observe(math, 'dblclick', grabTex);} ); function grabTex(event){ var tex = this.firstElementChild.lastElementChild.textContent; var win= window.open('','TeX','scrollbars,resizable,width=500,location=no,toolbar=no,titlebar=no,menubar=no,personalbar=no'); win.document.documentElement.lastElementChild.textContent = tex; win.focus(); } } function columnAlignShim() { var mtables = document.querySelectorAll('mtable[columnalign]'); if (mtables[0] && mtables[0].style) { for (var i = 0; i < mtables.length; i++) { var mtable = mtables[i]; var colAligns = mtable.getAttribute('columnalign').split(/\s+/); if (colAligns.length > 1) { var mtds = mtable.querySelectorAll(':scope > mtr > mtd'); for (var j = 0; j < mtds.length; j++) { mtds[j].style.textAlign = '-webkit-' + colAligns[j]; } } } } } function hrefShim() { // Chrome doesn't support href or xlink:href on MathML elements var mrows = document.querySelectorAll('mrow[href]'); if (mrows[0] && !mrows[0].querySelector(":link")) { for (var i = 0; i < mrows.length; i++) { var mrow = mrows[i]; replaceWithName(mrow, 'a'); } } } function replaceWithName(node, name) { newNode = document.createElement(name); var children = node.childNodes; for (var i = 0; i < children.length; i++){ var child = document.importNode(children[i], true); newNode.appendChild(child); } var attrs = node.attributes; for (var i = 0; i < attrs.length; i++){ newNode.setAttribute(attrs[i].name, attrs[i].value); } node.parentNode.replaceChild(newNode, node); } function mencloseShim() { var div = document.createElement('div'); var menc = document.createElementNS('http://www.w3.org/1998/Math/MathML', 'menclose'); var mi = document.createElementNS('http://www.w3.org/1998/Math/MathML', 'mi'); menc.setAttribute('notation', 'box'); mi.textContent = '1'; menc.appendChild(mi); div.appendChild(menc); document.body.appendChild(div); mencloseSupported = (div.getBoundingClientRect().height > mi.getBoundingClientRect().height); document.body.removeChild(div); if (!mencloseSupported) { var boxes = document.querySelectorAll('menclose[notation=box]'); if (boxes[0]) { for (var i = 0; i < boxes.length; i++){ boxes[i].style.border = '1px solid'; boxes[i].style.padding = '3px'; } } var slashed = document.querySelectorAll('menclose[notation=updiagonalstrike]'); if (slashed[0]) { for (var i = 0; i < slashed.length; i++){ slashed[i].className = 'strikediag'; } } } } function minMathWidth() { var maths = document.querySelectorAll('math[display=block]'); if (maths && maths.length > 0) { for (var i = 0; i < maths.length; i++) { var m = maths[i]; // m.style.minWidth = m.firstElementChild.clientWidth; // wrap in a div which supports overflow CSS property var wrapper = document.createElement('div'); wrapper.style.overflow = 'auto'; wrapper.style.padding = '3px 0'; m.parentNode.insertBefore(wrapper, m); m.parentNode.removeChild(m); wrapper.appendChild(m); } } } window.onload = function (){ warnIE(); styleAbbr(); if (document.getElementById(accesskeylistid)) {initializeAccessKeys()}; extractBlockquoteCitations(); mactionWorkarounds(); if(document.getElementById('comments')) {setupComments()}; resizeableTextarea(); moveSidebar(); retrieveTexSource(); columnAlignShim(); hrefShim(); mencloseShim(); minMathWidth(); if ( (navigator.appName == "Microsoft Internet Explorer" ) && !(navigator.userAgent.indexOf("Opera") > -1) ) { // document.body.style.behavior = 'url(\"csshover.htc\")'; document.body.style.background = '#000'; } };