User:Js/diffs.js
Appearance
< User:Js
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
![]() | This user script seems to have a documentation page at User:Js/diffs. |
/*
Parameters, most should be set to true to override standard behaviour:
dfNoPopups: no popups
dfNoAjaxDiff: no quick next/prev loading on usual diff pages
dfNoArrowKeys : disable keyboard shortcuts (left/right arrow keys) for next/prev diff
dfNoWikiParsing : completely disable wikicode parsing in diffs
dfParseContext : also parse gray columns
dfNoLargerFont: set to true to keep normal small font for changed areas
dfNoWaitCursor : set to true to disable cursor changing to "wait"
wikEdFullDiff: do not shorten JS Diff Engine output (pretty much useless)
dfImproveAdvanced : imrove diffs even more (make simple diffs as one column)
dfOneColumn : convert all diffs to one column view
dfDiffLinksCSS: set this to CSS string to replace default "{font-style:italic}" for all diff links
*/
var diffScript = new function(){ //wrapper
var dfNoWikiParsing = window.dfNoWikiParsing
var currentLink, currentTable
var noImprove, curTitle
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 (!window.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>'
improveDiff()
currentTable.parentNode.insertBefore(createToolbar(), currentTable.parentNode.firstChild)
}
}
function onClick(e){
cursorNormal() //cancel waiting indicator if something went wrong
//check if this was on a diff link
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 lnk = e.target || e.srcElement
var url = lnk.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 (lnk.parentNode.className == 't-print') return
//check if it was nex/prev diff link
currentLink = lnk
var isClickIntercepted = true
if (/differences-(prev|next)link/.test(lnk.id)) isClickIntercepted = followNextLink()
else if (!window.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 onClickError(msg){
jsMsg(msg)
markLink(currentLink, true)
return false
}
function improveDiff(){
if (noImprove || currentTable.innerHTML.length>70000) return
addDiffTableCSS()
var trs = currentTable.getElementsByTagName('tr'), tr, tds, td, stripes = false
curTitle = currentTable.parentNode.diffTitle //to be used in processHTML()
//trs[0].className = 'df-header'
for (var i=1; i<trs.length; i++){
tr = trs[i]
tds = tr.getElementsByTagName('td')
tr.className = 'df-change' //by default, as most common case
if (tds.length == 1){ // 'One intermediate revision not shown'
//tr.className = 'message'
continue
}else if (tds.length == 2){ // "Line xx:"
tr.className = 'df-lineno'
expandCell(tds[1])
continue
}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
continue
}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 (stripes) tr.className += ' odd'
if (/<span class="?sig"?>/i.test(htm)) stripes = !stripes
if (/^<div>==.*== *<\/div>$/i.test(htm))
tds[2].style.cssText = 'font-weight:bold; font-size:120%; padding-top:15px'
expandCell(tds[2])
continue
}else if (tds[1].className == 'diff-context') {
tr.className = 'df-context'
if (window.dfParseContext) processHTML(tds[1])
expandCell(tds[1])
stripes = false
continue
}
//from here we're left with normal yellow/green rows with 4 cells
if (!window.dfImproveAdvanced) continue
//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])
}
}
} // for
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
}
} //improveDiff()
function changeLevel(e){
e = e || window.event
var butt = e.target || e.srcElement
currentTable = getClickedTable(e)
var dfLevel = butt.innerHTML
if (dfLevel == '-'){
noImprove = false
//dfNoWikiParsing = true
butt.innerHTML = '='
//restore
improveDiff()
}else if (dfLevel == '='){
// dfNoWikiParsing = false
// butt.innerHTML = 'Ξ'
// }else if (dfLevel == 'Ξ'){
noImprove = true
butt.innerHTML = '-'
replaceTable(requestedPages[currentTable.parentNode.diffURL])
}
}
function createToolbar(){
var dToolbar = document.createElement('div')
//dToolbar.diffTable = currentTable
dToolbar.className = 'df-toolbar'
dToolbar.appendChild(btn(changeLevel, '=', 'Enable/disable diff improvement'))
dToolbar.appendChild(btn(diffJSEngine, 'js', 'Show diffs using JS engine'))
dToolbar.appendChild(btn(highlightDiffs, 'hl', 'Highlight diffs with red border', 'df-but-highlight'))
//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 = 'df-but'
if (clss) bt.className += ' ' + clss
return bt
}
function getClickedTable(e){
e = e || window.event
var button = e.target || e.srcElement
return button.parentNode.tableParent.getElementsByTagName('table')[0]
}
function checkNOBRs(){
var cntAdded = cntRemoved = 0
if (cntRemoved>0 || cntAdded>0){
//hide context rows that are not needed anymore
for (var i=1; i<trs.length-1; i++)
if (tr.className.match(/df-context|df-lineno/)
&& !trs[i-1].className.match(/df-change/) && !trs[i+1].className.match(/df-change/))
tr.style.display='none'
//add notice that 0x0A changes are hidden
var newtd = document.createElement('td')
newtd.colSpan=4; newtd.style.textAlign='center'; newtd.style.fontWeight = 'bold'
var notice = (cntRemoved>0)?' задушено: '+cntRemoved:''
notice += (cntAdded>0)?' вставлено: '+cntAdded:''
newtd.innerHTML = '<span style="border:2px solid orange; padding:2px">Неразрывных пробелов' + notice + '</span>'
trs[1].parentNode.insertBefore(newtd, trs[1])
}
}
function processHTML(elem){
if (dfNoWikiParsing) return
var html = elem.innerHTML
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 (isImagePage(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 || isImagePage(getTitleFromURL(currentLink.href))) 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 replaceTable(html){
var oldTable = currentTable
//create temp div with new table
var el, tempDiv = document.createElement('div')
tempDiv.innerHTML = html
currentTable = tempDiv.getElementsByTagName('table')[0]
//insert temp div
oldTable.parentNode.insertBefore(tempDiv, oldTable)
//remove old table and (now outdated) prevew below
while ((el=tempDiv.nextSibling) && !/visualClear|df-caption/.test(el.className))
el.parentNode.removeChild(el)
//get rid of temporary DIV
while (el=tempDiv.firstChild)
tempDiv.parentNode.insertBefore(el, tempDiv)
tempDiv.parentNode.removeChild(tempDiv)
}
// *** POPUP ***
function createPopup(lnk){
if (lnk) currentLink = lnk
//unfortunately, image diffs do not work with &action=render
if (isImagePage(getTitleFromURL(currentLink.href)))
return onClickError('Sorry, diffPopup doesn\'t work with diffs to images pages')
//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
currentTable = document.createElement('table')
pop.appendChild(currentTable)
loadDiff(createPopup2)
}
function createPopup2(){
var pop = currentTable.parentNode
//add bottom and top captions
pop.appendChild(createCaption())
pop.insertBefore(createCaption(), pop.firstChild)
document.body.appendChild(pop)
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){
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 tmpDiv = document.createElement('div')
tmpDiv.innerHTML = requestedPages[dTable.parentNode.diffURL]
var tempTable = tmpDiv.getElementsByTagName('table')[0]
//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()
//var
oldVer = newVer = ''
tds = tempTable.getElementsByTagName('td')
var isContent
for (var i=1; i<tds.length; i++){
td = tds[i]
switch(td.className){
case 'diff-context':
//oldVer += td.innerHTML.replace(/<.+?>/g,'') + '<hr>'
//newVer += td.innerHTML.replace(/<.+?>/g,'') + '<hr>'
/*
if (isContent){
marker = '\x03' + td.innerHTML.replace(/<.+?>/g,'') + '\x04'
oldVer += marker
newVer += marker
isContent = false
}*/
i++
break
case 'diff-lineno':
break // !!!
case 'diff-deletedline':
isContent = true
oldVer += '\n' + td.innerHTML.replace(/<.+?>/g,'')
break
case 'diff-addedline':
isContent = true
newVer += '\n' + td.innerHTML.replace(/<.+?>/g,'')
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)
}
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()
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>')
if (!window.wikEdFullDiff ) txt = WDiffShortenOutput(txt)
//txt = txt.replace(/¶/g,'<br>')
txt = txt.replace(/&/g,'&')
//txt = txt.replace(/</g,'<').replace(/>/g, '>')
difDiv.innerHTML += txt
cursorNormal()
}
}//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 getTitleFromURL(url){
var tt = url.match(/title=([^&>"]+)/) //"
if (!tt) return ''
else return decodeURIComponent(tt[1]).replace(/_/g,' ')
}
function isImagePage(page){
return /^image:|\.(jpg|png|svg|gif)$/i.test(page)
}
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(){
if (!window.dfNoWaitCursor) document.body.style.cursor = 'wait'
}
function cursorNormal(){
if (!window.dfNoWaitCursor) document.body.style.cursor = ''
}
// *** CSS/JS ***
var doneDiffTableCSS, doneDiffPopupCSS, highlighDiffCSS
function addDiffTableCSS(){
//table.diff td {padding-left:3px}\
//td.diff-addedline, td.diff-deletedline, td.df-deletedline
if (doneDiffTableCSS) return
addCSS('\
table.diff, td.diff-otitle, td.diff-ntitle {background:#FBFBFB}\
tr.df-lineno td.diff-lineno {padding-top:30px; font-size:80%; font-weight:normal}\
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%}\
div.df-toolbar{float:right; border:1px solid gray}\
span.df-but {cursor:pointer; padding:0 3px 0 3px; margin:0 3px 0 3px; border:1px dotted gray}'
+ (window.dfNoLargerFont ? '' : 'tr.df-change td {font-size:100%; padding-left:3px'))
doneDiffTableCSS = true
}
function addDiffPopupCSS(){
if (doneDiffPopupCSS) return
importCSS('/skins-1.5/common/diff.css')
addCSS('\
div.df-popup{position:absolute; margin-right:15px; border:1px solid #000033; z-index:50; \
font-size:130%; background-color:white}\
div.df-popup div.df-caption{float:none; background:#F0F0FF; font-size:120%;\
border:1px outset gray; padding:2px; cursor:pointer}\
div.df-popup div.df-toolbar {border:none}')
doneDiffPopupCSS = true
}
//div.df-popup table.diff {width:auto}\
function highlightDiffs(e){
if (!highlighDiffCSS)
highlighDiffCSS = addCSS('span.diffchange{border:1px solid red}\
span.df-but-highlight {border:1px inset gray}')
else highlighDiffCSS.disabled = !highlighDiffCSS.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){ //could use createStyleSheet for IE as well
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 //so we can disable it later, Safari insists on .sheet
}
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()
var url = currentLink.href + '&action=render&diffonly=yes'
requestPage(url, loadDiff2)
function loadDiff2(html){
replaceTable(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
improveDiff()
if (func) func()
cursorNormal()
}
}
/*
function dispDiffInfo(dTable){
var td = getElementsByClassName(dTable, 'td', 'diff-ntitle')[0]
if (!td) return
// emphasize if this is current revision
//var aa = tds[1].getElementsByTagName('a')[0]
//if (!/oldid=/.test(aa.href)) aa.style.cssText = 'border:2px solid green; padding:0 2px 0 2px'
//get title from (edit) link
dTable.parentNode.diffTitle = getTitleFromURL(td.getElementsByTagName('a')[1].href)
}
*/
//http://javascript.crockford.com/memory/leak.html
function purge(d) {
var a = d.attributes, i, l, n;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
n = a[i].name;
if (typeof d[n] === 'function') {
d[n] = null;
}
}
}
a = d.childNodes;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
purge(d.childNodes[i]);
}
}
}
} //wrapper
addOnloadHook(diffScript.start)