Thành viên:Unpear/patroller.js
Chú ý: Sau khi lưu thay đổi trang, bạn phải xóa bộ nhớ đệm của trình duyệt để nhìn thấy các thay đổi. Google Chrome, Firefox, Internet Explorer và Safari: Giữ phím ⇧ Shift và nhấn nút Reload/Tải lại trên thanh công cụ của trình duyệt. Để biết chi tiết và hướng dẫn cho các trình duyệt khác, xem Trợ giúp:Xóa bộ nhớ đệm.
if (doneOnloadHook) patrollerScript()
else addOnloadHook(patrollerScript)
function patrollerScript(){ //main wrapper
var isIE = navigator.userAgent.indexOf('MSIE') != -1
//localization
var mw = { //en.wp
patrol_word: 'patrol',
autosumm_new: /<\/a>Created page with '(.+)'$/i,
patrol_switch_tip: 'Add [patrol] link to each title',
olderArticlesID: 16100000,
patrol_tip: 'Mark page as patrolled',
patrol_wait: 'Marking as patrolled...'
}
var ul, lis, logTable, swLink, isTable = false
var imcomm = 'http://upload.wikimedia.org/wikipedia/commons/'
if (wgCanonicalNamespace=='Special' && wgCanonicalSpecialPageName=='Newpages')
startOnSpecialNewPages()
else if (wgNamespaceNumber==0 && wgAction=='view' && wgArticleId > mw.olderArticlesID)
startOnNewArtcile()
else return
// *** This part is executed on Special:NewPages ***
function startOnSpecialNewPages(){
//get page structure
var content = document.getElementById('content') || document.getElementById('mw_content')
ul = content.getElementsByTagName('ol')[0] || content.getElementsByTagName('ul')[0]
if (!ul) return
//attach switching link
swLink = document.createElement('span')
swLink.onclick = switchNewPages
swLink.style.cssText = 'margin-left:10px; font-size:85%; cursor:pointer'
ul.parentNode.insertBefore(swLink, ul)
//create table
lis = ul.getElementsByTagName('li')
if (window.ptMaxPages && lis.length > ptMaxPages) isTable = true //surpress creation if too many rows
switchNewPages()
}
function switchNewPages(){
if (isTable){
ul.style.display = 'block'
if (logTable) logTable.style.display = 'none'
swLink.innerHTML = '<img src='+imcomm+'thumb/4/41/List_icon.gif/12px-List_icon.gif>'
}else{
if (!logTable) createTable()
ul.style.display = 'none'
logTable.style.display = 'block'
swLink.innerHTML = '<img src='+imcomm+'thumb/c/cc/Simple_icon_table.svg/13px-Simple_icon_table.svg.png>'
}
isTable = !isTable
}
function createTable(){
//var comment, isOneUser
if (!window.logDateIn) logDateIn = /(\d\d:\d\d), (\d\d?) (\S\S\S)\S* (\d\d\d\d)/
if (!window.logDateOut) logDateOut = '$1 $2 $3'
if (!window.logBlDivider) logBlDivider = '<br>'
addCSS('\
.logtime {width:15px}\
tr.not-patrolled {background:transparent}\
tr.not-patrolled td.logtime {background:#FFFFAA}\
td.pagehist {text-align:right; padding-right:2px}\
td.quote {background:white}\
' + (window.newPagesCSS?newPagesCSS:''))
//create table
var tbody = '<tr><th><img src='+imcomm+'thumb/a/af/Relogio07_15.svg/15px-Relogio07_15.svg.png></th>'
var columns = 5
var ma
if (isOneUser=/&username=([^&]+)/.test(document.URL)) columns = 4
else tbody += '<th><img src=/skins-1.5/monobook/user.gif></th>'
tbody += '<th id=thTitles> </th><th> </th>'
+ '<th><img src=' + imcomm + '8/80/Icons-mini-comment_blue.gif></th></tr>'
//parse entries
for (var i=0; i<lis.length; i++){
row = lis[i].innerHTML
//get comment span
ma = row.match(/<span class="?comment"?>\((.+)\)<\/span> *$/i)
isQuote = ''
if (ma) {
comment = ma[0]
row = row.substring(0, row.length - comment.length)
ma = ma[1] //without SPAN
if (ma=ma.match(mw.autosumm_new)){ comment = ma[1]; isQuote = ' quote' }
}else comment = ''
//parse everything else
ma = row.match(/([^<]+)(<a[^<]+<\/a>) \((<a[^<]+<\/a>)[^\d]*([^ \]]+)[^<]*(<a[^<]+<\/a>) (.*)/i)
if (!ma || ma.length != 7) { //cannot parse
tbody +='<tr><td colspan='+columns+'>' + lis[i].innerHTML + '</td></tr>'
continue
}
tbody +='<tr class="' + lis[i].className + '">'
+ '<td class=logtime>' + ma[1].replace(logDateIn, logDateOut)
+ (isOneUser ? '' : '</td><td>'
+ ma[5] + ma[6].replace(/>(.)(.*?)</g, '>$1<').replace(/> </,'> <'))
+ '</td><td class=pagetitle>' + ma[2]
+ '</td><td class=pagehist>' + ma[3].replace(/>[^<]+</, '>'
+ma[4].replace(/[^\d,]/g,'')+'<') //number of bytes as history link
+ '</td><td class="comment'+isQuote+'">' + comment + '</td></tr>'
}
//insert table
logTable = document.createElement('div')
logTable.innerHTML = '<table class=wikitable width=100% id=logTable>' + tbody + '</table>'
ul.parentNode.insertBefore(logTable, ul)
ts_makeSortable(document.getElementById('logTable'))
//add [patrol] switch
var sp = document.createElement('span')
sp.style.cssText = 'cursor:pointer; font-size:smaller; font-weight:normal; margin-left:1em'
sp.appendChild(document.createTextNode('[+'+mw.patrol_word+']'))
sp.title = mw.patrol_switch_tip
sp.onclick = displayDirectPatrolLinks
document.getElementById('thTitles').appendChild(sp)
}
function displayDirectPatrolLinks(){
var tds = getElementsByClassName(logTable, 'td', 'pagetitle'), aa, pp
for (var i=0; i<tds.length; i++){
var aa = tds[i].getElementsByTagName('a')
if (!(aa=aa[0]) || !(href=aa.href) || (href.indexOf('&rcid=')==-1)) continue
pLink = aa.nextSibling
if (!pLink || pLink.nodeName != 'A'){ //create [patrol] link
pLink = document.createElement('a')
pLink.appendChild(document.createTextNode('['+mw.patrol_word+']'))
pLink.href = href + '&action=markpatrolled'
addHandler(pLink, 'click', patrolClick)
pLink.style.cssText = 'font-size:smaller; margin-left:1em; display:none'
aa.parentNode.appendChild(pLink)
}
pLink.style.display = (pLink.style.display == 'none') ? 'inline' : 'none'
}
}
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)
}
// *** This part is executed on articles ***
var mwPatrolLink
function startOnNewArtcile(){
//add 'patrol' tab
var pTabLink
if (!window.ptNoPatrolTab){
pTabLink = mw.util.addPortletLink('p-cactions', '', mw.patrol_word, 't-patrol', mw.patrol_tip).firstChild
addHandler(pTabLink, 'click', patrolClick)
}
//find MediaWiki built-in patrol link
var content = document.getElementById('content') || document.body
var mwPatrolLink = getElementsByClassName(content, 'div', 'patrollink')[0]
if (mwPatrolLink && (mwPatrolLink=mwPatrolLink.getElementsByTagName('a')[0])){
addHandler(mwPatrolLink, 'click', patrolClick)
if (pTabLink) pTabLink.href = mwPatrolLink.href
}
}
function patrolClick(e){
e = e || window.event
if (e.shiftKey || e.button == 2) return true // shift key or right click
if ((isIE && e.button == 4) || (!isIE && e.button == 1)) return true //middle click
var lnk = e.target || e.srcElement
var url = lnk.getAttribute('href')
if (url && window.ptNoInPagePatrolling) return true //let browser handle it
if (e.preventDefault) e.preventDefault(); else e.returnValue = false //otherwise intercept
if (url) markAsPatrolled(url)
else makeApiCall('query&list=recentchanges&rctype=new&rcprop=ids|patrolled&rctitles='
+ encodeURIComponent(mw.config.get('wgPageName')), getRCIDFirst)
return false
}
function getRCIDFirst(resp){
if (!resp) return jsMsg('Error while making API call')
var q
try {eval('q='+resp)}
catch (e) { return jsMsg('Error while evaluating API answer:<br />'+resp)}
if (q.error) return jsMsg('API says "' + q.error.code + ':' + q.error.info+'"')
if (!(q=q.query) || !(q=q.recentchanges) || !(q=q[0]))
return jsMsg('Cannot find «'+wgPageName+'» in recentchanges:<br />'+resp)
if (!q.rcid) return jsMsg('Cannot find RCID:<br />'+resp)
//define url
var patrolURL = mw.config.get('wgServer')+mw.config.get('wgScript')+'?action=markpatrolled&rcid='+q.rcid
+'&title='+encodeURIComponent(mw.config.get('wgPageName'))
//check if patrolled already
if (typeof q.patrolled == 'string'){
jsMsg('This page has been <b>already patrolled</b>'
+' (<a href="'+mw.config.get('wgServer')+mw.config.get('wgScript')+'?title=Special:Log&page='+encodeURIComponent(mw.config.get('wgPageName'))+'">log</a>).'
+ ' If you want, you can <a id=patrol-anyway href="'+patrolURL+'">mark it</a> as patrolled again')
addHandler(document.getElementById('patrol-anyway'), 'click', patrolClick)
return
}
markAsPatrolled(patrolURL)
}
function markAsPatrolled(url){
//url = url.replace(/action=markpatrolled/, 'action=watch') // debugging !!!
jsMsg(mw.patrol_wait)
if (window.ptNoInPagePatrolling) document.location.href = url
else openActionInFrame(url)
}
function openActionInFrame (url){
var ifr = document.createElement('iframe')
ifr.style.cssText = 'width:85%; height:150px; border:none; opacity:0.3'
//attch iframe
var jsm = document.getElementById('mw-js-message')
jsm.appendChild(ifr)
//attach onload
function iframeOnLoad(){ //hide unneeded HTML elements
var d = ifr.contentDocument || ifr.contentWindow.document
var pp = d.getElementsByTagName('p')
patrolMessage2 = '' //global var
for (var j=0; j<pp.length; j++) patrolMessage2 += '<br/>' + pp[j].innerHTML + '<br/>'
//jsm.removeChild(ifr); ifr = null
setTimeout('jsMsg(patrolMessage2)', 10) //otherwise Firefox 1.5 staying is "loading" state for some reason
}
if (isIE) ifr.onreadystatechange = function(){ if (/loaded|complete/.test(this.readyState)) iframeOnLoad()}
else ifr.onload = iframeOnLoad
//load
window.scrollTo(0, 0)
ifr.src = url + '&useskin=myskin'
}
// ** AJAX asynchronous call
function makeApiCall(params, func){
var aj = sajax_init_object()
var url = '/w/api.php?action=' + params
jsMsg('Making API <a href="'+wgServer+url +'">request</a>, please wait...')
aj.open('GET', url + '&format=json',true)
aj.onreadystatechange=function() {
if (aj.readyState != 4) return
if (aj.status == 200) func(aj.responseText)
else func(null)
}
aj.send(null)
}
}