- // ==UserScript==
- // @id habrActivity
- // @name habrActivity
- // @version 5.2014.12.31
- // @author spmbt0
- // @description view user activity in Habr comments for Fx-Opera-Chrome
- // @include http://habrahabr.ru/*
- // @include http://geektimes.ru/*
- // @exclude http://habrahabr.ru/api/*
- // @update 4 win.console; remove panel from Geektimes articles;
- // @icon data:image/gif;base64,R0lGODlhIAAgAMMBAG6Wyv///2+NtIucstfY2b/FzpSmvY+QkM3Nzunp6fLy8qGwweDg4MbFxa2trrm6uiwAAAAAIAAgAAAE/xDISau9OM/AOe2edoHBBwqiRZodmrKhRLqXYFfrdmLCQBQGWk62swgOiERAQQgChs9iRZBMKDgEFGnbMi4YDMU1gNBytzSJDcGwXhUD4lmqZofFioZrPqMIDARtYksIAzZ8dAINgngJVgkLUH1qBmBuCgmBYA6SUgKBl0wICA6lk1FdAAIFjngKDAgEpKYgWXIcKH8EDQ0EVwmjsrycIA4FZl2rDwcHDgivow8ODwzEHca3ASgDpMylsrEOzdUkDk59AtOl07wIDcwNkDbzCy7z8xIDD8Ps3Q5hCQqscxBHgw0DbEY1WIbEkRtHZV6oMsAq0wNqrcQ4KihR1Z9YjzUeKjjWcYqABUoaJeBY0k8bAm5ItqxgANjFBnBmTgnTQNw0nVOSNBjQLA1QXdEMATVioGnJCAA7
- // @namespace https://greasyfork.org/users/2323
- // ==/UserScript==
- (function(win, noConsole, css, hActHelp){
- var d = document
- ,dBody = d.body || d.documentElement
- ,$q = function(q, f){return (f||d).querySelector(q)}
- ,uHead = $q('.user_header')
- ,uName2a = $q('.username a', uHead)
- ,uName2 = uName2a && uName2a.innerHTML
- ,comms = $q('.comments_list');
- if(uName2 && comms && $q('.user_comments')){ //=====(всё работает только на странице комментариев некоторого пользователя)=====
-
- try{ //для оповещения об ошибках в Fx
- var NOWdate = new Date()
- ,lh = location.href
- ,HRU =location.protocol +'//'+ location.host
- ,lStorRoot ='habrAct_'
- ,setLocStor = function(name, hh){ if(!win.localStorage) return;
- localStorage[lStorRoot + name] = JSON.stringify({h: hh});
- }
- ,getLocStor = function(name){
- return (JSON.parse(localStorage && localStorage[lStorRoot + name] ||'{"h":{}}')).h;
- }
- ,removeLocStor = function(name){localStorage.removeItem(lStorRoot + name);}
- ,$qA = function(q, f){return (f||d).querySelectorAll(q)}
- ,$pd = function(ev){ev.preventDefault();}
- ,$sp = function(ev){ev.stopPropagation();}
- ,$x = function(el, h){ //===extend===
- if(h)
- for(var i in h)
- el[i] = h[i];
- return el;
- }
- ,$e = function(g){ //===создать или использовать имеющийся элемент===
- //g={el|clone,IF+ifA,q|[q,el],cl|(clAdd,clRemove),ht,cs,at,on,revent,apT,prT,bef,aft,f+fA}
- if(g.ht || g.at){
- var at = g.at ||{}; if(g.ht) at.innerHTML = g.ht;}
- if(typeof g.IF =='function')
- g.IF = g.IF.apply(g, g.ifA ||[]);
- g.el = g.el || g.clone || g.IF && g.IF.attributes && g.IF ||'DIV';
- var o = g.clone && g.clone.cloneNode(!0)
- || (typeof g.el =='string' ? d.createElement(g.el) : g.el);
- if(o && (g.IF===undefined || g.IF) && (!g.q || g.q && (g.dQ = g.q instanceof Array ? $q(g.q[0], g.q[1]) : $q(g.q)) ) ){ //выполнять, если существует; g.dQ - результат селектора для функций IF,f
- 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(at)
- for(var i in at){
- if(i=='innerHTML') o[i] = at[i];
- else o.setAttribute(i, at[i]);}
- if(g.on)
- for(var i in g.on)
- o.addEventListener(i, g.on[i],!1);
- if(g.revent)
- for(var i in g.revent)
- o.removeEventListener(i, g.revent[i],!1);
- 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) );
- if(typeof g.f =='function')
- g.f.apply(g, g.fA ||[]); //this - это g
- }
- return o;
- }
- ,parents = function(cl, elem){
- for(var el = elem; el!=null && !RegExp(cl).test(el.className); el = el.parentNode);
- 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);
- return el;
- }
- ,toTime = function(dat){
- var yestDate = new Date(+NOWdate - 86400000)
- ,datMonth ={"января":0,"февраля":1,"марта":2,"апреля":3,"мая":4,"июня":5,
- "июля":6,"августа":7,"сентября":8,"октября":9,"ноября":10,"декабря":11}
- ,datFull = dat.innerHTML
- ,datYest = /вчера/.test(datFull)
- ,dateText = datFull.replace(/ в /,' ').replace(/(сегодня |вчера )/,'')
- ,datArr = dateText.match(/(\d+)\s+([а-яё]+)\s+(\d{4})?/i);
- if(!datArr)
- datArr =[0,(datYest ? yestDate : NOWdate).getDate(),(datYest ? yestDate : NOWdate).getMonth(),(datYest ? yestDate : NOWdate).getFullYear()];
- var altArr = dateText.match(/(\d+)\:(\d+),([а-яё]+)\s*(\d+)\s*([а-яё]+)\s*(\d{4})?/i); //ччммддЧЧММГГГГ?
- if(altArr)
- datArr =[0,altArr[4],altArr[5],altArr[6]];
- //'altArr'.wcl(altArr)
- var mon = datArr && datMonth[datArr[2]] || datMonth[datArr[2]] !=0 && datArr[2] || datMonth[datArr[2]];
- //'datArr'.wcl(datArr, mon)
- if(datArr && !datArr[3])
- datArr[3] = NOWdate.getFullYear();
- var ret2 = new Date(datArr[3], mon, datArr[1], dateText.replace(/(.*?)(\d{1,2}):(\d\d)(.*)/,'$2'), dateText.replace(/(.*?)(\d{1,2}):(\d\d)(.*)/,'$3') ).getTime();
- if(+NOWdate < ret2)
- ret2 = new Date(datArr[3] -1, mon, datArr[1], dateText.replace(/(.*?)(\d{1,2}):(\d\d)(.*)/,'$2'), dateText.replace(/(.*?)(\d{1,2}):(\d\d)(.*)/,'$3') ).getTime();
- return ret2;
- }
- ,getYearWeekDay = function(dd){
- var d = new Date(dd), jan1 = new Date(d.getFullYear(),0,1);
- return [d.getFullYear(), Math.ceil(((dd - jan1) /86400000 + jan1.getDay() -1)/7)
- , d.getDay() + 7*(d.getDay()==0), d.getDate(), d.getMonth()];
- }
- ,wcl = function(a){ a = a ||''; //консоль как метод строки или функция, с отключением по noConsole
- if(win.console && (!noConsole || this =='ER_global:'))
- win.console.log.apply(win.console, this instanceof String
- ? ["'=="+ this +"'"].concat([].slice.call(arguments)) : arguments);
- };
- String.prototype.wcl = wcl;
-
- var hActUsersTmpl ={ //шаблон основной (индексной) записи в хранилище
- dataLen: 0 //число записей в хранилище вида habrActDataNNNNN, где NNNNN - число
- ,dataCount: 25 //огранчитель цикла чтения, страниц
- ,dateStart: 1000 //ограничитель периода чтения, до 365 дней, сравнивает дату начала цикла и посл.
- ,userS: [] //массив имён пользователей, для которых имеются данные
- }
- ,readAutoIntervalMax = 365
- ,hActDataTmpl ={ //шаблон записи данных в хранилище; запись имеет вид habrActData[число], от 1 до dataLen
- user:'' //пользователь, для которого со страницы комментариев сняли данные
- ,data: [] //массив дат (или сложнее)
- };
- (function(css){ var u = 'undefined'; //addRules
- if(typeof GM_addStyle !=u){ GM_addStyle(css);
- }else if(typeof addStyle !=u){ addStyle(css);
- }else{
- var node = d.createElement('style');
- node.type ='text/css';
- node.appendChild(d.createTextNode(css));
- (d.getElementsByTagName('head')[0] || dBody).appendChild(node);}
- })(css);
-
- var readPage
- ,ww =0
- ,startButt = $e({el:'button', ht:'Старт'
- ,on:{click: readPage = function(ev){ //читать статистику со страницы и переходить к следующей
- if(ev){
- var handStart =1;
- hActUsers = getLocStor('users');
- hActUsers.userS = hActUsers.userS ||[];
- hActUsers.dataLen = hActUsers.dataLen ||0;
- }
- var infoS = $qA('.info', comms)
- ,datC =[];
- clearTimeout(ww);
- if(startButt.innerHTML =='Стоп'){
- startButt.innerHTML ='Старт';
- hActUsers.dataCount =0;
- setLocStor('users', hActUsers);
- return;
- }
- hActUsers.dataLen++;
- startButt.innerHTML ='Стоп';
- if(handStart)
- hActUsers.dataCount = hActUsersTmpl.dataCount;
- for(var i in infoS){ var iI = infoS[i]; if(iI.attributes){
- var sco = $q('.voting .score',iI)
- ,apm = sco && sco.title.match(/\d+/g)
- ,text = $q('.message', iI.parentNode);
- datC.push(//{date:
- toTime($q('time',iI))/1000
- //,plus: apm && apm[1]
- //,minus: apm && apm[2]
- //,textLen: text && text.innerHTML.replace(/\t/g,'').length}
- );
- }}
- var pageA = lh.match(/^.+?page(\d+).*/);
- 'datC'.wcl(datC, pageA, ( + NOWdate/1000 - datC[datC.length -1]) /86400)
- $e({el: $q('.msg', startButt.parentNode) ||'span'
- ,cl:'msg'
- ,ht:'<br> До '+(0|((NOWdate/1000 - datC[datC.length -1]) /86400))
- +' дней от сегодня; интервал - '+ (0|((datC[0] - datC[datC.length -1]) /86400))+' дней'
- ,bef: $q('.clear',uHead)
- });
- if(handStart)
- hActUsers.dateStart = datC[0];
- if((hActUsers.dateStart - datC[datC.length -1]) /86400 < readAutoIntervalMax)
- ww = setTimeout(function(){
- location.href = pageA
- ? lh.replace(/page(\d+)/,'page'+ (+pageA[1] +1))
- : lh +'page2/';
- }, 3000);
- else{
- startButt.innerHTML ='Старт';
- hActUsers.dataCount =0;
- }
- if(!handStart)
- hActUsers.dataCount--;
- var noNewUser =0;
- for(var i in hActUsers.userS){ var uI = hActUsers.userS[i];
- if(uI == uName2){
- noNewUser =1; break;}
- }
- if(!noNewUser)
- hActUsers.userS.push(uName2);
- setLocStor('users', hActUsers); //накапливать статистику в хранилище
- wcl('2nd', hActUsers.dataLen);
- setLocStor('data'+ hActUsers.dataLen, {user: uName2, data: datC});
- }}
- ,bef: $q('.clear', uHead)
- }),
- hActUsers = getLocStor('users');
- hActUsers.userS = hActUsers.userS ||[];
- hActUsers.dataLen = hActUsers.dataLen ||0;
- if(hActUsers.dataCount >0){ //автозапуск анализа страницы
- wcl('1st');readPage();}
-
- var helpHAct,
- helpButt = $e({el:'button', ht:'Подробности'
- ,on:{click: function(ev){ if(!helpHAct || helpHAct.style.display=='none'){
- if(!helpHAct){
- helpHAct = $e({cl:'helpHAct'
- ,ht: hActHelp
- ,on:{click: function(){this.style.display ='none';}}
- ,apT: dBody
- });
- $q('.in', helpHAct).addEventListener('click', function(ev){$sp(ev);},!1);
- }else
- helpHAct.style.display ='block';
- }else helpHAct.style.display ='none'; } }
- ,aft: startButt
- }),
- eraseButt = $e({el:'button', ht:'Стереть'
- ,on:{click: function(ev){
- var hActUsers = getLocStor('users');
- if(confirm('Удалить всю статистику комментариев пользователей ('+ hActUsers.dataLen +' записей)?')){
- if(hActUsers.dataLen){
- for(var i = +hActUsers.dataLen; i >=1; i--)
- removeLocStor('data'+ i);
- removeLocStor('users');
- }
- $q('.diag', selUser) && $q('.diag', selUser).classList.add('empty');
- }
- }}
- ,aft: startButt
- }),
- dataButt = $e({el:'button', ht:'Данные'
- ,on:{click: function(ev){
- hActUsers = getLocStor('users');
- selectUser(showData);
- this.blur();
- }}
- ,aft: startButt
- }),
- selUser,
- selectUser = function(f){ //предложить выбор пользователей
- if(!selUser || selUser.style.display=='none'){
- if(!selUser){
- selUser = $e({cl:'selUser'
- ,ht: '<div class=under></div><div class=in><h2><input class="inUser" title="перейти -видео на комментарии пользователя; Ctrl-Enter - в новом окне"><span class="titl">Выбрать пользователя</span></h2><div class="diag empty"></div></div>'
- ,on:{click: function(){this.style.display ='none';}}
- ,apT: dBody
- });
- $q('.in', selUser).addEventListener('click', function(ev){$sp(ev);},!1);
- $q('.inUser',selUser).addEventListener('keyup',function(ev){ if(ev.keyCode ==13){
- var lnk = HRU +'/users/'+ this.value +'/comments/';
- if(!ev.ctrlKey)
- location.href = lnk;
- else
- window.open(lnk,"_blank")
- }},!1);
- }else{
- selUser.style.display ='block';
- var sC = $q('.in', selUser).childNodes;
- for(var i = sC.length -1; i >=0; i--){ var sI = sC[i];
- 'sI'.wcl(sI.tagName, sI.className)
- if(dI.attributes &&(sI.tagName =='BUTTON'|| sI.className =='hADel') )
- selUser.removeChild(sI);
- }
- }
- for(var i in hActUsers.userS){ var uI = hActUsers.userS[i];
- $e({el:'button'
- ,ht: uI
- ,on:{click: function(){
- var bS = $qA('button', this.parentNode);
- for(var j in bS) if(bS[j].attributes)
- bS[j].classList.remove('hAActive');
- this.classList.add('hAActive');
- f(this.innerHTML);
- this.blur();
- }}
- ,bef: $q('.diag', selUser)
- });
- $e({el:'button',cl:'hADel'
- ,ht:'X'
- ,at:{title:'Удалить из хранилища','data-user': uI}
- ,on:{click: function(){
- var t = this, u;
- del1user(u = this.getAttribute('data-user'));
- t.previousSibling.parentNode.removeChild(t.previousSibling);
- setTimeout(function(){t.parentNode.removeChild(t);},1);
- for(var i in hActUsers.userS){ var uI = hActUsers.userS[i];
- if(u == uI){
- hActUsers.userS.splice(i, 1); break;
- }}
- setLocStor('users', hActUsers);
- }}
- ,bef: $q('.diag', selUser)
- });
- }
- var hU = hActUsers.userS;
- 'hU'.wcl(hU,uName2)
- if(hU && hU.length ==1)
- f(hU[0]),$q('button',selUser).classList.add('hAActive');
- else if(hU && uName2){
- var bS = $qA('button', hU[0].parentNode);
- for(var i in bS) if(bS[i].attributes){
- bS[i].classList.remove('hAActive');
- if(bS[i].innerHTML == uName2)
- f(uName2),bS[i].classList.add('hAActive');
- }
- }
- }else selUser.style.display ='none';
- },
- showData = function(user){ //показать диаграмму активности
- var dA =[]
- ,diag = $q('.diag', selUser)
- ,dC = diag.childNodes;
- for(var i = dC.length -1; i >=0; i--){ var dI = dC[i]; if(dI.attributes)
- diag.removeChild(dI);}
- for(var i =1; i <= +hActUsers.dataLen; i++){ //всё ранее прочитанное по юзеру
- if(!RegExp(' '+ i +' ').test(hActUsers.removed ||'') ){
- var dat = getLocStor('data'+ i);
- if(user == dat.user)
- dA = dA.concat(dat.data);
- }}
- diag.style.height ='100px';
- dA.sort(function(a, b){return a - b});
- var ymd0 = getYearWeekDay(dA[0]*1000), ymdE =[] //год, неделя, день, число, месяц, кол-во комм.
- ,diagLeftMargin =7
- ,diagTopMargin =7
- ,stripeN =1 //число полос для диаграммы
- ,stripePeriod = 110
- ,nComm =0
- ,diagInnerWid = diag.offsetWidth -diagLeftMargin *2 -10 //ограничения ширины 1 полосы
- ,wasDoubles =0, dAClean =[]; //слежение за дублями
- for(var i in dA){
- var ymd = getYearWeekDay(dA[i]*1000);
- ymd[5] = ymdE[0]==ymd[0] && ymdE[1]==ymd[1] && ymdE[2]==ymd[2] ? ymdE[5]+1 : 1;
- if(dA[i] == ymdE[6]){ //игнор дублей чтения
- wasDoubles =1; continue;}
- dAClean.push(dA[i]);
- nComm++;
- ymdE = [ymd[0], ymd[1], ymd[2], ymd[3], ymd[4], ymd[5], dA[i]];
- var leftFirstShift = ((ymd[0]-ymd0[0])*52 + (ymd[1]-ymd0[1]) )*10
- ,iStripe = Math.floor(leftFirstShift / diagInnerWid);
- stripeN = Math.max(stripeN, iStripe +1);
- $e({cl:'comm'
- ,cs:{left: (leftFirstShift % diagInnerWid) + diagLeftMargin +'px'
- ,top: iStripe * stripePeriod + ymd[2] *10 + diagTopMargin +'px'}
- ,at:{title: ymd[5] +' / '+ ymd[3]+'янвфевмарапрмайиюниюлавгсеноктноядек'.match(/.../g)[ymd[4]]+(ymd[0] +'').substr(2,2) }
- ,apT: diag
- });
- }
- if(wasDoubles){ //удалить юзера и записать его же из очищенного от дублей массива dAClean
- del1user(user);
- wcl('delU')
- setLocStor('data'+ ++hActUsers.dataLen, {user: uName2, data: dAClean});
- setLocStor('users', hActUsers); //сохранить .removed
- }
- if(stripeN >1)
- diag.style.height = 110 * stripeN +'px';
- diag.classList.remove('empty');
- var hActTitle = '%N комментари%W <span title="%T">с %D0 по %D1</span>', days;
- if(ymd)
- $q('h2 .titl', selUser).innerHTML = hActTitle
- .replace(/%N/,nComm).replace(/%W/, nComm % 10 >0 && nComm % 10 <5 && Math.floor(nComm % 100 / 10) !=1 ? (nComm % 10 ==1 ?'й':'я'):'ев')
- .replace(/%D0/,ymd0[3] +'.'+ (ymd0[4]+1) +'.'+ (ymd0[0] +'').substr(2,2))
- .replace(/%D1/,ymd[3] +'.'+ (ymd[4]+1) +'.'+ (ymd[0] +'').substr(2,2))
- .replace('%T', Math.ceil(days = (dA[dA.length-1] - dA[0]) /86400) +' дней, '+ (nComm/days).toFixed(2) +' комм./д.' );
- },
- del1user = function(user){ //удалить данные 1 пользователя
- for(var i =1; i <= +hActUsers.dataLen; i++){ //всё ранее прочитанное по юзеру
- if(!RegExp(' '+ i +' ').test(hActUsers.removed ||'') ){
- var dat = getLocStor('data'+ i);
- if(user == dat.user){
- var dat = removeLocStor('data'+ i);
- hActUsers.removed = (hActUsers.removed ||' ')+ i +' ';
- }}}
- };
-
-
- }catch(er){
- 'ER_global:'.wcl(er +' (line '+(er.lineNumber||'')+')')}; //для оповещения об ошибках в Fx
- }} //=====/(конец основных операций)=====
- )(typeof unsafeWindow !='undefined'? unsafeWindow: (function(){return this})(), 'noConsole',
-
- /*===== css =====*/
-
- '.helpHAct,.selUser{position: absolute; z-index: 1201; top: 0; width: 100%; height: 100%;}'
- +'.helpHAct .under,.selUser .under{position: fixed; z-index: 1200; width: 100%; height: 100%; opacity:0.1; background:#777}'
- +'.helpHAct .in, .selUser .in{position: relative; z-index: 1201;max-width: 48em; margin: 120px auto 280px; padding: 12px; border: 1px solid #bbb; box-shadow: 0 0 7px 4px #a4b39D/*#afb6af*/; background: #fff;}'
- +'.selUser .in .inUser{float: right; padding: 1px 1px 3px; border: 1px solid #ccc;}'
- +'.selUser .in h2{margin-bottom: 6px;}'
- +'.selUser .diag{position: relative; height: 100px; margin-top: 12px; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABuAgMAAACsF16hAAAADFBMVEXu7u7x8fHz8/MAAACwIVgQAAAABHRSTlP///8AQCqp9AAAAAFiS0dEAIgFHUgAAAA9SURBVHjaY2AYBYMahCKBsDQkgCITtQoBVuKUWTUqMyozKjMqMyozKjMMZJABoyACCIw2G6gO/uMCI0cGAF7MVC7yox7wAAAAAElFTkSuQmCC) 6px 0;}'
- +'.selUser .comm{position: absolute; width: 8px; height: 8px; opacity: 0.2; background: #8b4;}'
- +'.selUser .hAActive, .user_header .hAActive{background-color: #f6f8e0/*#fff2d8*/}'
- +'.selUser button, .user_header button{height: 1.6em; margin: 10px 0 0 1px; padding: 0 4px 1px; line-height: 1.3em;'
- +'box-shadow: 0 0 2px rgba(255, 255, 255, 0.4) inset, 0 0 2px rgba(0, 0, 0, 0.2); transition-duration: 0.2s; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8); border-radius: 3px; border: 1px solid #e9d8e8; border-color: #e9DeD8 #bccbbb #9eae9e; background-color: #c8ead0/*#cfe8c4*/;}'
- +'.selUser button{margin-top: 5px}.user_header .rating{margin-right: 14px;}'
- +'.selUser button:hover,.user_header button:hover{background-color: #f2fddb/*#fcfcfc*/;}'
- +'.selUser .diag.empty{background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAAASFBMVEXu7u708uv7+PP7+fP28+z38+z08ev7+PLy8Oz69/H6+PP7+PHx8Oz69/L49Ovs7+749Oz38+v28uz18uz49O328+v49O78+fSGxIqmAAAAAWJLR0QAiAUdSAAAAE9JREFUeNqVzjEOwCAMA0BLWbqEASn0/z8F2lpKIaDW4w22AcaEyb/t0MDku2nUp6vdtDUEVhCYYLIsRPP24NtuHOzC0TpO1tDcF6Kzk1gBDdAFF3BuHgsAAAAASUVORK5CYII=)}'
- +'.selUser .hADel{position: relative; height: 14px; line-height: 1px; border-radius: 6px; margin:-0.6em; top:-0.9em; left: -3px; padding:0 0 1px; border: 1px solid #d99; font-size:10px; background-color: #ea7852; opacity: 0.15;}.selUser .hADel:hover{background-color: #E65E30; color: #fbb; opacity: 0.8}'
- +'.selUser button:hover +.hADel{opacity: 0.5}',
-
- /*===== help string =====*/
-
- '<div class=in><h2>Просмотр активности комментариев пользователей</h2><br><br>После установки юзерскрипта <b>habrActivity</b> на страницах комментариев пользователей (и только на них) появляются 4 кнопки: "Старт", "Данные", "Стереть", "Подробности".<br><br>'
-
- +'При нажатии на "<b>Старт</b>" запускается цикл чтения данных с перебором страниц комментариев для данного пользователя, а кнопка меняет название на "Стоп". Прочитывается не более 25 страниц в автоматическом режиме и читается интервал комментариев за не более 365 дней. В любой момент цикл автоматического чтения страниц останавливается вручную кнопкой "<b>Стоп</b>". Если нужно читать больше 365 дней, чтение возобновляется по кнопке "Старт".<br><br>'
-
- +'С каждой страницы собирается информация о датах создания комментариев и, возможно, впоследствии более сложная, и запоминается в хранилище. Таким образом, накапливается информация о комментариях разных пользователей в разные периоды времени. Хранятся только массивы чисел - например, даты написания комментариев. В последующих версиях возможно расширить статистику на сбор оценок, объёма текстов, количество ссылок и картинок и подобное.<br><br>'
-
- +'Чтобы просмотреть накопленные данные, нажимают кнопку "<b>Данные</b>". Если в браузере на данный момент хранится информация о более 1 пользователе, появится список кнопок с именами пользователей. Нажав одну из кнопок, переходим на просмотр статистики.<br><br>'
-
- +'Просмотр статистики по датам комментариев организован аналогично инфографике Гитхаба - показ активности комментариев пользователя по дням года и дням недели. Отображается не более 420 последних дней (60 недель). Данные подготовлены для "музыкальной иллюстрации активности" http://habrahabr.ru/post/173085/ .<br><br>'
-
- +'В результате, получаются 3 полезные вещи: смотрим активность любого пользователя в комментариях, видим наглядный график, прослушиваем в задумчивости озвучивание его. Делаем выводы.<br><br>'
-
- +'Чтобы стереть все данные пользователя, нажимается кнопка "<b>Стереть</b>". Память браузера очищается от накопленных данных.<br><br></div>')