MRAS Mobile Reactor advanced script

Представься, мразь! (с)

// ==UserScript==
// @name        MRAS Mobile Reactor advanced script
// @description Представься, мразь! (с)
// @author      Rus-Ivan
// @namespace   m.joyreactor.cc
// @version     1.3.1
// @include     *://m.joyreactor.cc/*
// @include     *://m.reactor.cc/*
// @require     https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
// @grant       GM_xmlhttpRequest
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM.xmlHttpRequest
// @grant       GM.getValue
// @grant       GM.setValue
// @grant       unsafeWindow
// @connect     m.joyreactor.cc
// @connect     joyreactor.cc
// @connect     reactor.cc
// @icon        http://joyreactor.cc/favicon.ico
// @run-at      document-end
// @license     MIT
// @copyright   2018, Rus-Ivan (https://github.com/Rus-Ivan)
// ==/UserScript==

/*
========================
 Для чего?
 Облегчает просмотр постов на m.joyreactor.cc
 Часто сижу на m.joyreactor.cc и приходится
 1. открывать пост, чтобы
	+ посмотреть гифку
	+ почитать комментарии
 2. открывать пост на основном хосте, чтобы
	+ добавить в избранное
	+ оценить комментарий
========================
 Что делает этот скрипт?
 1. при нажатии на кнопку/ссылку "Комментарии":
	+ открывает комментарии
	+ делает картинки/гифки/гиф-видео кликабельными (прим., чтобы загрузить гифки/гиф-видео, кликните на постер)
	+ показывает панель управления гиф-видео
 2. есть кнопка "Добавить в избранное"
 3. возможность оценивать комментарии
 ========================
 Дополнительные плюшки:
 1. убирает редиректы с ссылок
 2. сохраняет избранные посты в базе данных
 ========================
 P.S. Этот скрипт я писал чисто для личного пользования,
 если людям он покажется полезным, то могу добавить в него
 какие-нибудь дополнительные плюшки
*/
function consoleLog(){window['console']['log'].apply(this, arguments);}
consoleLog("====== start " + GM.info.script.name + " v" + GM.info.script.version + "\n" + GM.info.script.description);
var DEBUG = false;
var FAVKEY = 'favorite-key';
(async function(){
	'use strict';
	try{
	var uWindow = unsafeWindow;
	consoleLog("window: ", uWindow);
	var userFavorite = await GM.getValue( FAVKEY, "[]" );
	userFavorite = JSON.parse(userFavorite);
	var syncInProgress = false;
	startSync();
	removeRedirect();
	makeVotableComments();
	activateComments();
	activateFavorite();
	addNewStyle();
	consoleLog("======== end " + GM.info.script.name + " v" + GM.info.script.version);
	function startSync()
	{
		var html = '<div class="user-info-content" style="margin: 5px;">' +
		'<div id="user_id">user_id := ' + uWindow.user_id + '</div>' + 
		'<div id="token">token := ' + uWindow.token + '</div>' +
		'<div id="sync_fav">favorite sync</div></div>';
		makePopup({
			html: html,
			attr: {
				id: 'user-info',
				'class': 'popup-window',
			},
			'next': {
				html: '<div><span style="padding: 0 2px;"><<</span></div>',
				attr: {
					id: 'user-info-button',
					'class': 'popup-window',
				},
				'event': {
					type: 'click',
					handler: function(event){
						this.style.display = 'none';
					},
				},
				'next': {
					attr: {
						id: 'user-info',
					},
				},
			},
			'event': {
				type: 'click',
				handler: function(event){
					var t = event.target,
						that = this;
					that.style.zIndex = 15;
					setTimeout(function(){that.style.display = 'none';}, 200);
					if(t.id == 'sync_fav' )
						syncFavorite();
				},
			},
		});
		syncFavorite();
	}
	async function syncFavorite()
	{
		try{
		if( syncInProgress )
			return;
		var user_name = uWindow.user_name || getUserName();
		consoleLog("user_name: ", user_name);
		if( !user_name )
			return;
		var url = 'http://joyreactor.cc/user/' + user_name + '/favorite',
			el = $('#sync_fav');
		var lastPage = await GM.getValue('sync-favorite', -1);
		lastPage = parseInt(lastPage, 10);
		if( lastPage > 0 )
			url += '/' + lastPage;
		el.setAttribute('data-last-page', lastPage);
		el.setAttribute('title', url);
		el.setAttribute('data-user-favorite', url);
		el.setAttribute('data-user-name', user_name);
		el.innerHTML = 'favorite sync: ' + user_name + ' [' + lastPage + ']';
		uWindow.user_name = user_name;
		var syncComplete = await GM.getValue('sync-complete', false);
		el.addEventListener('click', function(event){
			if( event.ctrlKey )
				window.open(this.getAttribute('data-user-favorite'));
		}, false);
		if( syncComplete )
		{
			el.parentNode.click();
			return;
		}
		syncInProgress = true;
		GM.xmlHttpRequest({
			url: url,
			method: 'GET',
			Referer: 'http://joyreactor.cc',
			context: {'url': url, count: 1, maxCount: 20},
			onload: ajaxFavorite,
		});
		}catch(e){console.error(e);}
	}
	async function ajaxFavorite(xhr)
	{
		try{
		if( xhr.status != 200 )
		{
			console.error("Error: xhr.status = ", xhr.status, xhr.statusText);
			console.error("xhr: ", xhr);
			return;
		}
		var doc = document.implementation.createHTMLDocument(""),
			cntx = xhr.context, res;
		doc.documentElement.innerHTML = xhr.response;
		res = addPostsToFavorite(doc);
		saveFavoriteStorage();
		var page = getLocation(cntx.url, 'pathname').match(/\/[^\/]*$/)[0],
			next_url = null;
		page = /\d+/.test(page) ? parseInt(page.match(/\d+/)[0], 10) : -1;
		consoleLog("--------------");
		consoleLog("favorite page: ", page);
		consoleLog("iter: ", cntx.count, "/", cntx.maxCount);
		consoleLog("added: ", res);
		var sync_fav = $('#sync_fav'),
			usr_name = sync_fav.getAttribute('data-user-name');
		sync_fav.innerHTML = 'favorite sync: ' + usr_name + ' [' + page + ']';
		if( page > 0 )
			await GM.setValue('sync-favorite', page);
		next_url = $('.next', doc);
		if( (res == 0 && page == 1) || cntx.count >= cntx.maxCount || !next_url )
		{
			if( page == 1 && res == 0 )
			{
				sync_fav.click();
				GM.setValue('sync-complete', true);
			}
			syncInProgress = false;
			return;
		}
		next_url = 'http://joyreactor.cc' + next_url.pathname;
		setTimeout(function(){
			GM.xmlHttpRequest({
				url: next_url,
				method: 'GET',
				Referer: 'http://joyreactor.cc',
				context: {url: next_url, count: cntx.count + 1, maxCount: cntx.maxCount},
				onload: ajaxFavorite,
			});
		}, 2000 + getRandom(500, 1000) + getRandom(500, 900));
		}catch(e){console.error(e);}
	}
	function getRandom( min, max )
	{
		return Math.floor(Math.random() * (max - min) + min);
	}
	function addPostsToFavorite(doc)
	{
		doc = doc || document;
		var posts = $$('.postContainer', doc), count = 0;
		for( var i = 0, post_id; i < posts.length; ++i )
		{
			post_id = posts[i].id.slice(13);
			if( !isFavorite(post_id) )
			{
				++count;
				addToFavoriteStorage(post_id);
			}
		}
		return count;
	}
	function getUserName()
	{
		var spans = $$('span');
		for( var i = 0, len = spans.length, span; i < len; ++i )
		{
			span = spans[i];
			if( span.innerHTML.toString().indexOf('Привет') != -1 )
				return span.innerHTML.replace(/Привет\,/i, '').trim().replace(/\s/g, '+');
		}
		return null;
	}
	function removeRedirect( doc )
	{
		var links = $$('a', doc), link;
		consoleLog("links.length := ", links.length);
		for( var i = 0, len = links.length; i < len; ++i )
		{
			link = links[i];
			if( link['hostname'].indexOf('reactor') != -1 && link['pathname'].indexOf('redirect') != -1 )
				link.href = decodeURIComponent(link.search.slice(5));
		}
	}
	function makeVotableComments( doc )
	{
		var commentList = $$('.comment_rating'),
			voteHTML = '<div class="vote-plus" title="голосовать за"></div><div class="vote-minus" title="голосовать против"></div>';
		consoleLog("commentList.length := ", commentList.length);
		for( var i = 0, len = commentList.length, commentRating; i < len; ++i )
		{
			commentRating = commentList[i];
			if( !commentRating.querySelector('.vote-plus') )
				commentRating.innerHTML += voteHTML;
			if( !commentRating.classList.contains('comment-vote-active') )
			{
				commentRating.addEventListener('click', handleCommentVoteEvent, false);
				commentRating.classList.add('comment-vote-active');
			}
		}
	}
	function handleCommentVoteEvent(event)
	{
		var t = event.target, act;
		if( t.classList.contains('vote-plus') )
			act = 'plus';
		else if( t.classList.contains('vote-minus') )
			act = 'minus';
		if( !act )
			return;
		var commentId = t.parentNode.getAttribute('comment_id'),
			data = 'token=' + uWindow.token;
		GM.xmlHttpRequest({
			url: 'http://joyreactor.cc/comment_vote/add/' + commentId + '/' + act + '?' + data,
			method: 'GET',
			context: {'commentId': commentId, 'act': act},
			headers: {
				'X-Requested-With': 'XMLHttpRequest',
				'Referer': 'http://joyreactor.cc' + window.location.pathname,
			},
			onload: function(xhr){
				try{
				var cntx = xhr.context,
					regEx =	/\-?\d+(\.\d+)?/,
					commentR = $('[comment_id="' + cntx.commentId + '"]'),
					html = commentR.innerHTML,
					voteChangeAct = (cntx.act == 'plus' ? 'minus': 'plus');
				commentR.innerHTML = html.replace( regEx, xhr.responseText.match(regEx)[0] );
				if( !$('.vote-change', commentR) )
					$('.vote-' + voteChangeAct, commentR).classList.add('vote-change');
				if( DEBUG )
				{
					consoleLog("comment vote [" + act + "]");
					consoleLog("xhr.status: ", xhr.status, xhr.statusText);
					consoleLog("xhr.response: ", xhr.response);
				}
				}catch(e){console.error(e);}
			},
		});
	}
	function activateFavorite()
	{
		// начало создания кнопки "Добавить в избранное"
		var postList = $$('.postContainer');
		consoleLog("postList.length := ", postList.length);
		for( var i = 0, len = postList.length; i < len; ++i )
			makeFavorite( postList[i] );
	}
	function makeFavorite( postContainer )
	{
		var postId, postRating, fav;
		postRating = $('.post_rating', postContainer);
		if( !postRating )
			return;
		postId = postContainer.id.match(/\d+/)[0];
		fav = document.createElement('div');
		fav.setAttribute('class', 'favorite_link');
		fav.setAttribute('data-post-id', postId);
		fav.setAttribute('title', 'Добавить в избранное');
		postRating.parentNode.insertBefore( fav, postRating );
		fav.addEventListener('click', handleFavoriteEvent, false);
		//consoleLog("post_rating: ", postRating, postRating.innerHTML.toString().trim());
		if( isFavorite(postId) )
			fav.classList.add('favorite');
	}
	function handleFavoriteEvent(event)
	{
		var t = this,
			token = uWindow.token,
			data = 'token=' + token + '&rand=' + Math.floor(1e4*Math.random()),
			postId = t.getAttribute('data-post-id'),
			act = 'create', url;
		if( t.classList.contains('favorite') )
			act = 'delete';
		url = 'http://joyreactor.cc/favorite/' + act + '/' + postId + '?' + data;
		// отправка xml-http запроса на создание/удаление [из] избранного
		GM.xmlHttpRequest({
			url: url,
			method: 'GET',
			context: {'t': t, 'token': token, 'data': data, 'act': act, 'postId': postId, 'url': url},
			headers: {
				'X-Requested-With': 'XMLHttpRequest',
				'Referer': 'http://joyreactor.cc/post/' + postId,
			},
			onload: function(xhr){
				var cntx = xhr.context;
				if( cntx.t.classList.contains('favorite') )
				{
					cntx.t.classList.remove('favorite');
					cntx.t.setAttribute('title', 'Добавить в избранное');
					removeFromFavoriteStorage(cntx.postId);
				}else{
					cntx.t.classList.add('favorite');
					cntx.t.setAttribute('title', 'Удалить из избранного');
					addToFavoriteStorage(cntx.postId);
				}
				saveFavoriteStorage();
				if( DEBUG )
				{
					consoleLog("-------------");
					consoleLog("favorite[" + cntx.act + "] post-id: ", cntx.postId);
					consoleLog("xhr.status  : ", xhr.status, xhr.statusText);
					consoleLog("xhr.response: ", xhr.response);
					consoleLog("token: ", cntx.token);
					consoleLog("data : ", cntx.data);
					consoleLog("url  : ", cntx.url);
				}
			},
		});
	}
	function activateComments()
	{
		// начало создания кнопки "Комментарии"
		var links = $$('.article .comments > a');
		for( var i = 0, len = links.length; i < len; ++i )
			links[i].addEventListener('click', handleCommentListEvent, false);
	}
	function handleCommentListEvent(event)
	{
		try{
		// если зажать Ctrl, то ссылка откроется как обычно (в новом окне)
		if( event.ctrlKey )
			return;
		// простой click на ссылку
		event.preventDefault();
		var t = event.target, ufoot, commentList;
		if( t.tagName !== 'A' )
		{
			console.error("[handleCommentListEvent] invalid link: ", t);
			return;
		}
		ufoot = t.parentNode.parentNode;
		commentList = $('.comment_list_post', ufoot);
		if( commentList && t.classList.contains('comment-list-opened') )
		{
			// если комментарии были открыты - то скрыть их
			t.classList.remove('comment-list-opened');
			commentList.style.display = 'none';
			return;
		}
		else if( commentList )
		{
			// если комментарии были скрыты (см. выше), то показать их
			commentList.style.display = 'block';
			t.classList.add('comment-list-opened');
		}
		// загружает комментарии, делает картинки кликабельными
		openCommentList( t );
		}catch(e){console.error(e);}
	}
	function openCommentList( link )
	{
		if( !link || link.tagName !== 'A' )
		{
			console.error("[openCommentList] invalid link: ", link);
			return;
		}
		GM.xmlHttpRequest({
			url: link.href,
			method: 'GET',
			context: {
				'link': link, 
			},
			onload: setCommentList,
		});
	}
	function setCommentList( xhr )
	{
		try{
		if( xhr.status != 200 )
		{
			console.error("[setComments] xhr.status: ", xhr.status, xhr.statusText );
			return;
		}
		var doc = document.implementation.createHTMLDocument("");
		doc.documentElement.innerHTML = xhr.response;
		removeRedirect(doc);
		var xhrCommentList = $('.comment_list_post', doc),
			ufoot = xhr.context.link.parentNode.parentNode,
			commentList = $('.comment_list_post', ufoot);
		var xhrImageList = $$('.image', doc),
			imageList = $$('.image', ufoot.parentNode);
		// создает комментарии
		if( commentList )
			commentList.innerHTML = xhrCommentList.innerHTML;
		else
			ufoot.appendChild(xhrCommentList);
		makeVotableComments();
		xhr.context.link.classList.add('comment-list-opened');
		// создает кликабельную картинку в ленте на m.joyreactor.cc
		// если это гифка/гиф-видео, то для ее загрузки нужно кликнуть на постер
		for( var i = 0, xhrImg, img; i < imageList.length && i < xhrImageList.length; ++i )
		{
			xhrImg = xhrImageList[i];
			img = imageList[i];
			if( $('iframe', xhrImg) )
				continue;
			else if( $('.video_gif_holder', xhrImg) )
			{
				// код для гифок/видео-гифок
				$('a.attribute_preview', img).addEventListener('click',
					makeGifImageHandler(xhrImg, img), false);
			}else
				img.innerHTML = xhrImg.innerHTML;
		}
		}catch(err){console.error(err);}
	}
	function makeGifImageHandler( elm, img )
	{
		var video = $('video', elm);
		if( video )
			$('img', img).src = decodeURIComponent(video.getAttribute('poster'));
		function handler(event)
		{
			try{
			if( event.ctrlKey )
				return;
			event.preventDefault();
			if( video )
				video.setAttribute('controls', '');
			this.parentNode.innerHTML = elm.innerHTML;
			}catch(e){console.error(e);}
		}
		return handler;
	}
	async function saveFavoriteStorage()
	{
		GM.setValue( FAVKEY, JSON.stringify(userFavorite) );
	}
	function addToFavoriteStorage( postId )
	{
		if( userFavorite.indexOf(postId) == -1 )
			userFavorite.push(postId);
	}
	function removeFromFavoriteStorage( postId )
	{
		var idx = userFavorite.indexOf(postId);
		if( idx != -1 )
			userFavorite.splice(idx, 1);
	}
	function isFavorite( postId )
	{
		return userFavorite.indexOf(postId) != -1;
	}
	function addStyle( cssClass, id )
	{
		var style = document.createElement('style');
		style.type = 'text/css';
		style.innerHTML = cssClass;
		if( id !== undefined )
			style.setAttribute('id', id);
		var head = document.head || $('head');
		return head.appendChild(style);
	}
	function addNewStyle()
	{
		addGifStyle('video-gif-css');
		addFavoriteStyle('favorite-css');
		addCommentVoteStyle('comment-css');
		//addDarkStyle();
		//addDarkPopupStyle();
		addLightPopupStyle();
	}
	function addGifStyle( id )
	{
		addStyle(`
			.video_gif_source:hover {
				opacity: 1;
			}
			.video_gif_source[href*=".gif"] {
				display: none !important;
			}
			.video_gif_source {
				display: inline-block !important;
				opacity: 0.6;
				background: rgba(204, 204, 204, 0.6);
			}
		`, id );
	}
	function addFavoriteStyle( id )
	{
		var starN = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQfiAR0CNzizynofAAACcklEQVRIx52V30tTcRTAP3e7UKKGb5L0IOZssoEKI3oouUoZaT+g/gFfeglECiJoazub+AOKehCCkGTiW2APgS8heEsRqaA9bDS8KobJ3oS08kHd7WG67Y7uzXnezq/POd9z7v1+wVGkSqqcI1RnN2+AbqcAxbH+eXRAk0/H7SDMGBDm+rE6kABzaiPsLXNJvthFuRzrj4c2QhuME7YPsgXE2uhSRwDUEbpibWUDsmEmQusAoXUmsuEyAbEWuhnOq8N0x1rKAmTDTMpafpxrTNr1ULJGqaKRJnzcwGtxDJGWKCmWWJZfxQ5FTro8WY/iMT148HCaHVYweCfxEnQvN/FwlgoyGBiKYRouI2soksTL0qFJNYI/FNN+aaYyeGavUK6JtCJdvFXuR8YoW6J3zRfcdusr2iJx7af+ubx0ucczbslMTmmXrWh/WdX7ZUvaAdwA+nftA6879vWFI6Y/NCNck/k8APT1zlnzVYeqzx0hPWg+cl2NLOY096F5dqNzxnypVer6f84epd91JZyfmLvgms1o7xnVTugfHdJD9HE58rVgsXzKkiBKj2MDPUQlUWwo/RcaSDkCUjRYDaUAn+IIUFL4nAF+ko4dJPE7AKSGOtURoCapkxr7DvxsBjNFwIBMy7QECpZghk1rDxaA4iscYKBZpphnlVXmZWqguXAIxWcLMA8AUi/x/QTbeKVP+vCyvZ+QuNTnAKY9AL+SHKyVUdJUu1ulN3epyZr0ulupJi2jg7VKyRitV5rP/LP7lAUulj4kT75xRwIM7a6gWxdZ9DI9r9j6zSKPRbffgmgMceFU5YOdf7oHznEEOZjFgfwFS4LW7qbwLDkAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTgtMDEtMjlUMDI6NTU6NTYrMDE6MDB5Men4AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE4LTAxLTI5VDAyOjU1OjU2KzAxOjAwCGxRRAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAASUVORK5CYII=";
		var starF = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAulBMVEUAAAD//wD54Ab//wD54AX54Qb//wD54AX54Ab54AX44gf54AX44AP24wn54QX14AD74gT64AX54Qb54AT54AX54AX54AT54AX/5AD54AX/3wD53wX/2wD54AX/6gD43wX/5gD64AX/4wD54Qb/2wD54Ab63wX64AX64QX63wX54Ab/4wD54AX44AP53wX53wb63wX54AT64QX//wD44AX44AX44AT/3wD64AX53wT54QT/2AD54AUAAAAv4GzOAAAAPHRSTlMAA1oC1lYB01LPTsxKG8kZPWKHrNH1fPMTzhDKDsYMwgq9CbkHtDdjj7rmEtBL2lhp42UEletyCJSyfw1tcXAwAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0SU1FB+IBHBc1JtmiIwAAAAD/SURBVDjLfZLnFoIwDEbrQnGiguJgiFtQcK+8/3PJ8kgi7feryb3ntMkpYziFAhOnWBTzUrlcEgoVgIqIS1WAqiQQahCmJhDkSJD5vA5x6lyhkQgNHm9Cmmb+BK32V2i38CQdpdvrqxpkoqn9XlfpRHQgD4GboTxg+ggEGemMjSd8PhlHl0wNHjemySNNK59b5ncMe5bHZ/ZvUGf+z+dOdhWLJeXLBd6jTgWdLHpFhRUR1lRYE2FDhQ0RtlTYEmFHhR3mbtr29nsvPbpIUOLewQ8/iuQf4kJBQhB2jqdzUpxPx7AMkHCB6+3+K++3KzyQ8Hy98aPeryeqbfaXtPUB5yBig3vwmkMAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTgtMDEtMjhUMjM6NTM6MzgrMDE6MDBw72fcAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE4LTAxLTI4VDIzOjUzOjM4KzAxOjAwAbLfYAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAASUVORK5CYII=";
		addStyle(`
			.favorite_link {
				background: url(${starN});
				cursor: pointer;
				display: inline-block;
				width: 32px;
				height: 32px;
				vertical-align: middle;
				margin: 12px 16px 0 0;
				float: right;
			}
			.post_rating {
				margin-right: 16px;
			}
			.favorite_link:hover {
				background: url(${starF});
				transform: scale(1.4);
			}
			div.favorite {
				background: url(${starF});
			}
			div.favorite:hover {
				background: url(${starN});
				transform: scale(1.4);
			}
		`, id );
	}
	function addCommentVoteStyle( id )
	{
		addStyle(`
			span.comment_rating div.vote-plus {
				background-position: 0 -120px;
			}
			span.comment_rating div.vote-minus {
				background-position: -40px -120px;
			}
			.comment_rating div.vote-plus,
			.comment_rating div.vote-minus {
				width: 30px;
				height: 30px;
				line-height: 30px;
				margin: 0 0 0 3px;
				background: url(http://img0.joyreactor.cc/images/icon_smiles.png) no-repeat 0 -120px;
				cursor: pointer;
				display: inline-block;
				vertical-align: middle;
				/*transform: scale(0.75);*/
			}
			div.vote-change {
				opacity: 0.5;
			}
		`, id);
	}
	function addDarkStyle( id )
	{
		addStyle(`
		a ,
		div.uhead_nick a {
			color: #b1cbf7 !important;
		}
		a:hover ,
		div.uhead_nick a:hover {
			color: #d1ebf7 !important;
		}
		.post_content span {
			color: #d2d2d2 !important;*/
			/*background-color: #626f61 !important;*/
			/*color: #f6f7b9 !important;*/
		}
		.submenuitem a, .article .comments a {
			color: #FAF68C !important;
			/*text-shadow: 0 1px 1px #c04e03 !important;*/
		}
		.taglist a {
			color: #d2d2d2 !important;
		}
		.m_pagination a {
			color: #f8c010 !important;
		}
		.m_pagination a:hover {
			color: #F44336 !important;
		}
		`, id);
	}
	function addDarkPopupStyle( id )
	{
		addStyle(`
		.popup-window {
			position: fixed;
			top: 10px;
			right: 20px;
			background-color: #272727;
			color: #d0d0d0;
			text-align: center;
			z-index: 10;
			font-size: 14px;
			cursor: pointer;
			border-radius: 5px;
			border-color: #d0d0d0;
			border-style: solid;
			border-width: thin;
		}
		`, id);
	}
	function addLightPopupStyle( id )
	{
		addStyle(`
		.popup-window {
			position: fixed;
			top: 10px;
			right: 20px;
			background-color: #d78917;
			color: #faf68c;
			text-shadow: 0 1px 1px #c04e03;
			text-align: center;
			font-size: 14px;
			z-index: 10;
			/*cursor: pointer;*/
			border-radius: 5px;
			border-color: #c04e03;
			border-style: solid;
			border-width: thin;
		}
		.user-info-content {
			margin: 5px;
		}
		#sync_fav ,
		#user-info-button {
			cursor: pointer;
		}
		#sync_fav:hover {
			color: #ffffd6;
		}
		`, id);
	}
	function $( str, doc )
	{
		doc = doc || document;
		return doc.querySelector(str);
	}
	function $$( str, doc )
	{
		doc = doc || document;
		return doc.querySelectorAll(str);
	}
	function makePopup( prop )
	{
		if( !prop )
			return null;
		var wnd = $('#' + prop.attr.id);
		if( wnd )
		{
			wnd.style.display = 'block';
			return wnd;
		}
		wnd = document.createElement('div');
		for( var key in prop.attr )
			wnd.setAttribute( key, prop.attr[key] );
		wnd.innerHTML = prop.html || '';
		$('body').appendChild(wnd);
		var f = prop.event,
			n = prop.next,
			callback = function(event){
				f.handler.call(this, event);
				makePopup(n);
			};
		if( f )
			wnd.addEventListener(f.type, callback, false);
		return wnd;
	}
	function hide( str, doc )
	{
		var el = $(str, doc);
		if( el )
			el.style.display = 'none';
	}
	function show( str, doc )
	{
		var el = $(str, doc);
		if( el )
			el.style.display = 'block';
	}
	function getLocation( href, prop )
	{
		if( !href )
			return null;
		var a = document.createElement('a');
		a.href = href;
		return a[prop];
	}
	}catch(e){console.error(e);}
})();