vkch

%%добавляет поддержку разметки вакабы&макабы вконтакте%%

目前為 2015-06-22 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         vkch
// @icon         https://2ch.hk/favicon.ico
// @namespace    vkch
// @version      0.5.2
// @description  %%добавляет поддержку разметки вакабы&макабы вконтакте%%
// @author       .dmitry
// @include      *://vk.com/*
// @require      http://code.jquery.com/jquery-latest.min.js
// @require      https://greasyfork.org/scripts/386-waituntilexists/code/waitUntilExists.js?version=5026
// @encoding     UTF-8
// @license      GPL
// ==/UserScript==

// extend jQuery with my method .vkchWhenUpdated
(
	function( $ )
	{ 
		// wait until the main object will exists, parse all it childs for makaba&wakaba markup and bind on it's modification markup parser
		$.fn.vkchWhenUpdated = function( childAreasQuery )
		{
			function vkchPWNED( )
			{
				var $this = $( this );
				function vkchChildAreas( )
				{
					var childAreas = $this.find( childAreasQuery ).not( ".vkchPWNED" );
					
					childAreas.addClass( "vkchPWNED" );
					vkchPOWER( childAreas );
					vkchRainbow( childAreas );
				}
				$this.bind( "DOMNodeInserted", vkchChildAreas );
				vkchChildAreas( );
			}

			var $this = $( this.selector );
			$this.not( ".vkchPWNED" ).addClass( "vkchPWNED" )
			                         .each( vkchPWNED )
			                         ;

			// observer
			if( window.vkchWhenUpdatedIntervals == undefined || window.vkchWhenUpdatedIntervals[this.selector] == undefined )
			{
				window.vkchWhenUpdatedIntervals = window.vkchWhenUpdatedIntervals || [];
				window.vkchWhenUpdatedIntervals[this.selector] = setInterval( function (){ $this.vkchWhenUpdated( childAreasQuery ); }, 500 );
			}

			return $this;
		};
	}
	( jQuery )
);

function vkchPOWER( $htmlCollection )
{
	var rules =
	[
		// code
		{ rule: /``(.+?)``/gm, replacement: "<code style='display: inline-block; border: 1px solid #2b587a; max-width: 100%; overflow: auto; padding: calc( 1ex ); white-space: nowrap'>$1</code>" },
		// spoiler
		{ rule: /%%(.+?)%%/gm, replacement: "<span style='padding: 1px 0px; background-color: #edf1f5; color: #edf1f5 !important; cursor: text' onmouseover='this.style.setProperty( \"color\", \"black\", \"important\" )' onmouseout='this.style.setProperty( \"color\", \"#edf1f5\", \"important\" )'>$1</span>" },
		{ rule: /\[spoiler\](.+?)\[\/spoiler\]/gim, replacement: "<span style='padding: 1px 0px; background-color: #edf1f5; color: #edf1f5 !important; cursor: text' onmouseover='this.style.setProperty( \"color\", \"black\", \"important\" )' onmouseout='this.style.setProperty( \"color\", \"#edf1f5\", \"important\" )'>$1</span>" },
		// quote
		{ rule: /(^|\<br[^\>]*\>)\&gt\;(.*?)(?=\<br[^\>]*\>|$)/gim, replacement: "$1<span style='color: darkgreen !important'>&gt;$2</span>" },
		// unmarked list
		{ rule: /(^|\<br[^\>]*\>)(?:\*)\s(.*?)(?=\<br[^\>]*\>|$)/gim, replacement: "$1<li style='margin-top: 0 !important; margin-left: calc( 1em ) !important'>$2" },
		// boldness
		{ rule: /\*\*(.+?)\*\*/gm, replacement: "<span style='font-weight: bold'>$1</span>" },
		{ rule: /\[b\](.+?)\[\/b\]/gim, replacement: "<span style='font-weight: bold'>$1</span>" },
		// italic
		{ rule: /\*(.+?)\*/gm, replacement: "<span style='font-style: italic'>$1</span>" },
		{ rule: /\[i\](.+?)\[\/i\]/gim, replacement: "<span style='font-style: italic'>$1</span>" },
		// underline
		{ rule: /__(.+?)__/gm, replacement: "<span style='text-decoration: underline'>$1</span>" },
		{ rule: /\[u\](.+?)\[\/u\]/gim, replacement: "<span style='text-decoration: underline'>$1</span>" },
		// strike
		{ rule: /\[s\](.+?)\[\/s\]/gim, replacement: "<s>$1</s>" },
		// overline
		{ rule: /\[o\](.+?)\[\/o\]/gim, replacement: "<span style='text-decoration: overline'>$1</span>" },
		// sup
		{ rule: /\[sup\](.+?)\[\/sup\]/gim, replacement: "<sup>$1</sup>" },
		// sub
		{ rule: /\[sub\](.+?)\[\/sub\]/gim, replacement: "<sub>$1</sub>" },
	];
	for( var id = 0; id < $htmlCollection.length; id ++ )
	{
		var htmlObject = $htmlCollection[id];
		for( var i = 0; i < rules.length; i ++ )
		{
			if( rules[i].rule.test( htmlObject.innerHTML ) == true )
			{
				htmlObject.innerHTML = htmlObject.innerHTML.replace( rules[i].rule, rules[i].replacement );
			}
		}
	}
}

