(function(win, u){var alienFrame = /(plusone\.google\.com|spmbt\.github\.io)/.test(location.host)
,metaTx = !alienFrame && function(s){return(s=
//если Firefox+GreaseMonkey, требуется удалить "/*" перед "
)} // © licensed by LGPLv3 Open Source www.gnu.org/licenses/lgpl-3.0.en.html
,isFxScr = typeof GM_getMetadata !=u //-Scriptish
,readMeta = function(s, isFxScr){ //парсинг многострочного текста по мета-директивам
if(typeof s !='string') //очистка оболочки функций, выделение мн-стр-комментария
s = typeof s=='function'
? ((/\*/.test(function(){/**/}+1) ? s : s(!1) )+'')
.replace(/(^[\s\S]*\*\/\/\*\r?\n?|\r?\n?\*\/s[\s\S]*$)/gm,'')
: (typeof s !=u && s!==null && s.toString ? s.toString() :''); //здесь же- 'xml'
var metaD ={}, j =0;
if(s==='false'&& isFxScr){ //получать ли данные средствами Scriptish
metaD = GM_getMetadata();
for(var i in metaD){ //приведение к нормальному виду
if(metaD[i].length ==1)
metaD[i] = metaD[i][0];
j++;
}
}else{
var meta = s.split('\n'), aa, a2;
for(var i=0, mL = meta.length; i < mL; i++){
if(( aa = /^.*?\/\/\s*@([\S]+)\s(\s*)(.*)/g.exec(meta[i]) )){
a2 = aa[3] !==undefined && aa[3] || aa[2];
if(metaD[aa[1]]===undefined)
metaD[aa[1]] = a2;
else{
if(! (metaD[aa[1]] instanceof Array))
metaD[aa[1]] = [metaD[aa[1]]];
metaD[aa[1]].push(a2);
}
j++;
}else if(!/^.*?\/\/\s*[\-=]*\s*\/?\s*UserScript\s*[\-=]*\s*$/i.test(meta[i]))
metaD[j++] = meta[i];
}
}
return j >1 && metaD || undefined; //хеш директив + нум.список простых строк + _length -чис.простых строк или und., если не найдено
},
extMeta = function(m, callback, callErr){ //или (url, callback, callErr)//получение внешних метаданных
if(typeof m =='string')
var shortNum = (/^\d+(\.meta\.js)?$/.test(m) ? m :'') + (/^\d+$/.test(m) ?'meta.js':'')
,xUrl = shortNum ? URLSCR + HAJAX +'/code'+ shortNum : m ;
//wcl(m, shortNum, xUrl)
if(typeof GM_xmlhttpRequest !=u){
GM_xmlhttpRequest({
url: xUrl
,method:'get' //Chrome
,onload: callback //параметр - req (для req.responseText)
,onerror: callErr //параметр - req (для req.responseText)
});
}else if(win.opera && xUrl){ //load metadata for Opera
var ifr = document.createElement('iframe');
ifr.src = xUrl;
ifr.style.display ='none';
document.body.appendChild(ifr);
ifr.name = ifr.id ='operaEmbedMeta';
win.addEventListener('msg', function(ev){ //слушать приход Event
callback({responseText: ev.data.replace(/\n?\noperaEmbedMeta$/,''), finalUrl: xUrl});
},!1);
}else
wcl('~~No read metadata!'); //другой способ запроса внешнего сервера по ajax
return {waitHandler: 0 //для немедленного таймаута
,callback: callback, callErr: callErr}; //для немедленного завершения
};
win = (function(){return this})();
var DAY = 86400000
,CHKUPD = 15 //мин. период проверок обновлений скрипта (минут) при ошибках чтения
,NOWdate = new Date()
,NOW = +NOWdate,HSO='http://habrastorage.org',SHRU='https://habrahabr.ru/auth'
,HRU ='http://habrahabr.ru',sHQ='habr.statis.tk/c?id=@&in=@&zc=@&at=@' //37.230.115.43исп-ть ли сервер статистики
,HRs ={ha: HRU, geek:'http://geektimes.ru',manag:'http://megamozg.ru',qa:'http://toster.ru',haru:'http://haru'}
,HClons ={soha:'sohabr',sape:'savepearlharbor',haru:'haru'}
,ROOT = location.protocol +'//'+ location.host
,URLSCR ='https://greasyfork.org/scripts/'
,URLCSS ='http://userstyles.org/styles/33690/'
,HAJAX ='1970-habrajax/'
,userNameMaxLen = 25
,isFx = /Firefox/.test(navigator.userAgent)
,isChrome = /Chrome\//.test(navigator.userAgent)
,wcl = function(a){ a = a!==undefined ? a :''; //консоль как метод строки или функция, с отключением по hS.noConsole.val ==1
if(win.console && typeof hS !=u && !hS.noConsole.val)
win.console.log.apply(win.console, this instanceof String
? ["'=="+ this +"'"].concat([].slice.call(arguments))
: arguments);
}
, strongCutImgMinH;
String.prototype.wcl = wcl;
String.prototype.trim = function(s){var s = this ||s;
return s.replace(/(^\s+|\s+$)/g,'')};
if(win.opera || typeof GM_xmlhttpRequest ==u)
GM_xmlhttpRequest = function(h){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
var responseState ={
responseXML: xhr.readyState==4 ? xhr.responseXML :''
,responseText: xhr.readyState==4 ? xhr.responseText :''
,readyState: xhr.readyState
,responseHeaders: xhr.readyState==4 ? xhr.getAllResponseHeaders() :''
,status: xhr.readyState==4 ? xhr.status : 0
,statusText: xhr.readyState==4 ? xhr.statusText :''
};
h.onreadystatechange && h.onreadystatechange(responseState);
if(xhr.readyState==4){
if(h.onload && xhr.status>=200 && xhr.status<300)
h.onload(responseState);
if(h.onerror && (xhr.status<200 || xhr.status>=300))
h.onerror(responseState);
}};
try{//cannot do cross domain
xhr.open(h.method, h.url);
}catch(er){
if(h.onerror) //simulate a real error
h.onerror({responseXML:'',responseText:'',readyState:4,responseHeaders:'',status:403,statusText:'Forbidden'});
return;
}
if(h.headers)
for(var prop in h.headers)
xhr.setRequestHeader(prop, h.headers[prop]);
xhr.send((typeof(h.data) !=u) ? h.data : null);
};
try{ //для оповещения об ошибках в Fx
var metaD = readMeta(metaTx, isFxScr) //metaTx == false ||'false'(строка) - если Fx|| строки метаданных
,gPlusFrame = alienFrame && /plusone/.test(location.host);
win.adriver = function(){};
win.adriver.domReadyQueue ={execute: function(){},Plugin: function(){this.a =1;}};
//===============================================
//'testUScr'.wcl({isFxScr:isFxScr, unsafeWindow: typeof unsafeWindow !=u}); //win !==window при Greasemonkey|Scriptish
if(!alienFrame){
//alert(addEventListener)
win.addEventListener('message', function(ev){ //слушать приход данных
//'start_parse'.wcl(win.JSON , win.JSON.parse, win.JSON.decode)
if(win.JSON && !win.JSON.parse && win.JSON.decode) win.JSON.parse = win.JSON.decode; //habr - old //опера требует этого внутри хендлера
//'decode'.wcl(win.JSON , !win.JSON.parse , win.JSON.decode, win.JSON && !win.JSON.parse);
if(/likes/.test(ev.data) && /frme/.test(ev.data) && win.JSON && win.JSON.parse){ //поставить лайки снаружи
var n = JSON.parse(ev.data);
if(n){
//'parsed_data'.wcl(n);
var frs = document.getElementsByTagName('iframe');
for(var i in frs)
if(frs[i].name == n.frme){
frs[i].setAttribute('likes', n.likes);
var x = frs[i].parentNode.parentNode.querySelector('.likes div div');
x && (x.innerHTML = n.likes);
}
}
}
if(/\noperaEmbedMeta$/.test(ev.data) && win.JSON && win.JSON.parse){
//alert(ev.data)
var evt = document.createEvent('Event'); //генерировать для перехвата на приёме файла
evt.initEvent('msg',!0,!0);
evt.data = ev.data;
win.dispatchEvent(evt);}
},!1);
}
if(gPlusFrame){
/**
* evaluate script in window scope
* @param{Function} fs function or string is body of function
* @param{String|Array} s string or array of strings for arguments
* @param{Boolean} noOnce not delete script after exec
*/
var winEval = function(fs, s, noOnce){ //exec function/text in other scope
s = (s ||[]) instanceof Array? s ||[] : [s]; //wrap by array
alert(s +' '+ 'fs2')
var fs2 = typeof fs=='function'
? (fs +'').replace(/(^\s*function\s*\([^\)]*\)\s*\{\s*|\s*\}\s*$)/g,'') //clean wrapper
: fs
,as ='';
for(var i =0, sL =s.length; i < sL; i++) //sequential array
as += (i?',':'') +"'"+ s[i].replace(/'/g,"\\'").replace(/(\r\n|\r|\n)/g,"\\\n") +"'";
fs = '(function(){'+ fs2 +'}).apply(window,['+ as +']);';
//'fs'.wcl(fs, fs2)
var d = document
,scr = d.createElement('script');
scr.setAttribute('type','application/javascript');
scr.textContent = fs;
var dPlace = d.body || d.getElementsByTagName('head') && d.getElementsByTagName('head')[0];
dPlace.appendChild(scr);
if(!noOnce) dPlace.removeChild(scr);
};
/**
* check occurrence of third-party event with growing interval
* @constructor
* @param{Number} t start period of check
* @param{Number} i number of checks
* @param{Number} m multiplier of period increment
* @param{Function} check event condition
* @param{Function} occur event handler
*/
var Tout = function(h){
var th = this;
(function(){
if((h.dat = h.check() )) //wait of positive result, then occcurense
h.occur();
else if(h.i-- >0) //next slower step
th.ww = win.setTimeout(arguments.callee, (h.t *= h.m) );
})();
};
new Tout({t:320, i:6, m: 1.6
,check: function(){
return document && document.querySelector('#aggregateCount');
}
,occur: function(){
var id = location.hash.match(/(\?|#|&)id=([^&]+)/) //frame id [or name]
,w = win;
id = id && id.length && id[2];
var s = w.JSON && w.JSON.stringify && w.JSON.stringify( //must supported earlier
{likes: this.dat.innerHTML, frme: id}) //data format
,pHost = (function(a){ //host extract from parameter (#|&)parent
if(!a.match(/^https?\:\/\//)) return'';
var b = document.createElement('a');
b.href = a;
b.pathname = b.search = b.hash ='';
return b.href.replace(/\/\??\#?$/,'')
})( decodeURIComponent( (w.location.href.match(/.*(\?|#|&)parent=([^&]+)/) ||[])[2] ||'') );
try{
if(!isChrome || w.parent && w.parent.postMessage){
s && w.parent.postMessage(s, pHost); //all browsers except Chrome
}else if(s)
winEval(function(args){
var w = window
,p1 = arguments[0]
,p2 = arguments[1];
if(w.postMessage && p1 && w != w.parent){
function wpm(){
w.parent.postMessage(p1, p2); //msg with a glance Chrome bug
}
w.document.all ? w.setTimeout(wpm, 0) : wpm();
}
}, [s, pHost]);
}catch(er){wcl(er)}
}
});
}else if(alienFrame){ // для Оперы (только) в фрейме greasyfork.org - отправка метаданных
document.addEventListener('DOMContentLoaded',function(){
var dd = document.querySelector('pre')
,s = dd && dd.innerHTML;
if(s && win.parent && win.parent.postMessage)
win.parent.postMessage(s +'\noperaEmbedMeta', ROOT);
},!1);
} //(далее выполняется, если не в alienFrame)
if(alienFrame) return;
var setLocStor = function(name, hh){
if(!localStorage) return;
localStorage['habrAjax_'+ name] = JSON.stringify({h: hh});
},
getLocStor = function(name){
return (JSON.parse(localStorage && localStorage['habrAjax_'+ name] ||'{}')).h;
}
,removeLocStor = function(name){localStorage.removeItem('habrAjax_'+ name);}
,lh = location.href
,$q = function(q, f, f2, args){ // контекстный DOM-селектор или условная функция с ним: (elem)q | ((str)q, f, args) | ((str)q, elem) | ((str)q, (elem)context, f, args)
var Q = q && q.attributes && q || (!(f instanceof Function) && f||document).querySelector(q);
return f instanceof Function ? f && Q ? f.apply(Q, f2 instanceof Array && f2 || [f2]) : Q
: f2 instanceof Function ? f2 && Q ? f2.apply(Q, args instanceof Array && args || [args]) : Q : Q }
,$qA = function(q, f, f2, args){
var Q = q && q.attributes && q || (!(f instanceof Function) && f||document).querySelectorAll(q);
return f instanceof Function ? f && Q.length ? f.apply(Q, f2 instanceof Array && f2 || [f2]) : Q
: f2 instanceof Function ? f2 && Q.length ? f2.apply(Q, args instanceof Array && args || [args]) : Q : Q }
previButt = $q('#post_form .buttons input[name="preview"]')
wwPrevi =0;
previButt && previButt.addEventListener('click',function(ev){
wcl('previclick');
win.clearTimeout(wwPrevi);
textContentPrev ='00';
fillLetter();$pd(ev);
},!1);
var textContentPrev ='00'
,fillLetter = function(){ //сформировать письмо в ЛС
var aLHash = lh.replace(/^[^#]*#/,'').split('&')
,hLHash ={}
,lStor = getLocStor('composeLetter')
,lStNoBq = lStor && !/<\/?blockquote>/.test(lStor.cite);
if(/\/(add|edit)\//.test(lh)){ //страница редактирования (своей) статьи - по цитате
var ta = $q('#text_textarea')
,cite = lStor && lStor.cite
,text = lStor && lStor.text
,textContentDiv = $q('#preview_placeholder .content');
if(textContentDiv)
var textContent = textContentDiv.innerHTML; //содержимое статьи
if(ta && typeof cite !=u){
var tVal = ta.value
,iS =[]
,cL = cite.length;
for(var i =0, tL = tVal.length; i < tL; i++)
if(tVal.substr(i, cL) == cite)
iS.push(i); //все индексы вхождения строк
'cite'.wcl(iS, cite)
if(iS.length){
if(iS.length >1) //выделить найденное
hN && hN.addNote(nSufRu(iS.length, ['образ','ец','ца','цов'])+' для правки; следующий',0,0,function(){
var c1 = $q('a', this.o);
c1.addEventListener('click', function(ev){
var i = !c1.getAttribute('data-curr') ? 1: +c1.getAttribute('data-curr')
,a = JSON.parse(c1.getAttribute('data-match') )
,cite = c1.getAttribute('data-patrn');
ta && ta.setSelectionRange && ta.setSelectionRange(a[i], a[i] + cite.length);
c1.setAttribute('data-curr', (++i) % a.length);
ta.blur();
ta.focus();
$pd(ev);
},!1);
});
var i1 = iS[0];
'citeEnd0'.wcl(nSufRu(iS.length, ['образ','ец','ца','цов']) )
ta && ta.setSelectionRange && ta.setSelectionRange(i1, i1 + cL);
'citeEnd'.wcl(iS, cite)
}else
hN && hN.addNote('не найдено образцов для правки');
'citeEnd1'.wcl(iS, cite)
ta.focus();
removeLocStor('composeLetter');
}
if(textContentPrev !='00'&& textContent != textContentPrev){ //обработать подгруженное
'renderOfAvaxTxt'.wcl(textContentPrev && textContentPrev.length, textContent && textContent.length)
authorClicks(textContentDiv); //особые клики по авторам (напр. в фрейм)
//blockBrs(textContentDiv); //сокращение верт.зазоров
extLinks(textContentDiv); //ext.links и подписи к старым местным линкам
handlImgViews(textContentDiv); //images
byTextNodes(textContentDiv, haReplace); // --> XX
//обработка выделения текста
}else
wwPrevi = win.setTimeout(fillLetter, 1499); //проверка обновлений cite
if(textContentPrev =='00')
textContentPrev = textContent;
return;
}
'conversations'.wcl(lStor, hLHash, lStNoBq, aLHash.length);
if(aLHash[0] ==lh) aLHash =[];
for(var i =0; i < aLHash.length; i++){
var a = aLHash[i].split('=');
hLHash[a[1]!==undefined && a[0]] = decodeURIComponent(a[1]!==undefined && a[1] || a[0]);
}
var fieldTo = $q('.conversation_page input[name="users-suggest"]')
,fieldTheme ='Тема: '
,fieldText = $q('#text_textarea');
'fieldTo'.wcl(fieldTo, fieldTheme, fieldText);
fieldTo &&(fieldTo.value = hLHash.to && hLHash.to.trim() || lStor && lStor.to ||'');
fieldTheme += hLHash.subj && hLHash.subj.trim()
|| (lStor ?(lStor.url ?'':'')
+ lStor.subj +(lStor.url ?'':''):'')
+(!hLHash.subj && lStor && lStor.date && lStor.subj ?' ('+ lStor.date +')':'');
if(fieldText) fieldText.value = (fieldTheme ? fieldTheme +'\n':'')
+ (aLHash.length && !(/^comment_\d+$/.test(aLHash[0])) && ( //по URL-параметрам
hLHash.cite && ('
'+ hLHash.cite +'
') ||' '
)|| (lStor ?( //по хранилищу, если нет URL-параметров
(lStor.commId ?' # '+ lStor.commId +' '
+'@'+ lStor.commAuthor +'\n':'')
+(lStNoBq?'':'')+ (lStor.cite ||'')
+(lStor.commDate?' ('+lStor.commDate+')':'')
+(lStNoBq?'
':'')
+(lStor.text ? lStor.text :'')
):'') );
'lStor.cite'.wcl(lStor && '|'+lStor.cite+'|'+lStor.commAuthor)
if(lStor && !aLHash.length && !lStor.noReceiver)
removeLocStor('composeLetter');
if(lStor && lStor.noReceiver){
if(lStor && lStor.noReceiver ==2)
delete lStor.noReceiver;
'lStor'.wcl(lStor)
lStor.noReceiver =2;
setLocStor('composeLetter', lStor);
}
if(fieldTo)
fieldTo.focus(),fieldTo.select(); //выделен адресат для быстрой смены
if(fieldText){
fieldText.focus(); //в поле ввода текста
/*var evt = document.createEvent("KeyEvents");
evt.initKeyEvent('keyup',!0,!0, win,!1,!1,!1,!1, 40,0);
fieldText.dispatchEvent(evt);*/
}
},
nSufRu = function(n, vocab){ //числительные склонения слов ("день" и др.)
var an = Math.abs(n)
,vocab = typeof vocab =='number'? [['д','ень','ня','ней']][vocab] : vocab;
return n +' '+ vocab[0] + (an % 10 >0 && an % 10 <5 && Math.floor(an % 100 / 10) !=1
? (an % 10 ==1 ? vocab[1] : vocab[2]) : vocab[3]);
};
//===begin from Dollchan Extension Tools=== --группа функций просмотра изображений--
var doc = win.document
,$pd = function(ev){ev.preventDefault();}
,$sp = function(ev){ev.stopPropagation();},$pdsp = function(ev){ev.preventDefault();ev.stopPropagation();}
,$dispTogl = function(el){el.style.display = el.style.display ==='none'?'':'none'; return el;}
,$offset = function(el){
var box = el.getBoundingClientRect(), aa;
'offset'.wcl(aa={
top: Math.round(box.top + win.pageYOffset),
left: Math.round(box.left + win.pageXOffset) })
return aa;
},
addFullImg = function(a, sz, x2, isExp){ //построение изображения по клику на ссылке
x2 = x2 || 1;
var newW =''
,newH =''
,fullW = x2* sz[0]
,fullH = x2* sz[1]
,scrW = doc.documentElement.clientWidth -10
,scrH = win.innerHeight -3
,isA = a.tagName =='A'
,full = isA ? $q('.de-img-full', a) : a.nextSibling;
if(full && /de-img-full/.test(full.className) && isExp || !full && isExp === false)
return;
if(hS.viewImgs && hS.viewImgs.val && !hS.viewImgCenter.val && !$q('img[style*="fixed"]', a) )
$dispTogl($q('img', a)); //TODO зкспериментально; отключено
if(full && /de-img-full/.test(full.className)){
if(full.moved)
full.moved = false;
else{
$dispTogl(full);
setTimeout(function(){full.parentNode.removeChild(full);},1);
}
return;
}
if(hS.viewImgs && hS.viewImgs.val && !hS.viewImgCenter.val)
scrW -= $offset(a).left + 25; //TODO зкспериментально; отключено
else{
var el = $q('.de-img-center', doc);
el && el.parentNode.removeChild(el);
}
if(fullW && fullH){
newW = Math.min(fullW, scrW);
newH = newW * fullH / fullW;
if(hS.viewImgCenter.val && newH > scrH){
newH = scrH;
newW = newH * fullW / fullH;
}
if(newW/fullW < 1.13 && newW / fullW >0.88){
newW = +fullW;
newH = +fullH;
var title = x2 +'00%';
}
}
if(!title)
title = Math.round(newW / fullW *100)* x2 +'%';
var isViewUrl = !hS.addImgs.val && a.getAttribute('data-viewUrl')
,url = isA ? a.href : isViewUrl || (a.previousSibling && a.previousSibling.firstChild.src)|| a.src;
if(/#\.jpg/.test(url) )
url = a.firstChild.src;
if(isViewUrl)
title ='100%';
var ht ='
'
if(a.insertAdjacentHTML)
a.insertAdjacentHTML(isA ?'beforeend':'afterend', ht); //Fx8+
else
$e( $x(isA?{apT: a}:{aft: a}, {ht:ht}) ); //неточно, и ошибки в Fx3.6
if(hS.viewImgCenter.val){
var resizeImg = function(ev){ //обработчик колеса мыши - масштаб картинки
var curX = ev.clientX
,curY = ev.clientY
,oldL = parseInt(this.style.left, 10)
,oldT = parseInt(this.style.top, 10)
,oldW = parseFloat(this.style.width || this.width)
,oldH = parseFloat(this.style.height || this.height)
,d = isFx ? -ev.detail : ev.wheelDelta
,newW = oldW * (d >0 ? 1.25 : 0.8)
,newH = oldH * (d >0 ? 1.25 : 0.8)
,sizes = full.getAttribute('data-sizes').split('x');
if(newW/sizes[0] < 1.13 && newW / sizes[0] >0.88){
newW = +sizes[0];
newH = +sizes[1];
this.title = x2 +'00%';
}else
this.title = Math.round(newW / fullW *100)* x2 +'%';
$pd(ev);
this.style.width = newW +'px';
this.style.height = newH +'px';
this.style.left = parseInt(curX - (newW/oldW) * (curX - oldL), 10) +'px';
this.style.top = parseInt(curY - (newH/oldH) * (curY - oldT), 10) +'px';
};
full = $e({el: isA ? a.lastChild : a.nextSibling
,clAdd:'de-img-center'
,cs: {left: (scrW - newW)/2 +'px', top: (scrH - newH)/2 +'px'}
,at: {'data-sizes': fullW +'x'+ fullH}
,on: isFx ? {DOMMouseScroll: resizeImg}:{mousewheel: resizeImg}
});
!isA && full.addEventListener('click',function(ev){
$pdsp(ev);
if(full.moved)
full.moved = false;
else{
$dispTogl(full);
win.setTimeout(function(){full.parentNode && full.parentNode.removeChild(full);},1);
}
},!1);
(function(el){ //makeMoveable --перетаскивание
var elMove = function(ev){
el.style.left = ev.clientX - el.curX +'px';
el.style.top = ev.clientY - el.curY +'px';
el.moved = true;
},
elStop = function(ev){
var t = ev.target;
$e({el: doc.body
,revent:{mousemove: elMove, mouseup: elStop}});
if(ev.ctrlKey && t.parentNode.tagName=='A')
t.parentNode.click(); //нативный клик вынесен под Ctrl+
if((Math.abs(ev.clientX - el.startX) + Math.abs(ev.clientY - el.startY) ||0) <5 && ev.which ==1){
$dispTogl(t);
win.setTimeout(function(){t.parentNode.removeChild(t);},1);
}
};
el.onmousedown = function(ev){
$pd(ev);
el.curX = (el.startX = ev.clientX) - parseInt(el.style.left, 10);
el.curY = (el.startY = ev.clientY) - parseInt(el.style.top, 10);
$e({el: doc.body
,on:{mousemove: elMove, mouseup: elStop}});
};
})(full);
}
},
handlImgViews = function(el, selector){ //обработчики просмотров картинок
var selector = selector ||'.content a[href$=".jpg"],.content a[href$=".jpeg"],.content a[href$=".png"],.content a[href$=".gif"], .message a[href$=".jpg"],.message a[href$=".png"],.message a[href$=".gif"], .comments .text a[href$=".jpg"], .comments .text a[href$=".png"], .comments .text a[href$=".gif"]'
,els = $qA(selector, el); //все ссылки на картинки
//'handlImgViews'.wcl(el, selector, els )
for(var i =0, linkImg; linkImg = els[i++];){ //подгрузка картинок в рамках до 200 на 200 по расширениям файлов в ссылках
var a = linkImg.cloneNode(false)
,imgsInLink = $qA('img', linkImg);
if(imgsInLink && imgsInLink.length !=1 && hS.addImgs.val){ //подгружать картинки-ссылки
var lastLink = linkImg;
$e({el:'img' //малая картинка со ссылкой перед найденной ссылкой
,cl:'de-img-pre'
,at:{src: a.href, alt: a.href.substr(0,200)}
,on:{load: function(){
var t = this
,fullW = t.width
,fullH = t.height
,x2 = hS.viewX2.val && fullW *2 < win.innerHeight -3 ? 2:1; //признак "x2" - удваивать масштаб
t.title = (x2 ==2 ?'/':'')+ fullW +'x'+ fullH;
//'on:{load'.wcl(t.title, lastLink)
if(lastLink.firstChild && lastLink.firstChild.tagName =='BUTTON'){var evt = document.createEvent('Event');evt.initEvent('loadImg',!0,!0); evt.data = t.title; win.dispatchEvent(evt);}
t.style.cursor = x2 ?'ne-resize':'move';
if(/^imgL$/.test(t.parentNode.className)|| t.parentNode.className =='lnk'){ //включить видимость копий, выключить - оригиналы ссылок
t.parentNode.style.display ='inline-block';
t.parentNode.nextSibling.style.display ='none';
t.parentNode.title = t.title;
if(t.parentNode.className =='lnk')
t.parentNode.className ='lnk imgL';
}else
$dispTogl(t.parentNode);
if(fullW <= 200 && fullH <= 200)
return;
var k = fullW/fullH;
t.width = k < 1 ? 200 * k : 200;
t.height = k < 1 ? 200 : 200/k;
}},
apT: $e({el: function(){
var pImg = linkImg.previousSibling;
if(pImg && pImg.className=='aPrevi imgL')
pImg.parentNode.removeChild(pImg);
pImg = linkImg.previousSibling;
if(pImg && pImg.className=='aPrevi imgL')
pImg.parentNode.removeChild(pImg);
return $dispTogl(a);
}
,at:{target:'_blank'}
,on:{click: function(ev){ //eventLinkImg(a);
//'ev.button !==1'.wcl(ev.button,ev.button !==1, (hS.viewImgs.val || hS.viewImgCenter.val) && ev.button !==1)
if((hS.viewImgs && hS.viewImgs.val || hS.viewImgCenter.val) && ev.button !==1){
if(ev.ctrlKey)
return;
$pd(ev);
if(showImgMenu(ev, ev.currentTarget.frstChild) ) //по Shift+клик
return;
var titl = this.firstChild.title
,imgWH = titl.match(/(\d+)x(\d+)$/)
,x2 = titl.charAt(0)=='/'? 2:1; //признак "x2"
if(imgWH && imgWH.length ==3)
addFullImg(this, imgWH.slice(1), x2);
}
}}
,bef: linkImg
})
});
}else //подготовка тамбнейла для просмотра по клику на нём ссылки
imgsInLink && imgsInLink.length ==1 && $e({el: imgsInLink[0]
,clAdd:'de-img-thumb'
,at:{'data-viewUrl': linkImg.href} });
}
if(!(hS.viewImgs && hS.viewImgs.val) && !hS.viewImgCenter.val) //не просматривать картинки в странице
return;
for(var img, i =0, imgs = $qA('.content img:not(._noAddOwnView),.message img:not(._noAddOwnView),.message .text img:not(._noAddOwnView)', el); img = imgs[i++];){
//'12'.wcl(img,img.width , img.height)
if( (img.width >22 || img.height >22 || img.width==0 || img.height==0) && (!img.previousSibling || img.previousSibling && img.previousSibling.className !='de-img-hid') )
(function(img){$e({el:'img' //полная картинка в невидимом диве с overflow
,cl:'_noAddOwnView'
,at:{src: hS.addImgs.val && img.getAttribute('data-viewUrl') || img.src}
,cs:{position:'absolute', left:'-9999px'}
,on:{load: function(ev){
var fullW = this.width
,fullH = this.height;
this.title = fullW +'x'+ fullH;
$dispTogl(this.parentNode);
//'WHBig'.wcl(fullW, img.width, fullH, img.height, img);
if(fullW == img.width && fullH == img.height){
img.style.cursor ='ne-resize';
if(hS.viewX2.val)
this.title = '/'+ this.title; //признак "x2" (особый курсор)
}else if(!hS.viewX2.val){
img.style.cursor ='move';
img.setAttribute('data-view',1);
}
}},
apT: img.previousSibling && img.previousSibling.className =='de-img-hid' && img.previousSibling || $e({cl:'de-img-hid'
,cs:{overflow:'hidden', width:0, height:'8px'}
,bef: img
})
}) })($e({el: img //обработчик и смена курсора картинки
,cs: hS.viewX2.val ?{cursor:'move'}:{}
,on:{click: function(ev){ //eventLinkImg(a);
//'ev.button !==1'.wcl(ev.button,ev.button !==1, (hS.viewImgs.val || hS.viewImgCenter.val) && ev.button !==1)
var t = ev.currentTarget;
if(!hS.viewX2.val && !t.getAttribute('data-view') )
return; //не просматривать, если размер не изменится
if((hS.viewImgs && hS.viewImgs.val || hS.viewImgCenter.val) && ev.button !==1){
if(ev.ctrlKey)
return;
$pd(ev);
if(showImgMenu(ev, t)) //по Shift+клик
return;
var titl = this.previousSibling.firstChild.title
,imgWH = titl.match(/(\d+)x(\d+)$/)
,x2 = titl.charAt(0)=='/'? 2:1; //признак "x2"
if(imgWH && imgWH.length ==3)
addFullImg(this, imgWH.slice(1), x2);
}
}}
}));
}
},
showImgMenu = function(ev, img){ //контекстное меню на картинке - поиск по изображению
if(!ev.shiftKey) return;
else{
var srcD ={TinEye:{url:'tineye.com/search/?url='}
,Google:{url:'google.com/searchbyimage?image_url='}
,Yandex: {url:'images.yandex.ru/yandsearch?text=&rpt=imagedups&img_url='}
,SauceNAO:{url:'saucenao.com/search.php?url='}
,IQDB:{url:'iqdb.org/?url='} }
,srcMenu = $e({cl:'de-menu'
,on:{mouseout: function(){
$dispTogl(srcMenu);
win.setTimeout(function(){srcMenu.parentNode.removeChild(srcMenu);},1); }}
,cs:{left: ev.pageX -30 +'px', top: ev.pageY -24 +'px'}
,apT: doc.body
});
for(var i in srcD)
$e({el:'A'
,cl:'de-src'
,at:{target:'_blank', href:'http://'+ srcD[i].url + img.src}
,ht:'
'+ i
,on:{mouseout: function(ev){ $sp(ev);}}
,apT: srcMenu
});
}
return 1;
};//===end from Dollchan
var allASCII = function(s){ //все символы строки - ASCII
for(var i =0; i < s.length; i++)
if(s.charCodeAt(i) >127)
return !1;
return!0;
},
$x = function(el, h){if(h) for(var i in h) el[i] = h[i]; return el;}, //===extend===
$e = function(g){ //===создать или использовать имеющийся элемент===
//g={el|clone,blck,elA,cl|(clAdd,clRemove),ht,cs,at,atRemove,on,revent,ap,apT,prT,bef,aft,f+fA}
if(typeof g.el =='function') g.el = g.el.apply(g, g.elA);
if(!g.el && g.el !==undefined && g.el !='') return g.el; //null|0|false
var x, o = g.el = g.el || g.clone && typeof g.clone !='string' && g.clone.cloneNode(!0) || /\W/.test(g.clone) && (x = $q(g.clone, g.blck)) && x.cloneNode(!0) ||'DIV';
o = g.el = typeof o =='string'? /\W/.test(o) ? $q(o, g.blck) : document.createElement(o) : o;
if(o){ //выполнять, если существует el или clone
if(g.cl)
o.className = g.cl;
else{
if(g.clAdd)
o.classList.add(g.clAdd);
if(g.clRemove)
o.classList.remove(g.clRemove);}
if(g.cs)
$x(o.style, g.cs);
if(g.ht || g.at){
var at = g.at ||{}; if(g.ht) at.innerHTML = g.ht;}
if(at)
for(var i in at){
if(i=='innerHTML') o[i] = at[i];
else o.setAttribute(i, at[i]);}
if(g.atRemove)
for(var i in g.atRemove)
o.removeAttribute(g.atRemove[i]);
if(g.htT){ //подготовка шаблона
if(!(typeof g.htTA =='object')) g.htTA =[g.htTA];
for(var i in g.htTA)
g.htT = g.htT.replace(RegExp('\\{\\{'+ i +'\\}\\}','g'), g.htTA[i])
o.innerHTML = g.htT;}
if(g.on)
for(var i in g.on) if(g.on[i])
o.addEventListener(i, g.on[i],!1);
if(g.revent)
for(var i in g.revent) if(g.revent[i])
o.removeEventListener(i, g.revent[i],!1);
if(g.ap){ //добавление нод
if(g.ap instanceof Array){
for(var i in g.ap) if(g.ap[i] && i !='length')
o.appendChild(g.ap[i]);
}else o.appendChild(g.ap);}
g.apT && g.apT.appendChild(o);
g.prT && (g.prT.firstChild
? g.prT.insertBefore(o, g.prT.firstChild)
: g.prT.appendChild(o) );
g.bef && g.bef.parentNode.insertBefore(o, g.bef);
g.aft && (g.aft.nextSibling
? g.aft.parentNode.insertBefore(o, g.aft.nextSibling)
: g.aft.parentNode.appendChild(o) );
g.remove && g.remove.parentNode.removeChild(g.remove);
if(typeof g.f =='function')
g.f.apply(g, g.fA); //this - это g
}
return o;
/*
var x=
{cl: function(){o.className = g.cl;}
,clAdd: function(){o.classList.add(g.clAdd);}
,clRemove: function(){o.classList.remove(g.clRemove);}
,cs: function(){$x(o.style, g.cs);}
,ht: function(){var at = g.at ||{}; at.innerHTML = g.ht;}
,at: function(){var at = g.at ||{};
for(var i in at){
if(i=='innerHTML') o[i] = at[i];
else o.setAttribute(i, at[i]);}}
,ap:function(){if(g.ap instanceof Array){
for(var i in g.ap) if(g.ap[i] && i !='length')
o.appendChild(g.ap[i]);
}else o.appendChild(g.ap);}
,on:function(){for(var i in g.on) if(g.on[i])
o.addEventListener(i, g.on[i],!1);}
,revent:function(){for(var i in g.revent) if(g.revent[i])
o.removeEventListener(i, g.revent[i],!1);}
,apT:function(){g.apT.appendChild(o)}
,prT:function(){g.prT.firstChild
? g.prT.insertBefore(o, g.prT.firstChild)
: g.prT.appendChild(o)}
,bef:function(){g.bef.parentNode.insertBefore(o, g.bef)}
,aft:function(){g.aft.nextSibling
? g.aft.parentNode.insertBefore(o, g.aft.nextSibling)
: g.aft.parentNode.appendChild(o)}
};
for(var i in g) //проход по числу параметров, проп-о объёму задачи
g[i] && x[i] && x[i]();*/
},
addRules = function(css){
if(typeof GM_addStyle !=u) GM_addStyle(css); //Fx,Chr
else if(typeof addStyle !=u) addStyle(css);
else{ //Op
var heads = document.getElementsByTagName('head')
,node = $e({el:'style'
,apT: heads.length && heads[0]
});
node.appendChild(document.createTextNode(css)); //не проходит в Опере через $e
}
},
getPosition = function(o){
var x =0, y =0;
while(o){
x += o.offsetLeft ||0;
y += o.offsetTop ||0;
o = o.offsetParent || o.parentNode;
}
return {x:x, y:y};
},
parents = function(cl, elem){
for(var el = elem; el!=null && !RegExp(cl).test(el.className); el = el.parentNode);
return el;
},
parentsPrev = function(cl, elem){
for(var el = elem, pr; el!=null && !RegExp(cl).test(el.className); el = el.parentNode)
pr = el;
el.prev = pr;
return el;
},
prev = function(cl, elem){
for(var el = elem; el!=null && !RegExp(cl).test(el.className); el = el.previousSibling);
return el;
},
next = function(cl, elem){
for(var el = elem; el!=null && !RegExp(cl).test(el.className); el = el.nextSibling); //el.className != cl
return el;
},
evtChangeDom = function(voteA){ //===== сообщение о смене DOM, 'chgDom' ====
var evt = document.createEvent("CustomEvent");
if(evt && evt.initCustomEvent){ //TODO поддержку простых Event через хранилище или GM_setValue
evt.initCustomEvent('chgDom',!0,!0, voteA);
win.dispatchEvent(evt);
return!0;
}};
if(/habrastorage\.org/.test(lh)){
var hsoLogo = $q('.wrapper .header .logo'), hsoCloud = $q('.content #upload_cloud img');
if(hsoLogo && hsoCloud){
hsoCloud.src ='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAI4AAACPCAMAAAAbfxOfAAABPlBMVEVOhrqrx95/qszW4u5fotmWttbE2OlkmMJipt/w9fpWlsqZw+p+st6w1vLE3/VtsupUksXg7/i3z+Kiwttwos1xq9+Evu7+/v7Q4OymyuaqzOqMs9JunsZam9BWjr2fvttmq+T1+vzo8fljncvS4/Nck7/g6vLK3uudy/FSjr2xzuWXvt+91ud3tup4pcqQw+5nos/K2ur29vqRut6myuJ/uuy72/Z/rtbX6fmWxvB2qtSGuuaOutpuruijzfKyyuFqnsa+0uamw9ys0vKSttJqreXq9v16uu6qyuaGrs6avtnE2u5qmsTw9v5alsyexua21/PK4fW50uqfw+JyptKKv+2KttpentZmrurq8v5qnsrQ5vpdlcZ6tu5ysupSjsK+1u5qotaGuuqGstZqrupOirrY5vFeptqYutgAAAD/YHsOAAAAanRSTlP///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8AvOTc4wAAAAFiS0dEAIgFHUgAAAgHSURBVHjaxZz7Y9JIEMdDwUDwSoEqm5OSkliwaS2IHrT1TmpbW18FWx8Hnhzcg+Tg//8HLhtCy2N3M3ky/mRV+Djz3dnXzHJjryYrelTEppcF5PXDOPf/VKlF7q3FtTkrbb3fzkblkHHkJ2cVSaMaF89nyygkHD1S0QBWyvNC4Djl7fnwqINBOp1OJpNt81fS+M1gMFCtP107FQLEEU6u5kjSyXah04kl5iwW6xQKBpbFlBdRMDjl/DxKIWaAFA0bzln3wviRQdUxmAb478ZPZP9xxDvBqBgFk3SHdMNMGAkTSZuCvzh3MBOWRZfQkSZEUCAQTnltCjNIg1ms0GGidlrVpAjyB0cY3cIkO45YpkSJWMEAivM+4KBsyYJJFwyY7tCNGS4qGLpeU7ziKGuznhm6NhNIlU6QJxxe8gVmAoRDtia4x5GtTKMmC27DtAg0KPFuccpXU9HEfIAxgRKdpLqNXOFYgVK9x2lulBXSjIDRcSLcRDWGa4Y+GnbQleIUB72xAuWja6ZAsUIv6gxHXrMC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';
$e({el:hsoLogo
,cs:{backgroundImage:'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEsAAABHCAMAAAB4UkqjAAABblBMVEVorulnrednrObW5vX2+Pmhv9tTkcTm7/eVw+ygye681/LI3vS41vGCuemeutRNiLmKsdR0s+r1+Pn1+PihvtqGqsve6vb09vjt8fXi7PBakL6Vt9fz9vjr8fPR4OuRs9BNiblorua0yd3u8/iWuNhdkb6hu9aLsM9YjrxPibpOiLlNibtZmdForelOiruKr9PI1+WtyeNOiLpPibtRjL5cnNVorObE2/FPir5Xk8xkp95nrufl7PKpwdjN4PJwocxRi75cntVmrOVoruiIq83t8vXT3+yTstBOibxanNJmrOdNiLpUkshjp+Foreh6osfb5O3S3ulQjMBdnthnrOdOibtWlMtiqePk6/G+0OFQjr5gotlsmsJbnNNVlcpUkcVTkcZNirlXlstOiLxentXW5vRRjsBipNzU4e5Si75bmcxkqeNQjcBZmM5ko91nq+ZnrulOi7xVk8hcn9djpuJNibpQjb9jqN5lquVnrOicjUr2AAAAAWJLR0QAiAUdSAAAAWpJREFUeNrtlk1Lw0AQhgtdUCsGhVawfkCq1YuMejJ2G70YQ0+JCBVr0BxCsJSoh4J/39mPxB6kZLPBg+xz2ckGHt6ZLGwaDYPBYDAY/j2U1uNpEkLasZCtYL3Ky7UWYay3NqiiywIhY65NLLeapKBNVV1CxlwdLLcLk7fTjamqi8uEC3Zz097+gY9vbKV5gZBJVw+XwyPc6h+fdHE5VXahjLnOAM5xuYCCSWIr9shkfPbCdRnnKudqQNVdMBQ9umxW1zdyc5pQlR4XucUxeby680WuUWUX5oJOfiJ44PFcIxdAEMqn+z5A+kA1ciGWtIVYvzxWn70geOIyFw/Fs64LIAplsJG+CwIWjDVZg4t9Tw/X1+quiPRc9ugOZY+x5rnPsfR6DBdULJaTVHZF3o+KnVVIByVdb7/M3ueTIp7LP8Q0m5W9g2JYTpq9f3zWInPGydxWuB2XyCbZV+lQBoOh5j9XMwKD4S/4Bpvib4HQl4+eAAAAAElFTkSuQmCC)',opacity:1}
});
}
var testLegacyFrame =0;
$e({ht:'→ Перетащи картинку сюда ←
(куда-нибудь в это окно)
К сожалению, будет работать только для картинок размером менее 10КБ. Держатели сайта знают, а работа по устранению недостатка через клиент — ведётся.'
,apT:$q('#bittonsHolder') });
if(testLegacyFrame) $e({ht:'