// ==UserScript==
// @name Pikabu UI++
// @namespace pikabuUIPlusPlus
// @version 1.1
// @description Улучшение интерфейса
// @author Array
// @license CC-BY-SA-4.0
// @match *://pikabu.ru/*
// @grant unsafeWindow
// @grant window.close
// @grant GM_getValue
// @grant GM_setValue
// @run-at document-end
// ==/UserScript==
// simbols source http://myhomeinet.ru/smilegenerator/page-274.html
// colors source https://www.w3schools.com/colors/colors_names.asp
// special thanks:
// @nazarpunk
// @moretraher2020
(function() {
`use strict`;
const DATA_LIFETIME = 604800000;
const DATABASE = `db`;
const DATABASE_VERSION = `1`;
const EXP_VALUES = [3, 5, 8];
const EXP_ICO = [`❊`, `•`, `︿`, `︽`, `⁂`, `★`];
const NOTE_VALUES = [`#добро`, `#интересно`, `#осторожно`, `#неприемлемо`],
NOTE_ICO = [`❤`, `♞`, `⚠`, `✖`],
NOTE_COLORS = [`LimeGreen`, `DodgerBlue`, `OrangeRed`, `Violet`];
const SUBS_VALUES = [40, 900, 4000, 9000],
SUBS_ICO = [``, `◔`, `◑`, `◕`, `◉`];
const BAN_ICO = [``, `ϟ`, `†`];
const GENDER_ICO = [``, `♂`, `♀`];
// ************************ ENTRY POINT *************************
const SHOW_EXP = GM_getValue(`SHOW_EXP`, 1);
const SHOW_NOTE = GM_getValue(`SHOW_NOTE`, 1);
const SHOW_RATE = GM_getValue(`SHOW_RATE`, 1);
const SHOW_SUBS = GM_getValue(`SHOW_SUBS`, 1);
const SHOW_BAN = GM_getValue(`SHOW_BAN`, 1);
const SHOW_GENDER = GM_getValue(`SHOW_GENDER`, 0);
const SHOW_QUICK_NOTE = GM_getValue(`SHOW_QUICK_NOTE`, 1);
var database = new Map();
var loadingComments = new Map();
var loadingOrder = [];
var updateOrder = [];
var intersectionOrder = new Set();
var loadingComment = null;
var enableLoadingNavigator = false;
var loadingNavigator;
var userpageRendered = false;
// Intersections
const intersector = new IntersectionObserver(
entries => {
for (const entry of entries) {
if (entry.isIntersecting)
{
for (const userName of loadingOrder)
{
if(entry.target.dataset.name == userName)
{
intersectionOrder.add(userName);
break;
}
}
for (const userName of updateOrder)
{
if(entry.target.dataset.name == userName)
{
intersectionOrder.add(userName);
break;
}
}
}
else
{
intersectionOrder.delete(entry.target.dataset.name);
}
}
}, {
threshold: 0
});
addCustomCSS();
renderNavigatorLoading();
loadDatabase();
findComments();
findUsernames();
checkUserPage();
checkSettingsPage();
// Ajax listener
!function(send) {
XMLHttpRequest.prototype.send = function(body) {
send.call(this, body);
if(body?.includes(`note`))
{
checkUserPage();
}
};
}(XMLHttpRequest.prototype.send);
// Mutation listener
var mutationObserverTimeout = false;
new MutationObserver(mutations => {
for (const mutation of mutations) {
if(mutationObserverTimeout) break;
for (const node of mutation.addedNodes) {
if (!(node instanceof HTMLElement)) continue;
if(mutationObserverTimeout) break;
if (node.classList.contains(`comment`) || node.classList.contains(`story`))
{
findUsernames();
mutationObserverTimeout = true;
setTimeout(() => {mutationObserverTimeout = false}, 200);
break;
}
}
}
}).observe(document.body, {childList: true, subtree: true});
// ************************ DATABASE *************************
function loadDatabase()
{
let jobject = JSON.parse(GM_getValue(DATABASE, `{}`));
database = new Map(Object.entries(jobject));
let ver = GM_getValue(`version`, ``);
if(ver != DATABASE_VERSION)
{
GM_setValue(`version`, DATABASE_VERSION);
database = new Map();
}
}
function saveDatabase()
{
let json = JSON.stringify(Object.fromEntries(database.entries()));
GM_setValue(DATABASE, json);
}
// ************************ BASEMENT *************************
function checkUserPage()
{
let url = window.location.href;
let key = url.split(`@`)[1];
if(url.includes(`@`) && !userpageRendered)
{
userpageRendered = true;
renderUserpageTools();
}
if(database.has(key))
{
database.get(key).timestamp = 0;
saveDatabase();
findUsernames(key);
}
}
function checkSettingsPage()
{
let url = window.location.href;
if(url.includes(`settings`)) renderSettings();
}
function findComments()
{
if(!SHOW_QUICK_NOTE)
{
return;
}
document.querySelectorAll(`.comment`).forEach((comment) => {
let meta = comment.getAttribute(`data-meta`);
if(meta != null && !meta.includes(`ua`))
{
let uid = smartSlice(meta, `aid=`, `,`);
let tools = comment.querySelector(`.comment__tools`);
renderCommentTools(tools, uid);
}
});
}
function findUsernames(requestedUser)
{
// comemet usernames
document.querySelectorAll(`.comment__user`).forEach((commentBase) => {
let comment = commentBase.querySelector(`.user__nick`);
let userName = commentBase.getAttribute(`data-name`);
let checkRequest = requestedUser != undefined && requestedUser == userName;
// reg intersec events for new item
if(comment?.textContent == userName)
{
intersector.observe(commentBase);
}
if(comment?.textContent == userName || checkRequest)
{
if(checkRequest) intersectionOrder.add(userName);
addComment(comment, userName);
}
});
//post usernames
document.querySelectorAll(`.story__user-link`).forEach((post) => {
let userName = post.getAttribute(`data-name`);
let checkRequest = requestedUser != undefined && requestedUser == userName;
// reg intersec events for new item
if(post?.textContent.trim() == userName)
{
intersector.observe(post);
}
if(post?.textContent.trim() == userName || checkRequest)
{
addComment(post, userName);
}
});
if(loadingComment == null)
{
nextLoading();
}
}
function addComment(comment, userName)
{
if(database.has(userName))
{
let date = new Date();
let data = database.get(userName);
renderUsername(userName, comment, data);
// update data
if(date.getTime() > (data.timestamp + DATA_LIFETIME))
{
if(loadingComments.has(userName))
{
loadingComments.get(userName).push(comment);
}
else
{
loadingComments.set(userName, [comment]);
updateOrder.push(userName);
}
}
}
else
{
//request data
if(loadingComments.has(userName))
{
loadingComments.get(userName).push(comment);
}
else
{
loadingComments.set(userName, [comment]);
loadingOrder.push(userName);
nextLoading();
}
}
renderLoadingOrder();
}
// ************************ LOADING *************************
function nextLoading()
{
if(loadingComment == null && intersectionOrder.size > 0)
{
while (intersectionOrder.size > 0)
{
let forcedUsername = intersectionOrder.values().next().value;
intersectionOrder.delete(forcedUsername);
if(loadingOrder.includes(forcedUsername))
{
loadingOrder.splice(loadingOrder.indexOf(forcedUsername), 1);
loadingComment = forcedUsername;
loadData(loadingComment);
break;
}
if(updateOrder.includes(forcedUsername))
{
updateOrder.splice(updateOrder.indexOf(forcedUsername), 1);
loadingComment = forcedUsername;
loadData(loadingComment);
break;
}
}
// if all intersections check failed
if(loadingComment == null)
{
nextLoading();
return;
}
}
else if(loadingComment == null && loadingOrder.length > 0)
{
loadingComment = loadingOrder.shift();
loadData(loadingComment);
}
else if(loadingComment == null && updateOrder.length > 0)
{
// update expired data
loadingComment = updateOrder.shift();
loadData(loadingComment);
}
renderLoadingOrder();
}
function loadData(userName)
{
const body = new FormData();
body.set(`action`, `get_short_profile`);
body.set(`user_name`, userName);
fetch(`/ajax/user_info.php`, {
method: `post`,
body : body
})
.then(r => r.json())
.then(result => {
let data = parseData(result.data.html);
database.set(userName, data);
saveDatabase();
let comments = loadingComments.get(userName);
loadingComments.delete(userName);
for (let comment of comments) renderUsername(userName, comment, data);
loadingComment = null;
setTimeout(() => {nextLoading(); renderLoadingOrder();}, 100 + 400 * Math.random());
});
}
// ************************ EVENTS *************************
var clickTimeout = false;
function clickUserNote(e)
{
if(clickTimeout) return;
clickTimeout = true;
let note = e.target.getAttribute(`data-note`);
let uid = e.target.getAttribute(`data-uid`);
let url = window.location.href;
let userName = url.split(`@`)[1];
let data = database.get(userName);
let message = ``;
let mtype = `-`;
if(data.note != (parseInt(note)+1))
{
message = NOTE_VALUES[note];
mtype = `+`;
}
let textarea = document.querySelector(`.page-profile`).querySelector(`.profile-note__textarea`).value = message;
let textdiv = document.querySelector(`.page-profile`).querySelector(`.profile-note__text`).textContent = message;
const body = new FormData();
body.set(`action`, `note`+mtype);
body.set(`id`, uid);
body.set(`message`, message);
fetch(`/ajax/users_actions.php`, {
method: `post`,
body : body
})
.then(result => {
data.timestamp = 0;
findUsernames(userName);
clickTimeout = false;
});
}
function clickQuicknote(e)
{
if(clickTimeout) return;
clickTimeout = true;
let note = e.target.getAttribute(`data-note`);
let uid = e.target.getAttribute(`data-uid`);
let comment = e.target?.parentElement?.parentElement?.querySelector(`.comment__user`);
let userName = comment?.getAttribute(`data-name`);
let refTool = e.target.parentElement?.querySelector(`a`);
let ref = refTool?.getAttribute(`href`);
let data = database.get(userName);
let message = ``;
let mtype = `-`;
if(data.note != (parseInt(note)+1))
{
message = NOTE_VALUES[note]+` `+ref;
mtype = `+`;
}
const body = new FormData();
body.set(`action`, `note`+mtype);
body.set(`id`, uid);
body.set(`message`, message);
fetch(`/ajax/users_actions.php`, {
method: `post`,
body : body
})
.then(result => {
data.timestamp = 0;
findUsernames(userName);
clickTimeout = false;
});
}
// ************************ PARSING *************************
function smartSlice(text, start, end)
{
let strIndex = text.indexOf(start);
let endIndex = text.indexOf(end, strIndex);
return text.slice(strIndex+start.length, endIndex);
}
function parseData(html)
{
let data = new Object();
let regions = html.split(`information`);
// user id
//let uidSource = smartSlice(regions[0], `id="`, `">`);
// ban
let banStat = 0;
if(regions[0].includes(`ban-status`))
{
if(regions[0].includes(`навсегда`))
{
banStat = 2;
}
else
{
banStat = 1;
}
}
// note
let noteStat = 0;
if(regions[1].includes(`profile__note`))
{
let subRegions = regions[1].split(`profile__note-inner`);
regions[1] = subRegions[0];
for (let i = 0; i < NOTE_VALUES.length; i++)
{
if(subRegions[1].includes(NOTE_VALUES[i]))
{
noteStat = i + 1;
}
}
}
// gender
let genderStat = 0;
if(regions[1].includes(`шник`))
{
genderStat = 1;
}
if(regions[1].includes(`шница`))
{
genderStat = 2;
}
//exp
let expStat = 0;
let expSource = smartSlice(regions[1], `<span>`, `</div>`);
let y = expSource.includes(`лет`) || expSource.includes(`год`);
let m = expSource.includes(`месяц`);
if(y || m)
{
if(y)
{
let years = parseInt(expSource);
expStat = 2 + EXP_VALUES.length;
for (let i = EXP_VALUES.length - 1; i >= 0; i--)
{
if(years < EXP_VALUES[i])
{
expStat = 2 + i;
}
}
}
else
{
expStat = 1;
}
}
let digitalRegions = regions[1].split(`profile__digital`);
// 0 trash
// 1 rate
// 2 trash
// 3 subs
//rate
let rateStat = 0;
let rateRaw = smartSlice(digitalRegions[1], `<b>`, `</b>`);
if(rateRaw.includes(`К`))
{
rateStat = rateRaw.replace(`-`, `▽`);
}
else
{
rateStat = (Math.round(rateRaw/1000) + `K`).replace(`-`, `▽`);
}
// subs
let subsStat = 0;
let rawSubs = smartSlice(digitalRegions[3], `<b>`, `</b>`);
if(rawSubs.includes(`К`))
{
subsStat = 4;
}
else if(rawSubs > SUBS_VALUES[0])
{
subsStat = SUBS_VALUES.length;
for (let i = SUBS_VALUES.length - 1; i > 0 ; i--)
{
if(rawSubs < SUBS_VALUES[i])
{
subsStat = i;
}
}
}
// timestamp
let date = new Date();
data.timestamp = date.getTime();
data.exp = expStat;
data.note = noteStat;
data.rate = rateStat;
data.subs = subsStat;
data.ban = banStat;
data.gender = genderStat;
return data;
}
// ************************ CSS *************************
function addCustomCSS()
{
var styles = ``;
for (let i = 0; i < NOTE_COLORS.length; i++)
{
styles += `.`+NOTE_COLORS[i]+`_note {background-color: `+NOTE_COLORS[i]+`;}`;
}
styles += `.navigator__forced-on {opacity: 1 !important; visibility: visible !important;}`;
styles += `.navigator__forced-off {opacity: 0 !important; visibility: hidden !important; max-width: 1px !important;}`;
styles += `.navigator-loading-info {background-color: CornflowerBlue}`;
styles += `.navigator-update-info {background-color: Gainsboro !important}`;
styles += `.userpage-note-tools {margin-left: 15px !important; margin-top: 4px !important;}`;
styles += `.userpage-note-tool {font-size: 18px !important; padding: 5px; padding-left: 8px; padding-right: 8px;}`;
var styleSheet = document.createElement(`style`);
styleSheet.type = `text/css`;
styleSheet.innerText = styles;
document.head.appendChild(styleSheet);
}
// ************************ RENDERING *************************
function renderUsername(userName, comment, data)
{
if(comment == null)
{
return;
}
let exp = ``;
if(SHOW_EXP)
{
exp = EXP_ICO[data.exp] + ` `;
}
let note = ``;
if(SHOW_NOTE && data.note > 0)
{
note = NOTE_ICO[data.note - 1] + ` `;
let noteEl = comment?.parentElement?.parentElement?.querySelector(`.avatar__note`);
if(noteEl == null || noteEl == undefined)
{
let avatar = comment?.parentElement?.parentElement?.querySelector(`.avatar`);
noteEl = document.createElement(`span`);
noteEl.classList.add(`avatar__note`);
avatar.appendChild(noteEl);
}
// remove prev
for (let i = 0; i < NOTE_COLORS.length; i++)
{
noteEl.classList.toggle(NOTE_COLORS[i]+`_note`, false);
}
noteEl.classList.add(NOTE_COLORS[data.note - 1]+`_note`);
}
if(SHOW_NOTE && data.note == 0)
{
let noteEl = comment?.parentElement?.parentElement?.querySelector(`.avatar__note`);
if(noteEl != null && noteEl != undefined)
{
noteEl.remove();
}
}
let rate = ``;
if(SHOW_RATE)
{
rate = data.rate + ` `;
}
let subs = ``;
if(SHOW_SUBS)
{
subs = SUBS_ICO[data.subs] + ` `;
}
let ban = ``;
if(SHOW_BAN && data.ban > 0)
{
ban = ` `+BAN_ICO[data.ban];
}
let gender = ``;
if(SHOW_GENDER && data.gender > 0)
{
gender = ` `+GENDER_ICO[data.gender];
}
if(comment.childNodes.length > 1)
{
comment.childNodes[2].textContent = exp + note + rate + subs + userName + ban + gender;
}
else
{
comment.textContent = exp + note + rate + subs + userName + ban + gender;
}
}
function renderCommentTools(tools, uid)
{
if(!SHOW_QUICK_NOTE) return;
for (let i = 0; i < NOTE_VALUES.length; i++)
{
let tool = document.createElement(`div`);
tool.classList.add(`comment__tool`);
tool.classList.add(`hint`);
tool.setAttribute(`aria-label`, `Отметить как `+NOTE_VALUES[i]);
tool.setAttribute(`data-note`, i);
tool.setAttribute(`data-uid`, uid);
tool.textContent = NOTE_ICO[i];
tool.addEventListener(`click`, clickQuicknote);
tools.appendChild(tool);
}
}
function renderUserpageTools()
{
if(!SHOW_QUICK_NOTE) return;
let uid = document.querySelector(`.page-profile`).querySelector(`.section-group`).getAttribute(`data-user-id`);
let root = document.querySelector(`.main__inner`);
let panel = document.querySelector(`.feed-panel`);
let tools = document.createElement(`div`);
tools.classList.add(`comment__tools`);
tools.classList.add(`navigator__forced-on`);
tools.classList.add(`userpage-note-tools`);
root.insertBefore(tools, panel);
for (let i = 0; i < NOTE_VALUES.length; i++)
{
let tool = document.createElement(`div`);
tool.classList.add(`comment__tool`);
tool.classList.add(`hint`);
tool.classList.add(`userpage-note-tool`);
tool.setAttribute(`aria-label`, `Отметить как `+NOTE_VALUES[i]);
tool.setAttribute(`data-note`, i);
tool.setAttribute(`data-uid`, uid);
tool.textContent = NOTE_ICO[i];
tool.addEventListener(`click`, clickUserNote);
tools.appendChild(tool);
}
}
function renderNavigatorLoading()
{
let navParent = document.querySelector(`.comments-navigator__scroll`);
if(navParent == null)
{
setTimeout(() => renderNavigatorLoading(), 100);
return;
}
let refresh = navParent.querySelector(`.comments-navigator__refresh`);
let navBase = document.createElement(`div`);
navBase.classList.add(`comments-navigator__controls`);
navBase.classList.add(`navigator__forced-off`);
let navContent = document.createElement(`div`);
navContent.classList.add(`comments-navigator__count`);
navContent.classList.add(`navigator__forced-off`);
navContent.classList.add(`navigator-loading-info`);
navContent.setAttribute(`title`, `Количество загружаемых комментариев`);
navContent.textContent = `0`;
navBase.appendChild(navContent);
navParent?.insertBefore(navBase, refresh);
loadingNavigator = navContent;
renderLoadingOrder();
}
function renderLoadingOrder()
{
if(loadingNavigator == null)
{
return;
}
if(loadingOrder.length > 0 || updateOrder.length > 0 || (loadingComment != null))
{
if(!enableLoadingNavigator)
{
loadingNavigator.classList.add(`navigator__forced-on`);
loadingNavigator.classList.remove(`navigator__forced-off`);
loadingNavigator.parentElement.classList.add(`navigator__forced-on`);
loadingNavigator.parentElement.classList.remove(`navigator__forced-off`);
enableLoadingNavigator = true;
}
if(loadingOrder.length > 0 || updateOrder.length > 0)
{
loadingNavigator.classList.toggle(`navigator-update-info`, (loadingOrder.length == 0));
}
loadingNavigator.textContent = loadingOrder.length + updateOrder.length + (loadingComment != null);
}
else
{
if(enableLoadingNavigator)
{
loadingNavigator.classList.remove(`navigator__forced-on`);
loadingNavigator.classList.add(`navigator__forced-off`);
loadingNavigator.parentElement.classList.remove(`navigator__forced-on`);
loadingNavigator.parentElement.classList.add(`navigator__forced-off`);
enableLoadingNavigator = false;
}
}
}
// ************************ SETTINGS *************************
function renderSettings()
{
var enableUISection = false;
let header = document.querySelector(`.feed-panel`).querySelector(`.menu`);
let items = [];
header.querySelectorAll(`.menu__item`).forEach(item => {
items.push(item);
item.addEventListener(`click`, (e) => {
if(enableUISection)
{
settingItem.classList.toggle(`menu__item_current`, false);
settings?.remove();
if(settingsOld != null)
{
settingsContainer.appendChild(settingsOld);
setTimeout(() => e.target.classList.toggle(`menu__item_current`, true), 100);
}
enableUISection= false;
}
});
});
var settingsContainer = document.querySelector(`.settings`);
var settings;
var settingsOld;
let settingItem = document.createElement(`a`);
settingItem.classList.add(`menu__item`);
settingItem.classList.add(`menu__item_route`);
settingItem.textContent = `UI++`;
header.appendChild(settingItem);
settingItem.addEventListener(`click`, () => {
enableUISection = true;
items.forEach(item => {item.classList.toggle(`menu__item_current`, false);});
settingItem.classList.toggle(`menu__item_current`, true);
settingsOld = settingsContainer.querySelector(`.settings-main`)
|| settingsContainer.querySelector(`.settings-security`)
|| settingsContainer.querySelector(`.settings-save`)
|| settingsContainer.querySelector(`.settings-notifications`);
settingsOld?.remove();
settings = document.createElement(`div`);
settings.classList.add(`settings-main`);
settingsContainer.appendChild(settings);
let sectionGroup = document.createElement(`div`);
sectionGroup.classList.add(`section-group`);
settings.appendChild(sectionGroup);
let sectionHeader = document.createElement(`section`);
sectionHeader.classList.add(`section_gray`);
sectionGroup.appendChild(sectionHeader);
let h = document.createElement(`h4`);
h.textContent = `Настройки сторонего скрипта Pikabu UI++`;
sectionHeader.appendChild(h);
let sectionBody = document.createElement(`section`);
//sectionBody.classList.add(`section`);
sectionBody.classList.add(`section_padding_none`);
sectionGroup.appendChild(sectionBody);
let options = document.createElement(`div`);
options.classList.add(`settings-main__options`);
sectionBody.appendChild(options);
const addLine = tittle => {
let line = document.createElement(`h4`);
line.classList.add(`settings-main__sub-header`);
line.textContent = tittle;
options.appendChild(line);
};
const addCheckbox = (tittle, current, name, desc) => {
let op = document.createElement(`div`);
op.classList.add(`settings-main__option`);
options.appendChild(op);
let l = document.createElement(`label`);
op.appendChild(l);
let checkbox = document.createElement(`span`);
checkbox.classList.add(`checkbox`);
checkbox.classList.add(`checkbox_switch`);
checkbox.classList.toggle(`checkbox_checked`, current);
checkbox.setAttribute(`tabindex`, `0`);
checkbox.setAttribute(`unselectable`, `on`);
l.appendChild(checkbox);
var test = false;
checkbox.addEventListener(`click`, () => {
let value = !GM_getValue(name, 1);
GM_setValue(name, value);
checkbox.classList.toggle(`checkbox_checked`, value);
});
l.insertAdjacentHTML(`beforeend`, tittle);
if(desc != undefined) l.insertAdjacentHTML(`beforeend`,`<i class="fa fa-question-circle hint" aria-label="`+desc+`"></i>`);
};
addLine(`Дополнительная информация о пользователе`);
addCheckbox(`Показывать маркер даты регистрации `, SHOW_EXP, `SHOW_EXP`, `❊ - Менее месяца<br>• - 1 год<br>︿ - Более 1 года<br>︽ - Более `+EXP_VALUES[0]+` лет<br>⁂ - Более `+EXP_VALUES[1]+` лет<br>★ - Более `+EXP_VALUES[2]+` лет`);
addCheckbox(`Показывать маркер умной заметки `, SHOW_NOTE, `SHOW_NOTE`, `Оставьте в заметке пользователя один из хэштегов (#добро, #интересно, #агрессивный, #неприемлемый), чтобы показывать специальный маркер, а также изменить цвет заметки`);
addCheckbox(`Показывать маркер рейтинга `, SHOW_RATE, `SHOW_RATE`);
addCheckbox(`Показывать маркер подписчиков `, SHOW_SUBS, `SHOW_SUBS`, `◔ - Более `+SUBS_VALUES[0]+` подписчиков<br>◑ - Более `+SUBS_VALUES[1]+` подписчиков<br>◕ - Более `+SUBS_VALUES[2]+` подписчиков<br>◉ - Более `+SUBS_VALUES[3]+` подписчиков`);
addCheckbox(`Показывать маркер бана `, SHOW_BAN, `SHOW_BAN`, `ϟ - Временныый бан<br>† - Вечный бан` );
addCheckbox(`Показывать маркер пола `, SHOW_GENDER, `SHOW_GENDER`, `♂ - Пикабушник<br>♀ - Пикабушница` );
addLine(`Умные заметки`);
addCheckbox(`Показывать кнопки быстрого добавления умной заметки `, SHOW_QUICK_NOTE, `SHOW_QUICK_NOTE`, `Рядом с комментариями и на странице пользователя будут кнопки для быстрого добавления заметки с хэштегом. Кнопки рядом с комментариями также сохраняют ссылку на комментарий.<br>ОСТОРОЖНО: При добавлении хэтега через кнопку, предыдущая заметка полностью удаляется.` );
let sectionBottom = document.createElement(`section`);
sectionBottom.classList.add(`section_gray`);
sectionBottom.classList.add(`section_center`);
sectionGroup.appendChild(sectionBottom);
let buttonClear = document.createElement(`button`);
buttonClear.classList.add(`button_danger`);
buttonClear.textContent = `УДАЛИТЬ КЭШИРОВАННЫЕ ДАННЫЕ`;
sectionBottom.appendChild(buttonClear);
buttonClear.addEventListener(`click`, () => {
GM_setValue(DATABASE, {});
});
});
}
})();