Avanturist.org forum anchor threads

By eugenga Last update Oct 15, 2008 — Installed 260 times. Daily Installs: 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0

There are 3 previous versions of this script.

// ==UserScript==
// @name		Avanturist.org forum anchor threads
// @description	Save position in each forum topic - later start reading from it (click on topic name in table of content)
// @include  http://www.avanturist.org/forum/index.php
// @include  http://www.avanturist.org/forum/index.php/board*
// @include  http://www.avanturist.org/forum/index.php/topic*
// version 0.22
// ==/UserScript==


// begin 
var avanturistAnchors = new Array(); // в одномерном массиве пары - номерТопика, позицияВНём,......
var isFF = /firefox/.test(navigator.userAgent.toLowerCase());
avanturist_doAction();
// end

function avanturist_doAction(){ // main entry 
  avanturist_loadAllAnchors(); // загрузить позиции по всем темам
  if (document.location.toString().match("topic")) 
	  { avanturist_saveTopicPosition(); } // это заход в тему - запомнить позицию
 else  { avanturist_markIndex(); } // это заход в оглавление - проставить ссылки
} // конец

function avanturist_markIndex(){ // просмотр оглавления форума --> разметить его
var  allTopLinx = $x("//span"); //get all topix linx
for (i=0;i<allTopLinx.snapshotLength;i++)
{	var currTop = allTopLinx.snapshotItem(i);
	// названия тем имеют id=="msg_**"
	if (currTop.id.match('msg_')) {
		var topicLink= $xFirst('.//a',currTop); // первая ссылка с названием темы
		var topicAdress=avanturist_getTopOff_fromLink(topicLink.href);
		var topicNom=topicAdress[0];  // номер топика
		if (topicNom&&topicNom!=''){
			var storedPosition = avanturist_getAnchor(topicNom); // ==0 если не сохранено ранее
			// меняем ссылку на сохранённую позицию
			topicLink.href = "http://www.avanturist.org/forum/index.php/topic,"+topicNom+"."+storedPosition+".html";
			}
		}
} //for
} //end function avanturist_markIndex()

function avanturist_saveTopicPosition(){ // просмотр темы --> сохранить номер последней просмотренной стр.
	var topicAdress = avanturist_getPageAdress(); // получить # топика и смещение
	var topic=topicAdress[0], topicNewPos=topicAdress[1];
	var topicOldPos = avanturist_getAnchor(topic); // сохранённое предыдущее смещение для этого топика
//	alert ('topic # '+topic+'  curren position = '+topicNewPos+'  stored ='+topicOldPos);
	if (topicOldPos<topicNewPos)  // если продвинулись по топику
		{	avanturist_loadAllAnchors(); // на всякий случай, если что-то обновилось в соседнем окне
			avanturist_setAnchor(topic,topicNewPos);
			avanturist_saveAllAnchors();}
} //end function avanturist_saveTopicPosition()

function avanturist_getPageAdress(){ //найти #топика и смещение для текущей страницы
var adress = new Array(0,0); 
// такие сложности, т.к. бывают ссылки без смещения - /topic,31.msg106728.html#msg106728
// которые просто перебрасывают на конец топика, 
// тогда получить смещение из адресной строки невозможно
// получаем смещение из навигационной строки через Ж, т.е. соседние страницы
	var navigationString=$xFirst("//td[@class='middletext']");
	if  (navigationString.childNodes.length==3) 	{return (adress);} 	// всего 1 страница в теме - не запоминать
	for (i=1;i<navigationString.childNodes.length;i++)
	{ if (navigationString.childNodes[i].textContent.match(']'))
			{ 	 if (navigationString.childNodes[i-1].textContent=='1') // если  - это первая страница темы
					{ 	return (adress);	 // не обрабатываю этот случай
					}
				// беру адрес предыдущей страницы  + 20 к смещению
				var pageLink= navigationString.childNodes[i-3];
				adress=avanturist_getTopOff_fromLink(pageLink.href);
				adress[0]=parseInt(adress[0]); adress[1]=parseInt(adress[1])+20; 
				return (adress);
			}
	}
return (adress); // (0,0) 
} // end function avanturist_getPageAdress()

function avanturist_getTopOff_fromLink(linkURL){ // выделить номер топика и оффсет из ссылки
 if (linkURL.match('topic=')) { 
			var lastPart = linkURL.substring(linkURL.indexOf('topic=')+6); 
			var adres=lastPart.split('.'); 
			// alert ('Strange url '+ lastPart + ' result: '+adres);
			}
	else {var splitURL = linkURL.split('/');
			var lastPart=splitURL[splitURL.length-1];
			var adres=lastPart.substring(6,lastPart.length-4).split('.'); 
			}
return (adres); 
}

function avanturist_getAnchor(topicId){ // получить позицию по номеру топика (из массива)
 for (var i=0;i<avanturistAnchors.length; i+=2)
	{ if (avanturistAnchors[i]==topicId) { return avanturistAnchors[i+1];}
	}
 return  0; // не найдено
}

function avanturist_setAnchor(topicId, position){ // установить позицию по номеру топика (в массиве)
 for (var i=0; i<avanturistAnchors.length; i+=2)
	{ 	if (avanturistAnchors[i]==topicId) 	// топик уже в массиве
		{ avanturistAnchors[i+1]=position; return }
	}
 //такого # топика нет в массиве - добавляем новую пару
 avanturistAnchors[i]=topicId;
 avanturistAnchors[i+1]=position;
}

function avanturist_loadAllAnchors(){ // загрузить позиции по всем темам (сохранённые ранее)
	if (isFF) 	{	avanturistAnchors = GM_getValue('avanturistAnchors','0,0').split(','); }
	else 			{	var data = readCookie("avanturistAnchors");  
						if (data==null) {data = '0,0';} else {data = unescape(data);}
						avanturistAnchors = data.split('##');
					}
}

function avanturist_saveAllAnchors(){ // сохранить позиции по всем темам (постоянно)
	if (isFF)	{	GM_setValue('avanturistAnchors',avanturistAnchors.join(','));}
	else 			{	createCookie("avanturistAnchors",escape(avanturistAnchors.join('##')),30); // хранить 30 дней
					}
}

// cookies support
function createCookie(name,value,days) {
	if (days) {		var date = new Date();
						date.setTime(date.getTime()+(days*24*60*60*1000));
						var expires = "; expires="+date.toGMTString();
					}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}
// ------------------ 'macros' ------------------
function $(id) {return document.getElementById(id);}
function $x(xpath, contextNode, resultType) {
	contextNode = contextNode || document.body;
	resultType = resultType || XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE;
	return document.evaluate(xpath, contextNode, null, resultType, null); }
function $xFirst(xpath, contextNode) {
	var xpr = $x(xpath, contextNode, XPathResult.FIRST_ORDERED_NODE_TYPE);
	return xpr.singleNodeValue; }