User:Microchip08/uberdiff.js

/* This script is not supported by Microchip08 See [[:en:User:Js/diff]] for directions http://en.wikipedia.org/w/index.php?title=User:Js/diffs.js&oldid=279…

/*
This script is not supported by Microchip08
See [[:en:User:Js/diff]] for directions

http://en.wikipedia.org/w/index.php?title=User:Js/diffs.js&oldid=279812200

Parameters:
 
These parameters can 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
 
dfHighlightOn : turn diff highlighting (red borders) on by default
dfNoWaitCursor : set to true to disable cursor changing to "wait"
wikEdFullDiff: do not shorten JS Diff Engine output (pretty much useless)
 
dfDiffLinksCSS: set this to CSS string to replace default  "{font-style:italic}" for all diff links
dfDiffTableCSS: extra CSS for diff table
 
dfImproveAdvanced :  imrove diffs even more (make simple diffs as one column)
dfOneColumn : convert all diffs to one column view
 
-----------------
dfMaxImproveSize : diffs over this size (in Kb) will not be improved automatically
*/
 
 
 
 
ffNoPopups=true
 
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 = []
var articlePath = wgArticlePath.replace('$1', '')
var clickedLinkLast
 
this.start = function(){
 
 addHandler(document, 'click', onClick)
 if (!window.dfNoArrowKeys) addHandler(document, 'keyup', onKeyUp)
 if (!dfNoPopups) appendCSS('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 curTable = findDiffTable(content)
   if (!curTable) return
   var parent = curTable.parentNode
   //remember url and title, and cache
   parent.diffURL = document.URL
   parent.diffTitle = wgPageName
   requestedPages[document.URL] = '<table class=diff>' + curTable.innerHTML + '</table>'
   //improve diff Table
   improveTable(curTable)
   parent.insertBefore(createToolbar(parent), parent.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
 var isClickIntercepted = true
 if (/differences-(prev|next)link/.test(targ.id)) isClickIntercepted = followNextLink(targ)
 else if (!dfNoPopups) createPopup(targ)
 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 improveTable(dTable){
 if (window.dfMaxImproveSize && dTable.innerHTML.length>dfMaxImproveSize) return
 //remove diff marker colums
 //var cols = dTable.getElementsByTagName('col')
 //var col
 //while(col=dTable.getElementsByTagName('col')[0]) col.parentNode.removeChild(col)
 //improve rows
 var trs = dTable.getElementsByTagName('tr')
 curTitle = dTable.parentNode.diffTitle //needee in processHTML() for relative links
 curStripes = false
 for (var i=1; i<trs.length; i++) improveRow(trs[i])
 //add CSS
 addDiffTableCSS()
}
 
 
 
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'
   tr.className = 'df-message'
   return //plus maybe 
 
 }else if (tds.length == 2){ // "Line xx:"
   tr.className = 'df-lineno'
   return
 
 }else if (tds.length == 3 && tds[1].className == 'diff-deletedline'){
   tr.className += ' df-deleted'
   if (tds[1].innerHTML.length==0) tds[1].innerHTML = '<div>&nbsp;</div>'
   expandCell(tds[1]) //new class, means the line was simply deleted, has pink background
   return
 
 }else if (tds.length == 3 && tds[2].className == 'diff-addedline'){
   tr.className += ' df-added'
   processHTML(tds[2])
   htm = tds[2].innerHTML
   if (htm.length==0) tds[2].innerHTML = '<div>&nbsp;</div>'
   if (curStripes) tr.className += ' odd'
   if (/<span class="?sig"?>/i.test(htm)) curStripes = !curStripes
   if (/^<div>==.*== *<\/div>$/i.test(htm))
      tds[2].firstChild.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
 tr.removeChild(tds[2]); tr.removeChild(tds[0])
 if (!window.dfImproveAdvanced) return
 
 
 tds = tr.getElementsByTagName('td')
 var oldline = tds[0].innerHTML
 var newline = tds[1].innerHTML
 
 //check for simple  diffs
 if (oldline.length < 90 && oldline.replace(/<.+?>| |\n/g,'') == ''){ //old empty
   tds[1].className = 'diff-addedline'
   tds[1].innerHTML = newline.replace(/<span class="diffchange">/i,'').replace(/<\/span>/i,'')
   processHTML(tds[1])
   splitRowsUp(tds[0])
 
 }else if (newline.length < 90 && newline.replace(/<.+?>| |\n/g,'') == ''){ //new empty
   tds[0].className = 'df-deletedline' // !!! replace wih tr-deleted
   tds[0].innerHTML = oldline.replace(/<span class="diffchange">/i,'').replace(/<\/span>/i,'')
   splitRowsUp(tds[1])
 
 }else if (!/<span/i.test(newline)){ //simple change: something removed
   processHTML(tds[0])
   expandCell(tds[0], 'df-deletedwords')
 
 }else if (!/<span/i.test(oldline)){ //simple change: something added
   processHTML(tds[1])
   expandCell(tds[1], 'df-addedwords')
 
  }else{ //complex case
   //processHTML(tds[1])
   //processHTML(tds[3])
   if (window.dfOneColumn){ // separate into different rows anyway
    tds[0].firstChild.style.borderTop = '10px solid #FBFBFB'
    tds[1].firstChild.style.borderBottom = '10px solid #FBFBFB'
    splitRowsUp(tds[0])
   }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[0].colSpan = 4
  tds[1].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)
 }
 
} //improveRow()
 
 
 
 
 
function changeTable(e){ //switch between original diff table and improved
 e = e || window.event
 var butt = e.target || e.srcElement
 var curTable = getClickedTable(e)
 if (dfImprovementSheet.disabled) improveTable(curTable)
 else replaceTable(curTable, requestedPages[curTable.parentNode.diffURL])
 dfImprovementSheet.disabled = !dfImprovementSheet.disabled
}
 
 
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.indexOf('df-change') != -1){
   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(parent){
 var dToolbar = document.createElement('div')
 dToolbar.tableParent = parent //reference so we can find table later
 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
 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 = '&nbsp;'
 
 html = html.replace(/({\{userlinks\|)([^}]+)}\}/, function(str,tmpl,user){
  return tmpl + outputLink('special:contributions/'+user,'',user) + '}}' })
 
 //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
  }
  if (/^[a-z]{2,7}:/.test(page)) //possible interproject link, and some are not "local"
     page = 'Special:Search/'+page 
  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(clickedLink){ //loads next/prev diff using next/prev diff link
 //find old table
 var el = clickedLink
 while (el && el.nodeName != 'TABLE') el = el.parentNode
 if (!el || el.className != 'diff') return false
 var oldTable = el
 if (oldTable.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(clickedLink, oldTable)
 return true
}
 
 
 
function replaceTable(oldTable, html){
 //append new table
 var newTable = createTableFromHTML(html)
 oldTable.parentNode.insertBefore(newTable, oldTable)
 //remove everything below new table: old table, (now outdated) prevew, js engine diff
 var el
 while ((el=newTable.nextSibling) && !/visualClear|df-caption/.test(el.className))
   el.parentNode.removeChild(el)
 return newTable
}
 
 
function createTableFromHTML(html){
 if (!tempDiv) tempDiv = document.createElement('div')
 tempDiv.innerHTML = html
 return findDiffTable(tempDiv)
}
 
 
function findDiffTable(el){
 var i = 0, tables = el.getElementsByTagName('table')
 while (i < tables.length && tables[i].className != 'diff') i++
 if (i < tables.length) return tables[i]; else return null //then it's  div.firstrevisionheader
} 
 
 
// *** POPUP ***
 
 
function createPopup(clickedLink){
 //initialize
 if (clickedLinkLast) 
   changeClass(clickedLinkLast, 'df-clicked-last', 'df-clicked')
 clickedLinkLast = clickedLink
 changeClass(clickedLinkLast, 'df-clicked', 'df-clicked-last')
 addDiffPopupCSS()
 if (isIE) hideAllSelectElements(true)
 //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
 var oldTable = document.createElement('table')
 pop.appendChild(oldTable)
 document.body.appendChild(pop) //have to append now, otherwise table is broken in Safari 3 
 loadDiff(clickedLink, oldTable, showPopup)
 if (window.dfHighlightOn) highlightDiffs()
}
 
 
function showPopup(clickedLink, diffTable){
 //clickedLink.style.backgroundColor = '#DDDDFF'
 var pop = diffTable.parentNode
 pop.appendChild(createCaption())
 pop.insertBefore(createCaption(), diffTable)
 pop.style.visibility = 'visible'
 return true
 
 function createCaption(){
  var dCaption = document.createElement('div')
  dCaption.className = 'df-caption'
  //on special pages
  if (wgNamespaceNumber == -1){
   dCaption.appendChild( btn(function(e){neighborDiff(e,clickedLink,  1)},
     '↓', 'Open next diff link on that page'))
   dCaption.appendChild( btn(function(e){neighborDiff(e,clickedLink, -1)},
     '↑', 'Open previous diff link on that page'))
  }
  //add page title
  var sp = document.createElement('span')
  var dTitle = diffTable.parentNode.diffTitle
  sp.innerHTML = '<b>'+outputLink(dTitle)+'</b>'
   + ' (' + outputLink(dTitle, '?action=history', 'h') + ')'
  dCaption.appendChild(sp)
  //add toolbar
  dCaption.insertBefore(createToolbar(pop), dCaption.firstChild)
  return dCaption
 }
}
 
 
function closePopup(div){
 div.style.display = 'none'
 //purge(div)
 div.parentNode.removeChild(div)
 popupCount--
 if (isIE && (popupCount==0)) hideAllSelectElements() //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
 if (!followNextLink(lnk)) document.location.href = lnk.href
}
 
 
 
function hideAllSelectElements(isHide){ //workaround for IE  <select> zIndex bug
 var sels = document.getElementsByTagName('select')
 for (var i=0; i<sels.length; i++)
   sels[i].style.visibility = isHide ?  'hidden' : 'visible'
}
 
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 = mw.config.get('wgServer') + mw.config.get('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(/&amp;/g,'&')
  //txt = txt.replace(/&lt;/g,'<').replace(/&gt;/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, params, name, tooltip){
 if (!name) name = page
 if (!tooltip) tooltip = name //.replace(/'/g,'`')
 params = params || ''
 page = page.replace(/&amp;/gi,'&')
 var k = page.indexOf('#')
 if (k != -1) page = page.substring(0,k) + '#' + guessSectionName(page.substring(k+1))
 return '<a href="'+ articlePath + encodeURI(page).replace(/\?/g,'%3F') + params
    +'" title="' + tooltip.replace(/"/g,'&quot;') + '">' + 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(){
 if (dfImprovementSheet) return
 appendCSS('\
div.df-toolbar {float:right; margin-left:10px}\
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%}\
body table.diff, td.diff-otitle, td.diff-ntitle {background:#FBFBFB}\
table.diff td.diff-lineno {border-top: 25px solid #FBFBFB}\
tr.df-deleted td {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%}\
tr.df-added ins.diffchange {color:inherit; font-weight:normal; border:none}\
div.df-toolbar span.df-improve-btn {border:1px inset #EEEEEE}\
table.diff td {cursor:help}\
table.diff td div, table.diff td.diff-multi {margin:0 8px 0 2px; cursor:default}'
+ (window.dfDiffTableCSS ? dfDiffTableCSS : '')) //user CSS
 
//cursor stuff shows that TD is clickable (sticking out from under DIV inside)
 
//padding: 0 8px 0 2px
 
//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) importStylesheetURI('/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:90%}\
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% }\
a.df-clicked {background-color:#E5E5E5}\
a.df-clicked-last {background-color:#FFDDDD}\
')
}
// min-width was added for Safari
 
function highlightDiffs(e){
 if (!dfHighlightSheet)
   dfHighlightSheet = addCSS('.diffchange-inline, span.diffchange {border:1px solid red}\
 div.df-toolbar span.df-highlight-btn {border:1px inset #EEEEEE}')
 else dfHighlightSheet.disabled = !dfHighlightSheet.disabled
}
 
 
function addCSS(text){
 var s = appendCSS(text) //from wikibits
 return s.sheet || s //Safari compat
}
 
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(clickedLink, diffTable, func){
 diffTable.style.opacity = '0.5'
 cursorWait(true)
 var url = clickedLink.href + '&action=render&diffonly=yes'
 requestPage(url, loadDiff2)
 function loadDiff2(html){
  diffTable = replaceTable(diffTable, html)
  //remember diff url and title
  diffTable.parentNode.diffURL = url
  var td = getElementsByClassName(diffTable, 'td', 'diff-ntitle')[0]
  diffTable.parentNode.diffTitle = td ? getTitleFromURL(td.getElementsByTagName('a')[1].href) : ''
  //insert permalink to this diff
  var dv = document.createElement('span')
  dv.innerHTML = '<a href="'+clickedLink.href+'" title="direct link to this diff" style="font-style:normal">[]</a>'
  dv.style.cssText = 'float:right; font-size:smaller'
  td = getElementsByClassName(diffTable, 'td', 'diff-otitle')[0]
  if (td) td.firstChild.insertBefore(dv, td.firstChild.firstChild)
  //td.lastChild.insertBefore(dv,td.lastChild.firstChild)
 
  //improve
  improveTable(diffTable)
  cursorWait()
  if (func) func(clickedLink, diffTable)
 }
}
 
function changeClass(el, oldC, newC){
 el.className = el.className.replace(oldC, '').replace(/ +/g,' ') + ' ' + newC
}
 
} //wrapper
 
 
 
$(diffScript.start)

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.