NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name BtUtils
// @namespace http://tampermonkey.net/
// @version 2.2
// @description Добавляет фичи в vk.com/bugtracker
// @updateURL https://openuserjs.org/meta/flyink13/BtUtils.meta.js
// @author Flyink13
// @match https://vk.com/bugtracker*
// @license MIT
// @copyright 2017, flyink13 (https://openuserjs.org/users/flyink13)
// @grant none
// ==/UserScript==
/* global vk, cur, extend, ce, ajax, ge, geByClass, geByClass1, q2ajx, ajx2q, stManager */
function BtUtils() {
var on = {},
default_rules = [
'Пожалуйста, ознакомьтесь с:',
'1) Правилами составления отчетов https://vk.cc/71Wc3i',
'2) Поиском по отчётам, во избежание дублирования отчетов.',
'3) Описанием тестируемого продукта %productDescriptionLink%.'
].join('\n'),
blank_report = '1) \n2) \n\nРезультат: \nОжидание:\n',
bt_links = [];
function qce(name, d, c) {
var el, i;
if (Array.isArray(d)) {
c = d;
d = {};
}
if (typeof d == 'string') {
d = {
textContent: d
};
}
if (/^(.+?)(?:#(.+?))?(?:\.(.+))?$/.test(name)) {
name = name.match(/^(.+?)(?:#(.+?))?(?:\.(.+))?$/);
extend(d, {
tagName: name[1],
id: name[2] || '',
className: name[3] || ''
});
name = name[1];
}
el = ce(name, d);
extend(el.style, d.style);
if (c) {
for (i = 0; i < c.length; i += 1) {
el.appendChild(c[i] instanceof HTMLElement ? c[i] : qce.apply(this, c[i]));
}
}
return el;
}
function createBtSettingsRow(name, childs) {
return qce('div.bt_hform_block clear_fix', [
['div.bt_hform_label', name],
['div.bt_hform_control', childs]
]);
}
function createCounter(label, q) {
var count = qce('div.count', '---');
var page_counter = qce('a.page_counter', {
href: '/bugtracker?' + ajx2q(q)
}, [
count, ['div.label', label]
]);
ajax.plainpost('/bugtracker', {
al: 1,
load: 1,
status: q.status,
mid: q.mid,
severity: q.severity
}, function onDone(r) {
r = r.match(/bt_reports_found.+?(\d+)/);
if (!r) {
count.textContent = '???';
} else {
count.textContent = r[1];
}
});
return page_counter;
}
function drawBtUtilsBlock(title) {
var bt_utils_content;
if (ge('bt_utils')) {
ge('bt_utils_title').textContent = title;
return ge('bt_utils_content');
}
bt_utils_content = qce('div.bt_utils_content', '');
ge('narrow_column').appendChild(qce('div#bt_utils.page_block', [
['div.bt_sb_search_wrap', [
['div#bt_utils_title.bt_sb_search_filter_label', title],
bt_utils_content
]]
]));
return bt_utils_content;
}
function showBtVideoPlayer(href) {
document.body.appendChild(
qce('div.bt_video', {
onclick: function closeVideo(event) {
if (this !== event.target) return 1;
this.outerHTML = '';
}
}, [
['video', {
src: href,
controls: 1,
onclick: function toggleVideoState() {
if (this.paused) {
this.play();
} else {
this.pause();
}
}
}]
]));
return false;
}
on.settings = function btOnSettings() {
ge('wide_column').appendChild(
qce('div.page_block bt_page', [
['h2.page_block_h2', [
['div.page_block_header clear_fix', [
['div.page_block_header_inner _header_inner', [
['div.ui_crumb', 'Настройки BtUtils']
]]
]]
]],
['div.bt_page_content', [
['div.bt_settings', [
createBtSettingsRow('Шаблон отчета', [qce('textarea.text dark bt_form_text', {
style: {
width: '315px',
height: '105px'
},
value: localStorage.blank_report || blank_report,
onkeyup: function onKeyUp() {
localStorage.blank_report = this.value;
console.log('blank_report changed', this.value);
}
})]),
createBtSettingsRow('Шаблон комментария', [qce('textarea.text dark bt_form_text', {
style: {
width: '315px',
height: '105px'
},
value: localStorage.btRules || default_rules,
onkeyup: function onKeyUp() {
localStorage.btRules = this.value;
console.log('btRules changed', this.value);
}
})])
]]
]]
])
);
};
on.reporters = function btOnReporters(query) {
var d_all, info, BtUtilsBlock, c;
if (!query.product) query.product = 0;
if (!geByClass('bt_reporter_row')) return;
d_all = 0;
info = JSON.parse(localStorage.getItem('reporters_info_' + query.product) || '{}');
BtUtilsBlock = drawBtUtilsBlock('Обновления');
c = geByClass('bt_reporter_row').map(function drawRowCounter(e) {
var owner = geByClass1('bt_reporter_row_name', e);
var id = 'reporter_' + owner.href.substr(42);
var reports = geByClass1('bt_reporter_row_count', e).nextElementSibling;
var d = reports.textContent - (info[id] || 0);
if (id == 'reporter_' + vk.id) owner.parentNode.style.fontWeight = 'bold';
if (d !== 0) {
d_all += d;
info[id] = reports.textContent;
reports.textContent += ' (' + (d > 0 ? '+' + d : d) + ')';
reports.style.fontWeight = 'bold';
reports.style.color = d > 0 ? 'green' : 'red';
}
return [owner.textContent, d];
}).filter(function filterEmpty(x) {
return !!x[1];
}).sort(function sortTop(a, b) {
return b[1] - a[1];
}).map(function toUserFormat(r) {
return r[0] + (r[1] > 0 ? ('\t+' + r[1]) : ('\t-' + -r[1]));
});
localStorage.setItem('reporters_info_' + query.product, JSON.stringify(info));
if (geByClass1('bt_reporter_header_row__pos')) {
geByClass1('bt_reporter_header_row__pos').style.color = 'black';
}
if (d_all) {
geByClass1('bt_reporter_header_row__count').style.color = d_all > 0 ? 'green' : 'red';
BtUtilsBlock.innerHTML = '<ol><li>' + c.join('<li>') + '</ol>';
} else {
BtUtilsBlock.innerHTML = 'Пусто :(';
}
setTimeout(function expandList() {
var btFilter;
if (!cur || !cur.btProducts) return;
btFilter = geByClass('page_block')[1];
btFilter.className = 'page_block ui_rmenu ui_rmenu_pr bt_hide_products';
btFilter.role = 'list';
btFilter.innerHTML = '';
cur.btProducts.forEach(function addListItem(p) {
btFilter.appendChild(ce('a', {
className: 'ui_rmenu_item _ui_item_p' + p[0] + (p[0] == cur.btProduct ? ' ui_rmenu_item_sel' : ''),
href: 'bugtracker?act=reporters&product=' + p[0],
onclick: 'return uiRightMenu.go(this, event);',
id: 'ui_rmenu_p' + p[0]
})).appendChild(ce('span', {
className: 'bt_hide_products_placeholder',
title: (p[0] == '0' ? 'Все продукты' : p[1]),
textContent: (p[0] == '0' ? 'Все продукты' : 'Продукт #' + p[0])
}));
});
btFilter.appendChild(ce('div', {
className: 'ui_rmenu_slider _ui_rmenu_slider'
}));
}, 100);
console.log('BtUtils', 'reporters ok', query.product);
};
function btSaveReportsLink() {
bt_links = geByClass('bt_report_title_link').map(function getLink(x) {
return x.href;
});
console.log('BtUtils', 'bt_links saved');
}
on.reports = btSaveReportsLink;
on.my = btSaveReportsLink;
on.reporter = function btOnReporter(q) {
geByClass1('bt_reporter_block').appendChild(
qce('div#btu_counters.counts_module', [
createCounter('актуально', {
mid: q.id
}),
createCounter('отклонено', {
mid: q.id,
status: 3
}),
createCounter('исправлено', {
mid: q.id,
status: 2
}),
createCounter('выше среднего', {
mid: q.id,
status: 100,
severity: '4,3'
}),
createCounter('низких', {
mid: q.id,
status: 100,
severity: '1'
})
]));
stManager.add('module.css');
};
on.add = function btOnAdd() {
var descr = ge('bt_form_descr');
descr.value = localStorage.blank_report || blank_report;
descr.style.height = descr.scrollHeight + 'px';
};
on.show = function btOnShow() {
var BtUtilsBlock, nextHref, i;
geByClass('page_doc_icon6').forEach(function attachVideoIconClick(video_doc) {
video_doc.onclick = showBtVideoPlayer.bind(video_doc, video_doc.href);
});
ge('bt_comment_form_submit').parentNode.insertBefore(ce('div', {
className: 'flat_button secondary',
textContent: 'Правила',
onclick: function onRulesClick() {
var productDescriptionLink = document.querySelector('.bt_report_one_info_row a').href;
var el = ge('bt_comment_form_text');
el.value = (localStorage.btRules || default_rules).replace(/%productDescriptionLink%/gi, productDescriptionLink);
el.style.height = el.scrollHeight + 'px';
}
}, {
marginRight: '6px'
}), ge('bt_comment_form_submit'));
if (!bt_links.length) return;
i = bt_links.indexOf(window.location.href);
if (i == -1 || bt_links.length < i) return;
BtUtilsBlock = drawBtUtilsBlock('Разное');
nextHref = ce('a', {
className: 'flat_button secondary button_light button_wide',
href: bt_links[i + 1],
textContent: 'Следующий отчет'
});
BtUtilsBlock.appendChild(nextHref);
};
function loaded(act, query) {
if (!act) act = 'reports';
if (!Object.prototype.hasOwnProperty.call(on, act)) return;
on[act](query);
}
function replaceFunction(org, editor) {
return function fakeFunction() {
var args = editor.apply(this, arguments);
return org.apply(this, args || arguments);
};
}
ajax.post = replaceFunction(ajax.post, function fakeAjaxPost(url, query, options) {
if (url !== 'al_bugtracker.php' || !query || !options) return;
options.onDone = replaceFunction(options.onDone, function fakeOnDone() {
setTimeout(loaded.bind(this, query.act, query), 100);
});
return [url, query, options];
});
(function onLoaded() {
var query;
if (window.location.pathname !== '/bugtracker') return;
query = q2ajx(window.location.search.substr(1));
loaded(query.act, query);
})();
document.head.appendChild(ce('style', {
innerHTML: '.bt_hide_products:hover .bt_hide_products_placeholder{font-size:0}' +
'#btu_counters{margin: 20px -20px -20px -20px}' +
'.bt_hide_products:hover .bt_hide_products_placeholder:after{font-size:13px; content: attr(title)}' +
'.bt_video{position: fixed; top: 0; left: 0; background: rgba(0,0,0,.8);width: 100%; height: 100%; z-index: 1000;}' +
'.bt_video video{position: absolute; max-height: 100%;max-width: 100%;top: 0;left: 0;bottom: 0;right: 0;margin: auto;}'
}));
}
(function injectScript() {
var script = document.createElement('script');
script.appendChild(document.createTextNode('(' + BtUtils + ')();'));
(document.body || document.head || document.documentElement).appendChild(script);
})();