User:Js/diffs.js
From Wikipedia, the free encyclopedia
< User:Js
Note: After saving, you have to bypass your browser's cache to see the changes. In Internet Explorer and Firefox, hold down the Ctrl key and click the Refresh or Reload button. Opera users have to clear their caches through Tools→Preferences, see the instructions for Opera. Konqueror and Safari users can just click the Reload button.
/* Switches -------- (these should be set to true to override standard behaviour) dfNoAjaxDiff: no quick next/prev loading on usual diff pages dfNoPopups: no popups dfNoArrowKeys : disable keyboard shortcuts (left/right arrow keys) for next/prev diff dfNoWikiParsing : completely disable wikicode parsing in diffs dfParseContext : also parse gray columns dfNoWaitCursor : disable "wait" cursor wikEdFullDiff: do not shorten JS Diff Engine output (seems useless) CSS parameters -------------- dfDiffLinksCSS: CSS for diff links, default: "font-style:italic" dfDiffTableCSS: extra CSS for diff table */ var currentLink, currentTable // !! debugging var diffScript = new function(){ //wrapper var dfNoWikiParsing = window.dfNoWikiParsing, dfNoPopups = window.dfNoPopups var curTitle, tempDiv, curStripes var requestedPages = {} //aray of retreived diffs, used as cache var isIE = navigator.userAgent.indexOf('MSIE') != -1 var popupCount = 0 //, popupArray = [] this.start = function(){ addHandler(document, 'click', onClick) if (!window.dfNoArrowKeys) addHandler(document, 'keyup', onKeyUp) if (!dfNoPopups) addCSS('a[href^="'+wgServer+'/w/index.php"][href*="diff="],\ a[href^="/w/index.php"][href*="diff="]' + (window.dfDiffLinksCSS || '{font-style:italic}')) //if (isIE && isIE6) //no CSS3 support in IE6, should make links italic manually if (document.URL.indexOf('diff=') != -1){ //this is a diff page //find diff table var content = document.getElementById('content') || document.getElementById('mw_content') || document var i = 0, tables = content.getElementsByTagName('table') while (i < tables.length && tables[i].className != 'diff') i++ if (i == tables.length) return //then it's div.firstrevisionheader currentTable = tables[i] //remember url and title currentTable.parentNode.diffURL = document.URL currentTable.parentNode.diffTitle = wgPageName //improve diff Table requestedPages[document.URL] = '<table class=diff>' + currentTable.innerHTML + '</table>' improveCurrentTable() currentTable.parentNode.insertBefore(createToolbar(), currentTable.parentNode.firstChild) } } function onClick(e){ cursorWait() //cancel waiting indicator if something went wrong //find event and click target e = e || window.event if (e.shiftKey || e.button == 2) return // shift key or right click if ((isIE && e.button == 4) || (!isIE && e.button == 1)) return //middle click var targ = e.target || e.srcElement //log(targ) if (!targ) return //clicked on diff table // ... //clicked on diff popup if (targ.className) switch (targ.className){ case 'df-popup': closePopup(targ); return case 'df-caption': closePopup(targ.parentNode); return case 'diff-lineno': changeBlock(targ.parentNode); return case 'diff-addedline': case 'diff-deletedline': case 'diff-context': processCell(targ); return } /* if (!dfNoPopups && targ.className){ if (targ.className=='df-popup') return closePopup(targ) if (targ.className=='df-caption') return closePopup(targ.parentNode) } if (targ.className == 'diff-lineno') return changeBlock(targ.parentNode) //else if (targ.className == 'diff-marker') return changeRow(targ.parentNode) */ //clicked on a diff link var url = targ.href if (!url || url.indexOf('diff=') == -1) return //not a diff if (url.indexOf(wgServer) != 0 && url.charAt(0) != '/') return //diff, but not to this server if (targ.parentNode.className == 't-print') return //check if it was nex/prev diff link currentLink = targ var isClickIntercepted = true if (/differences-(prev|next)link/.test(targ.id)) isClickIntercepted = followNextLink() else if (!dfNoPopups) createPopup() else isClickIntercepted = false //do not follow the link if (isClickIntercepted){ if (e.preventDefault) e.preventDefault(); else e.returnValue = false return false }else return true } function improveCurrentTable(){ if (currentTable.innerHTML.length>70000) return addDiffTableCSS() var trs = currentTable.getElementsByTagName('tr') curTitle = currentTable.parentNode.diffTitle //to be used in processHTML() curStripes = false for (var i=1; i<trs.length; i++) improveRow(trs[i]) } function improveRow(tr){ var tds = tr.getElementsByTagName('td'), td tr.className = 'df-change' //by default, as most common case if (tds.length == 1){ // 'One intermediate revision not shown' return //plus maybe //tr.className = 'df-message' }else if (tds.length == 2){ // "Line xx:" tr.className = 'df-lineno' return }else if (tds.length == 3 && tds[1].className == 'diff-deletedline'){ if (tds[1].innerHTML.length==0) tds[1].innerHTML = ' ' expandCell(tds[1], 'df-deletedline') //new class, means the line was simply deleted, has pink background return }else if (tds.length == 3 && tds[2].className == 'diff-addedline'){ processHTML(tds[2]) htm = tds[2].innerHTML if (htm.length==0) tds[2].innerHTML = ' ' if (curStripes) tr.className += ' odd' if (/<span class="?sig"?>/i.test(htm)) curStripes = !curStripes if (/^<div>==.*== *<\/div>$/i.test(htm)) tds[2].style.cssText = 'font-weight:bold; font-size:120%; padding-top:15px' expandCell(tds[2]) return }else if (tds[1].className == 'diff-context') { tr.className = 'df-context' if (window.dfParseContext) processHTML(tds[1]) expandCell(tds[1]) curStripes = false return } //from here we're left with normal yellow/green rows with 4 cells tds[1].colSpan = tds[3].colSpan = 2 //tds[1].style.borderRight = '10px solid white' tr.removeChild(tds[2]); tr.removeChild(tds[0]) return if (!window.dfImproveAdvanced) return //check for simple diffs var oldline = tds[1].innerHTML var newline = tds[3].innerHTML if (oldline.length < 90 && oldline.replace(/<.+?>| |\n/g,'') == ''){ //old empty tds[3].className = 'diff-addedline' tds[3].innerHTML = newline.replace(/<span class="diffchange">/i,'').replace(/<\/span>/i,'') processHTML(tds[3]) splitRowsUp(tds[1]) }else if (newline.length < 90 && newline.replace(/<.+?>| |\n/g,'') == ''){ //new empty tds[1].className = 'df-deletedline' tds[1].innerHTML = oldline.replace(/<span class="diffchange">/i,'').replace(/<\/span>/i,'') splitRowsUp(tds[3]) }else if (!/<span/i.test(newline)){ //simple change: something removed processHTML(tds[1]) expandCell(tds[1], 'df-deletedwords') }else if (!/<span/i.test(oldline)){ //simple change: something added processHTML(tds[3]) expandCell(tds[3], 'df-addedwords') }else{ //complex case //processHTML(tds[1]) //processHTML(tds[3]) if (window.dfOneColumn){ // separate into different rows anyway tds[1].firstChild.style.borderTop = '10px solid #FBFBFB' tds[3].firstChild.style.borderBottom = '10px solid #FBFBFB' splitRowsUp(tds[1]) }else{ //remove + / - markers ? } } function expandCell(td, clss){ while (td.nextSibling) tr.removeChild(td.nextSibling) while (td.previousSibling) tr.removeChild(td.previousSibling) td.colSpan = 4 if (clss) td.className = clss } function splitRowsUp(tdGoesUp){ tds[1].colSpan = 4 tds[3].colSpan = 4 tr.removeChild(tds[2]) tr.removeChild(tds[0]) var trnew = document.createElement('tr') trnew.className = 'df-change' trnew.appendChild(tdGoesUp) tr.parentNode.insertBefore(trnew, tr) i++ //increment i in for loop } } //improveRow() function changeTable(e){ e = e || window.event var butt = e.target || e.srcElement currentTable = getClickedTable(e) var dfLevel = butt.innerHTML if (dfImprovementSheet.disabled){ improveCurrentTable() dfImprovementSheet.disabled = false }else{ //butt.innerHTML = '-' replaceCurrentTable(requestedPages[currentTable.parentNode.diffURL]) dfImprovementSheet.disabled = true } } function changeBlock(row){ //switch improvement level for this part of diff table var dTbody = row.parentNode, rowIdx = 1, isImproved //find clicked row number while (rowIdx < dTbody.rows.length && dTbody.rows[rowIdx] != row) rowIdx++ if (dTbody.rows[rowIdx] != row) return //check if rows are improved or not if (row.className == 'df-lineno'){ isImproved = true var origTable = createTableFromHTML(requestedPages[dTbody.parentNode.parentNode.diffURL]) }else dfImprovementSheet.disabled = false //improve / de-improve rows do{ if (isImproved) dTbody.replaceChild(origTable.rows[rowIdx].cloneNode(true), row) else improveRow(row) }while((row=dTbody.rows[++rowIdx]) && row.cells[0].className != 'diff-lineno') } function processCell(cell){ //parse wikicode in already improved row when clicked on white border above row if (cell.origHTML){ //restore cell.innerHTML = cell.origHTML cell.origHTML = null }else{ processHTML(cell) } } // NOT USED function changeRow(row){ //switch one rowl improvement level when clicked on +- marker on the left var dTbody = row.parentNode, rowIdx = 1 //find clicked row number while (rowIdx < dTbody.rows.length && dTbody.rows[rowIdx] != row) rowIdx++ if (dTbody.rows[rowIdx] != row) return //check if rows are improved or not if (row.className == 'df-change'){ var origTable = createTableFromHTML(requestedPages[dTbody.parentNode.parentNode.diffURL]) dTbody.replaceChild(origTable.rows[rowIdx].cloneNode(true), row) }else{ dfImprovementSheet.disabled = false improveRow(row) var tds = row.cells processHTML(tds[1]) processHTML(tds[3]) } } function createToolbar(){ var dToolbar = document.createElement('div') //dToolbar.diffTable = currentTable dToolbar.className = 'df-toolbar' dToolbar.appendChild(btn(changeTable, '¤', 'Enable/disable improvements', 'df-improve-btn')) //÷ dToolbar.appendChild(btn(highlightDiffs, 'π', 'Highlight differences with red border', 'df-highlight-btn')) dToolbar.appendChild(btn(diffJSEngine, 'Δ', 'Javascript diff engine')) //references back and forth dToolbar.tableParent = currentTable.parentNode //reference so we can find table later return dToolbar } function btn(func, htm, tooltip, clss){ //creates <span> button var bt = document.createElement('span') bt.innerHTML = htm bt.onclick = func bt.title = tooltip bt.className = clss || 'df-btn' return bt } function getClickedTable(e){ e = e || window.event var button = e.target || e.srcElement return button.parentNode.tableParent.getElementsByTagName('table')[0] } function processHTML(elem){ if (dfNoWikiParsing) return var html = elem.innerHTML elem.origHTML = html if (html.length == 0) return //elem.innerHTML = ' ' //mark signatures html = html.replace(/(\[\[[^\[]{4,65})?\d\d:\d\d, \d\d? \S{3,9} 20\d\d \(UTC\)/g, '<span class=sig>$&</span>') html = html.replace(/\{\{unsigned[^\}]\}\}/i, '<span class=sig>$&</span>') //[[link]] html = html.replace(/\[\[([^\]><}{|]+)\|?([^\]><]*)?\]\]/g, function(wikicode,page,name){ if (/http:\/\//i.test(page)) return wikicode //user made a mistake if (/^image:|\.(jpg|png|svg|gif)$/i.test(page) && name) name = page + name //display full image link, including "image:" if (!name) name = page if (page.substring(0,1)=='#' || page.substring(0,1)=='/') { page = curTitle + page //relative link } return outputLink(page, name, wikicode) }) // [http://...] html = html.replace(/\[(https?:\/\/[^ \]><]*)( [^\]]*)?\]/g, // function (str,link,name){ var output = '<a href=' + link, title, tip, nameWas = name if (link.indexOf(wgServer+wgScript) == 0){ //local link tip = tryDecodeURI(link.substring((wgServer+wgScript).length+1)) if (!name){ name = getTitleFromURL(link) || tip if (/diff=/.test(link)) name = 'diff: ' + name else if (tip.match(/action=history/)) name = 'hist: ' + name else if (tip.match(/oldid=/)) name = 'oldid: ' + name else name = 'wiki: ' + name } } else { //ext link tip = tryDecodeURI(link.substring(7)) output += ' class="external text"' if (!name) name = tip } if (!nameWas && (name.length > 70)) name = name.substring(0,60) + '… …' return output + ' title="' + tip + '">[' + name + ']</a>' }) elem.innerHTML = html function tryDecodeURI(s){ try{s=decodeURIComponent(s)}catch (e){}; return s } } function followNextLink(){ //loads next/prev diff using next/prev diff link //find old table var el = currentLink while (el && el.nodeName != 'TABLE') el = el.parentNode if (!el || el.className != 'diff') return false currentTable = el if (currentTable.parentNode.className != 'df-popup'){ //normal diff page, not a popup if (window.dfNoAjaxDiff) return false if (el=document.getElementById('t-print')) el.style.display = 'none' //hide "printable" link which becomes outdated } //replace diff with new table loadDiff() return true } function replaceCurrentTable(html){ var oldTable = currentTable, parent = oldTable.parentNode, el //append new table currentTable = createTableFromHTML(html) parent.insertBefore(currentTable, oldTable) //remove everything below new table: old table, (now outdated) prevew, js engine diff while ((el=currentTable.nextSibling) && !/visualClear|df-caption/.test(el.className)) parent.removeChild(el) } function createTableFromHTML(html){ if (!tempDiv) tempDiv = document.createElement('div') tempDiv.innerHTML = html return tempDiv.getElementsByTagName('table')[0] } // *** POPUP *** function createPopup(lnk){ if (lnk) currentLink = lnk //unfortunately, image diffs do not work with &action=render //initialize markLink(currentLink) addDiffPopupCSS() if (isIE) hideAllSelectElements() //create popup popupCount++ var pop = document.createElement('div') pop.className = 'df-popup' pop.style.top = windowScrolled() + 30 + popupCount*10 + 'px' pop.style.left = 10 + popupCount*10 + 'px' //load diff document.body.appendChild(pop) //have to append now, otherwise table is broken in Safari 3 currentTable = document.createElement('table') pop.appendChild(currentTable) loadDiff(createPopup2) } function createPopup2(){ var pop = currentTable.parentNode pop.style.visibility = 'visible' //add bottom and top captions pop.appendChild(createCaption()) pop.insertBefore(createCaption(), pop.firstChild) return true //if it's too wide //if (elementWidth(pop) +10 > windowWidth()) scrollBy(elementWidth(pop), 0) function createCaption(){ //for popup var dCaption = document.createElement('div') dCaption.className = 'df-caption' //dCaption.onclick = captionClick //on special pages if (wgNamespaceNumber == -1){ dCaption.appendChild( btn(function(e){neighborDiff(e,currentLink, 1)}, '↓', 'Open next diff link on that page')) dCaption.appendChild( btn(function(e){neighborDiff(e,currentLink, -1)}, '↑', 'Open previous diff link on that page')) } //add page title var sp = document.createElement('span') var dTitle = currentTable.parentNode.diffTitle sp.innerHTML = '<b>'+outputLink(dTitle)+'</b>' + ' (' + outputLink(dTitle+'?action=history', 'h') + ')' dCaption.appendChild(sp) //add toolbar dCaption.insertBefore(createToolbar(), dCaption.firstChild) return dCaption } } function captionClick(e){ // !! obsolete? e = e || window.event var el = e.target || e.srcElement if (el && el.className && el.className == 'df-caption') closePopup(el.parentNode) } function closePopup(div){ div.style.display = 'none' //purge(div) div.parentNode.removeChild(div) popupCount-- if (isIE && (popupCount==0)) hideAllSelectElements(true) //IE select zIndex bug } function onKeyUp(e){ e = e || window.event var lnk if (e.keyCode == 37) lnk = document.getElementById('differences-prevlink') else if (e.keyCode == 39) lnk = document.getElementById('differences-nextlink') if (!lnk) return currentLink = lnk if (!followNextLink()) document.location.href = lnk.href } function markLink(lnk, isError){ //mark link as 'clicked'. especially useful for watchlist/RC lnk.style.backgroundColor = isError ? '#FFDDDD' :'#DDDDFF' } function hideAllSelectElements(isRestore){ //workaround for IE <select> zIndex bug var sels = document.getElementsByTagName('select') for (var i=0; i<sels.length; i++) sels[i].style.visibility = isRestore ? 'visible' : 'hidden' } function neighborDiff(e, lnk, dir){ //close old popup e = e || window.event var el = e.target || e.srcElement closePopup (el.parentNode.parentNode) //try to find diff in neghbor TR (this happens inside expanded section of enhanced RC/WL) if ((el=findParentWithTag(lnk,/TR/)) && (el=findNeighborBlock(el)) && (el=findDiffIn(el))) createPopup(el) //try to find diff in neghbor LI (on contrib page and simple RC) or TABLE (on enhanced RC and WL) else if ((el=findParentWithTag(lnk,/LI|TABLE/)) && (el=findNeighborBlock(el)) && (el=findDiffIn(el))) createPopup(el) //functions function findParentWithTag(el, regexp){ while ((el=el.parentNode) && !regexp.test(el.nodeName)); return el } function findNeighborBlock(el){ //looks for next/prev block with the same tag var tag = el.nodeName do{ el = (dir == -1) ? el.previousSibling : el.nextSibling } while (el && el.nodeName != tag) return el } function findDiffIn(block){ var aa = block.getElementsByTagName('a') for (var i=0; i<aa.length; i++) if (/diff=/.test(aa[i].href)) return aa[i] } } // *** JS Diff Engine *** function diffJSEngine(e){ //create temporary table with original diff var dTable = getClickedTable(e) var curTitle = dTable.parentNode.diffTitle var tempTable = createTableFromHTML(requestedPages[dTable.parentNode.diffURL]) //create "full comparison" button var btFull = document.createElement('input'); btFull.type = 'button' btFull.value = 'Perform full comparison' btFull.title = 'Compare full revisions, in case MediaWiki diff engine is wrong' btFull.onclick = diffJSFull //call and run JS diff engine if (window.WDiffString) diffJSGo() else importScriptAndRun('http://en.wikipedia.org/w/index.php?title=User:Cacycle/diff.js', diffJSGo) function diffJSGo(){ cursorWait(true) //var oldVer = newVer = '' tds = tempTable.getElementsByTagName('td') var txt, isContent for (var i=1; i<tds.length; i++){ txt = tds[i].innerHTML.replace(/<.+?>/g,'') + '\n' switch(tds[i].className){ case 'diff-context': marker = '\x03' + txt + '\x04\n' oldVer += marker newVer += marker isContent = false i += 2 //skip other context cell break case 'diff-lineno': //oldVer += '\n\n\n\n\n\n' //newVer += '\n\n\n\n\n\n' break // !!! case 'diff-deletedline': isContent = true oldVer += txt break case 'diff-addedline': isContent = true newVer += txt break } } difDiv = document.createElement('div') difDiv.style.cssText = 'padding:2px' difDiv.innerHTML = '<br><br><h3>JS Engine diff</h3><hr style="height:5px" />' diffJSDisplay() difDiv.appendChild(document.createElement('hr')) difDiv.appendChild(btFull) dTable.parentNode.insertBefore(difDiv, dTable.nextSibling) scrollToElement(difDiv) } function diffJSFull(){ btFull.parentNode.removeChild(btFull) //get versions Ids var ma, newId, oldId ma = tempTable.rows[0].cells[0].innerHTML.match(/oldid=(\d+)/) if (ma) oldId = ma[1]; else { difDiv.innerHTML += '<p class=error>Could not find oldid</p>'; return } ma = tempTable.rows[0].cells[1].innerHTML.match(/oldid=(\d+)/) if (ma) newId = ma[1]; else newId = '' //request versions difDiv.innerHTML += '<br><br><h3>Full revisions comparison</h3><hr style="height:5px" />' cursorWait(true) oldVer = newVer = null var url = wgServer + wgScript + '?action=raw&maxage=0&title=' + encodeURIComponent(curTitle) requestPage(url + '&oldid=' + oldId, function(txt) { oldVer = txt if (newVer) diffJSDisplay() }) requestPage(url + '&oldid=' + newId, function(txt) { newVer = txt if (oldVer) diffJSDisplay() }) } function diffJSDisplay(){ var txt = WDiffString(oldVer, newVer) //txt = txt.replace(/\x03.*?\x04/g, '<br><br><hr><br><br>') txt = txt.replace(/\x03|\x04/g, '') if (!window.wikEdFullDiff ) txt = WDiffShortenOutput(txt) //txt = txt.replace(/¶/g,'<br>') txt = txt.replace(/&/g,'&') //txt = txt.replace(/</g,'<').replace(/>/g, '>') difDiv.innerHTML += txt cursorWait() } }//diffJSEngine // *** COMMON *** function windowScrolled(){ if (self.pageYOffset) // all except Explorer return self.pageYOffset else if (document.documentElement && document.documentElement.scrollTop) // Explorer 6 Strict return document.documentElement.scrollTop else if (document.body) // all other Explorers return document.body.scrollTop } function scrollToElement (el){ var yy = el.offsetTop while (el = el.offsetParent) yy += el.offsetTop scrollTo(0, yy) } function getTitleFromURL(url){ var tt = url.match(/title=([^&>"]+)/) //" if (!tt) return '' else return decodeURIComponent(tt[1]).replace(/_/g,' ') } function outputLink(page, name, tooltip){ if (!name) name = page if (!tooltip) tooltip = name //.replace(/'/g,'`') page = page.replace(/&/gi,'&') var k = page.indexOf('#') if (k != -1) page = page.substring(0,k) + '#' + guessSectionName(page.substring(k+1)) return '<a href="'+wgServer+wgArticlePath.replace('$1', page) +'" title="' + tooltip.replace(/"/g,'%22') + '">' + name + '</a>' //' } function guessTOCName(txt){ //make header into TOC item, will not work 100% txt = txt.replace(/^ */,'').replace(/ *$/,'') //trim spaces txt = txt.replace(/\[\[[^|]+\|([^\]]+)\]\]/g, '$1') //[[foo|bar]] -> bar txt = txt.replace(/\[\[([^\]]+)\]\]/g, '$1') //[[bar]] -> bar txt = txt.replace(/<.*?>/g, '').replace(/ /g,'_') //strip tags, spaces -> _ return txt } function guessSectionName(txt){ //make header into URL anchor, will not work 100% //should behave like like Parser.php::guessSectionNameFromWikiText() and Sanitizer.php txt = guessTOCName(txt) //... skipping step "HTML entities are turned into their proper characters" txt = encodeURIComponent(txt) //maybe encodeURI(p1.replace(/\?/g,'%3F').replace(/&/g,'%26')) txt = txt.replace('%3A', ':').replace(/%([0-9A-F][0-9A-F])/g, '.$1') return txt } function cursorWait(isWait){ if (window.dfNoWaitCursor) return document.body.style.cursor = isWait ? 'wait' : '' } // *** CSS/JS *** var dfHighlightSheet, dfImprovementSheet, dfPopupSheet function addDiffTableCSS(){ //table.diff td {padding-left:3px}\ //td.diff-addedline, td.diff-deletedline, td.df-deletedline if (dfImprovementSheet) return addCSS('\ div.df-toolbar {float:right}\ div.df-toolbar span\ {cursor:pointer; padding:0 3px 0 3px; margin:0 3px 0 3px; border:1px solid #EEEEEE}\ ') dfImprovementSheet = addCSS('\ table.diff {width:99%}\ table.diff td {padding-left:2px}\ table.diff, td.diff-otitle, td.diff-ntitle {background:#FBFBFB}\ table.diff td.diff-lineno {border-top: 25px solid #FBFBFB}\ td.df-deletedline {background-color:#FEC}\ table.diff td div {min-height:1em}\ td.df-deletedwords, td.df-addedwords\ {background:white; border:1px dotted gray; padding:2px}\ td.df-deletedwords span.diffchange {background-color:#FFA}\ td.df-addedwords span.diffchange {background-color:#CFC; color:black; font-weight:normal}\ tr.odd td.diff-addedline {background-color:#BEB}\ span.sig {border:1px dotted gray; border-bottom:none; font-family:cursive; font-size:90%}\ tr.df-change td {font-size:100%}\ div.df-toolbar span.df-improve-btn {border:1px inset #EEEEEE}\ table.diff td {padding-right:8px; cursor:help}\ table.diff td div, table.diff td.diff-multi {cursor:default}' //make TD clickable (sticking out from under DIV inside) + (window.dfDiffTableCSS ? dfDiffTableCSS : '')) //user CSS //different approach to make cells clickable //+ 'table.diff {border-spacing:0} table.diff td {border-top:4px solid #FBFBFB} table.diff td.diff-deletedline {border-right: 6px solid #FBFBFB}' } function addDiffPopupCSS(){ if (dfPopupSheet) return if (document.URL.indexOf('&diff=') == -1) importCSS('/skins-1.5/common/diff.css') dfPopupSheet = addCSS('\ div.df-popup{position:absolute; margin-right:15px; border:1px solid #000033; z-index:50; \ font-size:130%; background-color:white; visibility:hidden; min-width:75%}\ div.df-popup div.df-caption{float:none; background:#F0F0FF; font-size:120%;\ border:1px outset gray; padding:2px}\ div.df-popup table.diff {width:97%; margin:0 1% 0 1% }') } //div.df-popup div.df-toolbar {}\ //div.df-popup table.diff {width:auto}\ // min-width was added for Safari function highlightDiffs(e){ if (!dfHighlightSheet) dfHighlightSheet = addCSS('span.diffchange{border:1px solid red}\ div.df-toolbar span.df-highlight-btn {border:1px inset #EEEEEE}') else dfHighlightSheet.disabled = !dfHighlightSheet.disabled } function importCSS(url){ if (document.createStyleSheet) var s = document.createStyleSheet(url) //IE else { var s = document.createElement('style') s.type = 'text/css' s.appendChild (document.createTextNode('@import "' + url + '";')) document.getElementsByTagName('head')[0].appendChild(s) } return s } function addCSS(text){ var s = document.createElement('style') s.setAttribute('type', 'text/css') if (s.styleSheet) s.styleSheet.cssText = text //IE else s.appendChild(document.createTextNode(text)) document.getElementsByTagName('head')[0].appendChild(s) return s.sheet || s } function importScriptAndRun(url, func) { var s = document.createElement('script') s.type = 'text/javascript' s.src = url + '&action=raw&ctype=text/javascript' if (isIE) s.onreadystatechange = function(){ if (this.readyState == 'loaded' || this.readyState == 'complete') func() } else s.onload = func document.getElementsByTagName('head')[0].appendChild(s) } // *** AJAX *** function requestPage(url, func){ if (requestedPages[url]) {func(requestedPages[url]); return } var aj = sajax_init_object() aj.open('GET', url, true) aj.onreadystatechange=function() { if (aj.readyState != 4) return if (aj.status == 200) { requestedPages[url] = aj.responseText func(aj.responseText) }else func(null) } aj.send(null) } function loadDiff(func){ currentTable.style.opacity = '0.5' cursorWait(true) var url = currentLink.href + '&action=render&diffonly=yes' requestPage(url, loadDiff2) function loadDiff2(html){ replaceCurrentTable(html) //remember diff url and title currentTable.parentNode.diffURL = url var td = getElementsByClassName(currentTable, 'td', 'diff-ntitle')[0] currentTable.parentNode.diffTitle = td ? getTitleFromURL(td.getElementsByTagName('a')[1].href) : '??' //improve improveCurrentTable() if (func) func() cursorWait() } } } //wrapper if (doneOnloadHook) diffScript.start() addOnloadHook(diffScript.start)