function vkchRainbow( $htmlCollection )
{
	var rules = [ { rule: /vkch/gi, replacement: "VKCH" } ];
	if( typeof window.localStorage['vkchSettingsRainbowRules'] == "string" )
	{
		rules = window.localStorage['vkchSettingsRainbowRules'].split( ";" );
		for( var id = 0; id < rules.length; id ++ )
		{
			rules[id] = rules[id].match( /([^=]+)=(.*)/ );
			rules[id] = { rule: new RegExp( rules[id][1], "gi" ), replacement: rules[id][2] };
		}
	}
	
	for( var id = 0; id < $htmlCollection.length; id ++ )
	{
		var htmlObject = $htmlCollection[id];
		for( var i = 0; i < rules.length; i ++ )
		{
			if( rules[i].rule.test( htmlObject.innerHTML ) == true )
			{
				if( rules[i].replacement.indexOf( "<" ) == -1 ) // for regular rainbow text
				{
					var backgroundColor = Math.floor( Math.random( ) * 255 ) + ", " + Math.floor( Math.random( ) * 255 ) + ", " + Math.floor( Math.random( ) * 255 );
					var textColor = Math.floor( 255 - Math.random( ) * 255 ) + ", " + Math.floor( 255 - Math.random( ) * 255 ) + ", " + Math.floor( 255 - Math.random( ) * 255 );
					htmlObject.innerHTML = htmlObject.innerHTML.replace( rules[i].rule, "<span style='padding: 1px !important; background-color: rgb( " + backgroundColor + " ) !important; color: rgb( " + textColor + " ) !important'>" + rules[i].replacement.toUpperCase( ) + "</span>" );
				}
				else // for html hacks - smiles, whatever
				{
					htmlObject.innerHTML = htmlObject.innerHTML.replace( rules[i].rule, rules[i].replacement );
				}
			}
		}
	}
}

/* Instant Messages begings here */
$( "#im_content" ).vkchWhenUpdated( ".im_msg_text" ); // My Messages
$( ".fc_tab_log_msgs" ).vkchWhenUpdated( ".fc_msg" ); // Messages Widget
/* Instant Messages ends here */

/* Wall Posts and Comments begins here */
$( "#page_wall_posts" ).vkchWhenUpdated( ".wall_post_text" ); // Wall Posts
$( "#feed_rows" ).vkchWhenUpdated( ".wall_post_text" ); // Wall Posts in Feed
$( "#wl_post" ).vkchWhenUpdated( ".wall_post_text" ); // Extended Wall Post
$( ".im_msg_media" ).vkchWhenUpdated( ".wall_post_text" ); // Wall Post in Instant Messenger
$( ".replies_wrap" ).vkchWhenUpdated( ".wall_reply_text" ); // Wall Comments
$( ".reply_dived" ).vkchWhenUpdated( ".wall_reply_text" ); // Extended Posts Comments
/* Wall Posts and Comments ends here */

function vkchSettingsSaveRainbowRules( )
{
	window.localStorage['vkchSettingsRainbowRules'] = $( "#vkchSettingsRainbowRules" ).val( );
	$( "#vkchSettingsRainbowRulesLabel" ).html( "Изменения сохранены" )
	                                     .animate( { opacity: 0 }, 1500, "linear", function(){ $( this ).html( "Список правил:" ).css( "opacity", "1" ); } )
	                                     ;
}
function vkchSettingsInjectTemplate( )
{
	$injectArea = $( $( "#settings_panel #cposts" ) );
	if( $injectArea.length > 0 )
	{
		// vkchRainbow
		var vkchRainbowRules = window.localStorage['vkchSettingsRainbowRules'] || "vkch=VKCH;";
		var template =
		"<div id=\"vkchSettingsRainbow\" class=\"settings_section\">" +
			"<h2>Настройки автозамены</h2>" +
			"<div class=\"settings_row_wrap clear_fix\">" +
				"<div id=\"vkchSettingsRainbowRulesLabel\"class=\"settings_label fl_l ta_r\">Список правил:</div>" +
				"<div class=\"settings_labeled fl_l\">" +
					"<input type=\"text\" value=\"" + vkchRainbowRules + "\" class=\"text\" id=\"vkchSettingsRainbowRules\" style=\"width: 218px\" onmouseover=\"showTooltip(this, { shift: [ -25, 3, 3 ], text: 'Правила автозамены позволяют заменять любые слова на цветной текст БОЛЬШИМИ БУКВАМИ, как на Дваче.<br/ ><br />Для того чтобы добавить слово в правило, достаточно вписать его в это текстовое поле после других слов. Формат записи: совас=КЕПЧУК;<br />Точка с запятой в конце каждого правила обязательны, разделитель между словами - символ =', slide: 15, className: 'settings_about_tt', hasover: 1 } )\">" +
				"</div>" +
			"</div>" +
			"<div class=\"settings_row_button_wrap clear_fix\">" +
				"<button id=\"vkchSettingsSaveRainbowRules\" class=\"flat_button fl_l\">Сохранить правила</button>" +
			"</div>" +
		"</div>";
		$injectArea.after( template );
		$( "#vkchSettingsSaveRainbowRules" ).bind( "click", vkchSettingsSaveRainbowRules );
	}
}
$( "#settings_panel" ).waitUntilExists( vkchSettingsInjectTemplate );